Skip to main content

sql_middleware/sqlite/connection/
prepared.rs

1use crate::middleware::SqlMiddlewareDbError;
2use crate::types::StatementCacheMode;
3
4use super::{SqliteConnection, run_blocking};
5
6impl SqliteConnection {
7    /// Prepare a statement for repeated execution (auto-commit mode only).
8    ///
9    /// # Errors
10    /// Returns `SqlMiddlewareDbError` if preparing the statement fails or a transaction is active.
11    pub async fn prepare_statement(
12        &mut self,
13        query: &str,
14    ) -> Result<crate::sqlite::prepared::SqlitePreparedStatement<'_>, SqlMiddlewareDbError> {
15        self.prepare_statement_with_cache_mode(query, StatementCacheMode::Cached)
16            .await
17    }
18
19    /// Prepare a statement for repeated execution (auto-commit mode only) with explicit cache mode.
20    ///
21    /// # Errors
22    /// Returns `SqlMiddlewareDbError` if preparing the statement fails or a transaction is active.
23    pub async fn prepare_statement_with_cache_mode(
24        &mut self,
25        query: &str,
26        statement_cache_mode: StatementCacheMode,
27    ) -> Result<crate::sqlite::prepared::SqlitePreparedStatement<'_>, SqlMiddlewareDbError> {
28        if self.in_transaction {
29            return Err(SqlMiddlewareDbError::ExecutionError(
30                "SQLite transaction in progress; operation not permitted (prepare statement)"
31                    .into(),
32            ));
33        }
34        let query_arc = std::sync::Arc::new(query.to_owned());
35        // warm the cache so repeated executions don't re-prepare.
36        let query_clone = std::sync::Arc::clone(&query_arc);
37        run_blocking(self.conn_handle(), move |guard| {
38            match statement_cache_mode {
39                StatementCacheMode::Cached => {
40                    let _ = guard
41                        .prepare_cached(query_clone.as_ref())
42                        .map_err(SqlMiddlewareDbError::SqliteError)?;
43                }
44                StatementCacheMode::Uncached => {
45                    let _ = guard
46                        .prepare(query_clone.as_ref())
47                        .map_err(SqlMiddlewareDbError::SqliteError)?;
48                }
49            }
50            Ok(())
51        })
52        .await?;
53        Ok(crate::sqlite::prepared::SqlitePreparedStatement::new(
54            self,
55            query_arc,
56            statement_cache_mode,
57        ))
58    }
59}