Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b437f9a

Browse files
committed
Merge branch 'release-v0.11.8' into release
2 parents d1c28ee + 6918a8b commit b437f9a

File tree

7 files changed

+77
-27
lines changed

7 files changed

+77
-27
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ sudo: required
33
rust:
44
- nightly
55
- beta
6-
- 1.6.0
6+
- 1.7.0
77
addons:
88
postgresql: 9.4
99
before_script:
1010
- "./.travis/setup.sh"
1111
script:
1212
- cargo test
13+
- cargo update -p bitflags --precise 0.5.0
1314
- cargo test --features "uuid rustc-serialize time unix_socket serde_json chrono openssl bit-vec eui48"
1415
- (test $TRAVIS_RUST_VERSION != "nightly" || cargo test --features nightly)

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[package]
22
name = "postgres"
3-
version = "0.11.7"
3+
version = "0.11.8"
44
authors = ["Steven Fackler <[email protected]>"]
55
license = "MIT"
66
description = "A native PostgreSQL driver"
77
repository = "https://github.com/sfackler/rust-postgres"
8-
documentation = "https://sfackler.github.io/rust-postgres/doc/v0.11.7/postgres"
8+
documentation = "https://sfackler.github.io/rust-postgres/doc/v0.11.8/postgres"
99
readme = "README.md"
1010
keywords = ["database", "postgres", "postgresql", "sql"]
1111
include = ["src/*", "Cargo.toml", "LICENSE", "README.md", "THIRD_PARTY"]
@@ -43,4 +43,4 @@ eui48 = { version = "0.1", optional = true }
4343
clippy = { version = "0.0.61", optional = true }
4444

4545
[dev-dependencies]
46-
url = "0.5"
46+
url = "1.0"

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Rust-Postgres
22
A native PostgreSQL driver for Rust.
33

4-
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.11.7/postgres)
4+
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.11.8/postgres)
55

66
[![Build Status](https://travis-ci.org/sfackler/rust-postgres.png?branch=master)](https://travis-ci.org/sfackler/rust-postgres) [![Latest Version](https://img.shields.io/crates/v/postgres.svg)](https://crates.io/crates/postgres)
77

@@ -54,7 +54,7 @@ fn main() {
5454
```
5555

5656
## Requirements
57-
* **Rust** - Rust-Postgres is developed against the 1.6 release of Rust
57+
* **Rust** - Rust-Postgres is developed against the 1.7 release of Rust
5858
available on http://www.rust-lang.org. It should also compile against more
5959
recent releases.
6060

@@ -262,6 +262,13 @@ types. The driver currently supports the following conversions:
262262
</tbody>
263263
</table>
264264

265+
`Option<T>` implements `FromSql` where `T: FromSql` and `ToSql` where `T:
266+
ToSql`, and represents nullable Postgres values.
267+
268+
`&[T]` and `Vec<T>` implement `ToSql` where `T: ToSql`, and `Vec<T>`
269+
additionally implements `FromSql` where `T: FromSql`, which represent
270+
one-dimensional Postgres arrays.
271+
265272
More conversions can be defined by implementing the `ToSql` and `FromSql`
266273
traits.
267274

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
//! }
3939
//! }
4040
//! ```
41-
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.11.7")]
41+
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.11.8")]
4242
#![warn(missing_docs)]
4343
#![allow(unknown_lints, needless_lifetimes)] // for clippy
4444
#![cfg_attr(all(unix, feature = "nightly"), feature(unix_socket))]
@@ -421,6 +421,8 @@ impl InnerConnection {
421421
Err(Error::Io(e)) => return Err(ConnectError::Io(e)),
422422
// Old versions of Postgres and things like Redshift don't support enums
423423
Err(Error::Db(ref e)) if e.code == SqlState::UndefinedTable => {}
424+
// Some Postgres-like databases are missing a pg_catalog (e.g. Cockroach)
425+
Err(Error::Db(ref e)) if e.code == SqlState::InvalidCatalogName => return Ok(()),
424426
Err(Error::Db(e)) => return Err(ConnectError::Db(e)),
425427
Err(Error::Conversion(_)) => unreachable!(),
426428
}

src/transaction.rs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ impl Config {
151151
pub struct Transaction<'conn> {
152152
conn: &'conn Connection,
153153
depth: u32,
154+
savepoint_name: Option<String>,
154155
commit: Cell<bool>,
155156
finished: bool,
156157
}
@@ -177,6 +178,7 @@ impl<'conn> TransactionInternals<'conn> for Transaction<'conn> {
177178
Transaction {
178179
conn: conn,
179180
depth: depth,
181+
savepoint_name: None,
180182
commit: Cell::new(false),
181183
finished: false,
182184
}
@@ -195,14 +197,17 @@ impl<'conn> Transaction<'conn> {
195197
fn finish_inner(&mut self) -> Result<()> {
196198
let mut conn = self.conn.conn.borrow_mut();
197199
debug_assert!(self.depth == conn.trans_depth);
198-
let query = match (self.commit.get(), self.depth != 1) {
199-
(false, true) => "ROLLBACK TO sp",
200-
(false, false) => "ROLLBACK",
201-
(true, true) => "RELEASE sp",
202-
(true, false) => "COMMIT",
203-
};
204200
conn.trans_depth -= 1;
205-
conn.quick_query(query).map(|_| ())
201+
match (self.commit.get(), &self.savepoint_name) {
202+
(false, &Some(ref savepoint_name)) => {
203+
conn.quick_query(&format!("ROLLBACK TO {}", savepoint_name))
204+
}
205+
(false, &None) => conn.quick_query("ROLLBACK"),
206+
(true, &Some(ref savepoint_name)) => {
207+
conn.quick_query(&format!("RELEASE {}", savepoint_name))
208+
}
209+
(true, &None) => conn.quick_query("COMMIT"),
210+
}.map(|_| ())
206211
}
207212

208213
/// Like `Connection::prepare`.
@@ -233,22 +238,34 @@ impl<'conn> Transaction<'conn> {
233238
self.conn.batch_execute(query)
234239
}
235240

236-
/// Like `Connection::transaction`.
241+
/// Like `Connection::transaction`, but creates a nested transaction via
242+
/// a savepoint.
237243
///
238244
/// # Panics
239245
///
240246
/// Panics if there is an active nested transaction.
241247
pub fn transaction<'a>(&'a self) -> Result<Transaction<'a>> {
248+
self.savepoint("sp")
249+
}
250+
251+
/// Like `Connection::transaction`, but creates a nested transaction via
252+
/// a savepoint with the specified name.
253+
///
254+
/// # Panics
255+
///
256+
/// Panics if there is an active nested transaction.
257+
pub fn savepoint<'a>(&'a self, name: &str) -> Result<Transaction<'a>> {
242258
let mut conn = self.conn.conn.borrow_mut();
243259
check_desync!(conn);
244260
assert!(conn.trans_depth == self.depth,
245-
"`transaction` may only be called on the active transaction");
246-
try!(conn.quick_query("SAVEPOINT sp"));
261+
"`savepoint` may only be called on the active transaction");
262+
try!(conn.quick_query(&format!("SAVEPOINT {}", name)));
247263
conn.trans_depth += 1;
248264
Ok(Transaction {
249265
conn: self.conn,
250-
commit: Cell::new(false),
251266
depth: self.depth + 1,
267+
savepoint_name: Some(name.to_owned()),
268+
commit: Cell::new(false),
252269
finished: false,
253270
})
254271
}

src/url.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,17 @@ fn decode_inner(c: &str, full_url: bool) -> DecodeResult<String> {
131131
}
132132
};
133133

134+
let bytes_from_hex = match Vec::<u8>::from_hex(&bytes) {
135+
Ok(b) => b,
136+
_ => {
137+
return Err("Malformed input: found '%' followed by \
138+
invalid hex values. Character '%' must \
139+
escaped.".to_owned())
140+
}
141+
};
142+
134143
// Only decode some characters if full_url:
135-
match Vec::<u8>::from_hex(&bytes).unwrap()[0] as char {
144+
match bytes_from_hex[0] as char {
136145
// gen-delims:
137146
':' |
138147
'/' |

tests/test.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn test_unix_connection() {
8989
let unix_socket_directory = unix_socket_directories.split(',').next().unwrap();
9090

9191
let path = url::percent_encoding::utf8_percent_encode(
92-
unix_socket_directory, url::percent_encoding::USERNAME_ENCODE_SET);
92+
unix_socket_directory, url::percent_encoding::USERINFO_ENCODE_SET);
9393
let url = format!("postgres://postgres@{}", path);
9494
let conn = or_panic!(Connection::connect(&url[..], SslMode::None));
9595
assert!(conn.finish().is_ok());
@@ -202,9 +202,9 @@ fn test_nested_transactions() {
202202
}
203203

204204
{
205-
let trans3 = or_panic!(trans2.transaction());
206-
or_panic!(trans3.execute("INSERT INTO foo (id) VALUES (6)", &[]));
207-
assert!(trans3.commit().is_ok());
205+
let sp = or_panic!(trans2.savepoint("custom"));
206+
or_panic!(sp.execute("INSERT INTO foo (id) VALUES (6)", &[]));
207+
assert!(sp.commit().is_ok());
208208
}
209209

210210
assert!(trans2.commit().is_ok());
@@ -250,10 +250,10 @@ fn test_nested_transactions_finish() {
250250
}
251251

252252
{
253-
let trans3 = or_panic!(trans2.transaction());
254-
or_panic!(trans3.execute("INSERT INTO foo (id) VALUES (6)", &[]));
255-
trans3.set_commit();
256-
assert!(trans3.finish().is_ok());
253+
let sp = or_panic!(trans2.savepoint("custom"));
254+
or_panic!(sp.execute("INSERT INTO foo (id) VALUES (6)", &[]));
255+
sp.set_commit();
256+
assert!(sp.finish().is_ok());
257257
}
258258

259259
trans2.set_commit();
@@ -294,6 +294,15 @@ fn test_trans_with_nested_trans() {
294294
trans.transaction().unwrap();
295295
}
296296

297+
#[test]
298+
#[should_panic(expected = "active transaction")]
299+
fn test_trans_with_savepoints() {
300+
let conn = or_panic!(Connection::connect("postgres://postgres@localhost", SslMode::None));
301+
let trans = or_panic!(conn.transaction());
302+
let _sp = or_panic!(trans.savepoint("custom"));
303+
trans.savepoint("custom2").unwrap();
304+
}
305+
297306
#[test]
298307
fn test_stmt_execute_after_transaction() {
299308
let conn = or_panic!(Connection::connect("postgres://postgres@localhost", SslMode::None));
@@ -938,6 +947,11 @@ fn test_get_opt_wrong_type() {
938947
}
939948
}
940949

950+
#[test]
951+
fn url_unencoded_password() {
952+
assert!("postgresql://username:password%1*@localhost".into_connect_params().is_err())
953+
}
954+
941955
#[test]
942956
fn url_encoded_password() {
943957
let params = "postgresql://username%7b%7c:password%7b%7c@localhost".into_connect_params().unwrap();

0 commit comments

Comments
 (0)