use tokio::sync::Mutex;
use crate::error::FlozError;
use super::placeholder::replace_pg_placeholders;
pub(crate) enum TxInner {
#[cfg(feature = "postgres")]
Postgres(Mutex<sqlx::pool::PoolConnection<sqlx::Postgres>>),
#[cfg(feature = "sqlite")]
Sqlite(Mutex<sqlx::pool::PoolConnection<sqlx::Sqlite>>),
}
pub struct Tx {
pub(crate) inner: TxInner,
pub(crate) committed: bool,
}
impl Tx {
#[allow(unreachable_patterns)]
pub async fn commit(mut self) -> Result<(), FlozError> {
match &self.inner {
#[cfg(feature = "postgres")]
TxInner::Postgres(conn) => {
let mut c = conn.lock().await;
sqlx::query("COMMIT").execute(&mut **c).await?;
}
#[cfg(feature = "sqlite")]
TxInner::Sqlite(conn) => {
let mut c = conn.lock().await;
sqlx::query("COMMIT").execute(&mut **c).await?;
}
_ => unreachable!("no database backend enabled"),
}
self.committed = true;
Ok(())
}
#[allow(unreachable_patterns)]
pub async fn rollback(self) -> Result<(), FlozError> {
match &self.inner {
#[cfg(feature = "postgres")]
TxInner::Postgres(conn) => {
let mut c = conn.lock().await;
sqlx::query("ROLLBACK").execute(&mut **c).await?;
}
#[cfg(feature = "sqlite")]
TxInner::Sqlite(conn) => {
let mut c = conn.lock().await;
sqlx::query("ROLLBACK").execute(&mut **c).await?;
}
_ => unreachable!("no database backend enabled"),
}
Ok(())
}
#[allow(unreachable_patterns)]
pub(crate) fn adjust_sql(&self, sql: &str) -> String {
match &self.inner {
#[cfg(feature = "postgres")]
TxInner::Postgres(_) => sql.to_string(),
#[cfg(feature = "sqlite")]
TxInner::Sqlite(_) => replace_pg_placeholders(sql),
_ => unreachable!("no database backend enabled"),
}
}
}
impl std::fmt::Debug for Tx {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Tx")
.field("committed", &self.committed)
.finish()
}
}