Add optional UUID support

Closes #72
This commit is contained in:
Steven Fackler 2014-11-06 07:53:16 -08:00
parent fb0fbdd36d
commit 4f80c32967
4 changed files with 71 additions and 2 deletions

View File

@ -2,13 +2,16 @@ language: rust
env:
global:
- secure: Dl8GH7HCtwf0iG0EiBlQprZ5wQ7Wz8lfsMGxCSfTCjWoCbYK5+B5xuPnSaj8UYbrbXHmaZms23kSc5ZgQixuKs3zMCRDuEX1safT+t3AlhY/5/T3uyUWd1bv2Brw4TZg7M0Dubsu+3+3jNcDYv6vp+YWUNlKUcxjcX4EPrY0FKI=
matrix:
- FEATURES=""
- FEATURES="uuid_type"
addons:
postgresql: 9.3
before_script:
- ./.travis/setup.sh
script:
- cargo test
- cargo doc --no-deps
- cargo test --features "$FEATURES"
- cargo doc --no-deps --features "uuid_type"
after_script:
- mv target/doc .
- curl http://www.rust-ci.org/artifacts/put?t=$RUSTCI_TOKEN | sh

View File

@ -12,6 +12,9 @@ test = false
name = "test"
path = "tests/test.rs"
[features]
uuid_type = ["uuid"]
[dependencies.openssl]
git = "https://github.com/sfackler/rust-openssl"
@ -21,5 +24,10 @@ git = "https://github.com/sfackler/rust-phf"
[dependencies.phf_mac]
git = "https://github.com/sfackler/rust-phf"
[dependencies.uuid]
git = "https://github.com/rust-lang/uuid"
optional = true
[dev-dependencies.url]
git = "https://github.com/servo/rust-url"

View File

@ -1,6 +1,9 @@
//! Traits dealing with Postgres data types
#![macro_escape]
#[cfg(feature = "uuid_type")]
extern crate uuid;
use serialize::json;
use std::collections::HashMap;
use std::io::{AsRefReader, MemWriter, BufReader};
@ -49,6 +52,8 @@ const TIMESTAMPOID: Oid = 1114;
const TIMESTAMPARRAYOID: Oid = 1115;
const TIMESTAMPZOID: Oid = 1184;
const TIMESTAMPZARRAYOID: Oid = 1185;
const UUIDOID: Oid = 2950;
const UUIDARRAYOID: Oid = 2951;
const INT4RANGEOID: Oid = 3904;
const INT4RANGEARRAYOID: Oid = 3905;
const TSRANGEOID: Oid = 3908;
@ -175,6 +180,10 @@ make_postgres_type!(
TIMESTAMPZOID => TimestampTZ,
#[doc="TIMESTAMP WITH TIME ZONE[]"]
TIMESTAMPZARRAYOID => TimestampTZArray member TimestampTZ,
#[doc="UUID"]
UUIDOID => Uuid,
#[doc="UUID[]"]
UUIDARRAYOID => UuidArray member Uuid,
#[doc="CHAR(n)/CHARACTER(n)"]
BPCHAROID => CharN,
#[doc="VARCHAR/CHARACTER VARYING"]
@ -269,6 +278,16 @@ impl RawFromSql for Timespec {
}
}
#[cfg(feature = "uuid_type")]
impl RawFromSql for uuid::Uuid {
fn raw_from_sql<R: Reader>(raw: &mut R) -> Result<uuid::Uuid> {
match uuid::Uuid::from_bytes(try_pg!(raw.read_to_end())[]) {
Some(u) => Ok(u),
None => Err(PgBadData),
}
}
}
macro_rules! from_range_impl(
($t:ty) => (
impl RawFromSql for Range<$t> {
@ -372,6 +391,8 @@ from_raw_from_impl!(Int4, i32)
from_raw_from_impl!(Int8, i64)
from_raw_from_impl!(Float4, f32)
from_raw_from_impl!(Float8, f64)
#[cfg(feature = "uuid_type")]
from_raw_from_impl!(Uuid, uuid::Uuid)
from_raw_from_impl!(Json, json::Json)
from_raw_from_impl!(Timestamp | TimestampTZ, Timespec)
@ -422,6 +443,8 @@ from_array_impl!(Int4Array, i32)
from_array_impl!(TextArray | CharNArray | VarcharArray | NameArray, String)
from_array_impl!(Int8Array, i64)
from_array_impl!(TimestampArray | TimestampTZArray, Timespec)
#[cfg(feature = "uuid_type")]
from_array_impl!(UuidArray, uuid::Uuid)
from_array_impl!(JsonArray, json::Json)
from_array_impl!(Float4Array, f32)
from_array_impl!(Float8Array, f64)
@ -540,6 +563,13 @@ impl RawToSql for Timespec {
}
}
#[cfg(feature = "uuid_type")]
impl RawToSql for uuid::Uuid {
fn raw_to_sql<W: Writer>(&self, w: &mut W) -> Result<()> {
Ok(try_pg!(w.write(self.as_bytes())))
}
}
macro_rules! to_range_impl(
($t:ty) => (
impl RawToSql for Range<$t> {
@ -648,6 +678,8 @@ macro_rules! to_raw_to_impl(
to_raw_to_impl!(Bool, bool)
to_raw_to_impl!(ByteA, Vec<u8>)
to_raw_to_impl!(Varchar | Text | CharN | Name, String)
#[cfg(feature = "uuid_type")]
to_raw_to_impl!(Uuid, uuid::Uuid)
to_raw_to_impl!(Json, json::Json)
to_raw_to_impl!(Char, i8)
to_raw_to_impl!(Int2, i16)
@ -729,6 +761,8 @@ to_array_impl!(Float8Array, f64)
to_array_impl!(Int4RangeArray, Range<i32>)
to_array_impl!(TsRangeArray | TstzRangeArray, Range<Timespec>)
to_array_impl!(Int8RangeArray, Range<i64>)
#[cfg(feature = "uuid_type")]
to_array_impl!(UuidArray, uuid::Uuid)
to_array_impl!(JsonArray, json::Json)
impl ToSql for HashMap<String, Option<String>> {

View File

@ -1,3 +1,6 @@
#[cfg(feature = "uuid_type")]
extern crate uuid;
use serialize::json;
use std::collections::HashMap;
use std::f32;
@ -122,6 +125,15 @@ fn test_json_params() {
(None, "NULL")])
}
#[test]
#[cfg(feature = "uuid_type")]
fn test_uuid_params() {
test_type("UUID", [(Some(uuid::Uuid::parse_str("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11").unwrap()),
"'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'"),
(None, "NULL")])
}
#[test]
fn test_tm_params() {
fn make_check<'a>(time: &'a str) -> (Option<Timespec>, &'a str) {
@ -290,6 +302,18 @@ fn test_int4rangearray_params() {
range!('(', 10i32 ')'), "\"(,10)\"");
}
#[test]
#[cfg(feature = "uuid_type")]
fn test_uuidarray_params() {
fn make_check<'a>(uuid: &'a str) -> (uuid::Uuid, &'a str) {
(uuid::Uuid::parse_str(uuid).unwrap(), uuid)
}
let (v1, s1) = make_check("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11");
let (v2, s2) = make_check("00000000-0000-0000-0000-000000000000");
let (v3, s3) = make_check("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11");
test_array_params!("UUID", v1, s1, v2, s2, v3, s3);
}
#[test]
fn test_tsrangearray_params() {
fn make_check<'a>(time: &'a str) -> (Timespec, &'a str) {