Skip to content

Commit 5e197e8

Browse files
committed
Use postgres_protocol
1 parent 0a23f49 commit 5e197e8

File tree

3 files changed

+67
-82
lines changed

3 files changed

+67
-82
lines changed

‎Cargo.toml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ documentation = "https://sfackler.github.io/rust-postgres-range/doc/v0.8.2/postg
1010
[dependencies]
1111
time = "0.1"
1212
postgres = "0.11"
13-
byteorder = "0.5"
13+
postgres-protocol = {git = "https://github.com/sfackler/rust-postgres-protocol" }
1414

1515
[dev-dependencies]
16-
postgres ={version = "0.11", features = ["time"] }
16+
postgres ={version = "0.11", features = ["with-time"] }
17+
18+
[replace]
19+
"postgres:0.11.11" ={git = "https://github.com/sfackler/rust-postgres" }
20+
"fallible-iterator:0.1.2" ={git = "https://github.com/sfackler/rust-fallible-iterator" }

‎src/impls.rs‎

Lines changed: 60 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,24 @@
1-
use std::io::prelude::*;
2-
use std::error;
3-
use postgres;
1+
use std::error::Error;
42
use postgres::types::{Type,Kind,ToSql,FromSql,IsNull,SessionInfo};
5-
use postgres::error::Error;
6-
use byteorder::{ReadBytesExt,WriteBytesExt,BigEndian};
3+
use postgres_protocol::types;
74

85
use{Range,RangeBound,BoundType,BoundSided,Normalizable};
96

10-
constRANGE_UPPER_UNBOUNDED:i8 = 0b0001_0000;
11-
constRANGE_LOWER_UNBOUNDED:i8 = 0b0000_1000;
12-
constRANGE_UPPER_INCLUSIVE:i8 = 0b0000_0100;
13-
constRANGE_LOWER_INCLUSIVE:i8 = 0b0000_0010;
14-
constRANGE_EMPTY:i8 = 0b0000_0001;
15-
167
impl<T>FromSqlforRange<T>whereT:PartialOrd+Normalizable+FromSql{
17-
fnfrom_sql<R:Read>(ty:&Type,rdr:&mutR,info:&SessionInfo)
18-
-> postgres::Result<Range<T>>{
8+
fnfrom_sql(ty:&Type,raw:&[u8],info:&SessionInfo) -> Result<Range<T>,Box<Error + Sync + Send>>{
199
let element_type = match ty.kind(){
2010
&Kind::Range(ref ty) => ty,
2111
_ => panic!("unexpected type{:?}", ty)
2212
};
2313

24-
let t = try!(rdr.read_i8());
25-
26-
if t &RANGE_EMPTY != 0{
27-
returnOk(Range::empty());
28-
}
29-
30-
fnmake_bound<S,T,R>(ty:&Type,rdr:&mutR,info:&SessionInfo,
31-
tag:i8,bound_flag:i8,inclusive_flag:i8)
32-
-> postgres::Result<Option<RangeBound<S,T>>>
33-
whereS:BoundSided,T:PartialOrd+Normalizable+FromSql,R:Read{
34-
match tag & bound_flag {
35-
0 => {
36-
let type_ = match tag & inclusive_flag {
37-
0 => BoundType::Exclusive,
38-
_ => BoundType::Inclusive,
39-
};
40-
let len = try!(rdr.read_i32::<BigEndian>())asu64;
41-
letmut limit = rdr.take(len);
42-
let bound = try!(FromSql::from_sql(ty,&mut limit, info));
43-
if limit.limit() != 0{
44-
let err:Box<error::Error+Sync+Send> =
45-
"from_sql call did not consume all data".into();
46-
returnErr(Error::Conversion(err));
47-
}
48-
Ok(Some(RangeBound::new(bound, type_)))
49-
}
50-
_ => Ok(None)
14+
match try!(types::range_from_sql(raw)){
15+
types::Range::Empty => Ok(Range::empty()),
16+
types::Range::Nonempty(lower, upper) => {
17+
let lower = try!(bound_from_sql(lower, element_type, info));
18+
let upper = try!(bound_from_sql(upper, element_type, info));
19+
Ok(Range::new(lower, upper))
5120
}
5221
}
53-
54-
let lower = try!(make_bound(element_type, rdr, info, t,
55-
RANGE_LOWER_UNBOUNDED,RANGE_LOWER_INCLUSIVE));
56-
let upper = try!(make_bound(element_type, rdr, info, t,
57-
RANGE_UPPER_UNBOUNDED,RANGE_UPPER_INCLUSIVE));
58-
Ok(Range::new(lower, upper))
5922
}
6023

6124
fnaccepts(ty:&Type) -> bool{
@@ -66,47 +29,44 @@ impl<T> FromSql for Range<T> where T: PartialOrd+Normalizable+FromSql{
6629
}
6730
}
6831

32+
fnbound_from_sql<T,S>(bound: types::RangeBound<Option<&[u8]>>,ty:&Type,info:&SessionInfo) -> Result<Option<RangeBound<S,T>>,Box<Error + Sync + Send>>
33+
whereT:PartialOrd + Normalizable + FromSql,
34+
S:BoundSided
35+
{
36+
match bound {
37+
types::RangeBound::Exclusive(value) => {
38+
let value = match value {
39+
Some(value) => try!(T::from_sql(ty, value, info)),
40+
None => try!(T::from_sql_null(ty, info)),
41+
};
42+
Ok(Some(RangeBound::new(value,BoundType::Exclusive)))
43+
},
44+
types::RangeBound::Inclusive(value) => {
45+
let value = match value {
46+
Some(value) => try!(T::from_sql(ty, value, info)),
47+
None => try!(T::from_sql_null(ty, info)),
48+
};
49+
Ok(Some(RangeBound::new(value,BoundType::Inclusive)))
50+
},
51+
types::RangeBound::Unbounded => Ok(None),
52+
}
53+
}
54+
6955
impl<T>ToSqlforRange<T>whereT:PartialOrd+Normalizable+ToSql{
70-
fnto_sql<W: ?Sized+Write>(&self,ty:&Type,mutbuf:&mutW,info:&SessionInfo)
71-
-> postgres::Result<IsNull>{
56+
fnto_sql(&self,ty:&Type,mutbuf:&mutVec<u8>,info:&SessionInfo) -> Result<IsNull,Box<Error + Sync + Send>>{
7257
let element_type = match ty.kind(){
7358
&Kind::Range(ref ty) => ty,
7459
_ => panic!("unexpected type{:?}", ty)
7560
};
7661

77-
letmut tag = 0;
7862
ifself.is_empty(){
79-
tag |= RANGE_EMPTY;
63+
types::empty_range_to_sql(buf);
8064
}else{
81-
fnmake_tag<S,T>(bound:Option<&RangeBound<S,T>>,unbounded_tag:i8,
82-
inclusive_tag:i8) -> i8whereS:BoundSided{
83-
match bound {
84-
None => unbounded_tag,
85-
Some(&RangeBound{type_:BoundType::Inclusive, .. }) => inclusive_tag,
86-
_ => 0
87-
}
88-
}
89-
tag |= make_tag(self.lower(),RANGE_LOWER_UNBOUNDED,RANGE_LOWER_INCLUSIVE);
90-
tag |= make_tag(self.upper(),RANGE_UPPER_UNBOUNDED,RANGE_UPPER_INCLUSIVE);
91-
}
92-
93-
try!(buf.write_i8(tag));
94-
95-
fnwrite_value<S,T,W: ?Sized>(ty:&Type,mutbuf:&mutW,info:&SessionInfo,
96-
v:Option<&RangeBound<S,T>>) -> postgres::Result<()>
97-
whereS:BoundSided,T:ToSql,W:Write{
98-
ifletSome(bound) = v {
99-
letmut inner_buf = vec![];
100-
try!(bound.value.to_sql(ty,&mut inner_buf, info));
101-
try!(buf.write_u32::<BigEndian>(inner_buf.len()asu32));
102-
try!(buf.write_all(&*inner_buf));
103-
}
104-
Ok(())
65+
try!(types::range_to_sql(|buf| bound_to_sql(self.lower(), element_type, info, buf),
66+
|buf| bound_to_sql(self.upper(), element_type, info, buf),
67+
buf));
10568
}
10669

107-
try!(write_value(&element_type, buf, info,self.lower()));
108-
try!(write_value(&element_type, buf, info,self.upper()));
109-
11070
Ok(IsNull::No)
11171
}
11272

@@ -120,11 +80,32 @@ impl<T> ToSql for Range<T> where T: PartialOrd+Normalizable+ToSql{
12080
to_sql_checked!();
12181
}
12282

83+
fnbound_to_sql<S,T>(bound:Option<&RangeBound<S,T>>,ty:&Type,info:&SessionInfo,buf:&mutVec<u8>) -> Result<types::RangeBound<types::IsNull>,Box<Error + Sync + Send>>
84+
whereS:BoundSided,
85+
T:ToSql
86+
{
87+
match bound {
88+
Some(bound) => {
89+
let null = match try!(bound.value.to_sql(ty, buf, info)){
90+
IsNull::Yes => types::IsNull::Yes,
91+
IsNull::No => types::IsNull::No,
92+
};
93+
94+
match bound.type_{
95+
BoundType::Exclusive => Ok(types::RangeBound::Exclusive(null)),
96+
BoundType::Inclusive => Ok(types::RangeBound::Inclusive(null)),
97+
}
98+
}
99+
None => Ok(types::RangeBound::Unbounded),
100+
}
101+
102+
}
103+
123104
#[cfg(test)]
124105
mod test {
125106
use std::fmt;
126107

127-
use postgres::{Connection,SslMode};
108+
use postgres::{Connection,TlsMode};
128109
use postgres::types::{FromSql,ToSql};
129110
use time::{self,Timespec};
130111

@@ -150,7 +131,7 @@ mod test{
150131
}
151132

152133
fntest_type<T:PartialEq+FromSql+ToSql,S: fmt::Display>(sql_type:&str,checks:&[(T,S)]){
153-
let conn = Connection::connect("postgres://postgres@localhost",SslMode::None).unwrap();
134+
let conn = Connection::connect("postgres://postgres@localhost",TlsMode::None).unwrap();
154135
for&(ref val,ref repr)in checks {
155136
let stmt = conn.prepare(&*format!("SELECT{}::{}",*repr, sql_type)).unwrap();
156137
let result = stmt.query(&[]).unwrap().iter().next().unwrap().get(0);

‎src/lib.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
#[macro_use(to_sql_checked)]
55
externcrate postgres;
6+
externcrate postgres_protocol;
67
externcrate time;
7-
externcrate byteorder;
88

99
use std::cmp::Ordering;
1010
use std::fmt;

0 commit comments

Comments
(0)