use std::future::Future;
use super::connection::Db;
use sea_orm::TransactionTrait;
pub struct Transaction;
impl Transaction {
pub async fn orm<F, T>(db: &Db, f: F) -> Result<T, crate::Error>
where
F: for<'c> FnOnce(
&'c sea_orm::DatabaseTransaction,
) -> std::pin::Pin<
Box<dyn Future<Output = Result<T, sea_orm::DbErr>> + Send + 'c>,
> + Send,
T: Send,
{
db.orm().transaction(f).await.map_err(|e| match e {
sea_orm::TransactionError::Connection(err)
| sea_orm::TransactionError::Transaction(err) => crate::Error::from(err),
})
}
pub async fn sqlx<F, T>(db: &Db, f: F) -> Result<T, crate::Error>
where
F: for<'c> FnOnce(
&'c mut sqlx::Transaction<'_, super::Driver>,
) -> std::pin::Pin<
Box<dyn Future<Output = Result<T, sqlx::Error>> + Send + 'c>,
>,
T: Send,
{
let mut txn = db.sqlx().begin().await.map_err(crate::Error::from)?;
match f(&mut txn).await {
Ok(value) => {
txn.commit().await.map_err(crate::Error::from)?;
Ok(value)
}
Err(error) => {
drop(txn);
Err(crate::Error::from(error))
}
}
}
}