use std::future::Future;
use std::sync::Arc;
use crate::database::Database;
use crate::dialect::Dialect;
use crate::driver::ExecuteResult;
use crate::row::Row;
use crate::value::Value;
pub trait Executor {
fn dialect(&self) -> &dyn Dialect;
fn fetch_all(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<Vec<Row>>> + Send;
fn execute(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<ExecuteResult>> + Send;
}
impl Executor for Database {
fn dialect(&self) -> &dyn Dialect {
Database::dialect(self).as_ref()
}
fn fetch_all(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<Vec<Row>>> + Send {
Database::fetch_all(self, sql, params)
}
fn execute(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<ExecuteResult>> + Send {
Database::execute(self, sql, params)
}
}
impl Executor for Arc<Database> {
fn dialect(&self) -> &dyn Dialect {
<Database as Executor>::dialect(self)
}
fn fetch_all(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<Vec<Row>>> + Send {
<Database as Executor>::fetch_all(self, sql, params)
}
fn execute(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<ExecuteResult>> + Send {
<Database as Executor>::execute(self, sql, params)
}
}
impl<T> Executor for &T
where
T: Executor + Sync + ?Sized,
{
fn dialect(&self) -> &dyn Dialect {
T::dialect(self)
}
fn fetch_all(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<Vec<Row>>> + Send {
T::fetch_all(*self, sql, params)
}
fn execute(
&self,
sql: String,
params: Vec<Value>,
) -> impl Future<Output = crate::Result<ExecuteResult>> + Send {
T::execute(*self, sql, params)
}
}