Skip to main content

sql_middleware/sqlite/
config_options.rs

1use std::path::PathBuf;
2
3use crate::middleware::{ConfigAndPool, DatabaseType, MiddlewarePool, SqlMiddlewareDbError};
4
5use super::config::SqliteManager;
6
7/// Options for configuring a `SQLite` pool.
8#[derive(Debug, Clone)]
9pub struct SqliteOptions {
10    pub db_path: PathBuf,
11    pub translate_placeholders: bool,
12}
13
14impl SqliteOptions {
15    #[must_use]
16    pub fn new(db_path: String) -> Self {
17        Self {
18            db_path: db_path.into(),
19            translate_placeholders: false,
20        }
21    }
22
23    #[must_use]
24    pub fn from_path(db_path: impl Into<PathBuf>) -> Self {
25        Self {
26            db_path: db_path.into(),
27            translate_placeholders: false,
28        }
29    }
30
31    #[must_use]
32    pub fn with_translation(mut self, translate_placeholders: bool) -> Self {
33        self.translate_placeholders = translate_placeholders;
34        self
35    }
36}
37
38/// Fluent builder for `SQLite` options.
39#[derive(Debug, Clone)]
40pub struct SqliteOptionsBuilder {
41    opts: SqliteOptions,
42}
43
44impl SqliteOptionsBuilder {
45    #[must_use]
46    pub fn new(db_path: String) -> Self {
47        Self {
48            opts: SqliteOptions::new(db_path),
49        }
50    }
51
52    #[must_use]
53    pub fn from_path(db_path: impl Into<PathBuf>) -> Self {
54        Self {
55            opts: SqliteOptions::from_path(db_path),
56        }
57    }
58
59    #[must_use]
60    pub fn translation(mut self, translate_placeholders: bool) -> Self {
61        self.opts.translate_placeholders = translate_placeholders;
62        self
63    }
64
65    #[must_use]
66    pub fn finish(self) -> SqliteOptions {
67        self.opts
68    }
69
70    /// Build a `ConfigAndPool` for `SQLite`.
71    ///
72    /// # Errors
73    ///
74    /// Returns `SqlMiddlewareDbError` if pool creation or the initial smoke test fails.
75    pub async fn build(self) -> Result<ConfigAndPool, SqlMiddlewareDbError> {
76        ConfigAndPool::new_sqlite(self.finish()).await
77    }
78}
79
80impl ConfigAndPool {
81    #[must_use]
82    pub fn sqlite_builder(db_path: String) -> SqliteOptionsBuilder {
83        SqliteOptionsBuilder::new(db_path)
84    }
85
86    #[must_use]
87    pub fn sqlite_path_builder(db_path: impl Into<PathBuf>) -> SqliteOptionsBuilder {
88        SqliteOptionsBuilder::from_path(db_path)
89    }
90
91    /// Asynchronous initializer for `ConfigAndPool` with Sqlite using a bb8-backed pool.
92    ///
93    /// # Errors
94    /// Returns `SqlMiddlewareDbError::ConnectionError` if pool creation or connection test fails.
95    pub async fn new_sqlite(opts: SqliteOptions) -> Result<Self, SqlMiddlewareDbError> {
96        let manager = SqliteManager::from_path(opts.db_path.clone());
97        let pool = manager.build_pool().await?;
98
99        {
100            let mut conn = pool.get_owned().await.map_err(|e| {
101                SqlMiddlewareDbError::ConnectionError(format!("Failed to create SQLite pool: {e}"))
102            })?;
103
104            crate::sqlite::apply_wal_pragmas(&mut conn).await?;
105        }
106
107        Ok(ConfigAndPool {
108            pool: MiddlewarePool::Sqlite(pool),
109            db_type: DatabaseType::Sqlite,
110            translate_placeholders: opts.translate_placeholders,
111        })
112    }
113}