Skip to content

Commit 9a87c6e

Browse files
committed
Make time support optional
1 parent 22f4be2 commit 9a87c6e

11 files changed

Lines changed: 219 additions & 175 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ name = "test"
1313
path = "tests/test.rs"
1414

1515
[features]
16-
default = ["uuid"]
16+
default = ["uuid", "time"]
1717

1818
[dependencies.openssl]
1919
git = "https://github.com/sfackler/rust-openssl"
@@ -30,6 +30,7 @@ optional = true
3030

3131
[dependencies.time]
3232
git = "https://github.com/rust-lang/time"
33+
optional = true
3334

3435
[dev-dependencies.url]
3536
git = "https://github.com/servo/rust-url"

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,14 @@ traits.
297297
### UUID type
298298

299299
[UUID](http://www.postgresql.org/docs/9.4/static/datatype-uuid.html) support is
300-
provided optionally by the `uuid` feature. It is enabled by default. To disable
301-
`UUID` support, add `default-features = false` to your Cargo manifest:
300+
provided optionally by the `uuid` feature. It is enabled by default.
301+
302+
### Time types
303+
[Time](http://www.postgresql.org/docs/9.3/static/datatype-datetime.html)
304+
support is provided optionally by the `time` feature. It is enabled by default.
305+
306+
To disable support for optional features, add `default-features = false` to
307+
your Cargo manifest:
302308

303309
```toml
304310
[dependencies.postgres]

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
//!
55
//! ```rust,no_run
66
//! extern crate postgres;
7+
//! # #[cfg(feature = "time")]
78
//! extern crate time;
89
//!
10+
//! # #[cfg(not(feature = "time"))] fn main() {}
11+
//! # #[cfg(feature = "time")] fn main() {
912
//! use time::Timespec;
1013
//!
1114
//! use postgres::{Connection, SslMode};
@@ -49,14 +52,14 @@
4952
//! println!("Found person {}", person.name);
5053
//! }
5154
//! }
55+
//! # }
5256
//! ```
5357
#![doc(html_root_url="https://sfackler.github.io/doc")]
5458
#![feature(globs, macro_rules, phase, unsafe_destructor, slicing_syntax, default_type_params, if_let)]
5559
#![warn(missing_docs)]
5660

5761
extern crate openssl;
5862
extern crate serialize;
59-
extern crate time;
6063
extern crate phf;
6164
#[phase(plugin)]
6265
extern crate phf_mac;

src/types/mod.rs

Lines changed: 54 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,17 @@
33

44
use serialize::json;
55
use std::collections::HashMap;
6-
use std::io::{AsRefReader, MemWriter, BufReader};
7-
use std::io::util::LimitReader;
8-
use time::Timespec;
6+
use std::io::{ByRefReader, MemWriter, BufReader};
97

108
use Result;
119
use error::{PgWrongType, PgWasNull, PgBadData};
12-
use types::array::{Array, ArrayBase, DimensionInfo};
13-
use types::range::{RangeBound, Inclusive, Exclusive, Range};
10+
use types::range::{Inclusive, Exclusive, Range};
1411

1512
macro_rules! check_types(
1613
($($expected:pat)|+, $actual:ident) => (
1714
match $actual {
1815
$(&$expected)|+ => {}
19-
actual => return Err(PgWrongType(actual.clone()))
16+
actual => return Err(::Error::PgWrongType(actual.clone()))
2017
}
2118
)
2219
)
@@ -33,8 +30,14 @@ macro_rules! raw_from_impl(
3330

3431
macro_rules! from_range_impl(
3532
($t:ty) => (
36-
impl RawFromSql for Range<$t> {
33+
impl ::types::RawFromSql for ::types::range::Range<$t> {
3734
fn raw_from_sql<R: Reader>(rdr: &mut R) -> Result<Range<$t>> {
35+
use std::io::ByRefReader;
36+
use std::io::util::LimitReader;
37+
use types::{RANGE_EMPTY, RANGE_LOWER_UNBOUNDED, RANGE_LOWER_INCLUSIVE,
38+
RANGE_UPPER_UNBOUNDED, RANGE_UPPER_INCLUSIVE};
39+
use types::range::{BoundType, Range, RangeBound};
40+
3841
let t = try!(rdr.read_i8());
3942

4043
if t & RANGE_EMPTY != 0 {
@@ -43,8 +46,8 @@ macro_rules! from_range_impl(
4346
let lower = match t & RANGE_LOWER_UNBOUNDED {
4447
0 => {
4548
let type_ = match t & RANGE_LOWER_INCLUSIVE {
46-
0 => Exclusive,
47-
_ => Inclusive
49+
0 => BoundType::Exclusive,
50+
_ => BoundType::Inclusive
4851
};
4952
let len = try!(rdr.read_be_i32()) as uint;
5053
let mut limit = LimitReader::new(rdr.by_ref(), len);
@@ -58,8 +61,8 @@ macro_rules! from_range_impl(
5861
let upper = match t & RANGE_UPPER_UNBOUNDED {
5962
0 => {
6063
let type_ = match t & RANGE_UPPER_INCLUSIVE {
61-
0 => Exclusive,
62-
_ => Inclusive
64+
0 => BoundType::Exclusive,
65+
_ => BoundType::Inclusive
6366
};
6467
let len = try!(rdr.read_be_i32()) as uint;
6568
let mut limit = LimitReader::new(rdr.by_ref(), len);
@@ -81,9 +84,8 @@ macro_rules! from_range_impl(
8184
macro_rules! from_map_impl(
8285
($($expected:pat)|+, $t:ty, $blk:expr $(, $a:meta)*) => (
8386
$(#[$a])*
84-
impl FromSql for Option<$t> {
85-
fn from_sql(ty: &Type, raw: &Option<Vec<u8>>)
86-
-> Result<Option<$t>> {
87+
impl ::types::FromSql for Option<$t> {
88+
fn from_sql(ty: &Type, raw: &Option<Vec<u8>>) -> Result<Option<$t>> {
8789
check_types!($($expected)|+, ty)
8890
match *raw {
8991
Some(ref buf) => ($blk)(buf).map(|ok| Some(ok)),
@@ -93,14 +95,16 @@ macro_rules! from_map_impl(
9395
}
9496

9597
$(#[$a])*
96-
impl FromSql for $t {
97-
fn from_sql(ty: &Type, raw: &Option<Vec<u8>>)
98-
-> Result<$t> {
98+
impl ::types::FromSql for $t {
99+
fn from_sql(ty: &Type, raw: &Option<Vec<u8>>) -> Result<$t> {
100+
use Error;
101+
use types::FromSql;
102+
99103
// FIXME when you can specify Self types properly
100104
let ret: Result<Option<$t>> = FromSql::from_sql(ty, raw);
101105
match ret {
102106
Ok(Some(val)) => Ok(val),
103-
Ok(None) => Err(PgWasNull),
107+
Ok(None) => Err(Error::PgWasNull),
104108
Err(err) => Err(err)
105109
}
106110
}
@@ -111,6 +115,9 @@ macro_rules! from_map_impl(
111115
macro_rules! from_raw_from_impl(
112116
($($expected:pat)|+, $t:ty $(, $a:meta)*) => (
113117
from_map_impl!($($expected)|+, $t, |buf: &Vec<u8>| {
118+
use std::io::BufReader;
119+
use types::RawFromSql;
120+
114121
let mut reader = BufReader::new(buf[]);
115122
RawFromSql::raw_from_sql(&mut reader)
116123
} $(, $a)*)
@@ -119,7 +126,12 @@ macro_rules! from_raw_from_impl(
119126

120127
macro_rules! from_array_impl(
121128
($($oid:pat)|+, $t:ty $(, $a:meta)*) => (
122-
from_map_impl!($($oid)|+, ArrayBase<Option<$t>>, |buf: &Vec<u8>| {
129+
from_map_impl!($($oid)|+, ::types::array::ArrayBase<Option<$t>>, |buf: &Vec<u8>| {
130+
use std::io::{BufReader, ByRefReader};
131+
use std::io::util::LimitReader;
132+
use types::{Oid, RawFromSql};
133+
use types::array::{ArrayBase, DimensionInfo};
134+
123135
let mut rdr = BufReader::new(buf[]);
124136

125137
let ndim = try!(rdr.read_be_i32()) as uint;
@@ -164,20 +176,29 @@ macro_rules! raw_to_impl(
164176

165177
macro_rules! to_range_impl(
166178
($t:ty) => (
167-
impl RawToSql for Range<$t> {
179+
impl ::types::RawToSql for ::types::range::Range<$t> {
168180
fn raw_to_sql<W: Writer>(&self, buf: &mut W) -> Result<()> {
181+
use std::io::MemWriter;
182+
use types::{RANGE_EMPTY, RANGE_LOWER_UNBOUNDED, RANGE_LOWER_INCLUSIVE,
183+
RANGE_UPPER_UNBOUNDED, RANGE_UPPER_INCLUSIVE};
184+
use types::range::{BoundType, RangeBound};
185+
169186
let mut tag = 0;
170187
if self.is_empty() {
171188
tag |= RANGE_EMPTY;
172189
} else {
173190
match self.lower() {
174191
None => tag |= RANGE_LOWER_UNBOUNDED,
175-
Some(&RangeBound { type_: Inclusive, .. }) => tag |= RANGE_LOWER_INCLUSIVE,
192+
Some(&RangeBound { type_: BoundType::Inclusive, .. }) => {
193+
tag |= RANGE_LOWER_INCLUSIVE
194+
}
176195
_ => {}
177196
}
178197
match self.upper() {
179198
None => tag |= RANGE_UPPER_UNBOUNDED,
180-
Some(&RangeBound { type_: Inclusive, .. }) => tag |= RANGE_UPPER_INCLUSIVE,
199+
Some(&RangeBound { type_: BoundType::Inclusive, .. }) => {
200+
tag |= RANGE_UPPER_INCLUSIVE
201+
}
181202
_ => {}
182203
}
183204
}
@@ -214,7 +235,7 @@ macro_rules! to_range_impl(
214235
macro_rules! to_option_impl(
215236
($($oid:pat)|+, $t:ty $(,$a:meta)*) => (
216237
$(#[$a])*
217-
impl ToSql for Option<$t> {
238+
impl ::types::ToSql for Option<$t> {
218239
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
219240
check_types!($($oid)|+, ty)
220241

@@ -245,8 +266,10 @@ macro_rules! to_option_impl_lifetime(
245266
macro_rules! to_raw_to_impl(
246267
($($oid:pat)|+, $t:ty $(, $a:meta)*) => (
247268
$(#[$a])*
248-
impl ToSql for $t {
269+
impl ::types::ToSql for $t {
249270
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
271+
use std::io::MemWriter;
272+
250273
check_types!($($oid)|+, ty)
251274

252275
let mut writer = MemWriter::new();
@@ -262,8 +285,11 @@ macro_rules! to_raw_to_impl(
262285
macro_rules! to_array_impl(
263286
($($oid:pat)|+, $t:ty $(, $a:meta)*) => (
264287
$(#[$a])*
265-
impl ToSql for ArrayBase<Option<$t>> {
288+
impl ::types::ToSql for ::types::array::ArrayBase<Option<$t>> {
266289
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
290+
use std::io::MemWriter;
291+
use types::array::Array;
292+
267293
check_types!($($oid)|+, ty)
268294
let mut buf = MemWriter::new();
269295

@@ -293,14 +319,16 @@ macro_rules! to_array_impl(
293319
}
294320
}
295321

296-
to_option_impl!($($oid)|+, ArrayBase<Option<$t>> $(, $a)*)
322+
to_option_impl!($($oid)|+, ::types::array::ArrayBase<Option<$t>> $(, $a)*)
297323
)
298324
)
299325

300326
pub mod array;
301327
pub mod range;
302328
#[cfg(feature = "uuid")]
303329
mod uuid;
330+
#[cfg(feature = "time")]
331+
mod time;
304332

305333
/// A Postgres OID
306334
pub type Oid = u32;
@@ -347,12 +375,6 @@ const TSTZRANGEARRAYOID: Oid = 3911;
347375
const INT8RANGEOID: Oid = 3926;
348376
const INT8RANGEARRAYOID: Oid = 3927;
349377

350-
const USEC_PER_SEC: i64 = 1_000_000;
351-
const NSEC_PER_USEC: i64 = 1_000;
352-
353-
// Number of seconds from 1970-01-01 to 2000-01-01
354-
const TIME_SEC_CONVERSION: i64 = 946684800;
355-
356378
const RANGE_UPPER_UNBOUNDED: i8 = 0b0001_0000;
357379
const RANGE_LOWER_UNBOUNDED: i8 = 0b0000_1000;
358380
const RANGE_UPPER_INCLUSIVE: i8 = 0b0000_0100;
@@ -528,24 +550,8 @@ raw_from_impl!(i64, read_be_i64)
528550
raw_from_impl!(f32, read_be_f32)
529551
raw_from_impl!(f64, read_be_f64)
530552

531-
impl RawFromSql for Timespec {
532-
fn raw_from_sql<R: Reader>(raw: &mut R) -> Result<Timespec> {
533-
let t = try!(raw.read_be_i64());
534-
let mut sec = t / USEC_PER_SEC + TIME_SEC_CONVERSION;
535-
let mut usec = t % USEC_PER_SEC;
536-
537-
if usec < 0 {
538-
sec -= 1;
539-
usec = USEC_PER_SEC + usec;
540-
}
541-
542-
Ok(Timespec::new(sec, (usec * NSEC_PER_USEC) as i32))
543-
}
544-
}
545-
546553
from_range_impl!(i32)
547554
from_range_impl!(i64)
548-
from_range_impl!(Timespec)
549555

550556
impl RawFromSql for json::Json {
551557
fn raw_from_sql<R: Reader>(raw: &mut R) -> Result<json::Json> {
@@ -564,10 +570,8 @@ from_raw_from_impl!(Float4, f32)
564570
from_raw_from_impl!(Float8, f64)
565571
from_raw_from_impl!(Json, json::Json)
566572

567-
from_raw_from_impl!(Timestamp | TimestampTZ, Timespec)
568573
from_raw_from_impl!(Int4Range, Range<i32>)
569574
from_raw_from_impl!(Int8Range, Range<i64>)
570-
from_raw_from_impl!(TsRange | TstzRange, Range<Timespec>)
571575

572576
from_array_impl!(BoolArray, bool)
573577
from_array_impl!(ByteAArray, Vec<u8>)
@@ -576,12 +580,10 @@ from_array_impl!(Int2Array, i16)
576580
from_array_impl!(Int4Array, i32)
577581
from_array_impl!(TextArray | CharNArray | VarcharArray | NameArray, String)
578582
from_array_impl!(Int8Array, i64)
579-
from_array_impl!(TimestampArray | TimestampTZArray, Timespec)
580583
from_array_impl!(JsonArray, json::Json)
581584
from_array_impl!(Float4Array, f32)
582585
from_array_impl!(Float8Array, f64)
583586
from_array_impl!(Int4RangeArray, Range<i32>)
584-
from_array_impl!(TsRangeArray | TstzRangeArray, Range<Timespec>)
585587
from_array_impl!(Int8RangeArray, Range<i64>)
586588

587589
impl FromSql for Option<HashMap<String, Option<String>>> {
@@ -678,16 +680,8 @@ raw_to_impl!(i64, write_be_i64)
678680
raw_to_impl!(f32, write_be_f32)
679681
raw_to_impl!(f64, write_be_f64)
680682

681-
impl RawToSql for Timespec {
682-
fn raw_to_sql<W: Writer>(&self, w: &mut W) -> Result<()> {
683-
let t = (self.sec - TIME_SEC_CONVERSION) * USEC_PER_SEC + self.nsec as i64 / NSEC_PER_USEC;
684-
Ok(try!(w.write_be_i64(t)))
685-
}
686-
}
687-
688683
to_range_impl!(i32)
689684
to_range_impl!(i64)
690-
to_range_impl!(Timespec)
691685

692686
impl RawToSql for json::Json {
693687
fn raw_to_sql<W: Writer>(&self, raw: &mut W) -> Result<()> {
@@ -707,7 +701,6 @@ to_raw_to_impl!(Float4, f32)
707701
to_raw_to_impl!(Float8, f64)
708702
to_raw_to_impl!(Int4Range, Range<i32>)
709703
to_raw_to_impl!(Int8Range, Range<i64>)
710-
to_raw_to_impl!(TsRange | TstzRange, Range<Timespec>)
711704

712705
impl<'a> ToSql for &'a str {
713706
fn to_sql(&self, ty: &Type) -> Result<Option<Vec<u8>>> {
@@ -727,20 +720,16 @@ impl<'a> ToSql for &'a [u8] {
727720

728721
to_option_impl_lifetime!(ByteA, &'a [u8])
729722

730-
to_raw_to_impl!(Timestamp | TimestampTZ, Timespec)
731-
732723
to_array_impl!(BoolArray, bool)
733724
to_array_impl!(ByteAArray, Vec<u8>)
734725
to_array_impl!(CharArray, i8)
735726
to_array_impl!(Int2Array, i16)
736727
to_array_impl!(Int4Array, i32)
737728
to_array_impl!(Int8Array, i64)
738729
to_array_impl!(TextArray | CharNArray | VarcharArray | NameArray, String)
739-
to_array_impl!(TimestampArray | TimestampTZArray, Timespec)
740730
to_array_impl!(Float4Array, f32)
741731
to_array_impl!(Float8Array, f64)
742732
to_array_impl!(Int4RangeArray, Range<i32>)
743-
to_array_impl!(TsRangeArray | TstzRangeArray, Range<Timespec>)
744733
to_array_impl!(Int8RangeArray, Range<i64>)
745734
to_array_impl!(JsonArray, json::Json)
746735

src/types/range.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use std::fmt;
55
use std::i32;
66
use std::i64;
7-
use time::Timespec;
87

98
/// The `range!` macro can make it easier to create ranges. It roughly mirrors
109
/// traditional mathematic range syntax.
@@ -131,12 +130,6 @@ macro_rules! bounded_normalizable(
131130
bounded_normalizable!(i32)
132131
bounded_normalizable!(i64)
133132

134-
impl Normalizable for Timespec {
135-
fn normalize<S: BoundSided>(bound: RangeBound<S, Timespec>) -> RangeBound<S, Timespec> {
136-
bound
137-
}
138-
}
139-
140133
/// The possible sides of a bound
141134
#[deriving(PartialEq, Eq)]
142135
pub enum BoundSide {

0 commit comments

Comments
 (0)