Skip to main content

fond_store/
db.rs

1use std::path::Path;
2
3use refinery::embed_migrations;
4use rusqlite::Connection;
5
6embed_migrations!("migrations");
7
8/// A fond SQLite database connection.
9///
10/// Wraps a `rusqlite::Connection` with migrations, WAL mode,
11/// and foreign key enforcement. The database is a derived index —
12/// `.cook` files are the source of truth.
13pub struct FondDb {
14    conn: Connection,
15}
16
17impl FondDb {
18    /// Open (or create) a database file and run migrations.
19    pub fn open(path: &Path) -> Result<Self, crate::StoreError> {
20        let mut conn = Connection::open(path).map_err(|e| crate::StoreError::Database {
21            message: format!("failed to open database: {e}"),
22        })?;
23        Self::init(&mut conn)?;
24        Ok(Self { conn })
25    }
26
27    /// Open an in-memory database for tests.
28    pub fn open_memory() -> Result<Self, crate::StoreError> {
29        let mut conn = Connection::open_in_memory().map_err(|e| crate::StoreError::Database {
30            message: format!("failed to open in-memory database: {e}"),
31        })?;
32        Self::init(&mut conn)?;
33        Ok(Self { conn })
34    }
35
36    fn init(conn: &mut Connection) -> Result<(), crate::StoreError> {
37        conn.execute_batch("PRAGMA foreign_keys = ON;")
38            .map_err(|e| crate::StoreError::Database {
39                message: format!("failed to enable foreign keys: {e}"),
40            })?;
41
42        let _: String = conn
43            .query_row("PRAGMA journal_mode = WAL", [], |row| row.get(0))
44            .map_err(|e| crate::StoreError::Database {
45                message: format!("failed to set WAL mode: {e}"),
46            })?;
47
48        migrations::runner()
49            .run(conn)
50            .map_err(|e| crate::StoreError::Migration {
51                message: format!("{e}"),
52            })?;
53
54        Ok(())
55    }
56
57    /// Get a reference to the underlying connection.
58    pub fn conn(&self) -> &Connection {
59        &self.conn
60    }
61}