use crate::{
database::{Database, FromRecord, RecordValues, StmtCmd},
misc::{ConnectionState, DEController},
};
use core::future::Future;
pub trait Executor {
type Database: Database;
fn connection_state(&self) -> ConnectionState;
fn execute(
&mut self,
cmd: &str,
cb: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
) -> impl Future<Output = Result<(), <Self::Database as DEController>::Error>>;
fn execute_with_stmt<SC, RV>(
&mut self,
sc: SC,
rv: RV,
) -> impl Future<Output = Result<u64, <Self::Database as DEController>::Error>>
where
RV: RecordValues<Self::Database>,
SC: StmtCmd;
fn fetch_with_stmt<SC, RV>(
&mut self,
sc: SC,
rv: RV,
) -> impl Future<
Output = Result<
<Self::Database as Database>::Record<'_>,
<Self::Database as DEController>::Error,
>,
>
where
RV: RecordValues<Self::Database>,
SC: StmtCmd;
fn fetch_many_with_stmt<SC, RV>(
&mut self,
sc: SC,
rv: RV,
cb: impl FnMut(
&<Self::Database as Database>::Record<'_>,
) -> Result<(), <Self::Database as DEController>::Error>,
) -> impl Future<
Output = Result<
<Self::Database as Database>::Records<'_>,
<Self::Database as DEController>::Error,
>,
>
where
RV: RecordValues<Self::Database>,
SC: StmtCmd;
fn prepare(
&mut self,
cmd: &str,
) -> impl Future<Output = Result<u64, <Self::Database as DEController>::Error>>;
#[inline]
fn simple_entity<SV, T>(
&mut self,
cmd: &str,
sv: SV,
) -> impl Future<Output = Result<T, <Self::Database as DEController>::Error>>
where
T: FromRecord<Self::Database>,
SV: RecordValues<Self::Database>,
{
async move { T::from_record(&self.fetch_with_stmt(cmd, sv).await?) }
}
#[inline]
fn simple_entities<SV, T>(
&mut self,
cmd: &str,
sv: SV,
mut cb: impl FnMut(T) -> Result<(), <Self::Database as DEController>::Error>,
) -> impl Future<Output = Result<(), <Self::Database as DEController>::Error>>
where
SV: RecordValues<Self::Database>,
T: FromRecord<Self::Database>,
{
async move {
let _rec = self.fetch_many_with_stmt(cmd, sv, |record| cb(T::from_record(record)?)).await?;
Ok(())
}
}
fn transaction<'this, F, R>(
&'this mut self,
fun: impl FnOnce(&'this mut Self) -> F,
) -> impl Future<Output = Result<R, <Self::Database as DEController>::Error>>
where
F: Future<Output = Result<(R, &'this mut Self), <Self::Database as DEController>::Error>>,
{
async move {
self.execute("BEGIN", |_| Ok(())).await?;
let (rslt, this) = fun(self).await?;
this.execute("COMMIT", |_| Ok(())).await?;
Ok(rslt)
}
}
}
impl<T> Executor for &mut T
where
T: Executor,
{
type Database = T::Database;
#[inline]
fn connection_state(&self) -> ConnectionState {
(**self).connection_state()
}
#[inline]
async fn execute(
&mut self,
cmd: &str,
cb: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
) -> Result<(), <Self::Database as DEController>::Error> {
(**self).execute(cmd, cb).await
}
#[inline]
async fn execute_with_stmt<SC, RV>(
&mut self,
sc: SC,
rv: RV,
) -> Result<u64, <Self::Database as DEController>::Error>
where
RV: RecordValues<Self::Database>,
SC: StmtCmd,
{
(**self).execute_with_stmt(sc, rv).await
}
#[inline]
async fn fetch_many_with_stmt<SC, RV>(
&mut self,
sc: SC,
rv: RV,
cb: impl FnMut(
&<Self::Database as Database>::Record<'_>,
) -> Result<(), <Self::Database as DEController>::Error>,
) -> Result<<Self::Database as Database>::Records<'_>, <Self::Database as DEController>::Error>
where
RV: RecordValues<Self::Database>,
SC: StmtCmd,
{
(**self).fetch_many_with_stmt(sc, rv, cb).await
}
#[inline]
async fn fetch_with_stmt<S, RV>(
&mut self,
sc: S,
rv: RV,
) -> Result<<Self::Database as Database>::Record<'_>, <Self::Database as DEController>::Error>
where
RV: RecordValues<Self::Database>,
S: StmtCmd,
{
(**self).fetch_with_stmt(sc, rv).await
}
#[inline]
async fn prepare(&mut self, cmd: &str) -> Result<u64, <Self::Database as DEController>::Error> {
(**self).prepare(cmd).await
}
}
impl Executor for () {
type Database = ();
#[inline]
fn connection_state(&self) -> ConnectionState {
ConnectionState::Closed
}
#[inline]
async fn execute(
&mut self,
_: &str,
_: impl FnMut(u64) -> Result<(), <Self::Database as DEController>::Error>,
) -> crate::Result<()> {
Ok(())
}
#[inline]
async fn execute_with_stmt<SC, RV>(
&mut self,
_: SC,
_: RV,
) -> Result<u64, <Self::Database as DEController>::Error>
where
RV: RecordValues<Self::Database>,
SC: StmtCmd,
{
Ok(0)
}
#[inline]
async fn fetch_many_with_stmt<SC, RV>(
&mut self,
_: SC,
_: RV,
_: impl FnMut(
&<Self::Database as Database>::Record<'_>,
) -> Result<(), <Self::Database as DEController>::Error>,
) -> Result<<Self::Database as Database>::Records<'_>, <Self::Database as DEController>::Error>
where
RV: RecordValues<Self::Database>,
SC: StmtCmd,
{
Ok(())
}
#[inline]
async fn fetch_with_stmt<S, RV>(
&mut self,
_: S,
_: RV,
) -> Result<<Self::Database as Database>::Record<'_>, <Self::Database as DEController>::Error>
where
RV: RecordValues<Self::Database>,
S: StmtCmd,
{
Ok(())
}
#[inline]
async fn prepare(&mut self, _: &str) -> Result<u64, <Self::Database as DEController>::Error> {
Ok(0)
}
}