2018-07-05 04:02:08 +00:00
|
|
|
extern crate antidote;
|
2017-04-23 22:39:07 +00:00
|
|
|
extern crate bytes;
|
2016-12-21 03:50:44 +00:00
|
|
|
extern crate fallible_iterator;
|
2018-06-17 04:29:27 +00:00
|
|
|
extern crate futures_cpupool;
|
2016-12-20 23:42:28 +00:00
|
|
|
extern crate postgres_protocol;
|
2018-01-10 05:15:35 +00:00
|
|
|
extern crate postgres_shared;
|
2018-06-17 04:29:27 +00:00
|
|
|
extern crate tokio_codec;
|
2017-04-23 22:39:07 +00:00
|
|
|
extern crate tokio_io;
|
2018-06-17 04:29:27 +00:00
|
|
|
extern crate tokio_tcp;
|
|
|
|
extern crate tokio_timer;
|
2017-02-24 03:48:20 +00:00
|
|
|
|
2017-03-03 06:27:12 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate futures;
|
2018-06-17 04:29:27 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate lazy_static;
|
|
|
|
#[macro_use]
|
2018-06-19 02:34:25 +00:00
|
|
|
extern crate log;
|
|
|
|
#[macro_use]
|
2018-06-17 04:29:27 +00:00
|
|
|
extern crate state_machine_future;
|
2017-03-03 06:27:12 +00:00
|
|
|
|
2017-02-24 03:48:20 +00:00
|
|
|
#[cfg(unix)]
|
2016-12-20 23:42:28 +00:00
|
|
|
extern crate tokio_uds;
|
|
|
|
|
2018-06-21 00:06:11 +00:00
|
|
|
use futures::{Async, Future, Poll, Stream};
|
|
|
|
use postgres_shared::rows::RowIndex;
|
|
|
|
use std::fmt;
|
2016-12-20 23:42:28 +00:00
|
|
|
use std::io;
|
2018-06-19 02:34:25 +00:00
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
2016-12-20 23:42:28 +00:00
|
|
|
|
2017-07-20 04:22:27 +00:00
|
|
|
#[doc(inline)]
|
2018-06-18 12:18:04 +00:00
|
|
|
pub use postgres_shared::stmt::Column;
|
|
|
|
#[doc(inline)]
|
|
|
|
pub use postgres_shared::{error, params, types};
|
2018-04-15 21:38:01 +00:00
|
|
|
#[doc(inline)]
|
2018-06-17 04:29:27 +00:00
|
|
|
pub use postgres_shared::{CancelData, Notification};
|
2016-12-25 17:51:12 +00:00
|
|
|
|
2018-07-07 17:11:16 +00:00
|
|
|
use error::{DbError, Error};
|
2018-06-17 04:29:27 +00:00
|
|
|
use params::ConnectParams;
|
2018-06-26 04:16:18 +00:00
|
|
|
use tls::TlsConnect;
|
2018-06-21 00:06:11 +00:00
|
|
|
use types::{FromSql, ToSql, Type};
|
2016-12-20 23:42:28 +00:00
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
mod proto;
|
2018-06-26 04:16:18 +00:00
|
|
|
pub mod tls;
|
2017-07-20 04:22:27 +00:00
|
|
|
|
2018-06-19 02:34:25 +00:00
|
|
|
static NEXT_STATEMENT_ID: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
|
2018-07-08 23:02:45 +00:00
|
|
|
fn next_statement() -> String {
|
|
|
|
format!("s{}", NEXT_STATEMENT_ID.fetch_add(1, Ordering::SeqCst))
|
|
|
|
}
|
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
fn bad_response() -> Error {
|
|
|
|
Error::from(io::Error::new(
|
|
|
|
io::ErrorKind::InvalidInput,
|
|
|
|
"the server returned an unexpected response",
|
|
|
|
))
|
2016-12-20 23:42:28 +00:00
|
|
|
}
|
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
fn disconnected() -> Error {
|
|
|
|
Error::from(io::Error::new(
|
|
|
|
io::ErrorKind::UnexpectedEof,
|
|
|
|
"server disconnected",
|
|
|
|
))
|
2016-12-20 23:42:28 +00:00
|
|
|
}
|
|
|
|
|
2018-06-26 04:16:18 +00:00
|
|
|
pub enum TlsMode {
|
|
|
|
None,
|
|
|
|
Prefer(Box<TlsConnect>),
|
|
|
|
Require(Box<TlsConnect>),
|
|
|
|
}
|
|
|
|
|
2018-06-28 05:37:43 +00:00
|
|
|
pub fn cancel_query(params: ConnectParams, tls: TlsMode, cancel_data: CancelData) -> CancelQuery {
|
|
|
|
CancelQuery(proto::CancelFuture::new(params, tls, cancel_data))
|
|
|
|
}
|
|
|
|
|
2018-06-26 04:16:18 +00:00
|
|
|
pub fn connect(params: ConnectParams, tls: TlsMode) -> Handshake {
|
|
|
|
Handshake(proto::HandshakeFuture::new(params, tls))
|
2018-06-19 02:34:25 +00:00
|
|
|
}
|
|
|
|
|
2018-06-18 12:18:04 +00:00
|
|
|
pub struct Client(proto::Client);
|
2016-12-20 23:42:28 +00:00
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
impl Client {
|
2018-06-19 02:34:25 +00:00
|
|
|
pub fn prepare(&mut self, query: &str) -> Prepare {
|
|
|
|
self.prepare_typed(query, &[])
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn prepare_typed(&mut self, query: &str, param_types: &[Type]) -> Prepare {
|
2018-07-08 23:02:45 +00:00
|
|
|
Prepare(self.0.prepare(next_statement(), query, param_types))
|
2018-06-19 02:34:25 +00:00
|
|
|
}
|
2018-06-20 02:10:07 +00:00
|
|
|
|
|
|
|
pub fn execute(&mut self, statement: &Statement, params: &[&ToSql]) -> Execute {
|
|
|
|
Execute(self.0.execute(&statement.0, params))
|
|
|
|
}
|
2018-06-21 00:06:11 +00:00
|
|
|
|
|
|
|
pub fn query(&mut self, statement: &Statement, params: &[&ToSql]) -> Query {
|
|
|
|
Query(self.0.query(&statement.0, params))
|
|
|
|
}
|
2018-07-08 05:42:04 +00:00
|
|
|
|
2018-07-14 21:59:37 +00:00
|
|
|
pub fn transaction<T>(&mut self, future: T) -> Transaction<T>
|
|
|
|
where
|
|
|
|
T: Future,
|
|
|
|
T::Error: From<Error>,
|
|
|
|
{
|
|
|
|
Transaction(proto::TransactionFuture::new(self.0.clone(), future))
|
|
|
|
}
|
|
|
|
|
2018-07-08 05:42:04 +00:00
|
|
|
pub fn batch_execute(&mut self, query: &str) -> BatchExecute {
|
|
|
|
BatchExecute(self.0.batch_execute(query))
|
|
|
|
}
|
2016-12-20 23:42:28 +00:00
|
|
|
}
|
|
|
|
|
2018-06-19 23:54:29 +00:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
2018-06-17 04:29:27 +00:00
|
|
|
pub struct Connection(proto::Connection);
|
2016-12-21 03:50:44 +00:00
|
|
|
|
2016-12-20 23:42:28 +00:00
|
|
|
impl Connection {
|
|
|
|
pub fn cancel_data(&self) -> CancelData {
|
2018-06-17 04:29:27 +00:00
|
|
|
self.0.cancel_data()
|
2016-12-20 23:42:28 +00:00
|
|
|
}
|
2016-12-26 21:21:20 +00:00
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
pub fn parameter(&self, name: &str) -> Option<&str> {
|
|
|
|
self.0.parameter(name)
|
2018-01-29 11:05:16 +00:00
|
|
|
}
|
2018-07-07 17:11:16 +00:00
|
|
|
|
|
|
|
pub fn poll_message(&mut self) -> Poll<Option<AsyncMessage>, Error> {
|
|
|
|
self.0.poll_message()
|
|
|
|
}
|
2016-12-20 23:42:28 +00:00
|
|
|
}
|
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
impl Future for Connection {
|
|
|
|
type Item = ();
|
2017-03-03 06:27:12 +00:00
|
|
|
type Error = Error;
|
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
fn poll(&mut self) -> Poll<(), Error> {
|
|
|
|
self.0.poll()
|
2016-12-21 03:50:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-07 17:11:16 +00:00
|
|
|
pub enum AsyncMessage {
|
|
|
|
Notice(DbError),
|
|
|
|
Notification(Notification),
|
|
|
|
#[doc(hidden)]
|
|
|
|
__NonExhaustive,
|
|
|
|
}
|
|
|
|
|
2018-06-28 05:37:43 +00:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
|
|
|
pub struct CancelQuery(proto::CancelFuture);
|
|
|
|
|
|
|
|
impl Future for CancelQuery {
|
|
|
|
type Item = ();
|
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<(), Error> {
|
|
|
|
self.0.poll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-19 23:54:29 +00:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
2018-06-17 04:29:27 +00:00
|
|
|
pub struct Handshake(proto::HandshakeFuture);
|
2017-09-30 21:56:15 +00:00
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
impl Future for Handshake {
|
|
|
|
type Item = (Client, Connection);
|
|
|
|
type Error = Error;
|
2017-09-30 21:56:15 +00:00
|
|
|
|
2018-06-17 04:29:27 +00:00
|
|
|
fn poll(&mut self) -> Poll<(Client, Connection), Error> {
|
2018-06-18 12:18:04 +00:00
|
|
|
let (client, connection) = try_ready!(self.0.poll());
|
2017-09-30 21:56:15 +00:00
|
|
|
|
2018-06-18 12:18:04 +00:00
|
|
|
Ok(Async::Ready((Client(client), Connection(connection))))
|
2017-09-30 21:56:15 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-19 02:34:25 +00:00
|
|
|
|
2018-06-19 23:54:29 +00:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
2018-06-19 02:34:25 +00:00
|
|
|
pub struct Prepare(proto::PrepareFuture);
|
|
|
|
|
|
|
|
impl Future for Prepare {
|
|
|
|
type Item = Statement;
|
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<Statement, Error> {
|
|
|
|
let statement = try_ready!(self.0.poll());
|
|
|
|
|
|
|
|
Ok(Async::Ready(Statement(statement)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Statement(proto::Statement);
|
|
|
|
|
|
|
|
impl Statement {
|
|
|
|
pub fn params(&self) -> &[Type] {
|
|
|
|
self.0.params()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn columns(&self) -> &[Column] {
|
|
|
|
self.0.columns()
|
|
|
|
}
|
|
|
|
}
|
2018-06-20 02:10:07 +00:00
|
|
|
|
|
|
|
#[must_use = "futures do nothing unless polled"]
|
|
|
|
pub struct Execute(proto::ExecuteFuture);
|
|
|
|
|
|
|
|
impl Future for Execute {
|
|
|
|
type Item = u64;
|
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<u64, Error> {
|
|
|
|
self.0.poll()
|
|
|
|
}
|
|
|
|
}
|
2018-06-21 00:06:11 +00:00
|
|
|
|
|
|
|
#[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<Option<Row>, Error> {
|
|
|
|
match self.0.poll() {
|
|
|
|
Ok(Async::Ready(Some(row))) => Ok(Async::Ready(Some(Row(row)))),
|
|
|
|
Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
|
|
|
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
|
|
|
Err(e) => Err(e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Row(proto::Row);
|
|
|
|
|
|
|
|
impl Row {
|
|
|
|
pub fn columns(&self) -> &[Column] {
|
|
|
|
self.0.columns()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
self.0.len()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get<'a, I, T>(&'a self, idx: I) -> T
|
|
|
|
where
|
|
|
|
I: RowIndex + fmt::Debug,
|
|
|
|
T: FromSql<'a>,
|
|
|
|
{
|
|
|
|
self.0.get(idx)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn try_get<'a, I, T>(&'a self, idx: I) -> Result<Option<T>, Error>
|
|
|
|
where
|
|
|
|
I: RowIndex,
|
|
|
|
T: FromSql<'a>,
|
|
|
|
{
|
|
|
|
self.0.try_get(idx)
|
|
|
|
}
|
|
|
|
}
|
2018-07-08 05:42:04 +00:00
|
|
|
|
2018-07-14 21:59:37 +00:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
|
|
|
pub struct Transaction<T>(proto::TransactionFuture<T, T::Item, T::Error>)
|
|
|
|
where
|
|
|
|
T: Future,
|
|
|
|
T::Error: From<Error>;
|
|
|
|
|
|
|
|
impl<T> Future for Transaction<T>
|
|
|
|
where
|
|
|
|
T: Future,
|
|
|
|
T::Error: From<Error>,
|
|
|
|
{
|
|
|
|
type Item = T::Item;
|
|
|
|
type Error = T::Error;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<T::Item, T::Error> {
|
|
|
|
self.0.poll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-08 05:42:04 +00:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
|
|
|
pub struct BatchExecute(proto::SimpleQueryFuture);
|
|
|
|
|
|
|
|
impl Future for BatchExecute {
|
|
|
|
type Item = ();
|
|
|
|
type Error = Error;
|
|
|
|
|
|
|
|
fn poll(&mut self) -> Poll<(), Error> {
|
|
|
|
self.0.poll()
|
|
|
|
}
|
|
|
|
}
|