sql_middleware/sqlite/worker/
connection.rs

1use std::fmt;
2use std::sync::Arc;
3
4use deadpool::managed::ObjectId;
5use deadpool_sqlite::Object;
6use deadpool_sqlite::rusqlite;
7
8use crate::middleware::{ResultSet, SqlMiddlewareDbError};
9use crate::sqlite::prepared::SqlitePreparedStatement;
10
11use super::manager::SqliteWorker;
12
13/// Owned `SQLite` connection backed by a dedicated worker thread.
14#[derive(Clone)]
15pub struct SqliteConnection {
16    worker: Arc<SqliteWorker>,
17}
18
19impl SqliteConnection {
20    /// Construct a worker-backed `SQLite` connection handle.
21    ///
22    /// # Errors
23    /// Returns [`SqlMiddlewareDbError`] if the background worker thread cannot be spawned.
24    pub fn new(object: Object) -> Result<Self, SqlMiddlewareDbError> {
25        let worker = SqliteWorker::spawn(object)?;
26        Ok(Self {
27            worker: Arc::new(worker),
28        })
29    }
30
31    /// Execute a batch of SQL statements on the worker-owned connection.
32    ///
33    /// # Errors
34    /// Propagates any [`SqlMiddlewareDbError`] produced while dispatching the command or running
35    /// the query batch within the worker.
36    pub async fn execute_batch(&self, query: String) -> Result<(), SqlMiddlewareDbError> {
37        self.worker.execute_batch(query).await
38    }
39
40    /// Execute a SQL query and return a [`ResultSet`] produced by the worker thread.
41    ///
42    /// # Errors
43    /// Returns any [`SqlMiddlewareDbError`] encountered while the worker prepares or evaluates the
44    /// statement, or if channel communication with the worker fails.
45    pub async fn execute_select(
46        &self,
47        query: String,
48        params: Vec<rusqlite::types::Value>,
49    ) -> Result<ResultSet, SqlMiddlewareDbError> {
50        self.worker.execute_select(query, params).await
51    }
52
53    /// Execute a DML statement (INSERT/UPDATE/DELETE) and return the affected row count.
54    ///
55    /// # Errors
56    /// Returns any [`SqlMiddlewareDbError`] reported by the worker while executing the statement or
57    /// relaying the result back to the caller.
58    pub async fn execute_dml(
59        &self,
60        query: String,
61        params: Vec<rusqlite::types::Value>,
62    ) -> Result<usize, SqlMiddlewareDbError> {
63        self.worker.execute_dml(query, params).await
64    }
65
66    /// Run synchronous `rusqlite` logic against the underlying worker-owned connection.
67    ///
68    /// # Errors
69    /// Propagates any [`SqlMiddlewareDbError`] raised while executing the callback or interacting
70    /// with the worker.
71    pub async fn with_connection<F, R>(&self, func: F) -> Result<R, SqlMiddlewareDbError>
72    where
73        F: FnOnce(&mut rusqlite::Connection) -> Result<R, SqlMiddlewareDbError> + Send + 'static,
74        R: Send + 'static,
75    {
76        self.worker.with_connection(func).await
77    }
78
79    /// Prepare a cached statement on the worker and return a reusable handle.
80    ///
81    /// # Errors
82    /// Returns [`SqlMiddlewareDbError`] if the worker fails to prepare the statement or if the
83    /// preparation channel is unexpectedly closed.
84    pub async fn prepare_statement(
85        &self,
86        query: &str,
87    ) -> Result<SqlitePreparedStatement, SqlMiddlewareDbError> {
88        let query_arc = Arc::new(query.to_owned());
89        self.worker
90            .prepare_statement(Arc::clone(&query_arc))
91            .await?;
92        Ok(SqlitePreparedStatement::new(self.clone(), query_arc))
93    }
94
95    /// Execute a previously prepared query statement on the worker.
96    ///
97    /// # Errors
98    /// Returns any [`SqlMiddlewareDbError`] produced while dispatching the command or running the
99    /// query on the worker connection.
100    pub(crate) async fn execute_prepared_select(
101        &self,
102        query: Arc<String>,
103        params: Vec<rusqlite::types::Value>,
104    ) -> Result<ResultSet, SqlMiddlewareDbError> {
105        self.worker.execute_prepared_select(query, params).await
106    }
107
108    /// Execute a previously prepared DML statement on the worker.
109    ///
110    /// # Errors
111    /// Returns any [`SqlMiddlewareDbError`] encountered while the worker runs the statement or if
112    /// communication with the worker fails.
113    pub(crate) async fn execute_prepared_dml(
114        &self,
115        query: Arc<String>,
116        params: Vec<rusqlite::types::Value>,
117    ) -> Result<usize, SqlMiddlewareDbError> {
118        self.worker.execute_prepared_dml(query, params).await
119    }
120
121    fn object_id(&self) -> ObjectId {
122        self.worker.object_id()
123    }
124}
125
126impl fmt::Debug for SqliteConnection {
127    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128        f.debug_struct("SqliteConnection")
129            .field("object_id", &self.object_id())
130            .finish()
131    }
132}