use crate::{
debug_print, error::*, DatabaseConnection, DbBackend, ExecResult, ProxyDatabaseTrait,
QueryResult, Statement,
};
use std::{fmt::Debug, sync::Arc};
use tracing::instrument;
#[derive(Debug)]
pub struct ProxyDatabaseConnector;
#[derive(Debug)]
pub struct ProxyDatabaseConnection {
db_backend: DbBackend,
proxy: Arc<Box<dyn ProxyDatabaseTrait>>,
}
impl ProxyDatabaseConnector {
#[allow(unused_variables)]
pub fn accepts(string: &str) -> bool {
true
}
#[allow(unused_variables)]
#[instrument(level = "trace")]
pub fn connect(
db_type: DbBackend,
func: Arc<Box<dyn ProxyDatabaseTrait>>,
) -> Result<DatabaseConnection, DbErr> {
Ok(DatabaseConnection::ProxyDatabaseConnection(Arc::new(
ProxyDatabaseConnection::new(db_type, func),
)))
}
}
impl ProxyDatabaseConnection {
pub fn new(db_backend: DbBackend, funcs: Arc<Box<dyn ProxyDatabaseTrait>>) -> Self {
Self {
db_backend,
proxy: funcs.to_owned(),
}
}
pub fn get_database_backend(&self) -> DbBackend {
self.db_backend
}
#[instrument(level = "trace")]
pub async fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {
debug_print!("{}", statement);
Ok(self.proxy.execute(statement).await?.into())
}
#[instrument(level = "trace")]
pub async fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {
debug_print!("{}", statement);
let result = self.proxy.query(statement).await?;
if let Some(first) = result.first() {
return Ok(Some(QueryResult {
row: crate::QueryResultRow::Proxy(first.to_owned()),
}));
} else {
return Ok(None);
}
}
#[instrument(level = "trace")]
pub async fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {
debug_print!("{}", statement);
let result = self.proxy.query(statement).await?;
Ok(result
.into_iter()
.map(|row| QueryResult {
row: crate::QueryResultRow::Proxy(row),
})
.collect())
}
#[instrument(level = "trace")]
pub async fn begin(&self) {
self.proxy.begin().await
}
#[instrument(level = "trace")]
pub async fn commit(&self) {
self.proxy.commit().await
}
#[instrument(level = "trace")]
pub async fn rollback(&self) {
self.proxy.rollback().await
}
pub async fn ping(&self) -> Result<(), DbErr> {
self.proxy.ping().await
}
}
impl
From<(
Arc<crate::ProxyDatabaseConnection>,
Statement,
Option<crate::metric::Callback>,
)> for crate::QueryStream
{
fn from(
(conn, stmt, metric_callback): (
Arc<crate::ProxyDatabaseConnection>,
Statement,
Option<crate::metric::Callback>,
),
) -> Self {
crate::QueryStream::build(stmt, crate::InnerConnection::Proxy(conn), metric_callback)
}
}
impl crate::DatabaseTransaction {
pub(crate) async fn new_proxy(
inner: Arc<crate::ProxyDatabaseConnection>,
metric_callback: Option<crate::metric::Callback>,
) -> Result<crate::DatabaseTransaction, DbErr> {
use futures::lock::Mutex;
let backend = inner.get_database_backend();
Self::begin(
Arc::new(Mutex::new(crate::InnerConnection::Proxy(inner))),
backend,
metric_callback,
None,
None,
)
.await
}
}