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};
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    ) -> Result<ResultSet, SqlMiddlewareDbError>
24    where
25        F: FnOnce(
26                &mut rusqlite::Statement<'_>,
27                &[rusqlite::types::Value],
28            ) -> Result<ResultSet, SqlMiddlewareDbError>
29            + Send
30            + 'static,
31    {
32        let sql_owned = query.to_owned();
33        let params_owned = params.to_vec();
34        run_blocking(self.conn_handle(), move |guard| {
35            let mut stmt = guard
36                .prepare_cached(&sql_owned)
37                .map_err(SqlMiddlewareDbError::SqliteError)?;
38            builder(&mut stmt, &params_owned)
39        })
40        .await
41    }
42
43    /// Execute a query inside an open transaction and build a `ResultSet`.
44    ///
45    /// # Errors
46    /// Returns `SqlMiddlewareDbError` if preparing/executing the query fails or the transaction is not active.
47    pub async fn execute_select_in_tx<F>(
48        &mut self,
49        query: &str,
50        params: &[rusqlite::types::Value],
51        builder: F,
52    ) -> Result<ResultSet, SqlMiddlewareDbError>
53    where
54        F: FnOnce(
55                &mut rusqlite::Statement<'_>,
56                &[rusqlite::types::Value],
57            ) -> Result<ResultSet, SqlMiddlewareDbError>
58            + Send
59            + 'static,
60    {
61        if !self.in_transaction {
62            return Err(SqlMiddlewareDbError::ExecutionError(
63                "SQLite transaction not active".into(),
64            ));
65        }
66        let sql_owned = query.to_owned();
67        let params_owned = params.to_vec();
68        run_blocking(self.conn_handle(), move |guard| {
69            let mut stmt = guard
70                .prepare_cached(&sql_owned)
71                .map_err(SqlMiddlewareDbError::SqliteError)?;
72            builder(&mut stmt, &params_owned)
73        })
74        .await
75    }
76
77    /// Start a query builder (auto-commit per operation).
78    pub fn query<'a>(&'a mut self, sql: &'a str) -> QueryBuilder<'a, 'a> {
79        QueryBuilder::new_target(QueryTarget::from_typed_sqlite(&mut self.conn, false), sql)
80    }
81}
82
83/// Adapter for query builder select (typed-sqlite target).
84///
85/// # Errors
86/// Returns `SqlMiddlewareDbError` if converting parameters or executing the query fails.
87pub async fn select(
88    conn: &mut bb8::PooledConnection<'static, SqliteManager>,
89    query: &str,
90    params: &[RowValues],
91) -> Result<ResultSet, SqlMiddlewareDbError> {
92    let converted = convert_params::<Params>(params, ConversionMode::Query)?.0;
93    let sql_owned = query.to_owned();
94    let params_owned = converted.clone();
95    let handle = Arc::clone(&*conn);
96    run_blocking(handle, move |guard| {
97        let mut stmt = guard
98            .prepare_cached(&sql_owned)
99            .map_err(SqlMiddlewareDbError::SqliteError)?;
100        super::super::query::build_result_set(&mut stmt, &params_owned)
101    })
102    .await
103}