Merge branch 'release-v0.11.1' into release
This commit is contained in:
commit
fed121d921
@ -3,7 +3,7 @@ sudo: required
|
|||||||
rust:
|
rust:
|
||||||
- nightly
|
- nightly
|
||||||
- beta
|
- beta
|
||||||
- 1.4.0
|
- 1.5.0
|
||||||
addons:
|
addons:
|
||||||
postgresql: 9.4
|
postgresql: 9.4
|
||||||
before_script:
|
before_script:
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "postgres"
|
name = "postgres"
|
||||||
version = "0.11.0"
|
version = "0.11.1"
|
||||||
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
authors = ["Steven Fackler <sfackler@gmail.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "A native PostgreSQL driver"
|
description = "A native PostgreSQL driver"
|
||||||
repository = "https://github.com/sfackler/rust-postgres"
|
repository = "https://github.com/sfackler/rust-postgres"
|
||||||
documentation = "https://sfackler.github.io/rust-postgres/doc/v0.11.0/postgres"
|
documentation = "https://sfackler.github.io/rust-postgres/doc/v0.11.1/postgres"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["database", "sql"]
|
keywords = ["database", "postgres", "postgresql", "sql"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
include = ["src/*", "build.rs", "Cargo.toml", "LICENSE", "README.md", "THIRD_PARTY"]
|
include = ["src/*", "build.rs", "Cargo.toml", "LICENSE", "README.md", "THIRD_PARTY"]
|
||||||
|
|
||||||
@ -42,4 +42,4 @@ security-framework = { version = "0.1.2", optional = true }
|
|||||||
bit-vec = { version = "0.4", optional = true }
|
bit-vec = { version = "0.4", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
url = "0.2"
|
url = "0.5"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Rust-Postgres
|
# Rust-Postgres
|
||||||
A native PostgreSQL driver for Rust.
|
A native PostgreSQL driver for Rust.
|
||||||
|
|
||||||
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.11.0/postgres)
|
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.11.1/postgres)
|
||||||
|
|
||||||
[](https://travis-ci.org/sfackler/rust-postgres) [](https://crates.io/crates/postgres)
|
[](https://travis-ci.org/sfackler/rust-postgres) [](https://crates.io/crates/postgres)
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ fn main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
* **Rust** - Rust-Postgres is developed against the 1.4 release of Rust
|
* **Rust** - Rust-Postgres is developed against the 1.5 release of Rust
|
||||||
available on http://www.rust-lang.org. It should also compile against more
|
available on http://www.rust-lang.org. It should also compile against more
|
||||||
recent releases.
|
recent releases.
|
||||||
|
|
||||||
|
19
src/lib.rs
19
src/lib.rs
@ -38,7 +38,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.11.0")]
|
#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.11.1")]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
extern crate bufstream;
|
extern crate bufstream;
|
||||||
@ -462,7 +462,7 @@ impl InnerConnection {
|
|||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
fn setup_typeinfo_query(&mut self) -> result::Result<(), ConnectError> {
|
fn setup_typeinfo_query(&mut self) -> result::Result<(), ConnectError> {
|
||||||
match self.raw_prepare(TYPEINFO_QUERY,
|
match self.raw_prepare(TYPEINFO_QUERY,
|
||||||
"SELECT t.typname, t.typelem, r.rngsubtype, n.nspname \
|
"SELECT t.typname, t.typelem, r.rngsubtype, t.typbasetype, n.nspname \
|
||||||
FROM pg_catalog.pg_type t \
|
FROM pg_catalog.pg_type t \
|
||||||
LEFT OUTER JOIN pg_catalog.pg_range r ON \
|
LEFT OUTER JOIN pg_catalog.pg_range r ON \
|
||||||
r.rngtypid = t.oid \
|
r.rngtypid = t.oid \
|
||||||
@ -478,7 +478,7 @@ impl InnerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self.raw_prepare(TYPEINFO_QUERY,
|
match self.raw_prepare(TYPEINFO_QUERY,
|
||||||
"SELECT t.typname, t.typelem, NULL::OID, n.nspname \
|
"SELECT t.typname, t.typelem, NULL::OID, t.typbasetype, n.nspname \
|
||||||
FROM pg_catalog.pg_type t \
|
FROM pg_catalog.pg_type t \
|
||||||
INNER JOIN pg_catalog.pg_namespace n \
|
INNER JOIN pg_catalog.pg_namespace n \
|
||||||
ON t.typnamespace = n.oid \
|
ON t.typnamespace = n.oid \
|
||||||
@ -749,7 +749,7 @@ impl InnerConnection {
|
|||||||
}
|
}
|
||||||
_ => bad_response!(self),
|
_ => bad_response!(self),
|
||||||
}
|
}
|
||||||
let (name, elem_oid, rngsubtype, schema) = match try!(self.read_message()) {
|
let (name, elem_oid, rngsubtype, basetype, schema) = match try!(self.read_message()) {
|
||||||
DataRow { row } => {
|
DataRow { row } => {
|
||||||
let ctx = SessionInfo::new(self);
|
let ctx = SessionInfo::new(self);
|
||||||
let name = try!(String::from_sql(&Type::Name,
|
let name = try!(String::from_sql(&Type::Name,
|
||||||
@ -762,10 +762,13 @@ impl InnerConnection {
|
|||||||
Some(ref data) => try!(Option::<Oid>::from_sql(&Type::Oid, &mut &**data, &ctx)),
|
Some(ref data) => try!(Option::<Oid>::from_sql(&Type::Oid, &mut &**data, &ctx)),
|
||||||
None => try!(Option::<Oid>::from_sql_null(&Type::Oid, &ctx)),
|
None => try!(Option::<Oid>::from_sql_null(&Type::Oid, &ctx)),
|
||||||
};
|
};
|
||||||
let schema = try!(String::from_sql(&Type::Name,
|
let basetype = try!(Oid::from_sql(&Type::Oid,
|
||||||
&mut &**row[3].as_ref().unwrap(),
|
&mut &**row[3].as_ref().unwrap(),
|
||||||
&ctx));
|
&ctx));
|
||||||
(name, elem_oid, rngsubtype, schema)
|
let schema = try!(String::from_sql(&Type::Name,
|
||||||
|
&mut &**row[4].as_ref().unwrap(),
|
||||||
|
&ctx));
|
||||||
|
(name, elem_oid, rngsubtype, basetype, schema)
|
||||||
}
|
}
|
||||||
ErrorResponse { fields } => {
|
ErrorResponse { fields } => {
|
||||||
try!(self.wait_for_ready());
|
try!(self.wait_for_ready());
|
||||||
@ -783,7 +786,9 @@ impl InnerConnection {
|
|||||||
}
|
}
|
||||||
try!(self.wait_for_ready());
|
try!(self.wait_for_ready());
|
||||||
|
|
||||||
let kind = if elem_oid != 0 {
|
let kind = if basetype != 0 {
|
||||||
|
Kind::Domain(try!(self.get_type(basetype)))
|
||||||
|
} else if elem_oid != 0 {
|
||||||
Kind::Array(try!(self.get_type(elem_oid)))
|
Kind::Array(try!(self.get_type(elem_oid)))
|
||||||
} else {
|
} else {
|
||||||
match rngsubtype {
|
match rngsubtype {
|
||||||
|
@ -21,7 +21,8 @@ struct StepUp<T> {
|
|||||||
ammount: T,
|
ammount: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Iterator for StepUp<T> where T: Add<T, Output = T> + PartialOrd + Copy
|
impl<T> Iterator for StepUp<T>
|
||||||
|
where T: Add<T, Output = T> + PartialOrd + Copy
|
||||||
{
|
{
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
@ -41,7 +42,8 @@ trait RangeExt<T> {
|
|||||||
fn step_up(self, ammount: T) -> StepUp<T>;
|
fn step_up(self, ammount: T) -> StepUp<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RangeExt<T> for Range<T> where T: Add<T, Output = T> + PartialOrd + Copy
|
impl<T> RangeExt<T> for Range<T>
|
||||||
|
where T: Add<T, Output = T> + PartialOrd + Copy
|
||||||
{
|
{
|
||||||
fn step_up(self, ammount: T) -> StepUp<T> {
|
fn step_up(self, ammount: T) -> StepUp<T> {
|
||||||
StepUp {
|
StepUp {
|
||||||
|
@ -107,6 +107,8 @@ pub enum Kind {
|
|||||||
Array(Type),
|
Array(Type),
|
||||||
/// A range type along with the type of its elements.
|
/// A range type along with the type of its elements.
|
||||||
Range(Type),
|
Range(Type),
|
||||||
|
/// Domain type along with its underlying type.
|
||||||
|
Domain(Type),
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
__PseudoPrivateForExtensibility,
|
__PseudoPrivateForExtensibility,
|
||||||
}
|
}
|
||||||
@ -889,7 +891,8 @@ pub trait ToSql: fmt::Debug {
|
|||||||
fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) -> Result<IsNull>;
|
fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) -> Result<IsNull>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> ToSql for &'a T where T: ToSql
|
impl<'a, T> ToSql for &'a T
|
||||||
|
where T: ToSql
|
||||||
{
|
{
|
||||||
to_sql_checked!();
|
to_sql_checked!();
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#[macro_use]
|
||||||
extern crate postgres;
|
extern crate postgres;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
|
@ -2,10 +2,11 @@ use std::collections::HashMap;
|
|||||||
use std::f32;
|
use std::f32;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use postgres::{Connection, SslMode};
|
use postgres::{Connection, SslMode, Result};
|
||||||
use postgres::error::Error;
|
use postgres::error::Error;
|
||||||
use postgres::types::{ToSql, FromSql, Slice, WrongType};
|
use postgres::types::{ToSql, FromSql, Slice, WrongType, Type, IsNull, Kind, SessionInfo};
|
||||||
|
|
||||||
#[cfg(feature = "bit-vec")]
|
#[cfg(feature = "bit-vec")]
|
||||||
mod bit_vec;
|
mod bit_vec;
|
||||||
@ -233,3 +234,48 @@ fn test_slice_range() {
|
|||||||
Err(e) => panic!("Unexpected error {:?}", e),
|
Err(e) => panic!("Unexpected error {:?}", e),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn domain() {
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
struct SessionId(Vec<u8>);
|
||||||
|
|
||||||
|
impl ToSql for SessionId {
|
||||||
|
fn to_sql<W: ?Sized>(&self, ty: &Type, out: &mut W, ctx: &SessionInfo) -> Result<IsNull>
|
||||||
|
where W: Write
|
||||||
|
{
|
||||||
|
let inner = match *ty.kind() {
|
||||||
|
Kind::Domain(ref inner) => inner,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
self.0.to_sql(inner, out, ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accepts(ty: &Type) -> bool {
|
||||||
|
ty.name() == "session_id" && match *ty.kind() { Kind::Domain(_) => true, _ => false }
|
||||||
|
}
|
||||||
|
|
||||||
|
to_sql_checked!();
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromSql for SessionId {
|
||||||
|
fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> Result<Self> {
|
||||||
|
Vec::<u8>::from_sql(ty, raw, ctx).map(SessionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accepts(ty: &Type) -> bool {
|
||||||
|
// This is super weird!
|
||||||
|
<Vec<u8> as FromSql>::accepts(ty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
|
||||||
|
conn.batch_execute("CREATE DOMAIN pg_temp.session_id AS bytea CHECK(octet_length(VALUE) = 16);
|
||||||
|
CREATE TABLE pg_temp.foo (id pg_temp.session_id);")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let id = SessionId(b"0123456789abcdef".to_vec());
|
||||||
|
conn.execute("INSERT INTO pg_temp.foo (id) VALUES ($1)", &[&id]).unwrap();
|
||||||
|
let rows = conn.query("SELECT id FROM pg_temp.foo", &[]).unwrap();
|
||||||
|
assert_eq!(id, rows.get(0).get(0));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user