sea_orm/database/
executor.rs1use crate::{
2 AccessMode, ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbBackend, DbErr,
3 ExecResult, IsolationLevel, QueryResult, Statement, TransactionError, TransactionTrait,
4};
5use crate::{Schema, SchemaBuilder};
6use std::future::Future;
7use std::pin::Pin;
8
9#[derive(Debug)]
11pub enum DatabaseExecutor<'c> {
12 Connection(&'c DatabaseConnection),
14 Transaction(&'c DatabaseTransaction),
16}
17
18impl<'c> From<&'c DatabaseConnection> for DatabaseExecutor<'c> {
19 fn from(conn: &'c DatabaseConnection) -> Self {
20 Self::Connection(conn)
21 }
22}
23
24impl<'c> From<&'c DatabaseTransaction> for DatabaseExecutor<'c> {
25 fn from(trans: &'c DatabaseTransaction) -> Self {
26 Self::Transaction(trans)
27 }
28}
29
30impl ConnectionTrait for DatabaseExecutor<'_> {
31 fn get_database_backend(&self) -> DbBackend {
32 match self {
33 DatabaseExecutor::Connection(conn) => conn.get_database_backend(),
34 DatabaseExecutor::Transaction(trans) => trans.get_database_backend(),
35 }
36 }
37
38 fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {
39 match self {
40 DatabaseExecutor::Connection(conn) => conn.execute_raw(stmt),
41 DatabaseExecutor::Transaction(trans) => trans.execute_raw(stmt),
42 }
43 }
44
45 fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {
46 match self {
47 DatabaseExecutor::Connection(conn) => conn.execute_unprepared(sql),
48 DatabaseExecutor::Transaction(trans) => trans.execute_unprepared(sql),
49 }
50 }
51
52 fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {
53 match self {
54 DatabaseExecutor::Connection(conn) => conn.query_one_raw(stmt),
55 DatabaseExecutor::Transaction(trans) => trans.query_one_raw(stmt),
56 }
57 }
58
59 fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {
60 match self {
61 DatabaseExecutor::Connection(conn) => conn.query_all_raw(stmt),
62 DatabaseExecutor::Transaction(trans) => trans.query_all_raw(stmt),
63 }
64 }
65}
66
67impl TransactionTrait for DatabaseExecutor<'_> {
68 type Transaction = DatabaseTransaction;
69
70 fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
71 match self {
72 DatabaseExecutor::Connection(conn) => conn.begin(),
73 DatabaseExecutor::Transaction(trans) => trans.begin(),
74 }
75 }
76
77 fn begin_with_config(
78 &self,
79 isolation_level: Option<IsolationLevel>,
80 access_mode: Option<AccessMode>,
81 ) -> Result<DatabaseTransaction, DbErr> {
82 match self {
83 DatabaseExecutor::Connection(conn) => {
84 conn.begin_with_config(isolation_level, access_mode)
85 }
86 DatabaseExecutor::Transaction(trans) => {
87 trans.begin_with_config(isolation_level, access_mode)
88 }
89 }
90 }
91
92 fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>
93 where
94 F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,
95 E: std::fmt::Display + std::fmt::Debug,
96 {
97 match self {
98 DatabaseExecutor::Connection(conn) => conn.transaction(callback),
99 DatabaseExecutor::Transaction(trans) => trans.transaction(callback),
100 }
101 }
102
103 fn transaction_with_config<F, T, E>(
104 &self,
105 callback: F,
106 isolation_level: Option<IsolationLevel>,
107 access_mode: Option<AccessMode>,
108 ) -> Result<T, TransactionError<E>>
109 where
110 F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,
111 E: std::fmt::Display + std::fmt::Debug,
112 {
113 match self {
114 DatabaseExecutor::Connection(conn) => {
115 conn.transaction_with_config(callback, isolation_level, access_mode)
116 }
117 DatabaseExecutor::Transaction(trans) => {
118 trans.transaction_with_config(callback, isolation_level, access_mode)
119 }
120 }
121 }
122}
123
124pub trait IntoDatabaseExecutor<'c>
126where
127 Self: 'c,
128{
129 fn into_database_executor(self) -> DatabaseExecutor<'c>;
131}
132
133impl<'c> IntoDatabaseExecutor<'c> for DatabaseExecutor<'c> {
134 fn into_database_executor(self) -> DatabaseExecutor<'c> {
135 self
136 }
137}
138
139impl<'c> IntoDatabaseExecutor<'c> for &'c DatabaseConnection {
140 fn into_database_executor(self) -> DatabaseExecutor<'c> {
141 DatabaseExecutor::Connection(self)
142 }
143}
144
145impl<'c> IntoDatabaseExecutor<'c> for &'c DatabaseTransaction {
146 fn into_database_executor(self) -> DatabaseExecutor<'c> {
147 DatabaseExecutor::Transaction(self)
148 }
149}
150
151impl DatabaseExecutor<'_> {
152 pub fn get_schema_builder(&self) -> SchemaBuilder {
154 Schema::new(self.get_database_backend()).builder()
155 }
156
157 #[cfg(feature = "entity-registry")]
158 #[cfg_attr(docsrs, doc(cfg(feature = "entity-registry")))]
159 pub fn get_schema_registry(&self, prefix: &str) -> SchemaBuilder {
161 let schema = Schema::new(self.get_database_backend());
162 crate::EntityRegistry::build_schema(schema, prefix)
163 }
164}