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