1use crate::{
2 DbBackend, DbErr, ExecResult, QueryResult, Statement, StatementBuilder, TransactionError,
3};
4
5pub trait ConnectionTrait {
8 fn get_database_backend(&self) -> DbBackend;
10
11 fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr>;
13
14 fn execute<S: StatementBuilder>(&self, stmt: &S) -> Result<ExecResult, DbErr> {
16 let db_backend = self.get_database_backend();
17 let stmt = db_backend.build(stmt);
18 self.execute_raw(stmt)
19 }
20
21 fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr>;
23
24 fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr>;
26
27 fn query_one<S: StatementBuilder>(&self, stmt: &S) -> Result<Option<QueryResult>, DbErr> {
29 let db_backend = self.get_database_backend();
30 let stmt = db_backend.build(stmt);
31 self.query_one_raw(stmt)
32 }
33
34 fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr>;
36
37 fn query_all<S: StatementBuilder>(&self, stmt: &S) -> Result<Vec<QueryResult>, DbErr> {
39 let db_backend = self.get_database_backend();
40 let stmt = db_backend.build(stmt);
41 self.query_all_raw(stmt)
42 }
43
44 fn support_returning(&self) -> bool {
46 let db_backend = self.get_database_backend();
47 db_backend.support_returning()
48 }
49
50 fn is_mock_connection(&self) -> bool {
52 false
53 }
54}
55
56pub trait StreamTrait {
58 type Stream<'a>: Iterator<Item = Result<QueryResult, DbErr>>
60 where
61 Self: 'a;
62
63 fn get_database_backend(&self) -> DbBackend;
65
66 fn stream_raw<'a>(&'a self, stmt: Statement) -> Result<Self::Stream<'a>, DbErr>;
68
69 fn stream<'a, S: StatementBuilder>(&'a self, stmt: &S) -> Result<Self::Stream<'a>, DbErr> {
71 let db_backend = self.get_database_backend();
72 let stmt = db_backend.build(stmt);
73 self.stream_raw(stmt)
74 }
75}
76
77#[derive(Copy, Clone, Debug, PartialEq, Eq)]
78pub enum IsolationLevel {
80 RepeatableRead,
82 ReadCommitted,
84 ReadUncommitted,
86 Serializable,
88}
89
90impl std::fmt::Display for IsolationLevel {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 match self {
93 IsolationLevel::RepeatableRead => write!(f, "REPEATABLE READ"),
94 IsolationLevel::ReadCommitted => write!(f, "READ COMMITTED"),
95 IsolationLevel::ReadUncommitted => write!(f, "READ UNCOMMITTED"),
96 IsolationLevel::Serializable => write!(f, "SERIALIZABLE"),
97 }
98 }
99}
100
101#[derive(Copy, Clone, Debug, PartialEq, Eq)]
102pub enum AccessMode {
104 ReadOnly,
106 ReadWrite,
108}
109
110impl std::fmt::Display for AccessMode {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 match self {
113 AccessMode::ReadOnly => write!(f, "READ ONLY"),
114 AccessMode::ReadWrite => write!(f, "READ WRITE"),
115 }
116 }
117}
118
119#[derive(Copy, Clone, Debug, PartialEq, Eq)]
120pub enum SqliteTransactionMode {
123 Deferred,
126 Immediate,
128 Exclusive,
132}
133
134impl SqliteTransactionMode {
135 pub fn sqlite_keyword(&self) -> &'static str {
137 match self {
138 SqliteTransactionMode::Deferred => "DEFERRED",
139 SqliteTransactionMode::Immediate => "IMMEDIATE",
140 SqliteTransactionMode::Exclusive => "EXCLUSIVE",
141 }
142 }
143}
144
145#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
147pub struct TransactionOptions {
148 pub isolation_level: Option<IsolationLevel>,
150 pub access_mode: Option<AccessMode>,
152 pub sqlite_transaction_mode: Option<SqliteTransactionMode>,
154}
155
156pub trait TransactionTrait {
158 type Transaction: ConnectionTrait + TransactionTrait + TransactionSession;
160
161 fn begin(&self) -> Result<Self::Transaction, DbErr>;
164
165 fn begin_with_config(
168 &self,
169 isolation_level: Option<IsolationLevel>,
170 access_mode: Option<AccessMode>,
171 ) -> Result<Self::Transaction, DbErr>;
172
173 fn begin_with_options(&self, options: TransactionOptions) -> Result<Self::Transaction, DbErr>;
176
177 fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>
180 where
181 F: for<'c> FnOnce(&'c Self::Transaction) -> Result<T, E>,
182 E: std::fmt::Display + std::fmt::Debug;
183
184 fn transaction_with_config<F, T, E>(
187 &self,
188 callback: F,
189 isolation_level: Option<IsolationLevel>,
190 access_mode: Option<AccessMode>,
191 ) -> Result<T, TransactionError<E>>
192 where
193 F: for<'c> FnOnce(&'c Self::Transaction) -> Result<T, E>,
194 E: std::fmt::Display + std::fmt::Debug;
195}
196
197pub trait TransactionSession {
199 fn commit(self) -> Result<(), DbErr>;
201
202 fn rollback(self) -> Result<(), DbErr>;
204}