1use std::path::Path;
2
3use refinery::embed_migrations;
4use rusqlite::Connection;
5
6embed_migrations!("migrations");
7
8pub struct FondDb {
14 conn: Connection,
15}
16
17impl FondDb {
18 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 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 pub fn conn(&self) -> &Connection {
59 &self.conn
60 }
61}