Merge branch 'release-v0.9.4' into release
This commit is contained in:
commit
1ef2e8b217
@ -1,4 +1,5 @@
|
||||
language: rust
|
||||
sudo: required
|
||||
rust:
|
||||
- nightly
|
||||
- beta
|
||||
|
@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "postgres"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||
license = "MIT"
|
||||
description = "A native PostgreSQL driver"
|
||||
repository = "https://github.com/sfackler/rust-postgres"
|
||||
documentation = "https://sfackler.github.io/rust-postgres/doc/v0.9.3/postgres"
|
||||
documentation = "https://sfackler.github.io/rust-postgres/doc/v0.9.4/postgres"
|
||||
readme = "README.md"
|
||||
keywords = ["database", "sql"]
|
||||
build = "build.rs"
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Rust-Postgres
|
||||
A native PostgreSQL driver for Rust.
|
||||
|
||||
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.9.3/postgres)
|
||||
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.9.4/postgres)
|
||||
|
||||
[![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)
|
||||
|
||||
@ -216,9 +216,11 @@ types. The driver currently supports the following conversions:
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://github.com/rust-lang/time">time::Timespec</a>
|
||||
<a href="https://github.com/rust-lang/time">time::Timespec</a>,
|
||||
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime<UTC></a>,
|
||||
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime<Local></a>,
|
||||
and
|
||||
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime<UTC></a>
|
||||
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime<FixedOffset></a>
|
||||
(<a href="#optional-features">optional</a>)
|
||||
</td>
|
||||
<td>TIMESTAMP WITH TIME ZONE</td>
|
||||
|
@ -41,7 +41,7 @@
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.9.3")]
|
||||
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.9.4")]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
extern crate bufstream;
|
||||
@ -864,6 +864,11 @@ impl InnerConnection {
|
||||
}
|
||||
}
|
||||
|
||||
fn _ensure_send() {
|
||||
fn _is_send<T: Send>() {}
|
||||
_is_send::<Connection>();
|
||||
}
|
||||
|
||||
/// A connection to a Postgres database.
|
||||
pub struct Connection {
|
||||
conn: RefCell<InnerConnection>
|
||||
|
10
src/rows.rs
10
src/rows.rs
@ -1,5 +1,6 @@
|
||||
//! Query result rows.
|
||||
|
||||
use std::ascii::AsciiExt;
|
||||
use std::fmt;
|
||||
use std::collections::VecDeque;
|
||||
use debug_builders::DebugStruct;
|
||||
@ -274,7 +275,14 @@ impl RowIndex for usize {
|
||||
impl<'a> RowIndex for &'a str {
|
||||
#[inline]
|
||||
fn idx(&self, stmt: &Statement) -> Option<usize> {
|
||||
stmt.columns().iter().position(|d| d.name == *self)
|
||||
if let Some(idx) = stmt.columns().iter().position(|d| d.name == *self) {
|
||||
return Some(idx);
|
||||
};
|
||||
|
||||
// FIXME ASCII-only case insensitivity isn't really the right thing to
|
||||
// do. Postgres itself uses a dubious wrapper around tolower and JDBC
|
||||
// uses the US locale.
|
||||
stmt.columns().iter().position(|d| d.name.eq_ignore_ascii_case(*self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ extern crate chrono;
|
||||
use std::error;
|
||||
use std::io::prelude::*;
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
|
||||
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC};
|
||||
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC, Local, FixedOffset};
|
||||
|
||||
use Result;
|
||||
use error::Error;
|
||||
@ -52,6 +52,45 @@ impl ToSql for DateTime<UTC> {
|
||||
to_sql_checked!();
|
||||
}
|
||||
|
||||
impl FromSql for DateTime<Local> {
|
||||
fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo) -> Result<DateTime<Local>> {
|
||||
let utc = try!(DateTime::<UTC>::from_sql(type_, raw, info));
|
||||
Ok(utc.with_timezone(&Local))
|
||||
}
|
||||
|
||||
accepts!(Type::TimestampTZ);
|
||||
}
|
||||
|
||||
impl ToSql for DateTime<Local> {
|
||||
fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
|
||||
-> Result<IsNull> {
|
||||
self.with_timezone(&UTC).to_sql(type_, w, info)
|
||||
}
|
||||
|
||||
accepts!(Type::TimestampTZ);
|
||||
to_sql_checked!();
|
||||
}
|
||||
|
||||
impl FromSql for DateTime<FixedOffset> {
|
||||
fn from_sql<R: Read>(type_: &Type, raw: &mut R, info: &SessionInfo)
|
||||
-> Result<DateTime<FixedOffset>> {
|
||||
let utc = try!(DateTime::<UTC>::from_sql(type_, raw, info));
|
||||
Ok(utc.with_timezone(&FixedOffset::east(0)))
|
||||
}
|
||||
|
||||
accepts!(Type::TimestampTZ);
|
||||
}
|
||||
|
||||
impl ToSql for DateTime<FixedOffset> {
|
||||
fn to_sql<W: Write+?Sized>(&self, type_: &Type, mut w: &mut W, info: &SessionInfo)
|
||||
-> Result<IsNull> {
|
||||
self.with_timezone(&UTC).to_sql(type_, w, info)
|
||||
}
|
||||
|
||||
accepts!(Type::TimestampTZ);
|
||||
to_sql_checked!();
|
||||
}
|
||||
|
||||
impl FromSql for NaiveDate {
|
||||
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<NaiveDate> {
|
||||
let jd = try!(raw.read_i32::<BigEndian>());
|
||||
|
@ -565,16 +565,18 @@ impl error::Error for WasNull {
|
||||
/// name. For example, the `serde` feature enables the implementation for the
|
||||
/// `serde::json::Value` type.
|
||||
///
|
||||
/// | Rust type | Postgres type(s) |
|
||||
/// |-----------------------------|-------------------------------------|
|
||||
/// | serialize::json::Json | JSON, JSONB |
|
||||
/// | serde::json::Value | JSON, JSONB |
|
||||
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDateTime | TIMESTAMP |
|
||||
/// | chrono::DateTime<UTC> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDate | DATE |
|
||||
/// | chrono::NaiveTime | TIME |
|
||||
/// | uuid::Uuid | UUID |
|
||||
/// | Rust type | Postgres type(s) |
|
||||
/// |-------------------------------------|-------------------------------------|
|
||||
/// | serialize::json::Json | JSON, JSONB |
|
||||
/// | serde::json::Value | JSON, JSONB |
|
||||
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDateTime | TIMESTAMP |
|
||||
/// | chrono::DateTime<UTC> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::DateTime<Local> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::DateTime<FixedOffset> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDate | DATE |
|
||||
/// | chrono::NaiveTime | TIME |
|
||||
/// | uuid::Uuid | UUID |
|
||||
///
|
||||
/// # Nullability
|
||||
///
|
||||
@ -770,16 +772,18 @@ pub enum IsNull {
|
||||
/// name. For example, the `serde` feature enables the implementation for the
|
||||
/// `serde::json::Value` type.
|
||||
///
|
||||
/// | Rust type | Postgres type(s) |
|
||||
/// |-----------------------------|-------------------------------------|
|
||||
/// | serialize::json::Json | JSON, JSONB |
|
||||
/// | serde::json::Value | JSON, JSONB |
|
||||
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDateTime | TIMESTAMP |
|
||||
/// | chrono::DateTime<UTC> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDate | DATE |
|
||||
/// | chrono::NaiveTime | TIME |
|
||||
/// | uuid::Uuid | UUID |
|
||||
/// | Rust type | Postgres type(s) |
|
||||
/// |-------------------------------------|-------------------------------------|
|
||||
/// | serialize::json::Json | JSON, JSONB |
|
||||
/// | serde::json::Value | JSON, JSONB |
|
||||
/// | time::Timespec | TIMESTAMP, TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDateTime | TIMESTAMP |
|
||||
/// | chrono::DateTime<UTC> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::DateTime<Local> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::DateTime<FixedOffset> | TIMESTAMP WITH TIME ZONE |
|
||||
/// | chrono::NaiveDate | DATE |
|
||||
/// | chrono::NaiveTime | TIME |
|
||||
/// | uuid::Uuid | UUID |
|
||||
///
|
||||
/// # Nullability
|
||||
///
|
||||
|
@ -25,6 +25,7 @@ use postgres::error::SqlState::{SyntaxError,
|
||||
InvalidPassword,
|
||||
CardinalityViolation};
|
||||
use postgres::error::ErrorPosition::Normal;
|
||||
use postgres::rows::RowIndex;
|
||||
|
||||
macro_rules! or_panic {
|
||||
($e:expr) => (
|
||||
@ -886,3 +887,15 @@ fn test_rows_index() {
|
||||
assert_eq!(3, rows.len());
|
||||
assert_eq!(2i32, rows.get(1).get(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_row_case_insensitive() {
|
||||
let conn = Connection::connect("postgres://postgres@localhost", &SslMode::None).unwrap();
|
||||
conn.batch_execute("CREATE TEMPORARY TABLE foo (foo INT, \"bAr\" INT, \"Bar\" INT);").unwrap();
|
||||
let stmt = conn.prepare("SELECT * FROM foo").unwrap();
|
||||
assert_eq!(Some(0), "foo".idx(&stmt));
|
||||
assert_eq!(Some(0), "FOO".idx(&stmt));
|
||||
assert_eq!(Some(1), "bar".idx(&stmt));
|
||||
assert_eq!(Some(1), "bAr".idx(&stmt));
|
||||
assert_eq!(Some(2), "Bar".idx(&stmt));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user