1pub mod block_store;
2pub mod migrations;
3pub mod session_store;
4
5pub use block_store::BlockStore;
6pub use session_store::SessionStore;
7
8use rusqlite::Connection;
9use std::path::Path;
10use thiserror::Error;
11
12#[derive(Debug, Error)]
13pub enum StoreError {
14 #[error("SQLite error: {0}")]
15 Sqlite(#[from] rusqlite::Error),
16 #[error("Serialization error: {0}")]
17 Serde(#[from] serde_json::Error),
18 #[error("Block not found: {0}")]
19 NotFound(String),
20}
21
22pub type StoreResult<T> = Result<T, StoreError>;
23
24pub struct Store {
26 pub conn: Connection,
27}
28
29impl Store {
30 pub fn open(path: &Path) -> StoreResult<Self> {
31 if let Some(parent) = path.parent() {
32 std::fs::create_dir_all(parent).ok();
33 }
34 let conn = Connection::open(path)?;
35 conn.execute_batch("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;")?;
36 let store = Self { conn };
37 store.run_migrations()?;
38 Ok(store)
39 }
40
41 pub fn open_in_memory() -> StoreResult<Self> {
42 let conn = Connection::open_in_memory()?;
43 conn.execute_batch("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;")?;
44 let store = Self { conn };
45 store.run_migrations()?;
46 Ok(store)
47 }
48
49 fn run_migrations(&self) -> StoreResult<()> {
50 migrations::run(&self.conn)
51 }
52}