Skip to content

Commit 32dc892

Browse files
committed
Merge params
1 parent d17846f commit 32dc892

File tree

4 files changed

+68
-259
lines changed

4 files changed

+68
-259
lines changed

postgres-shared/src/params/mod.rs

+48-139
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,50 @@
1-
//! Postgres connection parameters.
2-
1+
//! Connection parameters
32
use std::error::Error;
4-
use std::path::{Path, PathBuf};
5-
use std::mem;
3+
use std::path::PathBuf;
64

75
use params::url::Url;
86

97
mod url;
108

11-
/// The host.
9+
/// Specifies the target server to connect to.
1210
#[derive(Clone, Debug)]
13-
pub enum Host {
14-
/// A TCP hostname.
11+
pub enum ConnectTarget {
12+
/// Connect via TCP to the specified host.
1513
Tcp(String),
16-
17-
/// The path to a directory containing the server's Unix socket.
14+
/// Connect via a Unix domain socket in the specified directory.
15+
///
16+
/// Unix sockets are only supported on Unixy platforms (i.e. not Windows).
1817
Unix(PathBuf),
1918
}
2019

2120
/// Authentication information.
2221
#[derive(Clone, Debug)]
23-
pub struct User {
24-
name: String,
25-
password: Option<String>,
26-
}
27-
28-
impl User {
22+
pub struct UserInfo {
2923
/// The username.
30-
pub fn name(&self) -> &str {
31-
&self.name
32-
}
33-
24+
pub user: String,
3425
/// An optional password.
35-
pub fn password(&self) -> Option<&str> {
36-
self.password.as_ref().map(|p| &**p)
37-
}
26+
pub password: Option<String>,
3827
}
3928

4029
/// Information necessary to open a new connection to a Postgres server.
4130
#[derive(Clone, Debug)]
4231
pub struct ConnectParams {
43-
host: Host,
44-
port: u16,
45-
user: Option<User>,
46-
database: Option<String>,
47-
options: Vec<(String, String)>,
48-
}
49-
50-
impl ConnectParams {
51-
/// Returns a new builder.
52-
pub fn builder() -> Builder {
53-
Builder {
54-
port: 5432,
55-
user: None,
56-
database: None,
57-
options: vec![],
58-
}
59-
}
60-
6132
/// The target server.
62-
pub fn host(&self) -> &Host {
63-
&self.host
64-
}
65-
33+
pub target: ConnectTarget,
6634
/// The target port.
6735
///
68-
/// Defaults to 5432.
69-
pub fn port(&self) -> u16 {
70-
self.port
71-
}
72-
36+
/// Defaults to 5432 if not specified.
37+
pub port: Option<u16>,
7338
/// The user to login as.
7439
///
75-
/// Connection requires a user but query cancellation does not.
76-
pub fn user(&self) -> Option<&User> {
77-
self.user.as_ref()
78-
}
79-
40+
/// `Connection::connect` requires a user but `cancel_query` does not.
41+
pub user: Option<UserInfo>,
8042
/// The database to connect to.
8143
///
82-
/// Defaults to the username.
83-
pub fn database(&self) -> Option<&str> {
84-
self.database.as_ref().map(|d| &**d)
85-
}
86-
44+
/// Defaults the value of `user`.
45+
pub database: Option<String>,
8746
/// Runtime parameters to be passed to the Postgres backend.
88-
pub fn options(&self) -> &[(String, String)] {
89-
&self.options
90-
}
91-
}
92-
93-
/// A builder type for `ConnectParams`.
94-
pub struct Builder {
95-
port: u16,
96-
user: Option<User>,
97-
database: Option<String>,
98-
options: Vec<(String, String)>,
99-
}
100-
101-
impl Builder {
102-
pub fn port(&mut self, port: u16) -> &mut Builder {
103-
self.port = port;
104-
self
105-
}
106-
107-
pub fn user(&mut self, name: &str, password: Option<&str>) -> &mut Builder {
108-
self.user = Some(User {
109-
name: name.to_owned(),
110-
password: password.map(ToOwned::to_owned),
111-
});
112-
self
113-
}
114-
115-
pub fn database(&mut self, database: &str) -> &mut Builder {
116-
self.database = Some(database.to_owned());
117-
self
118-
}
119-
120-
pub fn option(&mut self, name: &str, value: &str) -> &mut Builder {
121-
self.options.push((name.to_owned(), value.to_owned()));
122-
self
123-
}
124-
125-
pub fn build_tcp(&mut self, host: &str) -> ConnectParams {
126-
self.build(Host::Tcp(host.to_owned()))
127-
}
128-
129-
pub fn build_unix<P>(&mut self, host: P) -> ConnectParams
130-
where P: AsRef<Path>
131-
{
132-
self.build(Host::Unix(host.as_ref().to_owned()))
133-
}
134-
135-
pub fn build(&mut self, host: Host) -> ConnectParams {
136-
ConnectParams {
137-
host: host,
138-
port: self.port,
139-
database: self.database.take(),
140-
user: self.user.take(),
141-
options: mem::replace(&mut self.options, vec![]),
142-
}
143-
}
47+
pub options: Vec<(String, String)>,
14448
}
14549

14650
/// A trait implemented by types that can be converted into a `ConnectParams`.
@@ -172,32 +76,37 @@ impl IntoConnectParams for String {
17276

17377
impl IntoConnectParams for Url {
17478
fn into_connect_params(self) -> Result<ConnectParams, Box<Error + Sync + Send>> {
175-
let Url { host, port, user, path: url::Path { path, query: options, .. }, .. } = self;
176-
177-
let mut builder = ConnectParams::builder();
178-
179-
if let Some(port) = port {
180-
builder.port(port);
181-
}
182-
183-
if let Some(info) = user {
184-
builder.user(&info.user, info.pass.as_ref().map(|p| &**p));
185-
}
186-
187-
if !path.is_empty() {
188-
// path contains the leading /
189-
builder.database(&path[1..]);
190-
}
191-
192-
for (name, value) in options {
193-
builder.option(&name, &value);
194-
}
79+
let Url { host, port, user, path: url::Path { mut path, query: options, .. }, .. } = self;
19580

19681
let maybe_path = try!(url::decode_component(&host));
197-
if maybe_path.starts_with('/') {
198-
Ok(builder.build_unix(maybe_path))
82+
let target = if maybe_path.starts_with('/') {
83+
ConnectTarget::Unix(PathBuf::from(maybe_path))
19984
} else {
200-
Ok(builder.build_tcp(&maybe_path))
201-
}
85+
ConnectTarget::Tcp(host)
86+
};
87+
88+
let user = user.map(|url::UserInfo { user, pass }| {
89+
UserInfo {
90+
user: user,
91+
password: pass,
92+
}
93+
});
94+
95+
let database = if path.is_empty() {
96+
None
97+
} else {
98+
// path contains the leading /
99+
path.remove(0);
100+
Some(path)
101+
};
102+
103+
Ok(ConnectParams {
104+
target: target,
105+
port: port,
106+
user: user,
107+
database: database,
108+
options: options,
109+
})
202110
}
203111
}
112+

postgres-tokio/src/lib.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ pub fn cancel_query<T>(params: T,
7272
{
7373
let params = match params.into_connect_params() {
7474
Ok(params) => {
75-
Either::A(stream::connect(params.host().clone(), params.port(), tls_mode, handle))
75+
Either::A(stream::connect(params.target.clone(),
76+
params.port.unwrap_or(5432),
77+
tls_mode,
78+
handle))
7679
}
7780
Err(e) => Either::B(Err(ConnectError::ConnectParams(e)).into_future())
7881
};
@@ -173,7 +176,10 @@ impl Connection {
173176
{
174177
let fut = match params.into_connect_params() {
175178
Ok(params) => {
176-
Either::A(stream::connect(params.host().clone(), params.port(), tls_mode, handle)
179+
Either::A(stream::connect(params.target.clone(),
180+
params.port.unwrap_or(5432),
181+
tls_mode,
182+
handle)
177183
.map(|s| (s, params)))
178184
}
179185
Err(e) => Either::B(Err(ConnectError::ConnectParams(e)).into_future())
@@ -208,9 +214,9 @@ impl Connection {
208214
let result = {
209215
let options = [("client_encoding", "UTF8"), ("timezone", "GMT")];
210216
let options = options.iter().cloned();
211-
let options = options.chain(params.user().map(|u| ("user", u.name())));
212-
let options = options.chain(params.database().map(|d| ("database", d)));
213-
let options = options.chain(params.options().iter().map(|e| (&*e.0, &*e.1)));
217+
let options = options.chain(params.user.as_ref().map(|u| ("user", &*u.user)));
218+
let options = options.chain(params.database.as_ref().map(|d| ("database", &**d)));
219+
let options = options.chain(params.options.iter().map(|e| (&*e.0, &*e.1)));
214220

215221
frontend::startup_message(options, &mut buf)
216222
};
@@ -230,7 +236,7 @@ impl Connection {
230236
let response = match m {
231237
backend::Message::AuthenticationOk => Ok(None),
232238
backend::Message::AuthenticationCleartextPassword => {
233-
match params.user().and_then(|u| u.password()) {
239+
match params.user.as_ref().and_then(|u| u.password.as_ref()) {
234240
Some(pass) => {
235241
let mut buf = vec![];
236242
frontend::password_message(pass, &mut buf)
@@ -244,7 +250,7 @@ impl Connection {
244250
}
245251
}
246252
backend::Message::AuthenticationMd5Password(body) => {
247-
match params.user().and_then(|u| u.password().map(|p| (u.name(), p))) {
253+
match params.user.as_ref().and_then(|u| u.password.as_ref().map(|p| (&u.user, p))) {
248254
Some((user, pass)) => {
249255
let pass = authentication::md5_hash(user.as_bytes(),
250256
pass.as_bytes(),

postgres-tokio/src/stream.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use futures::{BoxFuture, Future, IntoFuture, Async, Sink, Stream as FuturesStream};
22
use futures::future::Either;
3-
use postgres_shared::params::Host;
3+
use postgres_shared::params::ConnectTarget;
44
use postgres_protocol::message::backend::{self, ParseResult};
55
use postgres_protocol::message::frontend;
66
use std::io::{self, Read, Write};
@@ -16,17 +16,17 @@ use tls::TlsStream;
1616

1717
pub type PostgresStream = Framed<Box<TlsStream>, PostgresCodec>;
1818

19-
pub fn connect(host: Host,
19+
pub fn connect(host: ConnectTarget,
2020
port: u16,
2121
tls_mode: TlsMode,
2222
handle: &Handle)
2323
-> BoxFuture<PostgresStream, ConnectError> {
2424
let inner = match host {
25-
Host::Tcp(ref host) => {
25+
ConnectTarget::Tcp(ref host) => {
2626
Either::A(tokio_dns::tcp_connect((&**host, port), handle.remote().clone())
2727
.map(|s| Stream(InnerStream::Tcp(s))))
2828
}
29-
Host::Unix(ref host) => {
29+
ConnectTarget::Unix(ref host) => {
3030
let addr = host.join(format!(".s.PGSQL.{}", port));
3131
Either::B(UnixStream::connect(addr, handle)
3232
.map(|s| Stream(InnerStream::Unix(s)))
@@ -68,8 +68,8 @@ pub fn connect(host: Host,
6868
(None, _) => Either::A(Err(ConnectError::Io(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected EOF"))).into_future()),
6969
_ => {
7070
let host = match host {
71-
Host::Tcp(ref host) => host,
72-
Host::Unix(_) => unreachable!(),
71+
ConnectTarget::Tcp(ref host) => host,
72+
ConnectTarget::Unix(_) => unreachable!(),
7373
};
7474
Either::B(handshaker.handshake(host, s).map_err(ConnectError::Tls))
7575
}

0 commit comments

Comments
 (0)