testkit_core/testdb/
transaction.rs1use async_trait::async_trait;
2
3#[async_trait]
9pub trait DBTransactionManager<Tx, Conn>: Send + Sync {
10 type Error: Send + Sync;
12
13 type Tx: DatabaseTransaction<Error = Self::Error> + Send + Sync;
15
16 async fn begin_transaction(&mut self) -> Result<Self::Tx, Self::Error>;
18
19 async fn commit_transaction(tx: &mut Self::Tx) -> Result<(), Self::Error>;
21
22 async fn rollback_transaction(tx: &mut Self::Tx) -> Result<(), Self::Error>;
24}
25
26#[async_trait]
31pub trait DatabaseTransaction: Send + Sync {
32 type Error: Send + Sync;
34
35 async fn commit(&mut self) -> Result<(), Self::Error>;
37
38 async fn rollback(&mut self) -> Result<(), Self::Error>;
40}
41
42#[cfg(test)]
44pub mod tests {
45 use super::*;
46 use crate::{
47 DatabaseBackend, DatabaseConfig, DatabaseName, DatabasePool, TestDatabaseConnection,
48 TestDatabaseInstance,
49 };
50 use std::fmt::Debug;
51
52 #[derive(Debug, Clone, Default)]
54 pub struct MockTransaction {
55 committed: bool,
56 rolled_back: bool,
57 }
58
59 impl MockTransaction {
60 pub fn is_committed(&self) -> bool {
61 self.committed
62 }
63
64 pub fn is_rolled_back(&self) -> bool {
65 self.rolled_back
66 }
67 }
68
69 #[async_trait]
70 impl DatabaseTransaction for MockTransaction {
71 type Error = String;
72
73 async fn commit(&mut self) -> Result<(), Self::Error> {
74 self.committed = true;
75 Ok(())
76 }
77
78 async fn rollback(&mut self) -> Result<(), Self::Error> {
79 self.rolled_back = true;
80 Ok(())
81 }
82 }
83
84 #[derive(Debug, Clone)]
86 pub struct MockConnection(i32);
87
88 impl MockConnection {
89 pub fn set_value(&mut self, value: i32) {
90 self.0 = value;
91 }
92
93 pub fn get_value(&self) -> i32 {
94 self.0
95 }
96 }
97
98 impl TestDatabaseConnection for MockConnection {
99 fn connection_string(&self) -> String {
100 format!("mock://localhost/test{}", self.0)
101 }
102 }
103
104 #[derive(Debug, Clone)]
106 pub struct MockPool;
107
108 #[async_trait]
109 impl DatabasePool for MockPool {
110 type Connection = MockConnection;
111 type Error = String;
112
113 async fn acquire(&self) -> Result<Self::Connection, Self::Error> {
114 Ok(MockConnection(0))
115 }
116
117 async fn release(&self, _conn: Self::Connection) -> Result<(), Self::Error> {
118 Ok(())
119 }
120
121 fn connection_string(&self) -> String {
122 "mock://localhost/test".to_string()
123 }
124 }
125
126 #[derive(Debug, Clone)]
128 pub struct MockBackend;
129
130 #[async_trait]
131 impl DatabaseBackend for MockBackend {
132 type Connection = MockConnection;
133 type Pool = MockPool;
134 type Error = String;
135
136 async fn new(_config: DatabaseConfig) -> Result<Self, Self::Error> {
137 Ok(MockBackend)
138 }
139
140 async fn connect(&self, _name: &DatabaseName) -> Result<Self::Connection, Self::Error> {
141 Ok(MockConnection(0))
142 }
143
144 async fn connect_with_string(
145 &self,
146 _connection_string: &str,
147 ) -> Result<Self::Connection, Self::Error> {
148 Ok(MockConnection(0))
149 }
150
151 async fn create_pool(
152 &self,
153 _name: &DatabaseName,
154 _config: &DatabaseConfig,
155 ) -> Result<Self::Pool, Self::Error> {
156 Ok(MockPool)
157 }
158
159 async fn create_database(
160 &self,
161 _pool: &Self::Pool,
162 _name: &DatabaseName,
163 ) -> Result<(), Self::Error> {
164 Ok(())
165 }
166
167 fn drop_database(&self, _name: &DatabaseName) -> Result<(), Self::Error> {
168 Ok(())
169 }
170
171 fn connection_string(&self, _name: &DatabaseName) -> String {
172 "mock://localhost/test".to_string()
173 }
174 }
175
176 #[async_trait]
178 impl DBTransactionManager<MockTransaction, MockConnection> for TestDatabaseInstance<MockBackend> {
179 type Error = String;
180 type Tx = MockTransaction;
181
182 async fn begin_transaction(&mut self) -> Result<Self::Tx, Self::Error> {
183 Ok(MockTransaction::default())
184 }
185
186 async fn commit_transaction(tx: &mut Self::Tx) -> Result<(), Self::Error> {
187 tx.commit().await
188 }
189
190 async fn rollback_transaction(tx: &mut Self::Tx) -> Result<(), Self::Error> {
191 tx.rollback().await
192 }
193 }
194}