eventuary_sqlite/
database.rs1use std::path::Path;
2use std::sync::{Arc, Mutex};
3
4use rusqlite::Connection;
5
6use eventuary_core::{Error, Result};
7
8pub type SqliteConn = Arc<Mutex<Connection>>;
9
10#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
11pub struct SqliteDatabaseConfig;
12
13pub struct SqliteDatabase {
14 conn: SqliteConn,
15 config: SqliteDatabaseConfig,
16}
17
18impl SqliteDatabase {
19 pub fn open(path: impl AsRef<Path>) -> Result<Self> {
20 let conn = Connection::open(path).map_err(|e| Error::Store(e.to_string()))?;
21 Self::init(conn, SqliteDatabaseConfig)
22 }
23
24 pub fn open_in_memory() -> Result<Self> {
25 let conn = Connection::open_in_memory().map_err(|e| Error::Store(e.to_string()))?;
26 Self::init(conn, SqliteDatabaseConfig)
27 }
28
29 pub fn open_with_config(path: impl AsRef<Path>, config: SqliteDatabaseConfig) -> Result<Self> {
30 let conn = Connection::open(path).map_err(|e| Error::Store(e.to_string()))?;
31 Self::init(conn, config)
32 }
33
34 pub fn open_in_memory_with_config(config: SqliteDatabaseConfig) -> Result<Self> {
35 let conn = Connection::open_in_memory().map_err(|e| Error::Store(e.to_string()))?;
36 Self::init(conn, config)
37 }
38
39 fn init(conn: Connection, config: SqliteDatabaseConfig) -> Result<Self> {
40 let _: String = conn
41 .pragma_update_and_check(None, "journal_mode", "WAL", |row| row.get(0))
42 .map_err(|e| Error::Store(e.to_string()))?;
43
44 Ok(Self {
45 conn: Arc::new(Mutex::new(conn)),
46 config,
47 })
48 }
49
50 pub fn conn(&self) -> SqliteConn {
51 Arc::clone(&self.conn)
52 }
53
54 pub fn config(&self) -> &SqliteDatabaseConfig {
55 &self.config
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn default_config_is_empty_database_config() {
65 let default_config: SqliteDatabaseConfig = Default::default();
66 assert_eq!(default_config, SqliteDatabaseConfig);
67 }
68
69 #[test]
70 fn open_in_memory_creates_no_component_tables() {
71 let db = SqliteDatabase::open_in_memory().unwrap();
72 let conn = db.conn();
73 let guard = conn.lock().unwrap();
74 let count: i64 = guard
75 .query_row(
76 "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'",
77 [],
78 |row| row.get(0),
79 )
80 .unwrap();
81 assert_eq!(count, 0);
82 }
83}