Skip to main content

max / balanced_breakfast

Migrate the database layer from sqlx to rusqlite, and move to 0.40 rusqlite for SQLite is the house standard (wiki `sql-library-standard`): BB had zero query! macros and no .sqlx offline dir across 180 call sites, so it was paying an async runtime, a connection pool and a version ceiling for the one sqlx feature it never used -- while already running a second driver against the same file through synckit's SyncStore. The repositories are synchronous now. Nothing wanted the async; it came from sqlx. BB's own async (plugin fetch, HTTP, the sync client) is untouched, and the Tauri commands call the sync repositories inline, which is fine for a local file on a desktop. The `_sqlx_migrations` ledger is kept verbatim -- same table, same columns, same sha384-over-file-bytes checksum. Renaming it would make an upgraded install believe it had applied nothing and re-run all 13 migrations against populated tables. Verified against a copy of a live install, not a synthetic database: all 13 checksums and descriptions sqlx recorded reproduce exactly, the runner applies nothing, and the ledger is byte-identical after. Those checksums are now a test constant, so editing a shipped migration fails in CI instead of in the field. The sync service still speaks raw rusqlite. That is not a shortcut: it walks arbitrary tables by name from the changelog, which no typed repository can express. It is the only place in BB that does. The PRAGMAs (WAL, foreign_keys, 5s busy timeout) are sqlx's defaults written down, so an existing database sees no change of behaviour.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-08 01:12 UTC
Signed with PGP, not checked
Commit: 8485ef900fc5410d34a791290fa3102541d8c1a0
Parent: af1aa2e
59 files changed, +4011 insertions, -3788 deletions
@@ -6,6 +6,9 @@
6 6
7 7 ## [Unreleased]
8 8
9 + ### Changed
10 + - The database layer moved from sqlx to rusqlite, the house SQLite standard. The repositories are synchronous now: SQLite has no async API, and the async this layer wore came from sqlx rather than from anything the app wanted. No schema change and no migration of your data -- the existing migration ledger is read and appended to exactly as before, so an upgraded install applies nothing on first launch.
11 +
9 12 ### Removed
10 13 - Supernote push. The `supernote` build feature, the "Send to Supernote" button, and the `supernote-push` dependency are all gone. The library behind it was decommissioned when the reMarkable displaced the Supernote as the daily e-ink device. Releases built before this carried the feature on; releases after it will not.
11 14
M CONTRIBUTING.md +1 -1
@@ -130,7 +130,7 @@
130 130 }
131 131 ```
132 132
133 - `ApiError` implements `From` for `sqlx::Error`, `FeedError`, and `OrchestratorError`. The frontend receives `{code: "BAD_REQUEST", message: "..."}`.
133 + `ApiError` implements `From` for `bb_db::DbError`, `rusqlite::Error`, `FeedError`, and `OrchestratorError`. The frontend receives `{code: "BAD_REQUEST", message: "..."}`.
134 134
135 135 ## Circuit Breaker
136 136
M Cargo.lock +44 -246
@@ -98,12 +98,6 @@
98 98 "alloc-no-stdlib",
99 99 ]
100 100
101 - [[package]]
102 - name = "allocator-api2"
103 - version = "0.2.21"
104 - source = "registry+https://github.com/rust-lang/crates.io-index"
105 - checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
106 -
107 101 [[package]]
108 102 name = "allsorts-azul"
109 103 version = "0.17.1"
@@ -356,15 +350,6 @@
356 350 "system-deps",
357 351 ]
358 352
359 - [[package]]
360 - name = "atoi"
361 - version = "2.0.0"
362 - source = "registry+https://github.com/rust-lang/crates.io-index"
363 - checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
364 - dependencies = [
365 - "num-traits",
366 - ]
367 -
368 353 [[package]]
369 354 name = "atomic-waker"
370 355 version = "1.1.2"
@@ -449,11 +434,11 @@
449 434 "rand 0.10.2",
450 435 "regex",
451 436 "roxmltree",
437 + "rusqlite",
452 438 "rustls",
453 439 "serde",
454 440 "serde_json",
455 441 "sha2 0.11.0",
456 - "sqlx",
457 442 "synckit-client",
458 443 "tagtree",
459 444 "tauri",
@@ -510,7 +495,6 @@
510 495 "rhai",
511 496 "roxmltree",
512 497 "serde_json",
513 - "sqlx",
514 498 "thiserror 2.0.18",
515 499 "tokio",
516 500 "tracing",
@@ -525,11 +509,13 @@
525 509 dependencies = [
526 510 "bb-interface",
527 511 "chrono",
512 + "r2d2",
513 + "rusqlite",
528 514 "serde",
529 515 "serde_json",
530 - "sqlx",
516 + "sha2 0.11.0",
531 517 "synckit-config",
532 - "tokio",
518 + "thiserror 2.0.18",
533 519 "tracing",
534 520 "uuid",
535 521 ]
@@ -543,9 +529,7 @@
543 529 "chrono",
544 530 "regex",
545 531 "serde_json",
546 - "sqlx",
547 532 "thiserror 2.0.18",
548 - "tokio",
549 533 "tracing",
550 534 ]
551 535
@@ -1035,21 +1019,6 @@
1035 1019 "libc",
1036 1020 ]
1037 1021
1038 - [[package]]
1039 - name = "crc"
1040 - version = "3.4.0"
1041 - source = "registry+https://github.com/rust-lang/crates.io-index"
1042 - checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
1043 - dependencies = [
1044 - "crc-catalog",
1045 - ]
1046 -
1047 - [[package]]
1048 - name = "crc-catalog"
1049 - version = "2.4.0"
1050 - source = "registry+https://github.com/rust-lang/crates.io-index"
1051 - checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
1052 -
1053 1022 [[package]]
1054 1023 name = "crc32fast"
1055 1024 version = "1.5.0"
@@ -1068,15 +1037,6 @@
1068 1037 "crossbeam-utils",
1069 1038 ]
1070 1039
1071 - [[package]]
1072 - name = "crossbeam-queue"
1073 - version = "0.3.12"
1074 - source = "registry+https://github.com/rust-lang/crates.io-index"
1075 - checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
1076 - dependencies = [
1077 - "crossbeam-utils",
1078 - ]
1079 -
1080 1040 [[package]]
1081 1041 name = "crossbeam-utils"
1082 1042 version = "0.8.21"
@@ -1359,7 +1319,6 @@
1359 1319 "block-buffer 0.12.1",
1360 1320 "const-oid",
1361 1321 "crypto-common 0.2.2",
1362 - "ctutils",
1363 1322 ]
1364 1323
1365 1324 [[package]]
@@ -1380,7 +1339,7 @@
1380 1339 "libc",
1381 1340 "option-ext",
1382 1341 "redox_users",
1383 - "windows-sys 0.59.0",
1342 + "windows-sys 0.61.2",
1384 1343 ]
1385 1344
1386 1345 [[package]]
@@ -1444,12 +1403,6 @@
1444 1403 "serde",
1445 1404 ]
1446 1405
1447 - [[package]]
1448 - name = "dotenvy"
1449 - version = "0.15.7"
1450 - source = "registry+https://github.com/rust-lang/crates.io-index"
1451 - checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
1452 -
1453 1406 [[package]]
1454 1407 name = "dpi"
1455 1408 version = "0.1.2"
@@ -1501,15 +1454,6 @@
1501 1454 source = "registry+https://github.com/rust-lang/crates.io-index"
1502 1455 checksum = "b04dc5a38e4f151a79d9f2451ae6037fb6eaf5cba34771f44781f80e508498e3"
1503 1456
1504 - [[package]]
1505 - name = "either"
1506 - version = "1.15.0"
1507 - source = "registry+https://github.com/rust-lang/crates.io-index"
1508 - checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
1509 - dependencies = [
1510 - "serde",
1511 - ]
1512 -
1513 1457 [[package]]
1514 1458 name = "embed-resource"
1515 1459 version = "3.0.6"
@@ -1590,16 +1534,6 @@
1590 1534 checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
1591 1535 dependencies = [
1592 1536 "libc",
1593 - "windows-sys 0.59.0",
1594 - ]
1595 -
1596 - [[package]]
1597 - name = "etcetera"
1598 - version = "0.11.0"
1599 - source = "registry+https://github.com/rust-lang/crates.io-index"
1600 - checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96"
1601 - dependencies = [
1602 - "cfg-if",
1603 1537 "windows-sys 0.61.2",
1604 1538 ]
1605 1539
@@ -1694,17 +1628,6 @@
1694 1628 "miniz_oxide",
1695 1629 ]
1696 1630
1697 - [[package]]
1698 - name = "flume"
1699 - version = "0.12.0"
1700 - source = "registry+https://github.com/rust-lang/crates.io-index"
1701 - checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be"
1702 - dependencies = [
1703 - "futures-core",
1704 - "futures-sink",
1705 - "spin 0.9.8",
1706 - ]
1707 -
1708 1631 [[package]]
1709 1632 name = "fnv"
1710 1633 version = "1.0.7"
@@ -1811,17 +1734,6 @@
1811 1734 "futures-util",
1812 1735 ]
1813 1736
1814 - [[package]]
1815 - name = "futures-intrusive"
1816 - version = "0.5.0"
1817 - source = "registry+https://github.com/rust-lang/crates.io-index"
1818 - checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
1819 - dependencies = [
1820 - "futures-core",
1821 - "lock_api",
1822 - "parking_lot",
1823 - ]
1824 -
1825 1737 [[package]]
1826 1738 name = "futures-io"
1827 1739 version = "0.3.33"
@@ -2262,8 +2174,6 @@
2262 2174 source = "registry+https://github.com/rust-lang/crates.io-index"
2263 2175 checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
2264 2176 dependencies = [
2265 - "allocator-api2",
2266 - "equivalent",
2267 2177 "foldhash",
2268 2178 ]
2269 2179
@@ -2272,14 +2182,17 @@
2272 2182 version = "0.17.1"
2273 2183 source = "registry+https://github.com/rust-lang/crates.io-index"
2274 2184 checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
2185 + dependencies = [
2186 + "foldhash",
2187 + ]
2275 2188
2276 2189 [[package]]
2277 2190 name = "hashlink"
2278 - version = "0.11.1"
2191 + version = "0.12.1"
2279 2192 source = "registry+https://github.com/rust-lang/crates.io-index"
2280 - checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f"
2193 + checksum = "32069d97bb81e38fa67eab65e3393bf804bb85969f2bc06bf13f64aef5aba248"
2281 2194 dependencies = [
2282 - "hashbrown 0.16.1",
2195 + "hashbrown 0.17.1",
2283 2196 ]
2284 2197
2285 2198 [[package]]
@@ -2312,16 +2225,7 @@
2312 2225 source = "registry+https://github.com/rust-lang/crates.io-index"
2313 2226 checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
2314 2227 dependencies = [
2315 - "hmac 0.12.1",
2316 - ]
2317 -
2318 - [[package]]
2319 - name = "hkdf"
2320 - version = "0.13.0"
2321 - source = "registry+https://github.com/rust-lang/crates.io-index"
2322 - checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018"
2323 - dependencies = [
2324 - "hmac 0.13.0",
2228 + "hmac",
2325 2229 ]
2326 2230
2327 2231 [[package]]
@@ -2333,15 +2237,6 @@
2333 2237 "digest 0.10.7",
2334 2238 ]
2335 2239
2336 - [[package]]
2337 - name = "hmac"
2338 - version = "0.13.0"
2339 - source = "registry+https://github.com/rust-lang/crates.io-index"
2340 - checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
2341 - dependencies = [
2342 - "digest 0.11.3",
2343 - ]
2344 -
2345 2240 [[package]]
2346 2241 name = "html5ever"
2347 2242 version = "0.25.2"
@@ -2977,9 +2872,9 @@
2977 2872
2978 2873 [[package]]
2979 2874 name = "libsqlite3-sys"
2980 - version = "0.37.0"
2875 + version = "0.38.1"
2981 2876 source = "registry+https://github.com/rust-lang/crates.io-index"
2982 - checksum = "b1f111c8c41e7c61a49cd34e44c7619462967221a6443b0ec299e0ac30cfb9b1"
2877 + checksum = "f6c19a05435c21ac299d71b6a9c13db3e3f47c520517d58990a462a1397a61db"
2983 2878 dependencies = [
2984 2879 "cc",
2985 2880 "pkg-config",
@@ -3308,7 +3203,7 @@
3308 3203 source = "registry+https://github.com/rust-lang/crates.io-index"
3309 3204 checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
3310 3205 dependencies = [
3311 - "spin 0.5.2",
3206 + "spin",
3312 3207 ]
3313 3208
3314 3209 [[package]]
@@ -3332,7 +3227,7 @@
3332 3227 source = "registry+https://github.com/rust-lang/crates.io-index"
3333 3228 checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
3334 3229 dependencies = [
3335 - "windows-sys 0.59.0",
3230 + "windows-sys 0.61.2",
3336 3231 ]
3337 3232
3338 3233 [[package]]
@@ -3440,7 +3335,7 @@
3440 3335 source = "registry+https://github.com/rust-lang/crates.io-index"
3441 3336 checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
3442 3337 dependencies = [
3443 - "proc-macro-crate 1.3.1",
3338 + "proc-macro-crate 3.4.0",
3444 3339 "proc-macro2",
3445 3340 "quote",
3446 3341 "syn 2.0.114",
@@ -3720,7 +3615,7 @@
3720 3615 checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
3721 3616 dependencies = [
3722 3617 "libc",
3723 - "windows-sys 0.59.0",
3618 + "windows-sys 0.61.2",
3724 3619 ]
3725 3620
3726 3621 [[package]]
@@ -4357,6 +4252,17 @@
4357 4252 source = "registry+https://github.com/rust-lang/crates.io-index"
4358 4253 checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
4359 4254
4255 + [[package]]
4256 + name = "r2d2"
4257 + version = "0.8.10"
4258 + source = "registry+https://github.com/rust-lang/crates.io-index"
4259 + checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
4260 + dependencies = [
4261 + "log",
4262 + "parking_lot",
4263 + "scheduled-thread-pool",
4264 + ]
4265 +
4360 4266 [[package]]
4361 4267 name = "rand"
4362 4268 version = "0.7.3"
@@ -4691,9 +4597,9 @@
4691 4597
4692 4598 [[package]]
4693 4599 name = "rusqlite"
4694 - version = "0.39.0"
4600 + version = "0.40.1"
4695 4601 source = "registry+https://github.com/rust-lang/crates.io-index"
4696 - checksum = "a0d2b0146dd9661bf67bb107c0bb2a55064d556eeb3fc314151b957f313bcd4e"
4602 + checksum = "11438310b19e3109b6446c33d1ed5e889428cf2e278407bc7896bc4aaea43323"
4697 4603 dependencies = [
4698 4604 "bitflags 2.13.1",
4699 4605 "fallible-iterator",
@@ -4740,7 +4646,7 @@
4740 4646 "errno",
4741 4647 "libc",
4742 4648 "linux-raw-sys",
4743 - "windows-sys 0.59.0",
4649 + "windows-sys 0.61.2",
4744 4650 ]
4745 4651
4746 4652 [[package]]
@@ -4797,7 +4703,7 @@
4797 4703 "security-framework",
4798 4704 "security-framework-sys",
4799 4705 "webpki-root-certs",
4800 - "windows-sys 0.59.0",
4706 + "windows-sys 0.61.2",
4801 4707 ]
4802 4708
4803 4709 [[package]]
@@ -4847,6 +4753,15 @@
4847 4753 "windows-sys 0.61.2",
4848 4754 ]
4849 4755
4756 + [[package]]
4757 + name = "scheduled-thread-pool"
4758 + version = "0.2.7"
4759 + source = "registry+https://github.com/rust-lang/crates.io-index"
4760 + checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
4761 + dependencies = [
4762 + "parking_lot",
4763 + ]
4764 +
4850 4765 [[package]]
4851 4766 name = "schemars"
4852 4767 version = "0.8.22"
@@ -4930,7 +4845,7 @@
4930 4845 "futures-util",
4931 4846 "generic-array",
4932 4847 "getrandom 0.2.17",
4933 - "hkdf 0.12.4",
4848 + "hkdf",
4934 4849 "num",
4935 4850 "once_cell",
4936 4851 "serde",
@@ -5217,17 +5132,6 @@
5217 5132 "stable_deref_trait",
5218 5133 ]
5219 5134
5220 - [[package]]
5221 - name = "sha1"
5222 - version = "0.11.0"
5223 - source = "registry+https://github.com/rust-lang/crates.io-index"
5224 - checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
5225 - dependencies = [
5226 - "cfg-if",
5227 - "cpufeatures 0.3.0",
5228 - "digest 0.11.3",
5229 - ]
5230 -
5231 5135 [[package]]
5232 5136 name = "sha2"
5233 5137 version = "0.10.9"
@@ -5425,15 +5329,6 @@
5425 5329 source = "registry+https://github.com/rust-lang/crates.io-index"
5426 5330 checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
5427 5331
5428 - [[package]]
5429 - name = "spin"
5430 - version = "0.9.8"
5431 - source = "registry+https://github.com/rust-lang/crates.io-index"
5432 - checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
5433 - dependencies = [
5434 - "lock_api",
5435 - ]
5436 -
5437 5332 [[package]]
5438 5333 name = "sqlite-wasm-rs"
5439 5334 version = "0.5.5"
@@ -5446,185 +5341,6 @@
5446 5341 "wasm-bindgen",
5447 5342 ]
5448 5343
5449 - [[package]]
5450 - name = "sqlx"
5451 - version = "0.9.0"
5452 - source = "registry+https://github.com/rust-lang/crates.io-index"
5453 - checksum = "378620ccc25c62c89d8be1c819e76a88d59bdcc3304733330788948e619bfd71"
5454 - dependencies = [
5455 - "sqlx-core",
5456 - "sqlx-macros",
5457 - "sqlx-mysql",
5458 - "sqlx-postgres",
5459 - "sqlx-sqlite",
5460 - ]
5461 -
5462 - [[package]]
5463 - name = "sqlx-core"
5464 - version = "0.9.0"
5465 - source = "registry+https://github.com/rust-lang/crates.io-index"
5466 - checksum = "05b44e85bf579a8eeb4ceaa77a3a523baf2bf0e9bac7e40f405d537b5d2d5ccb"
5467 - dependencies = [
5468 - "base64 0.22.1",
5469 - "bytes",
5470 - "cfg-if",
5471 - "chrono",
5472 - "crc",
5473 - "crossbeam-queue",
5474 - "either",
5475 - "event-listener",
5476 - "futures-core",
5477 - "futures-intrusive",
5478 - "futures-io",
5479 - "futures-util",
5480 - "hashbrown 0.16.1",
5481 - "hashlink",
5482 - "indexmap 2.14.0",
5483 - "log",
5484 - "memchr",
5485 - "percent-encoding",
5486 - "serde",
5487 - "serde_json",
5488 - "sha2 0.10.9",
5489 - "smallvec",
5490 - "thiserror 2.0.18",
5491 - "tokio",
5492 - "tokio-stream",
5493 - "tracing",
5494 - "url",
5495 - "uuid",
5496 - ]
5497 -
5498 - [[package]]
5499 - name = "sqlx-macros"
5500 - version = "0.9.0"
5501 - source = "registry+https://github.com/rust-lang/crates.io-index"
5502 - checksum = "bd2b84f2bc39a5705ef27ec785a11c934a41bbd4a24941e257927cddc26b60bf"
5503 - dependencies = [
5504 - "proc-macro2",
5505 - "quote",
5506 - "sqlx-core",
5507 - "sqlx-macros-core",
5508 - "syn 2.0.114",
5509 - ]
5510 -
5511 - [[package]]
5512 - name = "sqlx-macros-core"
5513 - version = "0.9.0"
5514 - source = "registry+https://github.com/rust-lang/crates.io-index"
5515 - checksum = "fb8d96de5fdc85a5c4ec813432b523ec637e80ba98f046555f75f7908ddac7c3"
5516 - dependencies = [
5517 - "cfg-if",
5518 - "dotenvy",
5519 - "either",
5520 - "heck 0.5.0",
5521 - "hex",
5522 - "proc-macro2",
5523 - "quote",
5524 - "serde",
5525 - "serde_json",
5526 - "sha2 0.10.9",
5527 - "sqlx-core",
5528 - "sqlx-mysql",
5529 - "sqlx-postgres",
5530 - "sqlx-sqlite",
5531 - "syn 2.0.114",
5532 - "thiserror 2.0.18",
5533 - "tokio",
5534 - "url",
5535 - ]
5536 -
5537 - [[package]]
5538 - name = "sqlx-mysql"
5539 - version = "0.9.0"
5540 - source = "registry+https://github.com/rust-lang/crates.io-index"
5541 - checksum = "90b8020fe17c5f2c245bfa2505d7ef59c5604839527c740266ad2214acebea27"
5542 - dependencies = [
5543 - "bitflags 2.13.1",
5544 - "byteorder",
5545 - "bytes",
Lines truncated
M Cargo.toml +8 -2
@@ -25,8 +25,14 @@
25 25 tracing = "0.1.44"
26 26 tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
27 27
28 - # Database
29 - sqlx = { version = "0.9", features = ["runtime-tokio", "sqlite", "chrono", "uuid"] }
28 + # Database. rusqlite for SQLite is the house standard; wiki `sql-library-standard`.
29 + # Kept in step with synckit-client/synckit-config, whose SyncStore opens its own
30 + # connection to the same file: two versions of `libsqlite3-sys` cannot co-link, so
31 + # this pin moves only when synckit does. The tree went to 0.40 on 2026-08-07.
32 + rusqlite = { version = "0.40", features = ["bundled"] }
33 + # Pooling. Deliberately r2d2 and not r2d2_sqlite, which requires rusqlite 0.40.
34 + r2d2 = "0.8"
35 + sha2 = "0.11"
30 36
31 37 # XML parsing
32 38 roxmltree = "0.21"
M README.md +1 -1
@@ -40,7 +40,7 @@
40 40 | `bb-interface` | `crates/bb-interface/` | Shared types for the plugin system: `FeedItem`, `FetchResult`, `ConfigSchema`, `ConfigField`, `BusserCapabilities`. Defines the contract between plugins and the host. |
41 41 | `bb-core` | `crates/bb-core/` | Orchestrator (feed refresh scheduling, lifecycle), Rhai plugin runtime (engine setup, script loading, host function registration), config encryption, URL tracker-stripping. |
42 42 | `bb-feed` | `crates/bb-feed/` | Feed aggregation and ordering. Merges items from all active sources and applies sort modes (newest, scored, unread-first, starred-first). |
43 - | `bb-db` | `crates/bb-db/` | SQLite persistence via sqlx. Repositories for feeds, items, tags, and busser key-value state. FTS5 full-text search. |
43 + | `bb-db` | `crates/bb-db/` | SQLite persistence via rusqlite. Repositories for feeds, items, tags, and busser key-value state. FTS5 full-text search. |
44 44 | `src-tauri` | `src-tauri/` | Tauri 2 desktop shell. Tauri commands (thin wrappers over the library crates), app state, background auto-fetch, frontend (vanilla HTML/CSS/JS). |
45 45
46 46 Dependency flow: `bb-interface` is leaf (no internal deps) -> `bb-core` and `bb-feed` depend on `bb-interface` -> `bb-db` depends on `bb-interface` -> `src-tauri` depends on all four.
@@ -17,7 +17,7 @@
17 17 | bb-interface | `crates/bb-interface/` | Leaf crate. Shared types for the plugin contract: `FeedItem`, `FetchResult`, `ConfigSchema`, `ConfigField`, `BusserCapabilities`, `BusserConfig`. No internal dependencies. |
18 18 | bb-core | `crates/bb-core/` | Orchestrator and plugin runtime. Coordinates plugins, database, and feed scheduling. Contains the Rhai engine setup, plugin manager, config encryption (`crypto`), and URL tracker stripping (`url_cleaner`). Depends on bb-interface. |
19 19 | bb-feed | `crates/bb-feed/` | Feed aggregation and ordering. `FeedGenerator` reads items from the DB and applies filters (source, unread, starred, search, tags, query feed conditions). `OrderBy` sorts results (chronological, score, unread-first, starred-first). Depends on bb-interface. |
20 - | bb-db | `crates/bb-db/` | SQLite persistence via sqlx. Repository types for feeds, items, tags, busser state, user config, and query feeds. FTS5 full-text search. Depends on bb-interface. |
20 + | bb-db | `crates/bb-db/` | SQLite persistence via rusqlite. Repository types for feeds, items, tags, busser state, user config, and query feeds. FTS5 full-text search. Depends on bb-interface. |
21 21 | src-tauri | `src-tauri/` | Tauri 2 desktop shell. Thin command wrappers over the library crates, app state management, background tasks (auto-fetch, stale cleanup), sync scheduler, and the vanilla JS frontend. Depends on all four library crates. |
22 22
23 23 Dependency flow: `bb-interface` (leaf) --> `bb-core`, `bb-feed`, `bb-db` --> `src-tauri` (root).
@@ -105,7 +105,7 @@
105 105
106 106 ## Database Layer
107 107
108 - SQLite via sqlx with compile-time migrations (12 migrations). The `Database` struct holds a connection pool (`max_connections: 16`) and provides typed repository accessors.
108 + SQLite via rusqlite behind an r2d2 pool (16 connections), with the 13 migrations in `migrations/sqlite/` embedded at build time. The `Database` struct holds the pool and provides typed repository accessors. The repositories are synchronous: SQLite has no async API, and the async this layer used to wear came from sqlx.
109 109
110 110 ### Tables
111 111
@@ -1,6 +1,6 @@
1 1 # Balanced Breakfast Database Schema
2 2
3 - SQLite schema reference. 12 migrations. Migrations live in `migrations/sqlite/` as numbered SQL files, applied on boot via sqlx-sqlite.
3 + SQLite schema reference. 13 migrations. Migrations live in `migrations/sqlite/` as numbered SQL files, embedded at build time and applied on boot by the runner in `crates/bb-db/src/migrate.rs`. The ledger table is still called `_sqlx_migrations`: sqlx wrote it in every install in the field, and adopting it verbatim is what lets an upgrade find nothing pending.
4 4
5 5 ## Domain Map
6 6
@@ -81,7 +81,7 @@
81 81
82 82 ## Database Issues
83 83
84 - **Database location:** `~/.local/share/balanced-breakfast/` (platform-dependent), SQLite via sqlx.
84 + **Database location:** `~/.local/share/balanced-breakfast/` (platform-dependent), SQLite via rusqlite.
85 85
86 86 | Symptom | Fix |
87 87 |---------|-----|
@@ -37,7 +37,10 @@
37 37 tokio.workspace = true
38 38
39 39 # Database
40 - sqlx.workspace = true
40 +
41 + # Database. Direct rusqlite use is confined to the sync service, which walks
42 + # arbitrary tables by name and so cannot go through a typed repository.
43 + rusqlite.workspace = true
41 44
42 45 # Serialization
43 46 serde.workspace = true
@@ -54,7 +57,7 @@
54 57 # provider before any TLS client is built. We install ring in `build_app`.
55 58 # Matches audiofiles. Trust anchors come from the OS via rustls-platform-verifier.
56 59 rustls = { version = "0.23", default-features = false, features = ["std", "tls12", "logging", "ring"] }
57 - sha2 = "0.11"
60 + sha2.workspace = true
58 61 base64.workspace = true
59 62 rand.workspace = true
60 63
@@ -9,7 +9,6 @@
9 9 bb-interface.workspace = true
10 10 bb-db.workspace = true
11 11 bb-feed.workspace = true
12 - sqlx.workspace = true
13 12 tokio.workspace = true
14 13 thiserror.workspace = true
15 14 tracing.workspace = true
@@ -7,9 +7,11 @@
7 7
8 8 [dependencies]
9 9 bb-interface.workspace = true
10 - sqlx.workspace = true
10 + rusqlite.workspace = true
11 + r2d2.workspace = true
12 + sha2.workspace = true
13 + thiserror.workspace = true
11 14 synckit-config.workspace = true
12 - tokio.workspace = true
13 15 tracing.workspace = true
14 16 chrono.workspace = true
15 17 uuid.workspace = true