2019-02-01 04:34:49 +00:00
|
|
|
use fallible_iterator::FallibleIterator;
|
2018-12-23 23:02:42 +00:00
|
|
|
use futures::{Async, Future, Poll, Stream};
|
2018-12-29 05:01:10 +00:00
|
|
|
use std::io::{self, Read};
|
2018-12-21 21:34:09 +00:00
|
|
|
use tokio_postgres::types::{ToSql, Type};
|
2018-12-29 04:39:32 +00:00
|
|
|
use tokio_postgres::Error;
|
2018-12-21 21:34:09 +00:00
|
|
|
#[cfg(feature = "runtime")]
|
2019-03-05 05:26:10 +00:00
|
|
|
use tokio_postgres::{Socket};
|
|
|
|
use tokio_postgres::tls::{MakeTlsConnect, TlsConnect};
|
2018-12-21 21:34:09 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "runtime")]
|
2018-12-30 05:00:58 +00:00
|
|
|
use crate::Config;
|
2019-02-01 04:34:49 +00:00
|
|
|
use crate::{CopyOutReader, Query, SimpleQuery, Statement, ToStatement, Transaction};
|
2018-12-21 21:34:09 +00:00
|
|
|
|
|
|
|
pub struct Client(tokio_postgres::Client);
|
|
|
|
|
|
|
|
impl Client {
|
|
|
|
#[cfg(feature = "runtime")]
|
|
|
|
pub fn connect<T>(params: &str, tls_mode: T) -> Result<Client, Error>
|
|
|
|
where
|
2019-01-13 22:53:19 +00:00
|
|
|
T: MakeTlsConnect<Socket> + 'static + Send,
|
|
|
|
T::TlsConnect: Send,
|
2018-12-21 21:34:09 +00:00
|
|
|
T::Stream: Send,
|
2019-01-13 22:53:19 +00:00
|
|
|
<T::TlsConnect as TlsConnect<Socket>>::Future: Send,
|
2018-12-21 21:34:09 +00:00
|
|
|
{
|
2018-12-30 05:00:58 +00:00
|
|
|
params.parse::<Config>()?.connect(tls_mode)
|
2018-12-21 21:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "runtime")]
|
2018-12-30 05:05:01 +00:00
|
|
|
pub fn configure() -> Config {
|
2018-12-30 05:00:58 +00:00
|
|
|
Config::new()
|
2018-12-21 21:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn prepare(&mut self, query: &str) -> Result<Statement, Error> {
|
|
|
|
self.0.prepare(query).wait().map(Statement)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn prepare_typed(&mut self, query: &str, types: &[Type]) -> Result<Statement, Error> {
|
|
|
|
self.0.prepare_typed(query, types).wait().map(Statement)
|
|
|
|
}
|
|
|
|
|
2018-12-22 04:13:15 +00:00
|
|
|
pub fn execute<T>(&mut self, query: &T, params: &[&dyn ToSql]) -> Result<u64, Error>
|
|
|
|
where
|
2018-12-29 04:20:31 +00:00
|
|
|
T: ?Sized + ToStatement,
|
2018-12-22 04:13:15 +00:00
|
|
|
{
|
|
|
|
let statement = query.__statement(self)?;
|
2018-12-21 21:34:09 +00:00
|
|
|
self.0.execute(&statement.0, params).wait()
|
|
|
|
}
|
|
|
|
|
2018-12-29 04:39:32 +00:00
|
|
|
pub fn query<T>(&mut self, query: &T, params: &[&dyn ToSql]) -> Result<Query<'_>, Error>
|
2018-12-22 04:13:15 +00:00
|
|
|
where
|
2018-12-29 04:20:31 +00:00
|
|
|
T: ?Sized + ToStatement,
|
2018-12-22 04:13:15 +00:00
|
|
|
{
|
|
|
|
let statement = query.__statement(self)?;
|
2018-12-29 04:39:32 +00:00
|
|
|
Ok(Query::new(self.0.query(&statement.0, params)))
|
2018-12-21 21:34:09 +00:00
|
|
|
}
|
|
|
|
|
2018-12-23 05:42:03 +00:00
|
|
|
pub fn copy_in<T, R>(
|
|
|
|
&mut self,
|
|
|
|
query: &T,
|
|
|
|
params: &[&dyn ToSql],
|
|
|
|
reader: R,
|
|
|
|
) -> Result<u64, Error>
|
|
|
|
where
|
2018-12-29 04:20:31 +00:00
|
|
|
T: ?Sized + ToStatement,
|
2018-12-23 05:42:03 +00:00
|
|
|
R: Read,
|
|
|
|
{
|
|
|
|
let statement = query.__statement(self)?;
|
2018-12-23 23:02:42 +00:00
|
|
|
self.0
|
|
|
|
.copy_in(&statement.0, params, CopyInStream(reader))
|
|
|
|
.wait()
|
2018-12-23 05:42:03 +00:00
|
|
|
}
|
|
|
|
|
2018-12-23 21:08:02 +00:00
|
|
|
pub fn copy_out<T>(
|
|
|
|
&mut self,
|
|
|
|
query: &T,
|
|
|
|
params: &[&dyn ToSql],
|
|
|
|
) -> Result<CopyOutReader<'_>, Error>
|
|
|
|
where
|
2018-12-29 04:20:31 +00:00
|
|
|
T: ?Sized + ToStatement,
|
2018-12-23 21:08:02 +00:00
|
|
|
{
|
|
|
|
let statement = query.__statement(self)?;
|
2018-12-29 05:01:10 +00:00
|
|
|
let stream = self.0.copy_out(&statement.0, params);
|
|
|
|
CopyOutReader::new(stream)
|
2018-12-23 21:08:02 +00:00
|
|
|
}
|
|
|
|
|
2019-02-01 04:34:49 +00:00
|
|
|
pub fn simple_query(&mut self, query: &str) -> Result<SimpleQuery<'_>, Error> {
|
|
|
|
Ok(SimpleQuery::new(self.0.simple_query(query)))
|
2018-12-21 21:34:09 +00:00
|
|
|
}
|
2018-12-21 21:46:50 +00:00
|
|
|
|
|
|
|
pub fn transaction(&mut self) -> Result<Transaction<'_>, Error> {
|
2019-02-01 04:34:49 +00:00
|
|
|
self.simple_query("BEGIN")?.count()?;
|
2018-12-21 21:46:50 +00:00
|
|
|
Ok(Transaction::new(self))
|
|
|
|
}
|
2018-12-22 05:08:26 +00:00
|
|
|
|
|
|
|
pub fn is_closed(&self) -> bool {
|
|
|
|
self.0.is_closed()
|
|
|
|
}
|
2018-12-23 23:58:39 +00:00
|
|
|
|
|
|
|
pub fn get_ref(&self) -> &tokio_postgres::Client {
|
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_mut(&mut self) -> &mut tokio_postgres::Client {
|
|
|
|
&mut self.0
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn into_inner(self) -> tokio_postgres::Client {
|
|
|
|
self.0
|
|
|
|
}
|
2018-12-21 21:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<tokio_postgres::Client> for Client {
|
|
|
|
fn from(c: tokio_postgres::Client) -> Client {
|
|
|
|
Client(c)
|
|
|
|
}
|
|
|
|
}
|
2018-12-23 05:42:03 +00:00
|
|
|
|
2018-12-23 23:02:42 +00:00
|
|
|
struct CopyInStream<R>(R);
|
2018-12-23 05:42:03 +00:00
|
|
|
|
2018-12-23 23:02:42 +00:00
|
|
|
impl<R> Stream for CopyInStream<R>
|
|
|
|
where
|
|
|
|
R: Read,
|
|
|
|
{
|
2018-12-23 05:42:03 +00:00
|
|
|
type Item = Vec<u8>;
|
|
|
|
type Error = io::Error;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<Option<Vec<u8>>, io::Error> {
|
2018-12-23 23:02:42 +00:00
|
|
|
let mut buf = vec![];
|
|
|
|
match self.0.by_ref().take(4096).read_to_end(&mut buf)? {
|
|
|
|
0 => Ok(Async::Ready(None)),
|
|
|
|
_ => Ok(Async::Ready(Some(buf))),
|
2018-12-23 05:42:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|