Skip to main content

sql_middleware/query_builder/
dml.rs

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