sea_orm/driver/
proxy.rs

1use crate::{
2    DatabaseConnection, DatabaseConnectionType, DbBackend, ExecResult, ProxyDatabaseTrait,
3    QueryResult, Statement, debug_print, error::*,
4};
5use std::{fmt::Debug, sync::Arc};
6use tracing::instrument;
7
8/// Defines a database driver for the [ProxyDatabase]
9#[derive(Debug)]
10pub struct ProxyDatabaseConnector;
11
12/// Defines a connection for the [ProxyDatabase]
13#[derive(Debug)]
14pub struct ProxyDatabaseConnection {
15    db_backend: DbBackend,
16    proxy: Arc<Box<dyn ProxyDatabaseTrait>>,
17}
18
19impl ProxyDatabaseConnector {
20    /// Check if the database URI given and the [DatabaseBackend](crate::DatabaseBackend) selected are the same
21    #[allow(unused_variables)]
22    pub fn accepts(string: &str) -> bool {
23        // As this is a proxy database, it accepts any URI
24        true
25    }
26
27    /// Connect to the [ProxyDatabase]
28    #[allow(unused_variables)]
29    #[instrument(level = "trace")]
30    pub fn connect(
31        db_type: DbBackend,
32        func: Arc<Box<dyn ProxyDatabaseTrait>>,
33    ) -> Result<DatabaseConnection, DbErr> {
34        Ok(
35            DatabaseConnectionType::ProxyDatabaseConnection(Arc::new(
36                ProxyDatabaseConnection::new(db_type, func),
37            ))
38            .into(),
39        )
40    }
41}
42
43impl ProxyDatabaseConnection {
44    /// Create a connection to the [ProxyDatabase]
45    pub fn new(db_backend: DbBackend, funcs: Arc<Box<dyn ProxyDatabaseTrait>>) -> Self {
46        Self {
47            db_backend,
48            proxy: funcs.to_owned(),
49        }
50    }
51
52    /// Get the [DatabaseBackend](crate::DatabaseBackend) being used by the [ProxyDatabase]
53    pub fn get_database_backend(&self) -> DbBackend {
54        self.db_backend
55    }
56
57    /// Execute the SQL statement in the [ProxyDatabase]
58    #[instrument(level = "trace")]
59    pub fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {
60        debug_print!("{}", statement);
61        Ok(self.proxy.execute(statement)?.into())
62    }
63
64    /// Return one [QueryResult] if the query was successful
65    #[instrument(level = "trace")]
66    pub fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {
67        debug_print!("{}", statement);
68        let result = self.proxy.query(statement)?;
69
70        if let Some(first) = result.first() {
71            return Ok(Some(QueryResult {
72                row: crate::QueryResultRow::Proxy(first.to_owned()),
73            }));
74        } else {
75            return Ok(None);
76        }
77    }
78
79    /// Return all [QueryResult]s if the query was successful
80    #[instrument(level = "trace")]
81    pub fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {
82        debug_print!("{}", statement);
83        let result = self.proxy.query(statement)?;
84
85        Ok(result
86            .into_iter()
87            .map(|row| QueryResult {
88                row: crate::QueryResultRow::Proxy(row),
89            })
90            .collect())
91    }
92
93    /// Create a statement block  of SQL statements that execute together.
94    #[instrument(level = "trace")]
95    pub fn begin(&self) {
96        self.proxy.begin()
97    }
98
99    /// Commit a transaction atomically to the database
100    #[instrument(level = "trace")]
101    pub fn commit(&self) {
102        self.proxy.commit()
103    }
104
105    /// Roll back a faulty transaction
106    #[instrument(level = "trace")]
107    pub fn rollback(&self) {
108        self.proxy.rollback()
109    }
110
111    /// Start rollback a transaction
112    #[instrument(level = "trace")]
113    pub fn start_rollback(&self) {
114        self.proxy.start_rollback()
115    }
116
117    /// Checks if a connection to the database is still valid.
118    pub fn ping(&self) -> Result<(), DbErr> {
119        self.proxy.ping()
120    }
121}
122
123impl
124    From<(
125        Arc<crate::ProxyDatabaseConnection>,
126        Statement,
127        Option<crate::metric::Callback>,
128    )> for crate::QueryStream
129{
130    fn from(
131        (conn, stmt, metric_callback): (
132            Arc<crate::ProxyDatabaseConnection>,
133            Statement,
134            Option<crate::metric::Callback>,
135        ),
136    ) -> Self {
137        crate::QueryStream::build(stmt, crate::InnerConnection::Proxy(conn), metric_callback)
138    }
139}
140
141impl crate::DatabaseTransaction {
142    pub(crate) fn new_proxy(
143        inner: Arc<crate::ProxyDatabaseConnection>,
144        metric_callback: Option<crate::metric::Callback>,
145    ) -> Result<crate::DatabaseTransaction, DbErr> {
146        use std::sync::Mutex;
147        let backend = inner.get_database_backend();
148        Self::begin(
149            Arc::new(Mutex::new(crate::InnerConnection::Proxy(inner))),
150            backend,
151            metric_callback,
152            None,
153            None,
154        )
155    }
156}