diff options
| author | jakka <jakkadoujin@gmail.com> | 2025-06-19 11:58:43 +0300 |
|---|---|---|
| committer | jakka <jakkadoujin@gmail.com> | 2025-06-19 11:58:43 +0300 |
| commit | 08021b436704645bdbade03bd70403f60dd594fb (patch) | |
| tree | b3a527bd6f89f2344ea3c9b0156f6a51b116f2a7 | |
| parent | aa95671996bc55f69305505c5da2e715a85da189 (diff) | |
better file path handling, fixed tests
| -rw-r--r-- | Cargo.lock | 30 | ||||
| -rw-r--r-- | src/db.rs | 38 | ||||
| -rw-r--r-- | src/files.rs | 62 | ||||
| -rw-r--r-- | src/main.rs | 4 |
4 files changed, 68 insertions, 66 deletions
@@ -37,7 +37,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.8.25", + "zerocopy 0.8.26", ] [[package]] @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" @@ -971,9 +971,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.173" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libflac-sys" @@ -1400,7 +1400,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.25", + "zerocopy 0.8.26", ] [[package]] @@ -1456,9 +1456,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" @@ -2092,9 +2092,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", @@ -2514,11 +2514,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ - "zerocopy-derive 0.8.25", + "zerocopy-derive 0.8.26", ] [[package]] @@ -2534,9 +2534,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", @@ -3,7 +3,7 @@ use directories::BaseDirs; use futures_util::Stream; use libsql::{Builder, Connection, params}; use std::{ - path::Path, + path::{Path, PathBuf}, time::{Duration, UNIX_EPOCH}, }; @@ -13,6 +13,7 @@ const TABLE_CREATE: &str = "CREATE TABLE IF NOT EXISTS flacs (path TEXT PRIMARY const ADD_NEW_ITEM: &str = "INSERT INTO flacs (path, toencode, modtime) VALUES (?1, ?2, ?3)"; const REPLACE_ITEM: &str = "REPLACE INTO flacs (path, toencode, modtime) VALUES (?1, ?2, ?3)"; const TOENCODE_QUERY: &str = "SELECT path FROM flacs WHERE toencode"; +const TOENCODE_NUMBER: &str = "SELECT COUNT(*) from flacs WHERE toencode"; const CHECK_FILE: &str = "SELECT exists(SELECT 1 FROM flacs WHERE path = ?1)"; const FETCH_MODTIME: &str = "SELECT modtime FROM flacs WHERE path = ?1"; const FETCH_FILES: &str = "SELECT path FROM flacs"; @@ -34,7 +35,8 @@ impl Database { pub async fn insert_file(&self, filename: impl AsRef<Path>) -> Result<()> { let toencode = !matches!(get_vendor(&filename)?.as_str(), CURRENT_VENDOR); - let modtime = filename.as_ref() + let modtime = filename + .as_ref() .metadata()? .modified()? .duration_since(UNIX_EPOCH)? @@ -51,7 +53,8 @@ impl Database { } pub async fn update_file(&self, filename: impl AsRef<Path>) -> Result<()> { - let modtime = filename.as_ref() + let modtime = filename + .as_ref() .metadata()? .modified()? .duration_since(UNIX_EPOCH)? @@ -104,7 +107,7 @@ impl Database { self.0.execute(DEDUPE_DB, ()).await?; let mut query_res = self.0.query(FETCH_FILES, ()).await?; while let Ok(Some(row)) = query_res.next().await { - let path = Path::new(row.get_str(0)?).to_path_buf(); + let path = PathBuf::from(row.get_str(0)?); let conn = self.0.clone(); tasks.spawn(async move { if !path.exists() { @@ -117,7 +120,7 @@ impl Database { tasks.join_all().await; - self.0.execute("VACUUM;", ()).await?; + self.0.execute("VACUUM", ()).await?; Ok(()) } @@ -127,6 +130,17 @@ impl Database { ) -> Result<impl Stream<Item = libsql::Result<libsql::Row>>> { Ok(self.0.query(TOENCODE_QUERY, ()).await?.into_stream()) } + + pub async fn get_toencode_number(&self) -> Result<u64> { + Ok(self + .0 + .query(TOENCODE_NUMBER, ()) + .await? + .next() + .await? + .unwrap() + .get::<u64>(0)?) + } } pub async fn open_default_db() -> Result<Database> { @@ -176,7 +190,9 @@ mod tests { let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"]; let conn = Database::new(&dbname).await.unwrap(); for file in filenames { - let _ = conn.insert_file(&file.to_string()).await; + let _ = conn + .insert_file(Path::new(file).canonicalize().unwrap()) + .await; } let _ = conn @@ -195,7 +211,15 @@ mod tests { ) .await; - conn.update_file(&"16bit.flac".to_string()).await.unwrap(); + conn.update_file( + Path::new("16bit.flac") + .canonicalize() + .unwrap() + .to_str() + .unwrap(), + ) + .await + .unwrap(); let returned = conn .0 diff --git a/src/files.rs b/src/files.rs index 045c5b4..a019cfb 100644 --- a/src/files.rs +++ b/src/files.rs @@ -36,10 +36,11 @@ impl Display for FileError { } } -async fn handle_file(file: PathBuf, conn: Database) -> Result<()> { +async fn handle_file(file: impl AsRef<Path>, conn: Database) -> Result<()> { match conn.check_file(&file).await { Ok(true) => { let modtime = file + .as_ref() .metadata()? .modified()? .duration_since(UNIX_EPOCH)? @@ -105,17 +106,7 @@ pub async fn index_files_recursively(path: impl AsRef<Path>, conn: &Database) -> Ok(()) } -fn check_path(folderpath: Option<&PathBuf>) -> Result<(PathBuf, bool)> { - if let Some(real_path) = folderpath { - Ok((real_path.canonicalize()?, false)) - } else { - Ok((PathBuf::new(), true)) - } -} - -pub async fn reencode_files(folderpath: Option<&PathBuf>, conn: &Database) -> Result<()> { - let (path, nocheck) = check_path(folderpath)?; - +pub async fn reencode_files(conn: &Database) -> Result<()> { let stream = conn.get_toencode_stream().await?; pin_mut!(stream); @@ -126,9 +117,7 @@ pub async fn reencode_files(folderpath: Option<&PathBuf>, conn: &Database) -> Re while let Some(Ok(row)) = stream.next().await { if let Some(file) = row.get_value(0)?.as_text() { let filename = Path::new(file).canonicalize()?; - if nocheck || filename.starts_with(&path) { - tasks.spawn_blocking(move || handle_encode(filename)); - } + tasks.spawn_blocking(move || handle_encode(filename)); } } @@ -158,25 +147,6 @@ pub async fn reencode_files(folderpath: Option<&PathBuf>, conn: &Database) -> Re Ok(()) } -pub async fn count_reencode_files(folderpath: Option<&PathBuf>, conn: &Database) -> Result<u64> { - let (path, nocheck) = check_path(folderpath)?; - - let mut counter: u64 = 0; - let stream = conn.get_toencode_stream().await?; - pin_mut!(stream); - - while let Some(Ok(row)) = stream.next().await { - if let Some(file) = row.get_value(0)?.as_text() { - let filename = Path::new(file).canonicalize()?; - if nocheck || filename.starts_with(&path) { - counter += 1; - } - } - } - - Ok(counter) -} - #[cfg(test)] mod tests { use super::*; @@ -191,15 +161,23 @@ mod tests { std::fs::remove_file("temp3.db").unwrap(); } - #[tokio::test] - async fn test_reencode_lots_of_files() { - let conn = Database::new("temp4.db").await.unwrap(); - let path = PathBuf::from("./testfiles"); - index_files_recursively(Path::new("./testfiles"), &conn) - .await + #[test] + fn test_reencode_lots_of_files() { + let runtime = tokio::runtime::Builder::new_multi_thread() + .max_blocking_threads(4) + .enable_all() + .build() .unwrap(); - println!("\n{}", count_reencode_files(None, &conn).await.unwrap()); - reencode_files(Some(&path), &conn).await.unwrap(); + runtime.block_on(async move { + let conn = Database::new("temp4.db").await.unwrap(); + index_files_recursively(Path::new("./testfiles"), &conn) + .await + .unwrap(); + println!("\n{}", conn.get_toencode_number().await.unwrap()); + reencode_files(&conn).await.unwrap(); + println!("\n{}", conn.get_toencode_number().await.unwrap()); + }); + std::fs::remove_file("temp4.db").unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 5d3835f..da04a9e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,7 +90,7 @@ fn main() -> Result<()> { let path = args.get_one::<PathBuf>("path"); if path.is_none() && !args.get_flag("clean") && !args.get_flag("doit") { - let count = files::count_reencode_files(path, &conn).await.unwrap(); + let count = conn.get_toencode_number().await?; println!("Files to reencode:\t{count}"); } else if let Some(realpath) = path { if !args.get_flag("doit") { @@ -103,7 +103,7 @@ fn main() -> Result<()> { } if args.get_flag("doit") { - files::reencode_files(path, &conn).await?; + files::reencode_files(&conn).await?; } Ok::<(), anyhow::Error>(()) })?; |
