huddle_core/storage/
mod.rs1pub mod keychain;
2pub mod repo;
3pub mod schema;
4
5use rusqlite::Connection;
6use std::path::Path;
7use std::sync::{Arc, Mutex};
8
9use crate::error::Result;
10
11pub type Db = Arc<Mutex<Connection>>;
12
13pub fn open_db(path: &Path, master_key: Option<&[u8; 32]>) -> Result<Db> {
17 let conn = Connection::open(path)?;
18 if let Some(key) = master_key {
19 let pragma = format!("PRAGMA key = \"x'{}'\";", hex::encode(key));
20 conn.execute_batch(&pragma)?;
21 }
22 conn.execute_batch("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;")?;
23 run_migrations(&conn)?;
24 Ok(Arc::new(Mutex::new(conn)))
25}
26
27pub fn open_db_in_memory() -> Result<Db> {
28 let conn = Connection::open_in_memory()?;
29 conn.execute_batch("PRAGMA foreign_keys=ON;")?;
30 run_migrations(&conn)?;
31 Ok(Arc::new(Mutex::new(conn)))
32}
33
34fn run_migrations(conn: &Connection) -> Result<()> {
40 let applied: i64 = conn.query_row("PRAGMA user_version", [], |row| row.get(0))?;
41 for (idx, migration) in schema::MIGRATIONS.iter().enumerate() {
42 if (idx as i64) < applied {
43 continue;
44 }
45 conn.execute_batch(migration)?;
46 conn.execute_batch(&format!("PRAGMA user_version = {};", idx + 1))?;
48 }
49 Ok(())
50}