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    /// Checks if a connection to the database is still valid.
109    pub async fn ping(&self) -> Result<(), DbErr> {
110        self.proxy.ping().await
111    }
112}
113
114impl
115    From<(
116        Arc<crate::ProxyDatabaseConnection>,
117        Statement,
118        Option<crate::metric::Callback>,
119    )> for crate::QueryStream
120{
121    fn from(
122        (conn, stmt, metric_callback): (
123            Arc<crate::ProxyDatabaseConnection>,
124            Statement,
125            Option<crate::metric::Callback>,
126        ),
127    ) -> Self {
128        crate::QueryStream::build(stmt, crate::InnerConnection::Proxy(conn), metric_callback)
129    }
130}
131
132impl crate::DatabaseTransaction {
133    pub(crate) async fn new_proxy(
134        inner: Arc<crate::ProxyDatabaseConnection>,
135        metric_callback: Option<crate::metric::Callback>,
136    ) -> Result<crate::DatabaseTransaction, DbErr> {
137        use futures_util::lock::Mutex;
138        let backend = inner.get_database_backend();
139        Self::begin(
140            Arc::new(Mutex::new(crate::InnerConnection::Proxy(inner))),
141            backend,
142            metric_callback,
143            None,
144            None,
145        )
146        .await
147    }
148}