diff options
| author | jakka <jakkadoujin@gmail.com> | 2025-07-02 17:34:49 +0300 |
|---|---|---|
| committer | jakka <jakkadoujin@gmail.com> | 2025-07-02 17:34:49 +0300 |
| commit | 28066d49d14516008e2ba1e9cf3dbd01a95aa788 (patch) | |
| tree | 93cde9d7a16f058db816abb255808c2acd5d9c92 | |
| parent | 4477f95a1ac95c248b96a2a824961a8cb1fad3e7 (diff) | |
removed all async code
| -rw-r--r-- | Cargo.lock | 899 | ||||
| -rw-r--r-- | Cargo.toml | 32 | ||||
| -rw-r--r-- | src/db.rs | 280 | ||||
| -rw-r--r-- | src/files.rs | 161 | ||||
| -rw-r--r-- | src/main.rs | 17 |
5 files changed, 438 insertions, 951 deletions
@@ -3,15 +3,6 @@ version = 4 [[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] name = "anstream" version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -68,173 +59,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" -dependencies = [ - "async-lock", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1237c0ae75a0f3765f58910ff9cdd0a12eeb39ab2f4c7de23262f337f0aacbb3" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 1.0.7", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-net" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" -dependencies = [ - "async-io", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-process" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde3f4e40e6021d7acffc90095cbd6dc54cb593903d1de5832f435eb274b85dc" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix 1.0.7", - "tracing", -] - -[[package]] -name = "async-signal" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7605a4e50d4b06df3898d5a70bf5fde51ed9059b0434b73105193bc27acce0d" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 1.0.7", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] -name = "bindgen" -version = "0.66.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", - "which", -] - -[[package]] name = "bitflags" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -250,19 +80,6 @@ dependencies = [ ] [[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] name = "bumpalo" version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -281,15 +98,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -dependencies = [ - "serde", -] - -[[package]] name = "cc" version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -299,15 +107,6 @@ dependencies = [ ] [[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] name = "cfg-if" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -320,17 +119,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] name = "clap" version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -387,15 +175,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] name = "console" version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -498,12 +277,6 @@ dependencies = [ ] [[package]] -name = "easy-parallel" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2afbb9b0aef60e4f0d2b18129b6c0dff035a6f7dbbd17c2f38c1432102ee223c" - -[[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -516,41 +289,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] -name = "errno" -version = "0.3.13" +name = "fallible-iterator" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] -name = "event-listener" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.3.0" +name = "fallible-streaming-iterator" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "flac-bound" @@ -563,7 +311,7 @@ dependencies = [ [[package]] name = "flac-reencoder" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "clap", @@ -572,123 +320,23 @@ dependencies = [ "console 0.15.11", "ctrlc", "directories", - "easy-parallel", "flac-bound", - "futures-util", "i24", "indicatif", - "libsql", - "macro_rules_attribute", "md-5", "metaflac", - "pin-utils", + "r2d2", + "r2d2_sqlite", "rayon", - "smol", - "smol-macros", + "rusqlite", "walkdir", ] [[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" +name = "foldhash" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "generic-array" @@ -708,35 +356,44 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", ] [[package]] -name = "glob" -version = "0.3.2" +name = "getrandom" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] [[package]] -name = "hermit-abi" -version = "0.5.2" +name = "hashbrown" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "foldhash", +] [[package]] -name = "hex" -version = "0.4.3" +name = "hashlink" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown", +] [[package]] -name = "home" -version = "0.5.11" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "i24" @@ -755,7 +412,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4adb2ee6ad319a912210a36e56e3623555817bcc877a7e6e8802d1d69c4d8056" dependencies = [ "console 0.16.0", - "futures-core", "portable-atomic", "unicode-segmentation", "unicode-width", @@ -780,18 +436,6 @@ dependencies = [ ] [[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] name = "libc" version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -808,16 +452,6 @@ dependencies = [ ] [[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - -[[package]] name = "libredox" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -828,80 +462,33 @@ dependencies = [ ] [[package]] -name = "libsql" -version = "0.9.11" +name = "libsqlite3-sys" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41c1c2106d415b8bf929ca6e644e2bc9a44ce5aea9819350276e4d97e27f3b1" +checksum = "91632f3b4fb6bd1d72aa3d78f41ffecfcf2b1a6648d8c241dbe7dbfaf4875e15" dependencies = [ - "async-trait", - "bitflags", - "bytes", - "futures", - "libsql-sys", - "thiserror 1.0.69", - "tracing", -] - -[[package]] -name = "libsql-ffi" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0df681b059a8672691e60232e78967ba821edd37e959f4e9fa8a3de36e9ca29" -dependencies = [ - "bindgen", "cc", - "cmake", - "glob", + "pkg-config", + "vcpkg", ] [[package]] -name = "libsql-sys" -version = "0.9.11" +name = "lock_api" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d1e07a691696cb18c2faba98313a194f0804aa6a1ce8aa9919b7ecd290d458" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ - "bytes", - "libsql-ffi", - "once_cell", - "tracing", - "zerocopy", + "autocfg", + "scopeguard", ] [[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] name = "log" version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] -name = "macro_rules_attribute" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520" -dependencies = [ - "macro_rules_attribute-proc_macro", - "paste", -] - -[[package]] -name = "macro_rules_attribute-proc_macro" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" - -[[package]] name = "md-5" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -912,12 +499,6 @@ dependencies = [ ] [[package]] -name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] name = "metaflac" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -928,12 +509,6 @@ dependencies = [ ] [[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] name = "nix" version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -946,16 +521,6 @@ dependencies = [ ] [[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -983,75 +548,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +name = "parking_lot" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", + "lock_api", + "parking_lot_core", ] [[package]] -name = "polling" -version = "3.8.0" +name = "parking_lot_core" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53a684391ad002dd6a596ceb6c74fd004fdce75f4be2e3f615068abbea5fd50" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 1.0.7", - "tracing", - "windows-sys 0.59.0", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", ] [[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] name = "portable-atomic" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] -name = "prettyplease" -version = "0.2.35" +name = "ppv-lite86" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "proc-macro2", - "syn", + "zerocopy", ] [[package]] @@ -1073,176 +610,157 @@ dependencies = [ ] [[package]] -name = "rayon" -version = "1.10.0" +name = "r-efi" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] -name = "rayon-core" -version = "1.12.1" +name = "r2d2" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "log", + "parking_lot", + "scheduled-thread-pool", ] [[package]] -name = "redox_users" -version = "0.5.0" +name = "r2d2_sqlite" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +checksum = "06cc23a61faf4643d8b59ed52c27ed434476dd7aa6f39e1eff7d6bbd35985093" dependencies = [ - "getrandom", - "libredox", - "thiserror 2.0.12", + "r2d2", + "rusqlite", + "uuid", ] [[package]] -name = "regex" -version = "1.11.1" +name = "rand" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "rand_chacha", + "rand_core", ] [[package]] -name = "regex-automata" -version = "0.4.9" +name = "rand_chacha" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "ppv-lite86", + "rand_core", ] [[package]] -name = "regex-syntax" -version = "0.8.5" +name = "rand_core" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] [[package]] -name = "rustc-hash" -version = "1.1.0" +name = "rayon" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] [[package]] -name = "rustix" -version = "0.38.44" +name = "rayon-core" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] -name = "rustix" -version = "1.0.7" +name = "redox_syscall" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ "bitflags", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", ] [[package]] -name = "same-file" -version = "1.0.6" +name = "redox_users" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "winapi-util", + "getrandom 0.2.16", + "libredox", + "thiserror", ] [[package]] -name = "serde" -version = "1.0.219" +name = "rusqlite" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "3de23c3319433716cf134eed225fe9986bc24f63bed9be9f20c329029e672dc7" dependencies = [ - "serde_derive", + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "rustversion" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] -name = "shlex" -version = "1.3.0" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] [[package]] -name = "signal-hook-registry" -version = "1.4.5" +name = "scheduled-thread-pool" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "libc", + "parking_lot", ] [[package]] -name = "slab" -version = "0.4.10" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "smol" -version = "2.0.2" +name = "shlex" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33bd3e260892199c3ccfc487c88b2da2265080acb316cd920da72fdfd7c599f" -dependencies = [ - "async-channel", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-net", - "async-process", - "blocking", - "futures-lite", -] +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "smol-macros" -version = "0.1.1" +name = "smallvec" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfcaedb62e0475a6898988138995ec7b1e5d116167a72bb12c7b59d0649fbbc2" -dependencies = [ - "async-executor", - "async-io", - "async-lock", - "event-listener", - "futures-lite", -] +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "strsim" @@ -1263,31 +781,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.12", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "thiserror-impl", ] [[package]] @@ -1302,37 +800,6 @@ dependencies = [ ] [[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] name = "typenum" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1369,6 +836,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] +name = "uuid" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +dependencies = [ + "getrandom 0.3.3", + "js-sys", + "rand", + "wasm-bindgen", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1391,6 +876,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] name = "wasm-bindgen" version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1398,6 +892,7 @@ checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] @@ -1458,18 +953,6 @@ dependencies = [ ] [[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - -[[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1625,20 +1108,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", @@ -1,6 +1,6 @@ [package] name = "flac-reencoder" -version = "0.2.0" +version = "0.2.1" edition = "2024" repository = "https://github.com/justjakka/reencoder/" license = "BSD-3-Clause" @@ -14,22 +14,30 @@ anyhow = "1.0.98" clap = { version = "4.5.40", features = ["cargo", "help", "std"] } clap_complete = "4.5.54" directories = "6.0.0" -flac-bound = { version = "0.5.0", features = [ - "libflac-noogg", -], default-features = false } +flac-bound = { version = "0.5.0", default-features = false } i24 = { version = "2.1.0", features = ["std"] } -indicatif = { version = "0.17.11", features = ["improved_unicode", "futures"] } +indicatif = { version = "0.17.11", features = ["improved_unicode"] } md-5 = "0.10.6" -pin-utils = "0.1.0" walkdir = "2.5.0" console = { version = "0.15.11", features = ["windows-console-colors"] } claxon = { git = "https://github.com/justjakka/claxon.git" } metaflac = "0.2.8" rayon = "1.10.0" -smol = "2.0.2" -futures-util = "0.3.31" -smol-macros = "0.1.1" -macro_rules_attribute = "0.2.2" +rusqlite = { version = "0.36.0", default-features = false, features = [ + "modern_sqlite", +] } +r2d2_sqlite = "0.30.0" +r2d2 = "0.8.10" ctrlc = "3.4.7" -easy-parallel = "3.3.1" -libsql = { version = "0.9.11", default-features = false, features = ["core"] } + +[features] +bundled = ["rusqlite/bundled", "flac-bound/libflac-noogg"] +linked = ["flac-bound/libflac-nobuild"] + +[target.'cfg(windows)'.dependencies] +rusqlite = { version = "0.36.0", default-features = false, features = [ + "bundled-windows", +] } +flac-bound = { version = "0.5.0", default-features = false, features = [ + "libflac-noogg", +] } @@ -1,9 +1,11 @@ use anyhow::{Result, anyhow}; use directories::BaseDirs; -use libsql::{Builder, Connection, params}; +use r2d2::{Pool, PooledConnection}; +use r2d2_sqlite::SqliteConnectionManager; +use rusqlite::params; use std::{ path::{Path, PathBuf}, - time::{Duration, UNIX_EPOCH}, + time::UNIX_EPOCH, }; use crate::flac::{CURRENT_VENDOR, get_vendor}; @@ -14,27 +16,39 @@ const REPLACE_ITEM: &str = "REPLACE INTO flacs (path, toencode, modtime) VALUES 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"; const REMOVE_FILE: &str = "DELETE FROM flacs WHERE path = ?1"; const DEDUPE_DB: &str = "DELETE FROM flacs WHERE rowid NOT IN (SELECT MAX(rowid) FROM flacs GROUP BY path)"; +const GET_MODTIME: &str = "SELECT modtime FROM flacs WHERE path = ?1"; -#[derive(Debug, Clone)] -pub struct Database(Connection); +pub fn open_db(path: Option<impl AsRef<Path>>) -> Result<Pool<SqliteConnectionManager>> { + if let Some(file) = path { + let manager = SqliteConnectionManager::file(file); + let pool = Pool::builder().build(manager)?; + let conn = pool.get()?; + conn.execute(TABLE_CREATE, ())?; + Ok(pool) + } else if let Some(base_dir) = BaseDirs::new() { + let file = Path::new(base_dir.data_dir()).join("reencoder.db"); + let manager = SqliteConnectionManager::file(file); + let pool = Pool::builder().build(manager)?; + let conn = pool.get()?; + conn.execute(TABLE_CREATE, ())?; + Ok(pool) + } else { + Err(anyhow!("Failed to locate data directory")) + } +} -impl Database { - pub async fn new(path: impl AsRef<Path>) -> Result<Self> { - let conn = Builder::new_local(path.as_ref().to_str().unwrap()) - .build() - .await? - .connect()?; - conn.execute(TABLE_CREATE, ()).await?; +pub struct Database(pub PooledConnection<SqliteConnectionManager>); - Ok(Database(conn)) +impl Database { + pub fn new(conn: PooledConnection<SqliteConnectionManager>) -> Self { + Database(conn) } - pub async fn insert_file(&self, filename: impl AsRef<Path>) -> Result<()> { + pub fn insert_file(&self, filename: impl AsRef<Path>) -> Result<()> { let toencode = !matches!(get_vendor(&filename)?.as_str(), CURRENT_VENDOR); let modtime = filename @@ -44,17 +58,15 @@ impl Database { .duration_since(UNIX_EPOCH)? .as_secs(); - self.0 - .execute( - ADD_NEW_ITEM, - params![filename.as_ref().to_str().unwrap(), toencode, modtime], - ) - .await?; + self.0.execute( + ADD_NEW_ITEM, + params![filename.as_ref().to_str().unwrap(), toencode, modtime], + )?; Ok(()) } - pub async fn update_file(&self, filename: impl AsRef<Path>) -> Result<()> { + pub fn update_file(&self, filename: impl AsRef<Path>) -> Result<()> { let modtime = filename .as_ref() .metadata()? @@ -62,176 +74,146 @@ impl Database { .duration_since(UNIX_EPOCH)? .as_secs(); - self.0 - .execute( - REPLACE_ITEM, - params![filename.as_ref().to_str().unwrap(), false, modtime], - ) - .await?; + self.0.execute( + REPLACE_ITEM, + params![filename.as_ref().to_str().unwrap(), false, modtime], + )?; Ok(()) } - pub async fn check_file(&self, filename: impl AsRef<Path>) -> Result<bool> { - if let Some(row) = self - .0 - .query(CHECK_FILE, params!(filename.as_ref().to_str().unwrap())) - .await? - .next() - .await? - { - Ok(matches!(row.get_value(0)?, libsql::Value::Integer(1))) + pub fn check_file(&self, filename: impl AsRef<Path>) -> Result<bool> { + if self.0.query_one( + CHECK_FILE, + params!(filename.as_ref().to_str().unwrap()), + |row| { + let num: bool = row.get(0)?; + Ok(num) + }, + )? { + Ok(true) } else { - Err(anyhow!("database error")) + Ok(false) } } - pub async fn get_modtime(&self, filename: impl AsRef<Path>) -> Result<u64> { - if let Some(row) = self - .0 - .query(FETCH_MODTIME, params!(filename.as_ref().to_str().unwrap())) - .await? - .next() - .await? - { - if let Some(sec) = row.get_value(0)?.as_integer() { - Ok(Duration::from_secs(*sec as u64).as_secs()) - } else { - Ok(Duration::from_secs(0).as_secs()) - } - } else { - Err(anyhow!("database error")) - } - } - - pub async fn init_clean_files(&self) -> Result<Vec<PathBuf>, libsql::Error> { - self.0.execute(DEDUPE_DB, ()).await?; - let mut rows = self.0.query(FETCH_FILES, ()).await?; + pub fn init_clean_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error> { + self.0.execute(DEDUPE_DB, ())?; + let mut stmt = self.0.prepare(FETCH_FILES)?; + let mut rows = stmt.query(())?; let mut files = Vec::new(); - while let Ok(Some(row)) = rows.next().await { - files.push(PathBuf::from(row.get_value(0)?.as_text().unwrap())) + while let Ok(Some(row)) = rows.next() { + let path: String = row.get(0)?; + files.push(PathBuf::from(path)); } Ok(files) } - pub async fn remove_file(&self, filename: impl AsRef<Path>) -> Result<()> { + pub fn remove_file(&self, filename: impl AsRef<Path>) -> Result<()> { self.0 - .execute(REMOVE_FILE, params!(filename.as_ref().to_str().unwrap())) - .await?; + .execute(REMOVE_FILE, params!(filename.as_ref().to_str().unwrap()))?; Ok(()) } - pub async fn get_toencode_files(&self) -> Result<Vec<PathBuf>, libsql::Error> { - let mut rows = self.0.query(TOENCODE_QUERY, ()).await?; - let mut files = Vec::new(); - while let Ok(Some(row)) = rows.next().await { - files.push(PathBuf::from(row.get_value(0)?.as_text().unwrap())) + pub fn get_toencode_files(&self) -> Result<Vec<PathBuf>, rusqlite::Error> { + let mut stmt = self.0.prepare(TOENCODE_QUERY)?; + let mut rows = stmt.query(())?; + let mut files: Vec<PathBuf> = Vec::new(); + while let Ok(Some(row)) = rows.next() { + let path: String = row.get(0)?; + files.push(PathBuf::from(path)); } Ok(files) } - pub async fn get_toencode_number(&self) -> Result<i64> { - Ok(*self - .0 - .query(TOENCODE_NUMBER, ()) - .await? - .next() - .await? - .unwrap() - .get_value(0)? - .as_integer() - .unwrap()) + pub fn get_toencode_number(&self) -> Result<u64, rusqlite::Error> { + self.0.query_one(TOENCODE_NUMBER, (), |row| { + let num: u64 = row.get(0)?; + Ok(num) + }) } - pub async fn vaccum(&self) -> Result<()> { - self.0.execute("VACUUM", ()).await?; - Ok(()) + pub fn get_modtime(&self, file: impl AsRef<Path>) -> Result<u64> { + Ok(self.0.query_one( + GET_MODTIME, + params![file.as_ref().to_str().unwrap()], + |row| { + let modtime: u64 = row.get(0)?; + Ok(modtime) + }, + )?) } -} -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"); - Ok(Database::new(db_name).await?) - } else { - Err(anyhow!("Failed to locate data directory")) + pub fn vaccum(&self) -> Result<()> { + self.0.execute("VACUUM", ())?; + Ok(()) } } #[cfg(test)] mod tests { - use macro_rules_attribute::apply; - use smol_macros::{Executor, test}; use super::*; - #[apply(test!)] - async fn check_localfiles(ex: &Executor<'_>) { - ex.spawn(async { - let dbname = String::from("temp1.db"); - let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"]; - let mut counter = 0; - let conn = Database::new(&dbname).await.unwrap(); - for file in filenames { - let _ = conn.insert_file(&file.to_string()).await; - } - let mut returned = conn.0.query(TOENCODE_QUERY, ()).await.unwrap(); + #[test] + fn check_localfiles() { + let dbname = String::from("temp1.db"); + let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"]; + let mut counter = 0; + let pool = open_db(Some(&dbname)).unwrap(); + let conn = Database::new(pool.get().unwrap()); + for file in filenames { + let _ = conn.insert_file(&file.to_string()); + } + let mut stmt = conn.0.prepare(TOENCODE_QUERY).unwrap(); + let mut returned = stmt.query(()).unwrap(); - while let Ok(Some(_)) = returned.next().await { - counter += 1 - } - std::fs::remove_file(dbname).unwrap(); - assert!(counter == 0) - }) - .await; + while let Ok(Some(_)) = returned.next() { + counter += 1 + } + std::fs::remove_file(dbname).unwrap(); + assert!(counter == 0) } - #[apply(test!)] - async fn check_update(ex: &Executor<'_>) { - ex.spawn(async { - let dbname = String::from("temp2.db"); - let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"]; - let conn = Database::new(&dbname).await.unwrap(); - for file in filenames { - let _ = conn - .insert_file(Path::new(file).canonicalize().unwrap()) - .await; - } - - let _ = conn - .0 - .execute( - REPLACE_ITEM, - params![ - Path::new("16bit.flac") - .canonicalize() - .unwrap() - .to_str() - .unwrap(), - true, - "" - ], - ) - .await; + #[test] + fn check_update() { + let dbname = String::from("temp2.db"); + let filenames = ["16bit.flac", "24bit.flac", "32bit.flac"]; + let pool = open_db(Some(&dbname)).unwrap(); + let conn = Database::new(pool.get().unwrap()); + for file in filenames { + let _ = conn.insert_file(Path::new(file).canonicalize().unwrap()); + } - conn.update_file( + let _ = conn.0.execute( + REPLACE_ITEM, + params![ Path::new("16bit.flac") .canonicalize() .unwrap() .to_str() .unwrap(), - ) - .await - .unwrap(); + true, + "" + ], + ); - let mut returned = conn.0.query(TOENCODE_QUERY, ()).await.unwrap(); - let mut counter = 0; - while let Ok(Some(_)) = returned.next().await { - counter += 1 - } - std::fs::remove_file(dbname).unwrap(); - assert!(counter == 0) - }) - .await; + conn.update_file( + Path::new("16bit.flac") + .canonicalize() + .unwrap() + .to_str() + .unwrap(), + ) + .unwrap(); + + let mut stmt = conn.0.prepare(TOENCODE_QUERY).unwrap(); + let mut returned = stmt.query(()).unwrap(); + let mut counter = 0; + while let Ok(Some(_)) = returned.next() { + counter += 1 + } + std::fs::remove_file(dbname).unwrap(); + assert!(counter == 0) } } diff --git a/src/files.rs b/src/files.rs index 797cad7..a92a07a 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,8 +1,9 @@ use anyhow::{Result, anyhow}; #[cfg(not(test))] use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; +use r2d2::Pool; +use r2d2_sqlite::SqliteConnectionManager; use rayon::prelude::*; -use smol::{Executor, fs::metadata}; use std::{ error::Error, fmt::Display, @@ -50,27 +51,24 @@ impl Display for FileError { impl Error for FileError {} -async fn handle_file(file: impl AsRef<Path>, conn: Database) -> Result<()> { - match conn.check_file(&file).await { - Ok(true) => { - let modtime = metadata(file.as_ref()) - .await? - .modified()? - .duration_since(UNIX_EPOCH)? - .as_secs(); - let db_time = conn.get_modtime(&file).await?; - if modtime != db_time { - if let Err(error) = conn.update_file(&file).await { - return Err(FileError::new(file, error).into()); - }; - } - return Ok(()); +fn handle_file(file: impl AsRef<Path>, conn: &Database) -> Result<()> { + if conn.check_file(&file)? { + let modtime = file + .as_ref() + .metadata()? + .modified()? + .duration_since(UNIX_EPOCH)? + .as_secs(); + let db_modtime = conn.get_modtime(&file)?; + if modtime != db_modtime { + if let Err(error) = conn.update_file(&file) { + return Err(FileError::new(&file, error).into()); + }; } - Err(error) => return Err(FileError::new(file, error).into()), - _ => {} + return Ok(()); } - if let Err(error) = conn.insert_file(&file).await { + if let Err(error) = conn.insert_file(&file) { return Err(FileError::new(file, error).into()); } @@ -79,7 +77,7 @@ async fn handle_file(file: impl AsRef<Path>, conn: Database) -> Result<()> { pub fn index_files_recursively( path: impl AsRef<Path>, - conn: &Database, + pool: &Pool<SqliteConnectionManager>, handler: Arc<AtomicBool>, ) -> Result<()> { if !path.as_ref().is_dir() { @@ -92,9 +90,7 @@ pub fn index_files_recursively( .with_style(ProgressStyle::with_template(BAR_TEMPLATE)?.progress_chars("#>-")) .with_message("Indexing"); - let ex = Executor::new(); - - let mut tasks = Vec::new(); + let mut paths = Vec::new(); for entry in WalkDir::new(abspath) { if handler.load(Ordering::SeqCst) { @@ -103,25 +99,7 @@ pub fn index_files_recursively( continue; } if path.extension().is_some_and(|x| x == "flac") { - let newconn = conn.clone(); - let newhandler = handler.clone(); - #[cfg(not(test))] - let newbar = bar.clone(); - - tasks.push(ex.spawn(async move { - if newhandler.load(Ordering::SeqCst) { - match handle_file(&path, newconn).await { - Err(error) => Err(FileError::new(path, error)), - Ok(_) => { - #[cfg(not(test))] - newbar.inc(1); - Ok(()) - } - } - } else { - Ok(()) - } - })); + paths.push(path); #[cfg(not(test))] bar.inc_length(1); @@ -131,10 +109,21 @@ pub fn index_files_recursively( } } - tasks.par_iter_mut().for_each(|task| { + paths.par_iter().for_each(|file| { if handler.load(Ordering::SeqCst) { - if let Err(error) = smol::block_on(async { ex.run(task).await }) { - eprintln!("{error}") + let conn = match pool.get() { + Ok(conn) => Database::new(conn), + Err(error) => { + eprintln!("{}", FileError::new(file, error.into())); + return; + } + }; + + if let Err(error) = handle_file(file, &conn) { + eprintln!("{}", FileError::new(file, error)) + } else { + #[cfg(not(test))] + bar.inc(1); } } }); @@ -150,23 +139,35 @@ pub fn index_files_recursively( Ok(()) } -pub fn reencode_files(conn: &Database, handler: Arc<AtomicBool>) -> Result<()> { +pub fn reencode_files( + pool: &Pool<SqliteConnectionManager>, + handler: Arc<AtomicBool>, +) -> Result<()> { + let conn = Database::new(pool.get()?); #[cfg(not(test))] let bar = ProgressBar::with_draw_target( - Some(smol::block_on(async { conn.get_toencode_number().await })?.try_into()?), + Some(conn.get_toencode_number()?), ProgressDrawTarget::stdout_with_hz(60), ) .with_style(ProgressStyle::with_template(BAR_TEMPLATE)?.progress_chars("#>-")) .with_message("Reencoding"); - let files = smol::block_on(async { conn.get_toencode_files().await })?; + let files = conn.get_toencode_files()?; + drop(conn); files.par_iter().for_each(|file| { if handler.load(Ordering::SeqCst) { + let conn = match pool.get() { + Ok(conn) => Database::new(conn), + Err(error) => { + eprintln!("{}", FileError::new(file, error.into())); + return; + } + }; if let Err(error) = handle_encode(file) { eprintln!("{}", FileError::new(file, error)); } else { - if let Err(error) = smol::block_on(async { conn.update_file(file).await }) { + if let Err(error) = conn.update_file(file) { eprintln!("{}", FileError::new(file, error)); } #[cfg(not(test))] @@ -186,8 +187,10 @@ pub fn reencode_files(conn: &Database, handler: Arc<AtomicBool>) -> Result<()> { Ok(()) } -pub fn clean_files(conn: &Database, handler: Arc<AtomicBool>) -> Result<()> { - let files = smol::block_on(async { conn.init_clean_files().await })?; +pub fn clean_files(pool: &Pool<SqliteConnectionManager>, handler: Arc<AtomicBool>) -> Result<()> { + let conn = Database::new(pool.get()?); + let files = conn.init_clean_files()?; + drop(conn); #[cfg(not(test))] let spinner = ProgressBar::with_draw_target(None, ProgressDrawTarget::stdout_with_hz(60)) @@ -195,7 +198,14 @@ pub fn clean_files(conn: &Database, handler: Arc<AtomicBool>) -> Result<()> { files.par_iter().for_each(|file| { if handler.load(Ordering::SeqCst) && !file.exists() { - if let Err(error) = smol::block_on(async { conn.remove_file(file).await }) { + let conn = match pool.get() { + Ok(conn) => Database::new(conn), + Err(error) => { + eprintln!("{}", FileError::new(file, error.into())); + return; + } + }; + if let Err(error) = conn.remove_file(file) { eprintln!("{}", FileError::new(file, error)) }; #[cfg(not(test))] @@ -205,7 +215,8 @@ pub fn clean_files(conn: &Database, handler: Arc<AtomicBool>) -> Result<()> { #[cfg(not(test))] spinner.finish(); - smol::block_on(async { conn.vaccum().await })?; + let conn = Database::new(pool.get()?); + conn.vaccum()?; Ok(()) } @@ -213,32 +224,28 @@ pub fn clean_files(conn: &Database, handler: Arc<AtomicBool>) -> Result<()> { #[cfg(test)] mod tests { use super::*; - use macro_rules_attribute::apply; - use smol_macros::{Executor, test}; + use crate::db::*; - #[apply(test!)] - async fn test_index_lots_of_files(ex: &Executor<'_>) { - ex.spawn(async { - let handler = Arc::new(AtomicBool::new(true)); - let conn = Database::new("temp3.db").await.unwrap(); - index_files_recursively(Path::new("./testfiles"), &conn, handler).unwrap(); - std::fs::remove_file("temp3.db").unwrap(); - }) - .await; + #[test] + fn test_index_lots_of_files() { + let handler = Arc::new(AtomicBool::new(true)); + let pool = open_db(Some("temp3.db")).unwrap(); + index_files_recursively(Path::new("./testfiles"), &pool, handler).unwrap(); + std::fs::remove_file("temp3.db").unwrap(); } - #[apply(test!)] - async fn test_reencode_lots_of_files(ex: &Executor<'_>) { - ex.spawn(async { - let handler = Arc::new(AtomicBool::new(true)); - let conn = Database::new("temp4.db").await.unwrap(); - let temp = handler.clone(); - index_files_recursively(Path::new("./testfiles"), &conn, temp).unwrap(); - println!("\n{}", conn.get_toencode_number().await.unwrap()); - reencode_files(&conn, handler).unwrap(); - println!("\n{}", conn.get_toencode_number().await.unwrap()); - std::fs::remove_file("temp4.db").unwrap(); - }) - .await; + #[test] + fn test_reencode_lots_of_files() { + let handler = Arc::new(AtomicBool::new(true)); + let pool = open_db(Some("temp4.db")).unwrap(); + let temp = handler.clone(); + index_files_recursively(Path::new("./testfiles"), &pool, temp).unwrap(); + let conn = Database::new(pool.get().unwrap()); + println!("\n{}", conn.get_toencode_number().unwrap()); + drop(conn); + reencode_files(&pool, handler).unwrap(); + let conn = Database::new(pool.get().unwrap()); + println!("\n{}", conn.get_toencode_number().unwrap()); + std::fs::remove_file("temp4.db").unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 206a13b..da62d1e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,8 @@ use std::{ }, }; +use crate::db::Database; + fn build_cli() -> Command { command!() .arg( @@ -90,16 +92,13 @@ fn main() -> Result<()> { r.store(false, Ordering::SeqCst); })?; - let conn = if let Some(path) = args.get_one::<PathBuf>("db") { - smol::block_on(async { db::Database::new(path).await })? - } else { - smol::block_on(async { db::open_default_db().await })? - }; + let dbpool = db::open_db(args.get_one::<PathBuf>("db"))?; let path = args.get_one::<PathBuf>("path"); if path.is_none() && !args.get_flag("clean") && !args.get_flag("doit") { - let count = smol::block_on(async { conn.get_toencode_number().await })?; + let conn = Database::new(dbpool.get()?); + let count = conn.get_toencode_number()?; println!("Files to reencode:\t{}", style(count).green()); return Ok(()); } @@ -110,17 +109,17 @@ fn main() -> Result<()> { if let Some(realpath) = path { let hanlder = running.clone(); - pool.install(|| files::index_files_recursively(realpath, &conn, hanlder))?; + pool.install(|| files::index_files_recursively(realpath, &dbpool, hanlder))?; } if args.get_flag("clean") { let handler = running.clone(); - pool.install(|| files::clean_files(&conn, handler))?; + pool.install(|| files::clean_files(&dbpool, handler))?; } if args.get_flag("doit") { let hanlder = running.clone(); - pool.install(|| files::reencode_files(&conn, hanlder))?; + pool.install(|| files::reencode_files(&dbpool, hanlder))?; } Ok::<(), anyhow::Error>(()) } |
