From 759256010d1a9c2eafbad1043126ada939a17cab Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 21 Dec 2018 13:34:09 -0800 Subject: [PATCH] Initial sync crate sketch --- Cargo.toml | 1 + postgres/Cargo.toml | 18 ++++++++++++ postgres/src/builder.rs | 50 ++++++++++++++++++++++++++++++++ postgres/src/client.rs | 60 +++++++++++++++++++++++++++++++++++++++ postgres/src/lib.rs | 22 ++++++++++++++ postgres/src/statement.rs | 14 +++++++++ 6 files changed, 165 insertions(+) create mode 100644 postgres/Cargo.toml create mode 100644 postgres/src/builder.rs create mode 100644 postgres/src/client.rs create mode 100644 postgres/src/lib.rs create mode 100644 postgres/src/statement.rs diff --git a/Cargo.toml b/Cargo.toml index 86e7becf..40e30b1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "codegen", + "postgres", "postgres-protocol", "tokio-postgres", "tokio-postgres-native-tls", diff --git a/postgres/Cargo.toml b/postgres/Cargo.toml new file mode 100644 index 00000000..03176d02 --- /dev/null +++ b/postgres/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "postgres" +version = "0.1.0" +authors = ["Steven Fackler "] +edition = "2018" + +[features] +default = ["runtime"] + +runtime = ["tokio-postgres/runtime", "tokio", "lazy_static", "log"] + +[dependencies] +futures = "0.1" +tokio-postgres = { version = "0.3", path = "../tokio-postgres", default-features = false } + +tokio = { version = "0.1", optional = true } +lazy_static = { version = "1.0", optional = true } +log = { version = "0.4", optional = true } diff --git a/postgres/src/builder.rs b/postgres/src/builder.rs new file mode 100644 index 00000000..43f35e6d --- /dev/null +++ b/postgres/src/builder.rs @@ -0,0 +1,50 @@ +use futures::sync::oneshot; +use futures::Future; +use log::error; +use std::str::FromStr; +use tokio_postgres::{Error, MakeTlsMode, Socket, TlsMode}; + +use crate::{Client, RUNTIME}; + +pub struct Builder(tokio_postgres::Builder); + +impl Default for Builder { + fn default() -> Builder { + Builder(tokio_postgres::Builder::default()) + } +} + +impl Builder { + pub fn new() -> Builder { + Builder(tokio_postgres::Builder::new()) + } + + pub fn param(&mut self, key: &str, value: &str) -> &mut Builder { + self.0.param(key, value); + self + } + + pub fn connect(&self, tls_mode: T) -> Result + where + T: MakeTlsMode + 'static + Send, + T::TlsMode: Send, + T::Stream: Send, + T::Future: Send, + >::Future: Send, + { + let connect = self.0.connect(tls_mode); + let (client, connection) = oneshot::spawn(connect, &RUNTIME.executor()).wait()?; + let connection = connection.map_err(|e| error!("postgres connection error: {}", e)); + RUNTIME.executor().spawn(connection); + + Ok(Client::from(client)) + } +} + +impl FromStr for Builder { + type Err = Error; + + fn from_str(s: &str) -> Result { + s.parse().map(Builder) + } +} diff --git a/postgres/src/client.rs b/postgres/src/client.rs new file mode 100644 index 00000000..2dce6d94 --- /dev/null +++ b/postgres/src/client.rs @@ -0,0 +1,60 @@ +use futures::{Future, Stream}; +use tokio_postgres::types::{ToSql, Type}; +use tokio_postgres::{Error, Row}; +#[cfg(feature = "runtime")] +use tokio_postgres::{MakeTlsMode, Socket, TlsMode}; + +#[cfg(feature = "runtime")] +use crate::Builder; +use crate::Statement; + +pub struct Client(tokio_postgres::Client); + +impl Client { + #[cfg(feature = "runtime")] + pub fn connect(params: &str, tls_mode: T) -> Result + where + T: MakeTlsMode + 'static + Send, + T::TlsMode: Send, + T::Stream: Send, + T::Future: Send, + >::Future: Send, + { + params.parse::()?.connect(tls_mode) + } + + #[cfg(feature = "runtime")] + pub fn builder() -> Builder { + Builder::new() + } + + pub fn prepare(&mut self, query: &str) -> Result { + self.0.prepare(query).wait().map(Statement) + } + + pub fn prepare_typed(&mut self, query: &str, types: &[Type]) -> Result { + self.0.prepare_typed(query, types).wait().map(Statement) + } + + pub fn execute(&mut self, statement: &Statement, params: &[&dyn ToSql]) -> Result { + self.0.execute(&statement.0, params).wait() + } + + pub fn query( + &mut self, + statement: &Statement, + params: &[&dyn ToSql], + ) -> Result, Error> { + self.0.query(&statement.0, params).collect().wait() + } + + pub fn batch_execute(&mut self, query: &str) -> Result<(), Error> { + self.0.batch_execute(query).wait() + } +} + +impl From for Client { + fn from(c: tokio_postgres::Client) -> Client { + Client(c) + } +} diff --git a/postgres/src/lib.rs b/postgres/src/lib.rs new file mode 100644 index 00000000..1072ea7c --- /dev/null +++ b/postgres/src/lib.rs @@ -0,0 +1,22 @@ +#[cfg(feature = "runtime")] +use lazy_static::lazy_static; +#[cfg(feature = "runtime")] +use tokio::runtime::{self, Runtime}; + +#[cfg(feature = "runtime")] +mod builder; +mod client; +mod statement; + +#[cfg(feature = "runtime")] +pub use crate::builder::*; +pub use crate::client::*; +pub use crate::statement::*; + +#[cfg(feature = "runtime")] +lazy_static! { + static ref RUNTIME: Runtime = runtime::Builder::new() + .name_prefix("postgres-") + .build() + .unwrap(); +} diff --git a/postgres/src/statement.rs b/postgres/src/statement.rs new file mode 100644 index 00000000..bcb74614 --- /dev/null +++ b/postgres/src/statement.rs @@ -0,0 +1,14 @@ +use tokio_postgres::types::Type; +use tokio_postgres::Column; + +pub struct Statement(pub(crate) tokio_postgres::Statement); + +impl Statement { + pub fn params(&self) -> &[Type] { + self.0.params() + } + + pub fn columns(&self) -> &[Column] { + self.0.columns() + } +}