1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use crate::{
DatabaseTransaction, DbBackend, DbErr, ExecResult, QueryResult, Statement, TransactionError,
};
use futures::Stream;
use std::{future::Future, pin::Pin};
#[async_trait::async_trait]
pub trait ConnectionTrait: Sync {
fn get_database_backend(&self) -> DbBackend;
async fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr>;
async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr>;
async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr>;
async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr>;
fn support_returning(&self) -> bool {
let db_backend = self.get_database_backend();
db_backend.support_returning()
}
fn is_mock_connection(&self) -> bool {
false
}
}
pub trait StreamTrait: Send + Sync {
type Stream<'a>: Stream<Item = Result<QueryResult, DbErr>> + Send
where
Self: 'a;
fn stream<'a>(
&'a self,
stmt: Statement,
) -> Pin<Box<dyn Future<Output = Result<Self::Stream<'a>, DbErr>> + 'a + Send>>;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum IsolationLevel {
RepeatableRead,
ReadCommitted,
ReadUncommitted,
Serializable,
}
impl std::fmt::Display for IsolationLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
IsolationLevel::RepeatableRead => write!(f, "REPEATABLE READ"),
IsolationLevel::ReadCommitted => write!(f, "READ COMMITTED"),
IsolationLevel::ReadUncommitted => write!(f, "READ UNCOMMITTED"),
IsolationLevel::Serializable => write!(f, "SERIALIZABLE"),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum AccessMode {
ReadOnly,
ReadWrite,
}
impl std::fmt::Display for AccessMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AccessMode::ReadOnly => write!(f, "READ ONLY"),
AccessMode::ReadWrite => write!(f, "READ WRITE"),
}
}
}
#[async_trait::async_trait]
pub trait TransactionTrait {
async fn begin(&self) -> Result<DatabaseTransaction, DbErr>;
async fn begin_with_config(
&self,
isolation_level: Option<IsolationLevel>,
access_mode: Option<AccessMode>,
) -> Result<DatabaseTransaction, DbErr>;
async fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>
where
F: for<'c> FnOnce(
&'c DatabaseTransaction,
) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>
+ Send,
T: Send,
E: std::error::Error + Send;
async fn transaction_with_config<F, T, E>(
&self,
callback: F,
isolation_level: Option<IsolationLevel>,
access_mode: Option<AccessMode>,
) -> Result<T, TransactionError<E>>
where
F: for<'c> FnOnce(
&'c DatabaseTransaction,
) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>
+ Send,
T: Send,
E: std::error::Error + Send;
}