sql_middleware/executor/
dispatch.rs

1use crate::error::SqlMiddlewareDbError;
2use crate::pool::MiddlewarePoolConnection;
3use crate::query_builder::QueryBuilder;
4use crate::results::ResultSet;
5use crate::types::RowValues;
6
7#[cfg(feature = "mssql")]
8use crate::mssql;
9#[cfg(feature = "postgres")]
10use crate::postgres;
11#[cfg(feature = "sqlite")]
12use crate::sqlite;
13#[cfg(feature = "turso")]
14use crate::turso;
15
16use super::targets::{BatchTarget, QueryTarget};
17
18/// Execute a batch against either a connection or a transaction.
19///
20/// # Errors
21/// Returns an error propagated from the underlying backend execution or transaction context.
22pub async fn execute_batch(
23    target: impl Into<BatchTarget<'_>>,
24    query: &str,
25) -> Result<(), SqlMiddlewareDbError> {
26    match target.into() {
27        BatchTarget::Connection(conn) => conn.execute_batch(query).await,
28        #[cfg(feature = "postgres")]
29        BatchTarget::PostgresTx(tx) => tx.execute_batch(query).await,
30        #[cfg(feature = "mssql")]
31        BatchTarget::MssqlTx(tx) => tx.execute_batch(query).await,
32        #[cfg(feature = "turso")]
33        BatchTarget::TursoTx(tx) => tx.execute_batch(query).await,
34        #[cfg(feature = "turso")]
35        BatchTarget::TypedTurso { conn } => {
36            crate::typed_turso::dml(conn, query, &[]).await?;
37            Ok(())
38        }
39        #[cfg(feature = "turso")]
40        BatchTarget::TypedTursoTx { conn } => {
41            crate::typed_turso::dml(conn, query, &[]).await?;
42            Ok(())
43        }
44    }
45}
46
47/// Start a fluent builder for either a connection or a transaction.
48pub fn query<'a>(target: impl Into<QueryTarget<'a>>, sql: &'a str) -> QueryBuilder<'a, 'a> {
49    QueryBuilder::new_target(target.into(), sql)
50}
51
52impl MiddlewarePoolConnection {
53    /// Executes a batch of SQL queries within a transaction by delegating to the specific database module.
54    ///
55    /// # Errors
56    /// Returns an error if the selected backend cannot execute the batch or the database responds with an error.
57    pub async fn execute_batch(&mut self, query: &str) -> Result<(), SqlMiddlewareDbError> {
58        match self {
59            #[cfg(feature = "postgres")]
60            MiddlewarePoolConnection::Postgres {
61                client: pg_client, ..
62            } => postgres::execute_batch(pg_client, query).await,
63            #[cfg(feature = "sqlite")]
64            MiddlewarePoolConnection::Sqlite { .. } => {
65                let sqlite_client = self.sqlite_conn_mut()?;
66                sqlite::execute_batch(sqlite_client, query).await
67            }
68            #[cfg(feature = "mssql")]
69            MiddlewarePoolConnection::Mssql {
70                conn: mssql_client, ..
71            } => mssql::execute_batch(mssql_client, query).await,
72            #[cfg(feature = "turso")]
73            MiddlewarePoolConnection::Turso {
74                conn: turso_conn, ..
75            } => turso::execute_batch(turso_conn, query).await,
76            #[allow(unreachable_patterns)]
77            _ => Err(SqlMiddlewareDbError::Unimplemented(
78                "This database type is not enabled in the current build".to_string(),
79            )),
80        }
81    }
82
83    /// Start a fluent query builder that can translate placeholders before executing.
84    ///
85    /// # Examples
86    /// ```rust,no_run
87    /// use sql_middleware::prelude::*;
88    ///
89    /// # async fn demo() -> Result<(), SqlMiddlewareDbError> {
90    /// let cap = ConfigAndPool::new_sqlite("file::memory:?cache=shared".into()).await?;
91    /// let mut conn = cap.get_connection().await?;
92    /// conn.execute_batch("CREATE TABLE t (id INTEGER)").await?;
93    ///
94    /// let rows = conn
95    ///     .query("SELECT id FROM t WHERE id = ?1")
96    ///     .params(&[RowValues::Int(1)])
97    ///     .select()
98    ///     .await?;
99    /// assert!(rows.results.is_empty());
100    /// # Ok(()) }
101    /// ```
102    pub fn query<'a>(&'a mut self, query: &'a str) -> QueryBuilder<'a, 'a> {
103        QueryBuilder::new(self, query)
104    }
105}
106
107pub(crate) async fn execute_select_dispatch(
108    conn: &mut MiddlewarePoolConnection,
109    query: &str,
110    params: &[RowValues],
111) -> Result<ResultSet, SqlMiddlewareDbError> {
112    match conn {
113        #[cfg(feature = "postgres")]
114        MiddlewarePoolConnection::Postgres {
115            client: pg_client, ..
116        } => postgres::execute_select(pg_client, query, params).await,
117        #[cfg(feature = "sqlite")]
118        MiddlewarePoolConnection::Sqlite { .. } => {
119            let sqlite_client = conn.sqlite_conn_mut()?;
120            sqlite::execute_select(sqlite_client, query, params).await
121        }
122        #[cfg(feature = "mssql")]
123        MiddlewarePoolConnection::Mssql {
124            conn: mssql_client, ..
125        } => mssql::execute_select(mssql_client, query, params).await,
126        #[cfg(feature = "turso")]
127        MiddlewarePoolConnection::Turso {
128            conn: turso_conn, ..
129        } => turso::execute_select(turso_conn, query, params).await,
130        #[allow(unreachable_patterns)]
131        _ => Err(SqlMiddlewareDbError::Unimplemented(
132            "This database type is not enabled in the current build".to_string(),
133        )),
134    }
135}
136
137pub(crate) async fn execute_dml_dispatch(
138    conn: &mut MiddlewarePoolConnection,
139    query: &str,
140    params: &[RowValues],
141) -> Result<usize, SqlMiddlewareDbError> {
142    match conn {
143        #[cfg(feature = "postgres")]
144        MiddlewarePoolConnection::Postgres {
145            client: pg_client, ..
146        } => postgres::execute_dml(pg_client, query, params).await,
147        #[cfg(feature = "sqlite")]
148        MiddlewarePoolConnection::Sqlite { .. } => {
149            let sqlite_client = conn.sqlite_conn_mut()?;
150            sqlite::execute_dml(sqlite_client, query, params).await
151        }
152        #[cfg(feature = "mssql")]
153        MiddlewarePoolConnection::Mssql {
154            conn: mssql_client, ..
155        } => mssql::execute_dml(mssql_client, query, params).await,
156        #[cfg(feature = "turso")]
157        MiddlewarePoolConnection::Turso {
158            conn: turso_conn, ..
159        } => turso::execute_dml(turso_conn, query, params).await,
160        #[allow(unreachable_patterns)]
161        _ => Err(SqlMiddlewareDbError::Unimplemented(
162            "This database type is not enabled in the current build".to_string(),
163        )),
164    }
165}