kanban_persistence_sqlite/
lib.rs1pub mod sqlite_store;
2
3pub use sqlite_store::SqliteStore;
4
5use kanban_persistence::{PersistenceError, PersistenceStore, StoreFactory};
6use std::sync::Arc;
7
8pub struct SqliteStoreFactory;
9
10impl StoreFactory for SqliteStoreFactory {
11 fn name(&self) -> &str {
12 "sqlite"
13 }
14
15 fn matches_content(&self, header: &[u8]) -> bool {
16 header.starts_with(b"SQLite format 3\0")
17 }
18
19 fn create(
20 &self,
21 locator: &str,
22 ) -> Result<Arc<dyn PersistenceStore + Send + Sync>, PersistenceError> {
23 let handle = tokio::runtime::Handle::current();
24 if handle.runtime_flavor() == tokio::runtime::RuntimeFlavor::CurrentThread {
25 return Err(PersistenceError::Database(
26 "SqliteStoreFactory::create requires a multi-thread Tokio runtime; \
27 block_in_place is unavailable on a current_thread runtime. \
28 Use #[tokio::test(flavor = \"multi_thread\")] in tests."
29 .to_string(),
30 ));
31 }
32 let store = tokio::task::block_in_place(|| handle.block_on(SqliteStore::open(locator)))
33 .map_err(|e| PersistenceError::Database(e.to_string()))?;
34 Ok(Arc::new(store))
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41 use kanban_persistence::StoreFactory;
42
43 #[test]
44 fn test_sqlite_factory_matches_content_sqlite_magic_bytes() {
45 let header = b"SQLite format 3\0extra";
46 assert!(SqliteStoreFactory.matches_content(header));
47 }
48
49 #[test]
50 fn test_sqlite_factory_matches_content_rejects_json() {
51 let header = b"{\"boards\": []}";
52 assert!(!SqliteStoreFactory.matches_content(header));
53 }
54
55 #[test]
56 fn test_sqlite_factory_matches_content_rejects_empty() {
57 assert!(!SqliteStoreFactory.matches_content(b""));
58 }
59
60 #[test]
61 fn test_sqlite_factory_name_is_sqlite() {
62 assert_eq!(SqliteStoreFactory.name(), "sqlite");
63 }
64
65 #[tokio::test(flavor = "multi_thread")]
66 async fn test_sqlite_factory_create_returns_persistence_store() {
67 let dir = tempfile::tempdir().unwrap();
68 let path = dir.path().join("test.db");
69 let store = SqliteStoreFactory.create(path.to_str().unwrap()).unwrap();
70 assert!(store.exists().await);
71 }
72}