pleme_database/
transaction.rs1use crate::Result;
4use async_trait::async_trait;
5
6#[cfg(feature = "postgres")]
7use sqlx::{Postgres, Transaction as SqlxTransaction};
8
9pub struct Transaction<'a> {
11 #[cfg(feature = "postgres")]
12 tx: SqlxTransaction<'a, Postgres>,
13}
14
15impl<'a> Transaction<'a> {
16 #[cfg(feature = "postgres")]
18 pub async fn commit(self) -> Result<()> {
19 self.tx
20 .commit()
21 .await
22 .map_err(|e| crate::DatabaseError::TransactionFailed(e.to_string()))
23 }
24
25 #[cfg(feature = "postgres")]
27 pub async fn rollback(self) -> Result<()> {
28 self.tx
29 .rollback()
30 .await
31 .map_err(|e| crate::DatabaseError::TransactionFailed(e.to_string()))
32 }
33}
34
35#[async_trait]
37pub trait Transactional {
38 async fn begin_transaction(&self) -> Result<Transaction>;
40
41 async fn with_transaction<F, T>(&self, f: F) -> Result<T>
43 where
44 F: FnOnce(&mut Transaction) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<T>> + Send>> + Send,
45 T: Send;
46}
47
48#[cfg(feature = "postgres")]
49#[async_trait]
50impl Transactional for crate::DatabasePool {
51 async fn begin_transaction(&self) -> Result<Transaction> {
52 let tx = self.inner()
53 .begin()
54 .await
55 .map_err(|e| crate::DatabaseError::TransactionFailed(e.to_string()))?;
56 Ok(Transaction { tx })
57 }
58
59 async fn with_transaction<F, T>(&self, _f: F) -> Result<T>
60 where
61 F: FnOnce(&mut Transaction) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<T>> + Send>> + Send,
62 T: Send,
63 {
64 unimplemented!("Use begin_transaction() for now")
66 }
67}