Skip to main content

sql_middleware/query_builder/
select.rs

1use crate::error::SqlMiddlewareDbError;
2use crate::executor::{
3    QueryTarget, QueryTargetKind, execute_select_dispatch, execute_select_prepared_dispatch,
4};
5use crate::pool::MiddlewarePoolConnection;
6use crate::results::ResultSet;
7use crate::translation::PrepareMode;
8use crate::types::RowValues;
9
10#[cfg(feature = "postgres")]
11use crate::postgres::typed::PgManager;
12#[cfg(feature = "sqlite")]
13use crate::sqlite::config::SqliteManager;
14#[cfg(feature = "turso")]
15use crate::typed_turso::TursoManager;
16#[cfg(any(feature = "postgres", feature = "sqlite", feature = "turso"))]
17use bb8::PooledConnection;
18
19use super::{QueryBuilder, translate_query_for_target};
20
21impl QueryBuilder<'_, '_> {
22    /// Execute a SELECT and return the result set.
23    ///
24    /// # Errors
25    /// Returns an error if placeholder translation fails or the backend query execution fails.
26    pub async fn select(self) -> Result<ResultSet, SqlMiddlewareDbError> {
27        let translated = translate_query_for_target(
28            &self.target,
29            self.sql.as_ref(),
30            self.params.as_ref(),
31            self.options,
32        );
33        let use_prepare = matches!(self.options.prepare, PrepareMode::Prepared);
34
35        match self.target {
36            QueryTarget {
37                kind: QueryTargetKind::Connection(conn),
38                ..
39            } => {
40                select_on_connection(conn, translated.as_ref(), self.params.as_ref(), use_prepare)
41                    .await
42            }
43            #[cfg(feature = "sqlite")]
44            QueryTarget {
45                kind:
46                    QueryTargetKind::TypedSqlite { conn } | QueryTargetKind::TypedSqliteTx { conn },
47                ..
48            } => select_typed_sqlite(conn, translated.as_ref(), self.params.as_ref()).await,
49            #[cfg(feature = "postgres")]
50            QueryTarget {
51                kind:
52                    QueryTargetKind::TypedPostgres { conn } | QueryTargetKind::TypedPostgresTx { conn },
53                ..
54            } => {
55                select_typed_postgres(conn, translated.as_ref(), self.params.as_ref(), use_prepare)
56                    .await
57            }
58            #[cfg(feature = "turso")]
59            QueryTarget {
60                kind: QueryTargetKind::TypedTurso { conn } | QueryTargetKind::TypedTursoTx { conn },
61                ..
62            } => select_typed_turso(conn, translated.as_ref(), self.params.as_ref()).await,
63            #[cfg(feature = "postgres")]
64            QueryTarget {
65                kind: QueryTargetKind::PostgresTx(tx),
66                ..
67            } => {
68                if use_prepare {
69                    let prepared = tx.prepare(translated.as_ref()).await?;
70                    tx.query_prepared(&prepared, self.params.as_ref()).await
71                } else {
72                    tx.query(translated.as_ref(), self.params.as_ref()).await
73                }
74            }
75            #[cfg(feature = "mssql")]
76            QueryTarget {
77                kind: QueryTargetKind::MssqlTx(tx),
78                ..
79            } => {
80                if use_prepare {
81                    let prepared = tx.prepare(translated.as_ref())?;
82                    tx.query_prepared(&prepared, self.params.as_ref()).await
83                } else {
84                    tx.query(translated.as_ref(), self.params.as_ref()).await
85                }
86            }
87            #[cfg(feature = "turso")]
88            QueryTarget {
89                kind: QueryTargetKind::TursoTx(tx),
90                ..
91            } => {
92                if use_prepare {
93                    let mut prepared = tx.prepare(translated.as_ref()).await?;
94                    tx.query_prepared(&mut prepared, self.params.as_ref()).await
95                } else {
96                    tx.execute_select(translated.as_ref(), self.params.as_ref())
97                        .await
98                }
99            }
100        }
101    }
102}
103
104async fn select_on_connection(
105    conn: &mut MiddlewarePoolConnection,
106    query: &str,
107    params: &[RowValues],
108    use_prepare: bool,
109) -> Result<ResultSet, SqlMiddlewareDbError> {
110    if use_prepare {
111        execute_select_prepared_dispatch(conn, query, params).await
112    } else {
113        execute_select_dispatch(conn, query, params).await
114    }
115}
116
117#[cfg(feature = "sqlite")]
118async fn select_typed_sqlite(
119    conn: &mut PooledConnection<'static, SqliteManager>,
120    query: &str,
121    params: &[RowValues],
122) -> Result<ResultSet, SqlMiddlewareDbError> {
123    crate::sqlite::connection::select(conn, query, params).await
124}
125
126#[cfg(feature = "postgres")]
127async fn select_typed_postgres(
128    conn: &mut PooledConnection<'static, PgManager>,
129    query: &str,
130    params: &[RowValues],
131    use_prepare: bool,
132) -> Result<ResultSet, SqlMiddlewareDbError> {
133    if use_prepare {
134        crate::typed_postgres::select_prepared(conn, query, params).await
135    } else {
136        crate::typed_postgres::select(conn, query, params).await
137    }
138}
139
140#[cfg(feature = "turso")]
141async fn select_typed_turso(
142    conn: &mut PooledConnection<'static, TursoManager>,
143    query: &str,
144    params: &[RowValues],
145) -> Result<ResultSet, SqlMiddlewareDbError> {
146    crate::typed_turso::select(conn, query, params).await
147}