summaryrefslogtreecommitdiff
path: root/src/database.rs
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.org>2020-06-06 18:58:52 -0400
committerJakob L. Kreuze <zerodaysfordays@sdf.org>2020-06-06 18:58:52 -0400
commit0f0d4477a4eab8ec0b99c134154ce0fedb4d6400 (patch)
tree34b28406cde6489726a65b67bc00e1eea78f018f /src/database.rs
parent52adceb6be36c121d3cfb16e7bf29ec4889dc6ec (diff)
Clean up for release.
Diffstat (limited to 'src/database.rs')
-rw-r--r--src/database.rs107
1 files changed, 62 insertions, 45 deletions
diff --git a/src/database.rs b/src/database.rs
index b83fc9b..14ff853 100644
--- a/src/database.rs
+++ b/src/database.rs
@@ -17,25 +17,79 @@
use anyhow::Result;
use blake2::{Blake2b, Digest};
-use rusqlite::{params, Connection};
+use rusqlite::Connection;
+
+use std::convert::AsRef;
use std::io;
use std::path::Path;
-/// A connection to бирка-тян's tag database.
+/// A connection to the tag database.
#[derive(Debug)]
pub struct TagDatabase(Connection);
/// Tag query with a sense of "state" for pagination.
#[derive(Debug)]
pub struct Query<'a> {
- pub tags: &'a [&'a str],
- pub last_id: Option<i64>,
- pub limit: Option<i64>,
+ tags: &'a [&'a str],
+ last_id: Option<i64>,
+ limit: Option<i64>,
+}
+
+impl<'a> Query<'a> {
+ /// Construct a new query for images tagged with `tags`.
+ ///
+ /// When given to the database, this query will return at most `limit`
+ /// results, if specified, and will return only images newer than `last_id`,
+ /// if specified.
+ pub fn new(tags: &'a [&'a str], last_id: Option<i64>, limit: Option<i64>) -> Self {
+ Query {
+ tags,
+ last_id,
+ limit,
+ }
+ }
+}
+
+/// The result of an image query in бирка-тян's tag database.
+#[derive(Debug)]
+pub struct Image {
+ pub id: i64,
+ pub blake2: String,
+ pub filename: String,
+ pub orig_dir: String,
+}
+
+/// Return a base64-encoded BLAKE2b hash identifying the file at `path`.
+pub fn hash_file(path: &Path) -> Result<String> {
+ let mut file = std::fs::File::open(path)?;
+ let mut hasher = Blake2b::new();
+ io::copy(&mut file, &mut hasher)?;
+ Ok(base64::encode(&hasher.result()))
+}
+
+/// Split the path into a tuple containing the parent directory and the filename.
+pub fn split_path(path: &Path) -> Result<(String, String)> {
+ if path.is_dir() {
+ bail!("`path` does not name a file.");
+ }
+
+ let file_name = path
+ .file_name()
+ .and_then(|os| os.to_str())
+ .ok_or(anyhow!("Couldn't parse file name."))?;
+
+ // Convert `path` to a string and strip off the `file_name` we've just
+ // obtained to yield the name of the parent directory.
+ let path = path.to_str().ok_or(anyhow!("Couldn't parse path."))?;
+ let split_index = path.len() - file_name.len();
+ let parent_directory = &path[0..split_index];
+
+ Ok((file_name.to_string(), parent_directory.to_string()))
}
impl TagDatabase {
/// Instantiate a new `TagDatabase` whose backing database is at `path`.
- pub fn new(path: &str) -> Result<Self> {
+ pub fn new<T: AsRef<Path>>(path: &T) -> Result<Self> {
let tb = TagDatabase(Connection::open(path)?);
tb.initialize_tables()?;
Ok(tb)
@@ -90,29 +144,9 @@ impl TagDatabase {
.query_row(params![tag], |row| Ok(row.get::<_, i64>(0)))??)
}
- /// Split the path into a tuple containing the parent directory and the filename.
- fn split_path(&self, path: &Path) -> Result<(String, String)> {
- if path.is_dir() {
- bail!("`path` does not name a file.");
- }
-
- let file_name = path
- .file_name()
- .and_then(|os| os.to_str())
- .ok_or(anyhow!("Couldn't parse file name."))?;
-
- // Convert `path` to a string and strip off the `file_name` we've just
- // obtained to yield the name of the parent directory.
- let path = path.to_str().ok_or(anyhow!("Couldn't parse path."))?;
- let split_index = path.len() - file_name.len();
- let parent_directory = &path[0..split_index];
-
- Ok((file_name.to_string(), parent_directory.to_string()))
- }
-
/// Insert the image at `path` into the data.
pub fn import_image(&self, path: &Path, hash: &str) -> Result<i64> {
- let (file_name, parent_directory) = self.split_path(path)?;
+ let (file_name, parent_directory) = split_path(path)?;
Ok(self
.0
.prepare("INSERT INTO images (blake2, filename, orig_dir) VALUES(?,?,?)")?
@@ -121,7 +155,7 @@ impl TagDatabase {
/// Return the internal id for the image at `path`.
pub fn image_id(&self, path: &Path) -> Result<i64> {
- let (file_name, path) = self.split_path(path)?;
+ let (file_name, path) = split_path(path)?;
Ok(self
.0
.prepare("SELECT id FROM images WHERE orig_dir = ? AND filename = ?")?
@@ -290,23 +324,6 @@ impl TagDatabase {
}
}
-/// The result of an image query in бирка-тян's tag database.
-#[derive(Debug)]
-pub struct Image {
- pub id: i64,
- pub blake2: String,
- pub filename: String,
- pub orig_dir: String,
-}
-
-/// Return a base64-encoded BLAKE2b hash identifying the file at `path`.
-pub fn hash_file(path: &Path) -> Result<String> {
- let mut file = std::fs::File::open(path)?;
- let mut hasher = Blake2b::new();
- io::copy(&mut file, &mut hasher)?;
- Ok(base64::encode(&hasher.result()))
-}
-
#[cfg(test)]
mod tests {
use super::*;