Skip to content

Commit 1ef2e8b

Browse files
committed
Merge branch 'release-v0.9.4' into release
2 parents d6616dd + b3e596b commit 1ef2e8b

File tree

8 files changed

+100
-28
lines changed

8 files changed

+100
-28
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
language: rust
2+
sudo: required
23
rust:
34
- nightly
45
- beta

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[package]
22
name = "postgres"
3-
version = "0.9.3"
3+
version = "0.9.4"
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.9.3/postgres"
8+
documentation = "https://sfackler.github.io/rust-postgres/doc/v0.9.4/postgres"
99
readme = "README.md"
1010
keywords = ["database", "sql"]
1111
build = "build.rs"

README.md

Lines changed: 5 additions & 3 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.9.3/postgres)
4+
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.9.4/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

@@ -216,9 +216,11 @@ types. The driver currently supports the following conversions:
216216
</tr>
217217
<tr>
218218
<td>
219-
<a href="https://github.com/rust-lang/time">time::Timespec</a>
219+
<a href="https://github.com/rust-lang/time">time::Timespec</a>,
220+
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime&lt;UTC&gt;</a>,
221+
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime&lt;Local&gt;</a>,
220222
and
221-
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime&lt;UTC&gt;</a>
223+
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime&lt;FixedOffset&gt;</a>
222224
(<a href="#optional-features">optional</a>)
223225
</td>
224226
<td>TIMESTAMP WITH TIME ZONE</td>

src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
//! }
4242
//! }
4343
//! ```
44-
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.9.3")]
44+
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.9.4")]
4545
#![warn(missing_docs)]
4646

4747
extern crate bufstream;
@@ -864,6 +864,11 @@ impl InnerConnection {
864864
}
865865
}
866866

867+
fn _ensure_send() {
868+
fn _is_send<T: Send>() {}
869+
_is_send::<Connection>();
870+
}
871+
867872
/// A connection to a Postgres database.
868873
pub struct Connection {
869874
conn: RefCell<InnerConnection>

src/rows.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Query result rows.
22
3+
use std::ascii::AsciiExt;
34
use std::fmt;
45
use std::collections::VecDeque;
56
use debug_builders::DebugStruct;
@@ -274,7 +275,14 @@ impl RowIndex for usize {
274275
impl<'a> RowIndex for &'a str {
275276
#[inline]
276277
fn idx(&self, stmt: &Statement) -> Option<usize> {
277-
stmt.columns().iter().position(|d| d.name == *self)
278+
if let Some(idx) = stmt.columns().iter().position(|d| d.name == *self) {
279+
return Some(idx);
280+
};
281+
282+
// FIXME ASCII-only case insensitivity isn't really the right thing to
283+
// do. Postgres itself uses a dubious wrapper around tolower and JDBC
284+
// uses the US locale.
285+
stmt.columns().iter().position(|d| d.name.eq_ignore_ascii_case(*self))
278286
}
279287
}
280288

src/types/chrono.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ extern crate chrono;
33
use std::error;
44
use std::io::prelude::*;
55
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
6-
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC};
6+
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC, Local, FixedOffset};
77

88
use Result;
99
use error::Error;
@@ -52,6 +52,45 @@ impl ToSql for DateTime<UTC> {
5252
to_sql_checked!();
5353
}
5454

55+
impl FromSql for DateTime<Local> {
56+
fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo) -> Result<DateTime<Local>> {
57+
let utc = try!(DateTime::<UTC>::from_sql(type_, raw, info));
58+
Ok(utc.with_timezone(&Local))
59+
}
60+
61+
accepts!(Type::TimestampTZ);
62+
}
63+
64+
impl ToSql for DateTime<Local> {
65+
fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
66+
-> Result<IsNull> {
67+
self.with_timezone(&UTC).to_sql(type_, w, info)
68+
}
69+
70+
accepts!(Type::TimestampTZ);
71+
to_sql_checked!();
72+
}
73+
74+
impl FromSql for DateTime<FixedOffset> {
75+
fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo)
76+
-> Result<DateTime<FixedOffset>> {
77+
let utc = try!(DateTime::<UTC>::from_sql(type_, raw, info));
78+
Ok(utc.with_timezone(&FixedOffset::east(0)))
79+
}
80+
81+
accepts!(Type::TimestampTZ);
82+
}
83+
84+
impl ToSql for DateTime<FixedOffset> {
85+
fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
86+
-> Result<IsNull> {
87+
self.with_timezone(&UTC).to_sql(type_, w, info)
88+
}
89+
90+
accepts!(Type::TimestampTZ);
91+
to_sql_checked!();
92+
}
93+
5594
impl FromSql for NaiveDate {
5695
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDate> {
5796
let jd = try!(raw.read_i32::<BigEndian>());

src/types/mod.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -565,16 +565,18 @@ impl error::Error for WasNull {
565565
/// name. For example, the `serde` feature enables the implementation for the
566566
/// `serde::json::Value` type.
567567
///
568-
/// | Rust type | Postgres type(s) |
569-
/// |-----------------------------|-------------------------------------|
570-
/// | serialize::json::Json | JSON, JSONB |
571-
/// | serde::json::Value | JSON, JSONB |
572-
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
573-
/// | chrono::NaiveDateTime | TIMESTAMP |
574-
/// | chrono::DateTime&lt;UTC&gt; | TIMESTAMP WITH TIME ZONE |
575-
/// | chrono::NaiveDate | DATE |
576-
/// | chrono::NaiveTime | TIME |
577-
/// | uuid::Uuid | UUID |
568+
/// | Rust type | Postgres type(s) |
569+
/// |-------------------------------------|-------------------------------------|
570+
/// | serialize::json::Json | JSON, JSONB |
571+
/// | serde::json::Value | JSON, JSONB |
572+
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
573+
/// | chrono::NaiveDateTime | TIMESTAMP |
574+
/// | chrono::DateTime&lt;UTC&gt; | TIMESTAMP WITH TIME ZONE |
575+
/// | chrono::DateTime&lt;Local&gt; | TIMESTAMP WITH TIME ZONE |
576+
/// | chrono::DateTime&lt;FixedOffset&gt; | TIMESTAMP WITH TIME ZONE |
577+
/// | chrono::NaiveDate | DATE |
578+
/// | chrono::NaiveTime | TIME |
579+
/// | uuid::Uuid | UUID |
578580
///
579581
/// # Nullability
580582
///
@@ -770,16 +772,18 @@ pub enum IsNull {
770772
/// name. For example, the `serde` feature enables the implementation for the
771773
/// `serde::json::Value` type.
772774
///
773-
/// | Rust type | Postgres type(s) |
774-
/// |-----------------------------|-------------------------------------|
775-
/// | serialize::json::Json | JSON, JSONB |
776-
/// | serde::json::Value | JSON, JSONB |
777-
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
778-
/// | chrono::NaiveDateTime | TIMESTAMP |
779-
/// | chrono::DateTime&lt;UTC&gt; | TIMESTAMP WITH TIME ZONE |
780-
/// | chrono::NaiveDate | DATE |
781-
/// | chrono::NaiveTime | TIME |
782-
/// | uuid::Uuid | UUID |
775+
/// | Rust type | Postgres type(s) |
776+
/// |-------------------------------------|-------------------------------------|
777+
/// | serialize::json::Json | JSON, JSONB |
778+
/// | serde::json::Value | JSON, JSONB |
779+
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
780+
/// | chrono::NaiveDateTime | TIMESTAMP |
781+
/// | chrono::DateTime&lt;UTC&gt; | TIMESTAMP WITH TIME ZONE |
782+
/// | chrono::DateTime&lt;Local&gt; | TIMESTAMP WITH TIME ZONE |
783+
/// | chrono::DateTime&lt;FixedOffset&gt; | TIMESTAMP WITH TIME ZONE |
784+
/// | chrono::NaiveDate | DATE |
785+
/// | chrono::NaiveTime | TIME |
786+
/// | uuid::Uuid | UUID |
783787
///
784788
/// # Nullability
785789
///

tests/test.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use postgres::error::SqlState::{SyntaxError,
2525
InvalidPassword,
2626
CardinalityViolation};
2727
use postgres::error::ErrorPosition::Normal;
28+
use postgres::rows::RowIndex;
2829

2930
macro_rules! or_panic {
3031
($e:expr) => (
@@ -886,3 +887,15 @@ fn test_rows_index() {
886887
assert_eq!(3, rows.len());
887888
assert_eq!(2i32, rows.get(1).get(0));
888889
}
890+
891+
#[test]
892+
fn test_row_case_insensitive() {
893+
let conn = Connection::connect("postgres://postgres@localhost", &SslMode::None).unwrap();
894+
conn.batch_execute("CREATE TEMPORARY TABLE foo (foo INT, \"bAr\" INT, \"Bar\" INT);").unwrap();
895+
let stmt = conn.prepare("SELECT * FROM foo").unwrap();
896+
assert_eq!(Some(0), "foo".idx(&stmt));
897+
assert_eq!(Some(0), "FOO".idx(&stmt));
898+
assert_eq!(Some(1), "bar".idx(&stmt));
899+
assert_eq!(Some(1), "bAr".idx(&stmt));
900+
assert_eq!(Some(2), "Bar".idx(&stmt));
901+
}

0 commit comments

Comments
 (0)