diff --git a/postgres/src/copy_out_reader.rs b/postgres/src/copy_out_reader.rs index 9cf8174b..0bea15be 100644 --- a/postgres/src/copy_out_reader.rs +++ b/postgres/src/copy_out_reader.rs @@ -2,10 +2,11 @@ use bytes::{Buf, Bytes}; use futures::stream::{self, Stream}; use std::io::{self, BufRead, Cursor, Read}; use std::marker::PhantomData; +use tokio_postgres::impls; use tokio_postgres::Error; pub struct CopyOutReader<'a> { - it: stream::Wait, + it: stream::Wait, cur: Cursor, _p: PhantomData<&'a mut ()>, } @@ -17,7 +18,7 @@ impl<'a> Drop for CopyOutReader<'a> { impl<'a> CopyOutReader<'a> { #[allow(clippy::new_ret_no_self)] - pub(crate) fn new(stream: tokio_postgres::CopyOut) -> Result, Error> { + pub(crate) fn new(stream: impls::CopyOut) -> Result, Error> { let mut it = stream.wait(); let cur = match it.next() { Some(Ok(cur)) => cur, diff --git a/postgres/src/query.rs b/postgres/src/query.rs index e7eb7948..7376fa99 100644 --- a/postgres/src/query.rs +++ b/postgres/src/query.rs @@ -1,10 +1,11 @@ use fallible_iterator::FallibleIterator; use futures::stream::{self, Stream}; use std::marker::PhantomData; +use tokio_postgres::impls; use tokio_postgres::{Error, Row}; pub struct Query<'a> { - it: stream::Wait, + it: stream::Wait, _p: PhantomData<&'a mut ()>, } @@ -14,7 +15,7 @@ impl<'a> Drop for Query<'a> { } impl<'a> Query<'a> { - pub(crate) fn new(stream: tokio_postgres::Query) -> Query<'a> { + pub(crate) fn new(stream: impls::Query) -> Query<'a> { Query { it: stream.wait(), _p: PhantomData, diff --git a/postgres/src/query_portal.rs b/postgres/src/query_portal.rs index 0ed8250a..d2ee4067 100644 --- a/postgres/src/query_portal.rs +++ b/postgres/src/query_portal.rs @@ -1,10 +1,11 @@ use fallible_iterator::FallibleIterator; use futures::stream::{self, Stream}; use std::marker::PhantomData; +use tokio_postgres::impls; use tokio_postgres::{Error, Row}; pub struct QueryPortal<'a> { - it: stream::Wait, + it: stream::Wait, _p: PhantomData<&'a mut ()>, } @@ -14,7 +15,7 @@ impl<'a> Drop for QueryPortal<'a> { } impl<'a> QueryPortal<'a> { - pub(crate) fn new(stream: tokio_postgres::QueryPortal) -> QueryPortal<'a> { + pub(crate) fn new(stream: impls::QueryPortal) -> QueryPortal<'a> { QueryPortal { it: stream.wait(), _p: PhantomData, diff --git a/tokio-postgres/src/config.rs b/tokio-postgres/src/config.rs index b38c1a0c..5ce8d880 100644 --- a/tokio-postgres/src/config.rs +++ b/tokio-postgres/src/config.rs @@ -15,12 +15,15 @@ use std::sync::Arc; use std::time::Duration; use tokio_io::{AsyncRead, AsyncWrite}; +#[cfg(feature = "runtime")] +use crate::impls::Connect; +use crate::impls::ConnectRaw; #[cfg(feature = "runtime")] use crate::proto::ConnectFuture; use crate::proto::ConnectRawFuture; +use crate::{Error, TlsConnect}; #[cfg(feature = "runtime")] -use crate::{Connect, MakeTlsConnect, Socket}; -use crate::{ConnectRaw, Error, TlsConnect}; +use crate::{MakeTlsConnect, Socket}; /// Properties required of a session. #[cfg(feature = "runtime")] diff --git a/tokio-postgres/src/impls.rs b/tokio-postgres/src/impls.rs new file mode 100644 index 00000000..9db60cde --- /dev/null +++ b/tokio-postgres/src/impls.rs @@ -0,0 +1,178 @@ +use bytes::{Bytes, IntoBuf}; +use futures::{try_ready, Async, Future, Poll, Stream}; +use std::error; +use tokio_io::{AsyncRead, AsyncWrite}; + +use crate::proto; +use crate::{Client, Connection, Error, Portal, Row, Statement, TlsConnect}; +#[cfg(feature = "runtime")] +use crate::{MakeTlsConnect, Socket}; + +#[must_use = "futures do nothing unless polled"] +pub struct CancelQueryRaw(pub(crate) proto::CancelQueryRawFuture) +where + S: AsyncRead + AsyncWrite, + T: TlsConnect; + +impl Future for CancelQueryRaw +where + S: AsyncRead + AsyncWrite, + T: TlsConnect, +{ + type Item = (); + type Error = Error; + + fn poll(&mut self) -> Poll<(), Error> { + self.0.poll() + } +} + +#[cfg(feature = "runtime")] +#[must_use = "futures do nothing unless polled"] +pub struct CancelQuery(pub(crate) proto::CancelQueryFuture) +where + T: MakeTlsConnect; + +#[cfg(feature = "runtime")] +impl Future for CancelQuery +where + T: MakeTlsConnect, +{ + type Item = (); + type Error = Error; + + fn poll(&mut self) -> Poll<(), Error> { + self.0.poll() + } +} + +#[must_use = "futures do nothing unless polled"] +pub struct ConnectRaw(pub(crate) proto::ConnectRawFuture) +where + S: AsyncRead + AsyncWrite, + T: TlsConnect; + +impl Future for ConnectRaw +where + S: AsyncRead + AsyncWrite, + T: TlsConnect, +{ + type Item = (Client, Connection); + type Error = Error; + + fn poll(&mut self) -> Poll<(Client, Connection), Error> { + let (client, connection) = try_ready!(self.0.poll()); + + Ok(Async::Ready((Client(client), Connection(connection)))) + } +} + +#[cfg(feature = "runtime")] +#[must_use = "futures do nothing unless polled"] +pub struct Connect(pub(crate) proto::ConnectFuture) +where + T: MakeTlsConnect; + +#[cfg(feature = "runtime")] +impl Future for Connect +where + T: MakeTlsConnect, +{ + type Item = (Client, Connection); + type Error = Error; + + fn poll(&mut self) -> Poll<(Client, Connection), Error> { + let (client, connection) = try_ready!(self.0.poll()); + + Ok(Async::Ready((Client(client), Connection(connection)))) + } +} + +#[must_use = "futures do nothing unless polled"] +pub struct Prepare(pub(crate) proto::PrepareFuture); + +impl Future for Prepare { + type Item = Statement; + type Error = Error; + + fn poll(&mut self) -> Poll { + let statement = try_ready!(self.0.poll()); + + Ok(Async::Ready(Statement(statement))) + } +} + +#[must_use = "streams do nothing unless polled"] +pub struct Query(pub(crate) proto::QueryStream); + +impl Stream for Query { + type Item = Row; + type Error = Error; + + fn poll(&mut self) -> Poll, Error> { + self.0.poll() + } +} + +#[must_use = "futures do nothing unless polled"] +pub struct Bind(pub(crate) proto::BindFuture); + +impl Future for Bind { + type Item = Portal; + type Error = Error; + + fn poll(&mut self) -> Poll { + match self.0.poll() { + Ok(Async::Ready(portal)) => Ok(Async::Ready(Portal(portal))), + Ok(Async::NotReady) => Ok(Async::NotReady), + Err(e) => Err(e), + } + } +} + +#[must_use = "streams do nothing unless polled"] +pub struct QueryPortal(pub(crate) proto::QueryStream); + +impl Stream for QueryPortal { + type Item = Row; + type Error = Error; + + fn poll(&mut self) -> Poll, Error> { + self.0.poll() + } +} + +#[must_use = "futures do nothing unless polled"] +pub struct CopyIn(pub(crate) proto::CopyInFuture) +where + S: Stream, + S::Item: IntoBuf, + ::Buf: Send, + S::Error: Into>; + +impl Future for CopyIn +where + S: Stream, + S::Item: IntoBuf, + ::Buf: Send, + S::Error: Into>, +{ + type Item = u64; + type Error = Error; + + fn poll(&mut self) -> Poll { + self.0.poll() + } +} + +#[must_use = "streams do nothing unless polled"] +pub struct CopyOut(pub(crate) proto::CopyOutStream); + +impl Stream for CopyOut { + type Item = Bytes; + type Error = Error; + + fn poll(&mut self) -> Poll, Error> { + self.0.poll() + } +} diff --git a/tokio-postgres/src/lib.rs b/tokio-postgres/src/lib.rs index 5c8779e9..095be98f 100644 --- a/tokio-postgres/src/lib.rs +++ b/tokio-postgres/src/lib.rs @@ -101,7 +101,7 @@ //! all dependence on the tokio runtime is removed. #![warn(rust_2018_idioms, clippy::all)] -use bytes::{Bytes, IntoBuf}; +use bytes::IntoBuf; use futures::{try_ready, Async, Future, Poll, Stream}; use std::error::Error as StdError; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -118,6 +118,7 @@ use crate::types::{ToSql, Type}; mod config; pub mod error; +pub mod impls; mod proto; mod row; #[cfg(feature = "runtime")] @@ -144,11 +145,11 @@ fn next_portal() -> String { /// /// [`Config`]: ./Config.t.html #[cfg(feature = "runtime")] -pub fn connect(config: &str, tls: T) -> Connect +pub fn connect(config: &str, tls: T) -> impls::Connect where T: MakeTlsConnect, { - Connect(proto::ConnectFuture::new(tls, config.parse())) + impls::Connect(proto::ConnectFuture::new(tls, config.parse())) } /// An asynchronous PostgreSQL client. @@ -162,7 +163,7 @@ impl Client { /// /// Prepared statements can be executed repeatedly, and may contain query parameters (indicated by `$1`, `$2`, etc), /// which are set when executed. Prepared statements can only be used with the connection that created them. - pub fn prepare(&mut self, query: &str) -> Prepare { + pub fn prepare(&mut self, query: &str) -> impls::Prepare { self.prepare_typed(query, &[]) } @@ -170,8 +171,8 @@ impl Client { /// /// The list of types may be smaller than the number of parameters - the types of the remaining parameters will be /// inferred. For example, `client.prepare_typed(query, &[])` is equivalent to `client.prepare(query)`. - pub fn prepare_typed(&mut self, query: &str, param_types: &[Type]) -> Prepare { - Prepare(self.0.prepare(next_statement(), query, param_types)) + pub fn prepare_typed(&mut self, query: &str, param_types: &[Type]) -> impls::Prepare { + impls::Prepare(self.0.prepare(next_statement(), query, param_types)) } /// Executes a statement, returning the number of rows modified. @@ -190,8 +191,8 @@ impl Client { /// # Panics /// /// Panics if the number of parameters provided does not match the number expected. - pub fn query(&mut self, statement: &Statement, params: &[&dyn ToSql]) -> Query { - Query(self.0.query(&statement.0, params)) + pub fn query(&mut self, statement: &Statement, params: &[&dyn ToSql]) -> impls::Query { + impls::Query(self.0.query(&statement.0, params)) } /// Binds a statement to a set of parameters, creating a `Portal` which can be incrementally queried. @@ -202,16 +203,16 @@ impl Client { /// # Panics /// /// Panics if the number of parameters provided does not match the number expected. - pub fn bind(&mut self, statement: &Statement, params: &[&dyn ToSql]) -> Bind { - Bind(self.0.bind(&statement.0, next_portal(), params)) + pub fn bind(&mut self, statement: &Statement, params: &[&dyn ToSql]) -> impls::Bind { + impls::Bind(self.0.bind(&statement.0, next_portal(), params)) } /// Continues execution of a portal, returning a stream of the resulting rows. /// /// Unlike `query`, portals can be incrementally evaluated by limiting the number of rows returned in each call to /// query_portal. If the requested number is negative or 0, all rows will be returned. - pub fn query_portal(&mut self, portal: &Portal, max_rows: i32) -> QueryPortal { - QueryPortal(self.0.query_portal(&portal.0, max_rows)) + pub fn query_portal(&mut self, portal: &Portal, max_rows: i32) -> impls::QueryPortal { + impls::QueryPortal(self.0.query_portal(&portal.0, max_rows)) } /// Executes a `COPY FROM STDIN` statement, returning the number of rows created. @@ -223,7 +224,7 @@ impl Client { statement: &Statement, params: &[&dyn ToSql], stream: S, - ) -> CopyIn + ) -> impls::CopyIn where S: Stream, S::Item: IntoBuf, @@ -231,12 +232,12 @@ impl Client { // FIXME error type? S::Error: Into>, { - CopyIn(self.0.copy_in(&statement.0, params, stream)) + impls::CopyIn(self.0.copy_in(&statement.0, params, stream)) } /// Executes a `COPY TO STDOUT` statement, returning a stream of the resulting data. - pub fn copy_out(&mut self, statement: &Statement, params: &[&dyn ToSql]) -> CopyOut { - CopyOut(self.0.copy_out(&statement.0, params)) + pub fn copy_out(&mut self, statement: &Statement, params: &[&dyn ToSql]) -> impls::CopyOut { + impls::CopyOut(self.0.copy_out(&statement.0, params)) } /// Executes a sequence of SQL statements. @@ -283,21 +284,21 @@ impl Client { /// /// Requires the `runtime` Cargo feature (enabled by default). #[cfg(feature = "runtime")] - pub fn cancel_query(&mut self, make_tls_mode: T) -> CancelQuery + pub fn cancel_query(&mut self, make_tls_mode: T) -> impls::CancelQuery where T: MakeTlsConnect, { - CancelQuery(self.0.cancel_query(make_tls_mode)) + impls::CancelQuery(self.0.cancel_query(make_tls_mode)) } /// Like `cancel_query`, but uses a stream which is already connected to the server rather than opening a new /// connection itself. - pub fn cancel_query_raw(&mut self, stream: S, tls_mode: T) -> CancelQueryRaw + pub fn cancel_query_raw(&mut self, stream: S, tls_mode: T) -> impls::CancelQueryRaw where S: AsyncRead + AsyncWrite, T: TlsConnect, { - CancelQueryRaw(self.0.cancel_query_raw(stream, tls_mode)) + impls::CancelQueryRaw(self.0.cancel_query_raw(stream, tls_mode)) } /// Determines if the connection to the server has already closed. @@ -375,100 +376,6 @@ pub enum AsyncMessage { __NonExhaustive, } -#[must_use = "futures do nothing unless polled"] -pub struct CancelQueryRaw(proto::CancelQueryRawFuture) -where - S: AsyncRead + AsyncWrite, - T: TlsConnect; - -impl Future for CancelQueryRaw -where - S: AsyncRead + AsyncWrite, - T: TlsConnect, -{ - type Item = (); - type Error = Error; - - fn poll(&mut self) -> Poll<(), Error> { - self.0.poll() - } -} - -#[cfg(feature = "runtime")] -#[must_use = "futures do nothing unless polled"] -pub struct CancelQuery(proto::CancelQueryFuture) -where - T: MakeTlsConnect; - -#[cfg(feature = "runtime")] -impl Future for CancelQuery -where - T: MakeTlsConnect, -{ - type Item = (); - type Error = Error; - - fn poll(&mut self) -> Poll<(), Error> { - self.0.poll() - } -} - -#[must_use = "futures do nothing unless polled"] -pub struct ConnectRaw(proto::ConnectRawFuture) -where - S: AsyncRead + AsyncWrite, - T: TlsConnect; - -impl Future for ConnectRaw -where - S: AsyncRead + AsyncWrite, - T: TlsConnect, -{ - type Item = (Client, Connection); - type Error = Error; - - fn poll(&mut self) -> Poll<(Client, Connection), Error> { - let (client, connection) = try_ready!(self.0.poll()); - - Ok(Async::Ready((Client(client), Connection(connection)))) - } -} - -#[cfg(feature = "runtime")] -#[must_use = "futures do nothing unless polled"] -pub struct Connect(proto::ConnectFuture) -where - T: MakeTlsConnect; - -#[cfg(feature = "runtime")] -impl Future for Connect -where - T: MakeTlsConnect, -{ - type Item = (Client, Connection); - type Error = Error; - - fn poll(&mut self) -> Poll<(Client, Connection), Error> { - let (client, connection) = try_ready!(self.0.poll()); - - Ok(Async::Ready((Client(client), Connection(connection)))) - } -} - -#[must_use = "futures do nothing unless polled"] -pub struct Prepare(proto::PrepareFuture); - -impl Future for Prepare { - type Item = Statement; - type Error = Error; - - fn poll(&mut self) -> Poll { - let statement = try_ready!(self.0.poll()); - - Ok(Async::Ready(Statement(statement))) - } -} - /// A prepared statement. /// /// Prepared statements can only be used with the connection that created them. @@ -499,87 +406,12 @@ impl Future for Execute { } } -#[must_use = "streams do nothing unless polled"] -pub struct Query(proto::QueryStream); - -impl Stream for Query { - type Item = Row; - type Error = Error; - - fn poll(&mut self) -> Poll, Error> { - self.0.poll() - } -} - -#[must_use = "futures do nothing unless polled"] -pub struct Bind(proto::BindFuture); - -impl Future for Bind { - type Item = Portal; - type Error = Error; - - fn poll(&mut self) -> Poll { - match self.0.poll() { - Ok(Async::Ready(portal)) => Ok(Async::Ready(Portal(portal))), - Ok(Async::NotReady) => Ok(Async::NotReady), - Err(e) => Err(e), - } - } -} - -#[must_use = "streams do nothing unless polled"] -pub struct QueryPortal(proto::QueryStream); - -impl Stream for QueryPortal { - type Item = Row; - type Error = Error; - - fn poll(&mut self) -> Poll, Error> { - self.0.poll() - } -} - /// A portal. /// /// Portals can only be used with the connection that created them, and only exist for the duration of the transaction /// in which they were created. pub struct Portal(proto::Portal); -#[must_use = "futures do nothing unless polled"] -pub struct CopyIn(proto::CopyInFuture) -where - S: Stream, - S::Item: IntoBuf, - ::Buf: Send, - S::Error: Into>; - -impl Future for CopyIn -where - S: Stream, - S::Item: IntoBuf, - ::Buf: Send, - S::Error: Into>, -{ - type Item = u64; - type Error = Error; - - fn poll(&mut self) -> Poll { - self.0.poll() - } -} - -#[must_use = "streams do nothing unless polled"] -pub struct CopyOut(proto::CopyOutStream); - -impl Stream for CopyOut { - type Item = Bytes; - type Error = Error; - - fn poll(&mut self) -> Poll, Error> { - self.0.poll() - } -} - /// A builder type which can wrap a future in a database transaction. pub struct TransactionBuilder(proto::Client); diff --git a/tokio-postgres/tests/test/main.rs b/tokio-postgres/tests/test/main.rs index 965d22f4..cf10269a 100644 --- a/tokio-postgres/tests/test/main.rs +++ b/tokio-postgres/tests/test/main.rs @@ -11,6 +11,7 @@ use tokio::prelude::*; use tokio::runtime::current_thread::Runtime; use tokio::timer::Delay; use tokio_postgres::error::SqlState; +use tokio_postgres::impls; use tokio_postgres::types::{Kind, Type}; use tokio_postgres::{AsyncMessage, Client, Connection, NoTls, NoTlsStream}; @@ -745,7 +746,7 @@ fn poll_idle_running() { fn poll_idle_new() { struct IdleFuture { client: tokio_postgres::Client, - prepare: Option, + prepare: Option, } impl Future for IdleFuture {