use crate::database::Database;
use crate::describe::Describe;
use futures_core::future::BoxFuture;
use futures_core::stream::BoxStream;
use futures_util::TryStreamExt;
pub trait Executor {
type Database: Database + ?Sized;
fn send<'e, 'q: 'e>(&'e mut self, command: &'q str) -> BoxFuture<'e, crate::Result<()>>;
fn execute<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxFuture<'e, crate::Result<u64>>;
fn fetch<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxStream<'e, crate::Result<<Self::Database as Database>::Row>>;
fn fetch_optional<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxFuture<'e, crate::Result<Option<<Self::Database as Database>::Row>>> {
let mut s = self.fetch(query, args);
Box::pin(async move {
match s.try_next().await? {
Some(val) => {
if s.try_next().await?.is_some() {
Err(crate::Error::FoundMoreThanOne)
} else {
Ok(Some(val))
}
}
None => Ok(None),
}
})
}
fn fetch_one<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: <Self::Database as Database>::Arguments,
) -> BoxFuture<'e, crate::Result<<Self::Database as Database>::Row>> {
let mut s = self.fetch(query, args);
Box::pin(async move { s.try_next().await?.ok_or(crate::Error::NotFound) })
}
#[doc(hidden)]
fn describe<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
) -> BoxFuture<'e, crate::Result<Describe<Self::Database>>>;
}