Add tokio_postgres::GenericClient

We have to make the trait methods differ from the normal methods a bit
by adding Sync + Send bounds to the ToStatement parameter which is a bit
unfortunate, but necessary until GATs async_trait unnecessary.

Closes #357
This commit is contained in:
Steven Fackler 2020-01-02 20:58:38 -05:00
parent a865207ff6
commit 3ba416ded6
6 changed files with 97 additions and 10 deletions

View File

@ -1,8 +1,7 @@
use crate::{Statement, ToStatement, Transaction};
use tokio_postgres::types::ToSql;
use tokio_postgres::{Error, Row};
use crate::types::ToSql;
use crate::{Error, Row, Statement, ToStatement, Transaction};
/// A trait allowing abstraction over connections and transactions
/// A trait allowing abstraction over connections and transactions.
pub trait GenericClient {
/// Like `Client::execute`.
fn execute<T>(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>

View File

@ -35,6 +35,7 @@ with-serde_json-1 = ["postgres-types/with-serde_json-1"]
with-uuid-0_8 = ["postgres-types/with-uuid-0_8"]
[dependencies]
async-trait = "0.1"
bytes = "0.5"
byteorder = "1.0"
fallible-iterator = "0.2"

View File

@ -4,18 +4,17 @@ use crate::connection::{Request, RequestMessages};
use crate::copy_out::CopyOutStream;
use crate::query::RowStream;
use crate::simple_query::SimpleQueryStream;
use crate::slice_iter;
#[cfg(feature = "runtime")]
use crate::tls::MakeTlsConnect;
use crate::tls::TlsConnect;
use crate::to_statement::ToStatement;
use crate::types::{Oid, ToSql, Type};
#[cfg(feature = "runtime")]
use crate::Socket;
use crate::{copy_in, copy_out, query, CancelToken, CopyInSink, Transaction};
use crate::{prepare, SimpleQueryMessage};
use crate::{simple_query, Row};
use crate::{Error, Statement};
use crate::{
copy_in, copy_out, prepare, query, simple_query, slice_iter, CancelToken, CopyInSink, Error,
GenericClient, Row, SimpleQueryMessage, Statement, ToStatement, Transaction,
};
use async_trait::async_trait;
use bytes::{Buf, BytesMut};
use fallible_iterator::FallibleIterator;
use futures::channel::mpsc;
@ -495,3 +494,32 @@ impl Client {
self.inner.sender.is_closed()
}
}
#[async_trait]
impl GenericClient for Client {
async fn execute<T>(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
where
T: ?Sized + ToStatement + Sync + Send,
{
self.execute(query, params).await
}
async fn query<T>(
&mut self,
query: &T,
params: &[&(dyn ToSql + Sync)],
) -> Result<Vec<Row>, Error>
where
T: ?Sized + ToStatement + Sync + Send,
{
self.query(query, params).await
}
async fn prepare(&mut self, query: &str) -> Result<Statement, Error> {
self.prepare(query).await
}
async fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
self.transaction().await
}
}

View File

@ -0,0 +1,27 @@
use crate::types::ToSql;
use crate::{Error, Row, Statement, ToStatement, Transaction};
use async_trait::async_trait;
/// A trait allowing abstraction over connections and transactions.
#[async_trait]
pub trait GenericClient {
/// Like `Client::execute`.
async fn execute<T>(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
where
T: ?Sized + ToStatement + Sync + Send;
/// Like `Client::query`.
async fn query<T>(
&mut self,
query: &T,
params: &[&(dyn ToSql + Sync)],
) -> Result<Vec<Row>, Error>
where
T: ?Sized + ToStatement + Sync + Send;
/// Like `Client::prepare`.
async fn prepare(&mut self, query: &str) -> Result<Statement, Error>;
/// Like `Client::transaction`.
async fn transaction(&mut self) -> Result<Transaction<'_>, Error>;
}

View File

@ -107,6 +107,7 @@ pub use crate::copy_in::CopyInSink;
pub use crate::copy_out::CopyOutStream;
use crate::error::DbError;
pub use crate::error::Error;
pub use crate::generic_client::GenericClient;
pub use crate::portal::Portal;
pub use crate::query::RowStream;
pub use crate::row::{Row, SimpleQueryRow};
@ -140,6 +141,7 @@ mod connection;
mod copy_in;
mod copy_out;
pub mod error;
mod generic_client;
mod maybe_tls_stream;
mod portal;
mod prepare;

View File

@ -12,6 +12,7 @@ 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;
@ -285,3 +286,32 @@ impl<'a> Transaction<'a> {
})
}
}
#[async_trait]
impl crate::GenericClient for Transaction<'_> {
async fn execute<T>(&mut self, query: &T, params: &[&(dyn ToSql + Sync)]) -> Result<u64, Error>
where
T: ?Sized + ToStatement + Sync + Send,
{
self.execute(query, params).await
}
async fn query<T>(
&mut self,
query: &T,
params: &[&(dyn ToSql + Sync)],
) -> Result<Vec<Row>, Error>
where
T: ?Sized + ToStatement + Sync + Send,
{
self.query(query, params).await
}
async fn prepare(&mut self, query: &str) -> Result<Statement, Error> {
self.prepare(query).await
}
async fn transaction<'a>(&'a mut self) -> Result<Transaction<'a>, Error> {
self.transaction().await
}
}