use crate::query::RowStream; use crate::types::{BorrowToSql, ToSql, Type}; use crate::{Client, Error, Row, Statement, ToStatement, Transaction}; use async_trait::async_trait; mod private { pub trait Sealed {} } /// A trait allowing abstraction over connections and transactions. /// /// This trait is "sealed", and cannot be implemented outside of this crate. #[async_trait] pub trait GenericClient: private::Sealed { /// Like `Client::execute`. async fn execute(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where T: ?Sized + ToStatement + Sync + Send; /// Like `Client::execute_raw`. async fn execute_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, P: BorrowToSql, I: IntoIterator + Sync + Send, I::IntoIter: ExactSizeIterator; /// Like `Client::query`. async fn query(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> where T: ?Sized + ToStatement + Sync + Send; /// Like `Client::query_one`. async fn query_one( &self, statement: &T, params: &[&(dyn ToSql + Sync)], ) -> Result where T: ?Sized + ToStatement + Sync + Send; /// Like `Client::query_opt`. async fn query_opt( &self, statement: &T, params: &[&(dyn ToSql + Sync)], ) -> Result, Error> where T: ?Sized + ToStatement + Sync + Send; /// Like `Client::query_raw`. async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, P: BorrowToSql, I: IntoIterator + Sync + Send, I::IntoIter: ExactSizeIterator; /// Like `Client::prepare`. async fn prepare(&self, query: &str) -> Result; /// Like `Client::prepare_typed`. async fn prepare_typed( &self, query: &str, parameter_types: &[Type], ) -> Result; /// Like `Client::transaction`. async fn transaction(&mut self) -> Result, Error>; } impl private::Sealed for Client {} #[async_trait] impl GenericClient for Client { async fn execute(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where T: ?Sized + ToStatement + Sync + Send, { self.execute(query, params).await } async fn execute_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, P: BorrowToSql, I: IntoIterator + Sync + Send, I::IntoIter: ExactSizeIterator, { self.execute_raw(statement, params).await } async fn query(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> where T: ?Sized + ToStatement + Sync + Send, { self.query(query, params).await } async fn query_one( &self, statement: &T, params: &[&(dyn ToSql + Sync)], ) -> Result where T: ?Sized + ToStatement + Sync + Send, { self.query_one(statement, params).await } async fn query_opt( &self, statement: &T, params: &[&(dyn ToSql + Sync)], ) -> Result, Error> where T: ?Sized + ToStatement + Sync + Send, { self.query_opt(statement, params).await } async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, P: BorrowToSql, I: IntoIterator + Sync + Send, I::IntoIter: ExactSizeIterator, { self.query_raw(statement, params).await } async fn prepare(&self, query: &str) -> Result { self.prepare(query).await } async fn prepare_typed( &self, query: &str, parameter_types: &[Type], ) -> Result { self.prepare_typed(query, parameter_types).await } async fn transaction(&mut self) -> Result, Error> { self.transaction().await } } impl private::Sealed for Transaction<'_> {} #[async_trait] #[allow(clippy::needless_lifetimes)] impl GenericClient for Transaction<'_> { async fn execute(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where T: ?Sized + ToStatement + Sync + Send, { self.execute(query, params).await } async fn execute_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, P: BorrowToSql, I: IntoIterator + Sync + Send, I::IntoIter: ExactSizeIterator, { self.execute_raw(statement, params).await } async fn query(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> where T: ?Sized + ToStatement + Sync + Send, { self.query(query, params).await } async fn query_one( &self, statement: &T, params: &[&(dyn ToSql + Sync)], ) -> Result where T: ?Sized + ToStatement + Sync + Send, { self.query_one(statement, params).await } async fn query_opt( &self, statement: &T, params: &[&(dyn ToSql + Sync)], ) -> Result, Error> where T: ?Sized + ToStatement + Sync + Send, { self.query_opt(statement, params).await } async fn query_raw(&self, statement: &T, params: I) -> Result where T: ?Sized + ToStatement + Sync + Send, P: BorrowToSql, I: IntoIterator + Sync + Send, I::IntoIter: ExactSizeIterator, { self.query_raw(statement, params).await } async fn prepare(&self, query: &str) -> Result { self.prepare(query).await } async fn prepare_typed( &self, query: &str, parameter_types: &[Type], ) -> Result { self.prepare_typed(query, parameter_types).await } #[allow(clippy::needless_lifetimes)] async fn transaction<'a>(&'a mut self) -> Result, Error> { self.transaction().await } }