1use async_trait::async_trait;
2use std::fmt::Debug;
3use std::marker::PhantomData;
4
5use crate::testdb::{
6 DatabaseBackend, DatabasePool, TestDatabaseConnection,
7 transaction::{DBTransactionManager, DatabaseTransaction},
8};
9
10use crate::TestContext;
11
12pub trait TransactionStarter<DB: DatabaseBackend> {
14 type Transaction: DatabaseTransaction<Error = DB::Error> + Send + Sync + 'static;
16 type Connection: TestDatabaseConnection + Send + Sync + 'static;
18
19 fn begin_transaction_type() -> Self::Transaction;
21}
22
23impl<DB> TransactionStarter<DB> for TestContext<DB>
25where
26 DB: DatabaseBackend + Send + Sync + Debug + 'static,
27{
28 type Transaction = MockTransactionFor<DB>;
30 type Connection = MockConnectionFor<DB>;
31
32 fn begin_transaction_type() -> Self::Transaction {
33 panic!("This method should never be called")
35 }
36}
37
38pub struct MockTransactionFor<DB: DatabaseBackend>(PhantomData<DB>);
41pub struct MockConnectionFor<DB: DatabaseBackend>(PhantomData<DB>);
42
43#[async_trait]
45impl<DB: DatabaseBackend> DatabaseTransaction for MockTransactionFor<DB> {
46 type Error = DB::Error;
47
48 async fn commit(&mut self) -> Result<(), Self::Error> {
49 Ok(())
51 }
52
53 async fn rollback(&mut self) -> Result<(), Self::Error> {
54 Ok(())
56 }
57}
58
59impl<DB: DatabaseBackend> TestDatabaseConnection for MockConnectionFor<DB> {
60 fn connection_string(&self) -> String {
61 "mock".to_string()
62 }
63}
64
65#[async_trait]
67impl<DB, T, Conn> DBTransactionManager<T, Conn> for TestContext<DB>
68where
69 DB: DatabaseBackend + Send + Sync + Debug + 'static,
70 T: DatabaseTransaction<Error = DB::Error> + Send + Sync + 'static,
71 Conn: TestDatabaseConnection + Send + Sync + 'static,
72 DB::Pool: DatabasePool<Connection = Conn, Error = DB::Error>,
73{
74 type Error = DB::Error;
75 type Tx = T;
76
77 async fn begin_transaction(&mut self) -> Result<Self::Tx, Self::Error> {
79 Err(From::from(
87 "Transaction implementation is database-specific and must be provided for each backend"
88 .to_string(),
89 ))
90 }
91
92 async fn commit_transaction(tx: &mut Self::Tx) -> Result<(), Self::Error> {
94 tx.commit().await
95 }
96
97 async fn rollback_transaction(tx: &mut Self::Tx) -> Result<(), Self::Error> {
99 tx.rollback().await
100 }
101}