Skip to main content

mxr_store/
pool.rs

1use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePoolOptions, SqliteSynchronous};
2use sqlx::SqlitePool;
3use std::path::Path;
4use std::str::FromStr;
5
6pub struct Store {
7    writer: SqlitePool,
8    reader: SqlitePool,
9}
10
11impl Store {
12    pub async fn new(db_path: &Path) -> Result<Self, sqlx::Error> {
13        let db_url = format!("sqlite:{}", db_path.display());
14
15        let write_opts = SqliteConnectOptions::from_str(&db_url)?
16            .create_if_missing(true)
17            .journal_mode(SqliteJournalMode::Wal)
18            .synchronous(SqliteSynchronous::Normal)
19            .pragma("foreign_keys", "ON");
20
21        let writer = SqlitePoolOptions::new()
22            .max_connections(1)
23            .connect_with(write_opts)
24            .await?;
25
26        let read_opts = SqliteConnectOptions::from_str(&db_url)?
27            .journal_mode(SqliteJournalMode::Wal)
28            .synchronous(SqliteSynchronous::Normal)
29            .pragma("foreign_keys", "ON")
30            .read_only(true);
31
32        let reader = SqlitePoolOptions::new()
33            .max_connections(4)
34            .connect_with(read_opts)
35            .await?;
36
37        let store = Self { writer, reader };
38        store.run_migrations().await?;
39        Ok(store)
40    }
41
42    pub async fn in_memory() -> Result<Self, sqlx::Error> {
43        let opts = SqliteConnectOptions::from_str("sqlite::memory:")?
44            .journal_mode(SqliteJournalMode::Wal)
45            .pragma("foreign_keys", "ON");
46
47        let pool = SqlitePoolOptions::new()
48            .max_connections(1)
49            .connect_with(opts)
50            .await?;
51
52        let store = Self {
53            writer: pool.clone(),
54            reader: pool,
55        };
56        store.run_migrations().await?;
57        Ok(store)
58    }
59
60    async fn run_migrations(&self) -> Result<(), sqlx::Error> {
61        let _ = sqlx::raw_sql(include_str!("../migrations/001_initial.sql"))
62            .execute(&self.writer)
63            .await;
64        let _ = sqlx::raw_sql(include_str!("../migrations/002_body_metadata.sql"))
65            .execute(&self.writer)
66            .await;
67        let _ = sqlx::raw_sql(include_str!("../migrations/003_sync_runtime_status.sql"))
68            .execute(&self.writer)
69            .await;
70        let _ = sqlx::raw_sql(include_str!("../migrations/004_semantic_search.sql"))
71            .execute(&self.writer)
72            .await;
73        Ok(())
74    }
75
76    pub fn writer(&self) -> &SqlitePool {
77        &self.writer
78    }
79
80    pub fn reader(&self) -> &SqlitePool {
81        &self.reader
82    }
83}