Skip to main content

sql_middleware/sqlite/connection/
select.rs

1use std::sync::Arc;
2
3use crate::adapters::params::convert_params;
4use crate::executor::QueryTarget;
5use crate::middleware::{ConversionMode, ResultSet, SqlMiddlewareDbError, StatementCacheMode};
6use crate::query_builder::QueryBuilder;
7use crate::types::RowValues;
8
9use super::{SqliteConnection, run_blocking};
10use crate::sqlite::config::SqliteManager;
11use crate::sqlite::params::Params;
12
13impl SqliteConnection {
14    /// Execute a SELECT and materialize into a `ResultSet`.
15    ///
16    /// # Errors
17    /// Returns `SqlMiddlewareDbError` if preparing or executing the query fails.
18    pub async fn execute_select<F>(
19        &mut self,
20        query: &str,
21        params: &[rusqlite::types::Value],
22        builder: F,
23        statement_cache_mode: StatementCacheMode,
24    ) -> Result<ResultSet, SqlMiddlewareDbError>
25    where
26        F: FnOnce(
27                &mut rusqlite::Statement<'_>,
28                &[rusqlite::types::Value],
29            ) -> Result<ResultSet, SqlMiddlewareDbError>
30            + Send
31            + 'static,
32    {
33        let sql_owned = query.to_owned();
34        let params_owned = params.to_vec();
35        run_blocking(
36            self.conn_handle(),
37            move |guard| match statement_cache_mode {
38                StatementCacheMode::Cached => {
39                    let mut stmt = guard
40                        .prepare_cached(&sql_owned)
41                        .map_err(SqlMiddlewareDbError::SqliteError)?;
42                    builder(&mut stmt, &params_owned)
43                }
44                StatementCacheMode::Uncached => {
45                    let mut stmt = guard
46                        .prepare(&sql_owned)
47                        .map_err(SqlMiddlewareDbError::SqliteError)?;
48                    builder(&mut stmt, &params_owned)
49                }
50            },
51        )
52        .await
53    }
54
55    /// Execute a query inside an open transaction and build a `ResultSet`.
56    ///
57    /// # Errors
58    /// Returns `SqlMiddlewareDbError` if preparing/executing the query fails or the transaction is not active.
59    pub async fn execute_select_in_tx<F>(
60        &mut self,
61        query: &str,
62        params: &[rusqlite::types::Value],
63        builder: F,
64    ) -> Result<ResultSet, SqlMiddlewareDbError>
65    where
66        F: FnOnce(
67                &mut rusqlite::Statement<'_>,
68                &[rusqlite::types::Value],
69            ) -> Result<ResultSet, SqlMiddlewareDbError>
70            + Send
71            + 'static,
72    {
73        if !self.in_transaction {
74            return Err(SqlMiddlewareDbError::ExecutionError(
75                "SQLite transaction not active".into(),
76            ));
77        }
78        let sql_owned = query.to_owned();
79        let params_owned = params.to_vec();
80        run_blocking(self.conn_handle(), move |guard| {
81            let mut stmt = guard
82                .prepare_cached(&sql_owned)
83                .map_err(SqlMiddlewareDbError::SqliteError)?;
84            builder(&mut stmt, &params_owned)
85        })
86        .await
87    }
88
89    /// Start a query builder (auto-commit per operation).
90    pub fn query<'a>(&'a mut self, sql: &'a str) -> QueryBuilder<'a, 'a> {
91        QueryBuilder::new_target(QueryTarget::from_typed_sqlite(&mut self.conn, false), sql)
92    }
93}
94
95/// Adapter for query builder select (typed-sqlite target).
96///
97/// # Errors
98/// Returns `SqlMiddlewareDbError` if converting parameters or executing the query fails.
99pub async fn select(
100    conn: &mut bb8::PooledConnection<'static, SqliteManager>,
101    query: &str,
102    params: &[RowValues],
103) -> Result<ResultSet, SqlMiddlewareDbError> {
104    select_with_cache_mode(conn, query, params, StatementCacheMode::Cached).await
105}
106
107/// Adapter for query builder select with explicit statement cache mode.
108///
109/// # Errors
110/// Returns `SqlMiddlewareDbError` if converting parameters or executing the query fails.
111pub async fn select_with_cache_mode(
112    conn: &mut bb8::PooledConnection<'static, SqliteManager>,
113    query: &str,
114    params: &[RowValues],
115    statement_cache_mode: StatementCacheMode,
116) -> Result<ResultSet, SqlMiddlewareDbError> {
117    let converted = convert_params::<Params>(params, ConversionMode::Query)?.0;
118    let sql_owned = query.to_owned();
119    let params_owned = converted.clone();
120    let handle = Arc::clone(&*conn);
121    run_blocking(handle, move |guard| match statement_cache_mode {
122        StatementCacheMode::Cached => {
123            let mut stmt = guard
124                .prepare_cached(&sql_owned)
125                .map_err(SqlMiddlewareDbError::SqliteError)?;
126            super::super::query::build_result_set(&mut stmt, &params_owned)
127        }
128        StatementCacheMode::Uncached => {
129            let mut stmt = guard
130                .prepare(&sql_owned)
131                .map_err(SqlMiddlewareDbError::SqliteError)?;
132            super::super::query::build_result_set(&mut stmt, &params_owned)
133        }
134    })
135    .await
136}