sql_middleware/sqlite/connection/
select.rs

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