diff options
| author | jakka <jakkadoujin@gmail.com> | 2025-06-13 15:39:38 +0300 |
|---|---|---|
| committer | jakka <jakkadoujin@gmail.com> | 2025-06-13 15:39:38 +0300 |
| commit | 692ef8fb41a11f24b19beeb4fbbb668130ef5736 (patch) | |
| tree | 2f5be3700f407afc6e0d235da23cabe153a996b3 /src | |
| parent | 743b87fc7aea1aa90cfacee17cdac8ca818c5661 (diff) | |
cleaned up code
Diffstat (limited to 'src')
| -rw-r--r-- | src/db.rs | 91 | ||||
| -rw-r--r-- | src/files.rs | 24 |
2 files changed, 47 insertions, 68 deletions
@@ -33,17 +33,18 @@ impl Display for Errors { } } -pub trait Reencoder { - async fn insert_file(&self, filename: &impl AsRef<OsStr>) -> Result<()>; - async fn update_file(&self, filename: &impl AsRef<OsStr>) -> Result<()>; - async fn get_files_toencode(&self) -> Result<Vec<String>>; - async fn check_file(&self, filename: &impl AsRef<OsStr>) -> Result<bool>; - async fn get_modtime(&self, filename: &impl AsRef<OsStr>) -> Result<u64>; - async fn clean_files(&self) -> Result<()>; -} +#[derive(Debug, Clone)] +pub struct Database(pub Connection); + +impl Database { + pub async fn new(path: impl AsRef<Path>) -> Result<Self> { + let conn = Builder::new_local(path).build().await?.connect()?; + conn.execute(TABLE_CREATE, ()).await?; + + Ok(Database(conn)) + } -impl Reencoder for Connection { - async fn insert_file(&self, filename: &impl AsRef<OsStr>) -> Result<()> { + pub async fn insert_file(&self, filename: &impl AsRef<OsStr>) -> Result<()> { let abs_filename = absolute(Path::new(filename))?; let toencode = !matches!(get_vendor(&abs_filename)?.as_str(), CURRENT_VENDOR); @@ -53,16 +54,17 @@ impl Reencoder for Connection { .duration_since(UNIX_EPOCH)? .as_secs(); - self.execute( - ADD_NEW_ITEM, - params![abs_filename.to_str().unwrap(), toencode, modtime], - ) - .await?; + self.0 + .execute( + ADD_NEW_ITEM, + params![abs_filename.to_str().unwrap(), toencode, modtime], + ) + .await?; Ok(()) } - async fn update_file(&self, filename: &impl AsRef<OsStr>) -> Result<()> { + pub async fn update_file(&self, filename: &impl AsRef<OsStr>) -> Result<()> { let abs_filename = absolute(Path::new(filename))?; let modtime = abs_filename @@ -71,17 +73,18 @@ impl Reencoder for Connection { .duration_since(UNIX_EPOCH)? .as_secs(); - self.execute( - REPLACE_ITEM, - params![abs_filename.to_str().unwrap(), false, modtime], - ) - .await?; + self.0 + .execute( + REPLACE_ITEM, + params![abs_filename.to_str().unwrap(), false, modtime], + ) + .await?; Ok(()) } - async fn get_files_toencode(&self) -> Result<Vec<String>> { - let rows = self.query(TOENCODE_QUERY, ()).await?; + pub async fn get_files_toencode(&self) -> Result<Vec<String>> { + let rows = self.0.query(TOENCODE_QUERY, ()).await?; if rows.column_count() == 0 { return Err(anyhow!(Errors::EmptyQuery)); }; @@ -95,10 +98,11 @@ impl Reencoder for Connection { Ok(filenames) } - async fn check_file(&self, filename: &impl AsRef<OsStr>) -> Result<bool> { + pub async fn check_file(&self, filename: &impl AsRef<OsStr>) -> Result<bool> { let abs_filename = absolute(Path::new(filename))?; if let Some(row) = self + .0 .query(CHECK_FILE, params!(abs_filename.to_str().unwrap())) .await? .next() @@ -110,10 +114,11 @@ impl Reencoder for Connection { } } - async fn get_modtime(&self, filename: &impl AsRef<OsStr>) -> Result<u64> { + pub async fn get_modtime(&self, filename: &impl AsRef<OsStr>) -> Result<u64> { let abs_filename = absolute(Path::new(filename))?; if let Some(row) = self + .0 .query(FETCH_MODTIME, params!(abs_filename.to_str().unwrap())) .await? .next() @@ -129,11 +134,11 @@ impl Reencoder for Connection { } } - async fn clean_files(&self) -> Result<()> { + pub async fn clean_files(&self) -> Result<()> { let mut tasks = tokio::task::JoinSet::new(); - while let Ok(Some(row)) = self.query(FETCH_FILES, ()).await?.next().await { + while let Ok(Some(row)) = self.0.query(FETCH_FILES, ()).await?.next().await { let path = absolute(Path::new(row.get_str(0)?))?; - let conn = self.clone(); + let conn = self.0.clone(); tasks.spawn(async move { if !path.exists() { let _ = conn @@ -149,39 +154,24 @@ impl Reencoder for Connection { } } -pub async fn open_db() -> Result<Connection> { - let conn = if let Some(base_dir) = BaseDirs::new() { +pub async fn open_default_db() -> Result<Database> { + if let Some(base_dir) = BaseDirs::new() { let db_name = Path::new(base_dir.data_dir()).join("reencoder.db"); - Builder::new_local(db_name).build().await?.connect()? + Ok(Database::new(db_name).await?) } else { - return Err(anyhow!("Failed to locate data directory")); - }; - - conn.execute(TABLE_CREATE, ()).await?; - - Ok(conn) + Err(anyhow!("Failed to locate data directory")) + } } #[cfg(test)] mod tests { use super::*; - async fn dummy_db(name: impl AsRef<Path>) -> Connection { - let conn = Builder::new_local(name) - .build() - .await - .unwrap() - .connect() - .unwrap(); - conn.execute(TABLE_CREATE, ()).await.unwrap(); - conn - } - #[tokio::test] async fn check_localfiles() { let dbname = String::from("temp1.db"); let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"]; - let conn = dummy_db(&dbname).await; + let conn = Database::new(&dbname).await.unwrap(); for file in filenames { let _ = conn.insert_file(&file.to_string()).await; } @@ -194,12 +184,13 @@ mod tests { async fn check_update() { let dbname = String::from("temp2.db"); let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"]; - let conn = dummy_db(&dbname).await; + let conn = Database::new(&dbname).await.unwrap(); for file in filenames { let _ = conn.insert_file(&file.to_string()).await; } let _ = conn + .0 .execute( REPLACE_ITEM, params![ diff --git a/src/files.rs b/src/files.rs index df596f8..e0d9757 100644 --- a/src/files.rs +++ b/src/files.rs @@ -7,7 +7,7 @@ use std::{ }; use tokio::{fs::read_dir, task::JoinSet}; -use crate::db::Reencoder; +use crate::db::Database; #[derive(Debug)] struct FileError { @@ -26,7 +26,7 @@ impl Display for FileError { } } -async fn handle_file(file: PathBuf, conn: Connection) -> Result<()> { +async fn handle_file(file: PathBuf, conn: Database) -> Result<()> { match conn.check_file(&file).await { Ok(true) => { let modtime = file @@ -53,7 +53,7 @@ async fn handle_file(file: PathBuf, conn: Connection) -> Result<()> { Ok(()) } -pub async fn index_files_recursively(path: &Path, conn: &Connection) -> Result<()> { +pub async fn index_files_recursively(path: &Path, conn: &Database) -> Result<()> { if !path.is_dir() { return Err(anyhow!("Invalid root directory")); } @@ -96,30 +96,18 @@ pub async fn index_files_recursively(path: &Path, conn: &Connection) -> Result<( #[cfg(test)] mod tests { - use libsql::Builder; - use super::*; - async fn dummy_db(name: impl AsRef<Path>) -> Connection { - let conn = Builder::new_local(name) - .build() - .await - .unwrap() - .connect() - .unwrap(); - conn.execute("CREATE TABLE IF NOT EXISTS flacs (path TEXT PRIMARY KEY, toencode BOOLEAN NOT NULL, modtime INTEGER)", ()).await.unwrap(); - conn - } - #[tokio::test] async fn test_lots_of_files() { - let conn = dummy_db("temp3.db").await; + let conn = Database::new("temp3.db").await.unwrap(); index_files_recursively(Path::new("/mnt/Music"), &conn) .await .unwrap(); println!( "\n{}", - conn.query("SELECT COUNT(DISTINCT path) FROM flacs", ()) + conn.0 + .query("SELECT COUNT(DISTINCT path) FROM flacs", ()) .await .unwrap() .next() |
