sea_orm/driver/
proxy.rs

1use crate::{
2    debug_print, error::*, DatabaseConnection, DbBackend, ExecResult, ProxyDatabaseTrait,
3    QueryResult, Statement,
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(DatabaseConnection::ProxyDatabaseConnection(Arc::new(
35            ProxyDatabaseConnection::new(db_type, func),
36        )))
37    }
38}
39
40impl ProxyDatabaseConnection {
41    /// Create a connection to the [ProxyDatabase]
42    pub fn new(db_backend: DbBackend, funcs: Arc<Box<dyn ProxyDatabaseTrait>>) -> Self {
43        Self {
44            db_backend,
45            proxy: funcs.to_owned(),
46        }
47    }
48
49    /// Get the [DatabaseBackend](crate::DatabaseBackend) being used by the [ProxyDatabase]
50    pub fn get_database_backend(&self) -> DbBackend {
51        self.db_backend
52    }
53
54    /// Execute the SQL statement in the [ProxyDatabase]
55    #[instrument(level = "trace")]
56    pub async fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {
57        debug_print!("{}", statement);
58        Ok(self.proxy.execute(statement).await?.into())
59    }
60
61    /// Return one [QueryResult] if the query was successful
62    #[instrument(level = "trace")]
63    pub async fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {
64        debug_print!("{}", statement);
65        let result = self.proxy.query(statement).await?;
66
67        if let Some(first) = result.first() {
68            return Ok(Some(QueryResult {
69                row: crate::QueryResultRow::Proxy(first.to_owned()),
70            }));
71        } else {
72            return Ok(None);
73        }
74    }
75
76    /// Return all [QueryResult]s if the query was successful
77    #[instrument(level = "trace")]
78    pub async fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {
79        debug_print!("{}", statement);
80        let result = self.proxy.query(statement).await?;
81
82        Ok(result
83            .into_iter()
84            .map(|row| QueryResult {
85                row: crate::QueryResultRow::Proxy(row),
86            })
87            .collect())
88    }
89
90    /// Create a statement block  of SQL statements that execute together.
91    #[instrument(level = "trace")]
92    pub async fn begin(&self) {
93        self.proxy.begin().await
94    }
95
96    /// Commit a transaction atomically to the database
97    #[instrument(level = "trace")]
98    pub async fn commit(&self) {
99        self.proxy.commit().await
100    }
101
102    /// Roll back a faulty transaction
103    #[instrument(level = "trace")]
104    pub async fn rollback(&self) {
105        self.proxy.rollback().await
106    }
107
108    /// Start rollback a transaction
109    #[instrument(level = "trace")]
110    pub fn start_rollback(&self) {
111        self.proxy.start_rollback()
112    }
113
114    /// Checks if a connection to the database is still valid.
115    pub async fn ping(&self) -> Result<(), DbErr> {
116        self.proxy.ping().await
117    }
118}
119
120impl
121    From<(
122        Arc<crate::ProxyDatabaseConnection>,
123        Statement,
124        Option<crate::metric::Callback>,
125    )> for crate::QueryStream
126{
127    fn from(
128        (conn, stmt, metric_callback): (
129            Arc<crate::ProxyDatabaseConnection>,
130            Statement,
131            Option<crate::metric::Callback>,
132        ),
133    ) -> Self {
134        crate::QueryStream::build(stmt, crate::InnerConnection::Proxy(conn), metric_callback)
135    }
136}
137
138impl crate::DatabaseTransaction {
139    pub(crate) async fn new_proxy(
140        inner: Arc<crate::ProxyDatabaseConnection>,
141        metric_callback: Option<crate::metric::Callback>,
142    ) -> Result<crate::DatabaseTransaction, DbErr> {
143        use futures_util::lock::Mutex;
144        let backend = inner.get_database_backend();
145        Self::begin(
146            Arc::new(Mutex::new(crate::InnerConnection::Proxy(inner))),
147            backend,
148            metric_callback,
149            None,
150            None,
151        )
152        .await
153    }
154}