use rusqlite::{Connection, OptionalExtension};
#[derive(Debug, Default, PartialEq)]
pub struct Gathered {
pub dims: Option<(u32, u32)>,
pub location: Option<String>,
}
pub fn gather_for_hash(conn: &Connection, hash: &str) -> rusqlite::Result<Gathered> {
let dims = conn
.query_row(
"SELECT width, height FROM file_hashes
WHERE hash = ?1 AND width IS NOT NULL AND height IS NOT NULL",
[hash],
|r| Ok((r.get::<_, u32>(0)?, r.get::<_, u32>(1)?)),
)
.optional()?;
let location = conn
.query_row(
"SELECT lc.name FROM file_hashes fh
JOIN location_clusters lc ON lc.id = fh.location_cluster_id
WHERE fh.hash = ?1 AND lc.name IS NOT NULL",
[hash],
|r| r.get::<_, String>(0),
)
.optional()?;
Ok(Gathered { dims, location })
}
#[cfg(test)]
mod tests {
use super::*;
use rusqlite::Connection;
fn setup() -> Connection {
let c = Connection::open_in_memory().unwrap();
c.execute_batch(
"CREATE TABLE file_hashes (path TEXT, hash TEXT, ext TEXT, mime TEXT,
width INTEGER, height INTEGER, location_cluster_id INTEGER);
CREATE TABLE location_clusters (id INTEGER PRIMARY KEY, centroid_lat REAL,
centroid_lon REAL, name TEXT, photo_count INTEGER, radius_km REAL, created_at TEXT);
INSERT INTO location_clusters VALUES (7, 41.0, 29.0, 'Kadıköy', 1, 0.5, '');
INSERT INTO file_hashes VALUES ('/p.jpg','h1','jpg','image/jpeg',4000,3000,7);",
)
.unwrap();
c
}
#[test]
fn gathers_dims_and_location() {
let c = setup();
let g = gather_for_hash(&c, "h1").unwrap();
assert_eq!(g.dims, Some((4000, 3000)));
assert_eq!(g.location.as_deref(), Some("Kadıköy"));
}
#[test]
fn missing_data_yields_none_not_error() {
let c = setup();
let g = gather_for_hash(&c, "absent").unwrap();
assert_eq!(g.dims, None);
assert_eq!(g.location, None);
}
}