|
1 |
| -//! Postgres connection parameters. |
2 |
| -
|
| 1 | +//! Connection parameters |
3 | 2 | use std::error::Error;
|
4 |
| -use std::path::{Path, PathBuf}; |
5 |
| -use std::mem; |
| 3 | +use std::path::PathBuf; |
6 | 4 |
|
7 | 5 | use params::url::Url;
|
8 | 6 |
|
9 | 7 | mod url;
|
10 | 8 |
|
11 |
| -/// The host. |
| 9 | +/// Specifies the target server to connect to. |
12 | 10 | #[derive(Clone, Debug)]
|
13 |
| -pub enum Host { |
14 |
| - /// A TCP hostname. |
| 11 | +pub enum ConnectTarget { |
| 12 | + /// Connect via TCP to the specified host. |
15 | 13 | 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). |
18 | 17 | Unix(PathBuf),
|
19 | 18 | }
|
20 | 19 |
|
21 | 20 | /// Authentication information.
|
22 | 21 | #[derive(Clone, Debug)]
|
23 |
| -pub struct User { |
24 |
| - name: String, |
25 |
| - password: Option<String>, |
26 |
| -} |
27 |
| - |
28 |
| -impl User { |
| 22 | +pub struct UserInfo { |
29 | 23 | /// The username.
|
30 |
| - pub fn name(&self) -> &str { |
31 |
| - &self.name |
32 |
| - } |
33 |
| - |
| 24 | + pub user: String, |
34 | 25 | /// An optional password.
|
35 |
| - pub fn password(&self) -> Option<&str> { |
36 |
| - self.password.as_ref().map(|p| &**p) |
37 |
| - } |
| 26 | + pub password: Option<String>, |
38 | 27 | }
|
39 | 28 |
|
40 | 29 | /// Information necessary to open a new connection to a Postgres server.
|
41 | 30 | #[derive(Clone, Debug)]
|
42 | 31 | 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 |
| - |
61 | 32 | /// The target server.
|
62 |
| - pub fn host(&self) -> &Host { |
63 |
| - &self.host |
64 |
| - } |
65 |
| - |
| 33 | + pub target: ConnectTarget, |
66 | 34 | /// The target port.
|
67 | 35 | ///
|
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>, |
73 | 38 | /// The user to login as.
|
74 | 39 | ///
|
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>, |
80 | 42 | /// The database to connect to.
|
81 | 43 | ///
|
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>, |
87 | 46 | /// 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)>, |
144 | 48 | }
|
145 | 49 |
|
146 | 50 | /// A trait implemented by types that can be converted into a `ConnectParams`.
|
@@ -172,32 +76,37 @@ impl IntoConnectParams for String {
|
172 | 76 |
|
173 | 77 | impl IntoConnectParams for Url {
|
174 | 78 | 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; |
195 | 80 |
|
196 | 81 | 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)) |
199 | 84 | } 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 | + }) |
202 | 110 | }
|
203 | 111 | }
|
| 112 | + |
0 commit comments