1use tokio::sync::Mutex;
9
10use crate::error::FlozError;
11use super::placeholder::replace_pg_placeholders;
12
13pub(crate) enum TxInner {
15 #[cfg(feature = "postgres")]
16 Postgres(Mutex<sqlx::pool::PoolConnection<sqlx::Postgres>>),
17 #[cfg(feature = "sqlite")]
18 Sqlite(Mutex<sqlx::pool::PoolConnection<sqlx::Sqlite>>),
19}
20
21pub struct Tx {
23 pub(crate) inner: TxInner,
24 pub(crate) committed: bool,
25}
26
27impl Tx {
28 #[allow(unreachable_patterns)]
30 pub async fn commit(mut self) -> Result<(), FlozError> {
31 match &self.inner {
32 #[cfg(feature = "postgres")]
33 TxInner::Postgres(conn) => {
34 let mut c = conn.lock().await;
35 sqlx::query("COMMIT").execute(&mut **c).await?;
36 }
37 #[cfg(feature = "sqlite")]
38 TxInner::Sqlite(conn) => {
39 let mut c = conn.lock().await;
40 sqlx::query("COMMIT").execute(&mut **c).await?;
41 }
42 _ => unreachable!("no database backend enabled"),
43 }
44 self.committed = true;
45 Ok(())
46 }
47
48 #[allow(unreachable_patterns)]
50 pub async fn rollback(self) -> Result<(), FlozError> {
51 match &self.inner {
52 #[cfg(feature = "postgres")]
53 TxInner::Postgres(conn) => {
54 let mut c = conn.lock().await;
55 sqlx::query("ROLLBACK").execute(&mut **c).await?;
56 }
57 #[cfg(feature = "sqlite")]
58 TxInner::Sqlite(conn) => {
59 let mut c = conn.lock().await;
60 sqlx::query("ROLLBACK").execute(&mut **c).await?;
61 }
62 _ => unreachable!("no database backend enabled"),
63 }
64 Ok(())
65 }
66
67 #[allow(unreachable_patterns)]
69 pub(crate) fn adjust_sql(&self, sql: &str) -> String {
70 match &self.inner {
71 #[cfg(feature = "postgres")]
72 TxInner::Postgres(_) => sql.to_string(),
73 #[cfg(feature = "sqlite")]
74 TxInner::Sqlite(_) => replace_pg_placeholders(sql),
75 _ => unreachable!("no database backend enabled"),
76 }
77 }
78}
79
80impl std::fmt::Debug for Tx {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 f.debug_struct("Tx")
83 .field("committed", &self.committed)
84 .finish()
85 }
86}