mod cache;
pub use cache::Caching;
use async_trait::async_trait;
use postgres_types::ToSql;
use tokio_postgres::{error::Error as SqlError, Client, RowStream, Statement, Transaction};
#[async_trait]
pub trait GenericClient {
async fn prepare(&self, sql: &str) -> Result<Statement, SqlError>;
async fn prepare_static(&self, sql: &'static str) -> Result<Statement, SqlError> {
self.prepare(sql).await
}
async fn execute_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<u64, SqlError>;
async fn query_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<RowStream, SqlError>;
}
fn slice_iter<'a>(
s: &'a [&'a (dyn ToSql + Sync)],
) -> impl ExactSizeIterator<Item = &'a dyn ToSql> + 'a {
s.iter().map(|s| *s as _)
}
#[async_trait]
impl GenericClient for Client {
async fn prepare(&self, sql: &str) -> Result<Statement, SqlError> {
Client::prepare(self, sql).await
}
async fn execute_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<u64, SqlError> {
Client::execute_raw(self, statement, slice_iter(parameters)).await
}
async fn query_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<RowStream, SqlError> {
Client::query_raw(self, statement, slice_iter(parameters)).await
}
}
#[async_trait]
impl GenericClient for Transaction<'_> {
async fn prepare(&self, sql: &str) -> Result<Statement, SqlError> {
Transaction::prepare(self, sql).await
}
async fn execute_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<u64, SqlError> {
Transaction::execute_raw::<_, Statement>(self, statement, slice_iter(parameters)).await
}
async fn query_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<RowStream, SqlError> {
Transaction::query_raw(self, statement, slice_iter(parameters)).await
}
}
macro_rules! client_deref_impl {
($($target:tt)+) => {
#[async_trait]
impl<T> GenericClient for $($target)+ where T: GenericClient + Sync {
async fn prepare(&self, sql: &str) -> Result<Statement, SqlError> {
T::prepare(self, sql).await
}
async fn execute_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<u64, SqlError> {
T::execute_raw(self, statement, parameters).await
}
async fn query_raw<'a>(
&'a self,
statement: &Statement,
parameters: &[&'a (dyn ToSql + Sync)],
) -> Result<RowStream, SqlError> {
T::query_raw(self, statement, parameters).await
}
}
}
}
client_deref_impl!(&T);