diff --git a/postgres/src/client.rs b/postgres/src/client.rs index bbe4a8bc..90834508 100644 --- a/postgres/src/client.rs +++ b/postgres/src/client.rs @@ -1,6 +1,6 @@ use crate::{ - CancelToken, Config, CopyInWriter, CopyOutReader, GenericClient, RowIter, Statement, - ToStatement, Transaction, TransactionBuilder, + CancelToken, Config, CopyInWriter, CopyOutReader, RowIter, Statement, ToStatement, Transaction, + TransactionBuilder, }; use std::ops::{Deref, DerefMut}; use tokio::runtime::Runtime; @@ -517,27 +517,3 @@ impl Client { self.client.is_closed() } } - -impl GenericClient for Client { - fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result - where - T: ?Sized + ToStatement, - { - self.execute(query, params) - } - - fn query(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> - where - T: ?Sized + ToStatement, - { - self.query(query, params) - } - - fn prepare(&mut self, query: &str) -> Result { - self.prepare(query) - } - - fn transaction(&mut self) -> Result, Error> { - self.transaction() - } -} diff --git a/postgres/src/generic_client.rs b/postgres/src/generic_client.rs index b586d0d4..42a466df 100644 --- a/postgres/src/generic_client.rs +++ b/postgres/src/generic_client.rs @@ -1,8 +1,17 @@ -use crate::types::ToSql; -use crate::{Error, Row, Statement, ToStatement, Transaction}; +use crate::types::{ToSql, Type}; +use crate::{ + Client, CopyInWriter, CopyOutReader, Error, Row, RowIter, SimpleQueryMessage, Statement, + ToStatement, Transaction, +}; + +mod private { + pub trait Sealed {} +} /// A trait allowing abstraction over connections and transactions. -pub trait GenericClient { +/// +/// This trait is "sealed", and cannot be implemented outside of this crate. +pub trait GenericClient: private::Sealed { /// Like `Client::execute`. fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where @@ -13,9 +22,207 @@ pub trait GenericClient { where T: ?Sized + ToStatement; + /// Like `Client::query_one`. + fn query_one(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement; + + /// Like `Client::query_opt`. + fn query_opt( + &mut self, + query: &T, + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + ToStatement; + + /// Like `Client::query_raw`. + fn query_raw<'a, T, I>(&mut self, query: &T, params: I) -> Result, Error> + where + T: ?Sized + ToStatement, + I: IntoIterator, + I::IntoIter: ExactSizeIterator; + /// Like `Client::prepare`. fn prepare(&mut self, query: &str) -> Result; + /// Like `Client::prepare_typed`. + fn prepare_typed(&mut self, query: &str, types: &[Type]) -> Result; + + /// Like `Client::copy_in`. + fn copy_in(&mut self, query: &T) -> Result, Error> + where + T: ?Sized + ToStatement; + + /// Like `Client::copy_out`. + fn copy_out(&mut self, query: &T) -> Result, Error> + where + T: ?Sized + ToStatement; + + /// Like `Client::simple_query`. + fn simple_query(&mut self, query: &str) -> Result, Error>; + + /// Like `Client::batch_execute`. + fn batch_execute(&mut self, query: &str) -> Result<(), Error>; + /// Like `Client::transaction`. fn transaction(&mut self) -> Result, Error>; } + +impl private::Sealed for Client {} + +impl GenericClient for Client { + fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + self.execute(query, params) + } + + fn query(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.query(query, params) + } + + fn query_one(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + self.query_one(query, params) + } + + fn query_opt( + &mut self, + query: &T, + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.query_opt(query, params) + } + + fn query_raw<'a, T, I>(&mut self, query: &T, params: I) -> Result, Error> + where + T: ?Sized + ToStatement, + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { + self.query_raw(query, params) + } + + fn prepare(&mut self, query: &str) -> Result { + self.prepare(query) + } + + fn prepare_typed(&mut self, query: &str, types: &[Type]) -> Result { + self.prepare_typed(query, types) + } + + fn copy_in(&mut self, query: &T) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.copy_in(query) + } + + fn copy_out(&mut self, query: &T) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.copy_out(query) + } + + fn simple_query(&mut self, query: &str) -> Result, Error> { + self.simple_query(query) + } + + fn batch_execute(&mut self, query: &str) -> Result<(), Error> { + self.batch_execute(query) + } + + fn transaction(&mut self) -> Result, Error> { + self.transaction() + } +} + +impl private::Sealed for Transaction<'_> {} + +impl GenericClient for Transaction<'_> { + fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + self.execute(query, params) + } + + fn query(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.query(query, params) + } + + fn query_one(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result + where + T: ?Sized + ToStatement, + { + self.query_one(query, params) + } + + fn query_opt( + &mut self, + query: &T, + params: &[&(dyn ToSql + Sync)], + ) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.query_opt(query, params) + } + + fn query_raw<'a, T, I>(&mut self, query: &T, params: I) -> Result, Error> + where + T: ?Sized + ToStatement, + I: IntoIterator, + I::IntoIter: ExactSizeIterator, + { + self.query_raw(query, params) + } + + fn prepare(&mut self, query: &str) -> Result { + self.prepare(query) + } + + fn prepare_typed(&mut self, query: &str, types: &[Type]) -> Result { + self.prepare_typed(query, types) + } + + fn copy_in(&mut self, query: &T) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.copy_in(query) + } + + fn copy_out(&mut self, query: &T) -> Result, Error> + where + T: ?Sized + ToStatement, + { + self.copy_out(query) + } + + fn simple_query(&mut self, query: &str) -> Result, Error> { + self.simple_query(query) + } + + fn batch_execute(&mut self, query: &str) -> Result<(), Error> { + self.batch_execute(query) + } + + fn transaction(&mut self) -> Result, Error> { + self.transaction() + } +} diff --git a/postgres/src/transaction.rs b/postgres/src/transaction.rs index c1fdcf06..e5b3682f 100644 --- a/postgres/src/transaction.rs +++ b/postgres/src/transaction.rs @@ -1,6 +1,5 @@ use crate::{ - CancelToken, CopyInWriter, CopyOutReader, GenericClient, Portal, RowIter, Rt, Statement, - ToStatement, + CancelToken, CopyInWriter, CopyOutReader, Portal, RowIter, Rt, Statement, ToStatement, }; use tokio::runtime::Runtime; use tokio_postgres::types::{ToSql, Type}; @@ -185,27 +184,3 @@ impl<'a> Transaction<'a> { }) } } - -impl<'a> GenericClient for Transaction<'a> { - fn execute(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result - where - T: ?Sized + ToStatement, - { - self.execute(query, params) - } - - fn query(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result, Error> - where - T: ?Sized + ToStatement, - { - self.query(query, params) - } - - fn prepare(&mut self, query: &str) -> Result { - self.prepare(query) - } - - fn transaction(&mut self) -> Result, Error> { - self.transaction() - } -} diff --git a/tokio-postgres/src/client.rs b/tokio-postgres/src/client.rs index 78f295e3..84ebfcbb 100644 --- a/tokio-postgres/src/client.rs +++ b/tokio-postgres/src/client.rs @@ -12,10 +12,8 @@ use crate::types::{Oid, ToSql, Type}; use crate::Socket; use crate::{ copy_in, copy_out, prepare, query, simple_query, slice_iter, CancelToken, CopyInSink, Error, - GenericClient, Row, SimpleQueryMessage, Statement, ToStatement, Transaction, - TransactionBuilder, + Row, SimpleQueryMessage, Statement, ToStatement, Transaction, TransactionBuilder, }; -use async_trait::async_trait; use bytes::{Buf, BytesMut}; use fallible_iterator::FallibleIterator; use futures::channel::mpsc; @@ -503,76 +501,3 @@ impl Client { self.inner.sender.is_closed() } } - -#[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<'b, I, T>(&self, statement: &T, params: I) -> Result - where - T: ?Sized + ToStatement + Sync + Send, - 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<'b, T, I>(&self, statement: &T, params: I) -> Result - where - T: ?Sized + ToStatement + Sync + Send, - 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 - } -} diff --git a/tokio-postgres/src/generic_client.rs b/tokio-postgres/src/generic_client.rs index cfbd83e9..30351bd0 100644 --- a/tokio-postgres/src/generic_client.rs +++ b/tokio-postgres/src/generic_client.rs @@ -1,11 +1,17 @@ use crate::query::RowStream; use crate::types::{ToSql, Type}; -use crate::{Error, Row, Statement, ToStatement, Transaction}; +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 { +pub trait GenericClient: private::Sealed { /// Like `Client::execute`. async fn execute(&self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result where @@ -61,3 +67,154 @@ pub trait GenericClient { /// 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<'b, I, T>(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + 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<'b, T, I>(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + 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] +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<'b, I, T>(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + 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<'b, T, I>(&self, statement: &T, params: I) -> Result + where + T: ?Sized + ToStatement + Sync + Send, + 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 + } +} diff --git a/tokio-postgres/src/transaction.rs b/tokio-postgres/src/transaction.rs index c7508737..a1ee4f6c 100644 --- a/tokio-postgres/src/transaction.rs +++ b/tokio-postgres/src/transaction.rs @@ -12,7 +12,6 @@ use crate::{ bind, query, slice_iter, CancelToken, Client, CopyInSink, Error, Portal, Row, SimpleQueryMessage, Statement, ToStatement, }; -use async_trait::async_trait; use bytes::Buf; use futures::TryStreamExt; use postgres_protocol::message::frontend; @@ -286,77 +285,3 @@ impl<'a> Transaction<'a> { }) } } - -#[async_trait] -impl crate::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<'b, I, T>(&self, statement: &T, params: I) -> Result - where - T: ?Sized + ToStatement + Sync + Send, - 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<'b, T, I>(&self, statement: &T, params: I) -> Result - where - T: ?Sized + ToStatement + Sync + Send, - 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 - } -}