Skip to content

Commit a229973

Browse files
committed
Update to new postgres
1 parent e9381be commit a229973

File tree

4 files changed

+61
-108
lines changed

4 files changed

+61
-108
lines changed

‎Cargo.toml‎

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ repository = "https://github.com/sfackler/rust-postgres-array"
88
documentation = "https://sfackler.github.io/rust-postgres-array/doc/v0.6.2/postgres_array"
99

1010
[dependencies]
11-
postgres = "0.11"
12-
byteorder = "0.5"
13-
14-
[dev-dependencies]
15-
rustc-serialize = "0.3"
16-
time = "0.1"
17-
uuid = "0.1"
18-
postgres ={version = "0.11", features = ["rustc-serialize", "time", "uuid"] }
11+
fallible-iterator = "0.1"
12+
postgres ={git = "https://github.com/sfackler/rust-postgres" }
13+
postgres-protocol = "0.1"

‎src/array.rs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl<T: fmt::Display> fmt::Display for Array<T>{
1919
try!(write!(fmt,
2020
"[{}:{}]",
2121
dim.lower_bound,
22-
dim.lower_bound + dim.len asisize - 1));
22+
dim.lower_bound asisize+ dim.len asisize - 1));
2323
}
2424
try!(write!(fmt,"="));
2525
}
@@ -61,7 +61,7 @@ impl<T> Array<T>{
6161
/// elements specified by the dimensions.
6262
pubfnfrom_parts(data:Vec<T>,dimensions:Vec<Dimension>) -> Array<T>{
6363
assert!((data.is_empty() && dimensions.is_empty()) ||
64-
data.len() == dimensions.iter().fold(1, |acc, i| acc * i.len),
64+
data.len() == dimensions.iter().fold(1, |acc, i| acc * i.lenasusize),
6565
"size mismatch");
6666
Array{
6767
dims: dimensions,
@@ -70,10 +70,10 @@ impl<T> Array<T>{
7070
}
7171

7272
/// Creates a new one-dimensional array.
73-
pubfnfrom_vec(data:Vec<T>,lower_bound:isize) -> Array<T>{
73+
pubfnfrom_vec(data:Vec<T>,lower_bound:i32) -> Array<T>{
7474
Array{
7575
dims:vec![Dimension{
76-
len: data.len(),
76+
len: data.len()asi32,
7777
lower_bound: lower_bound,
7878
}],
7979
data: data,
@@ -84,7 +84,7 @@ impl<T> Array<T>{
8484
///
8585
/// For example, the one dimensional array `[1, 2]` would turn into the
8686
/// two-dimensional array `[[1, 2]]`.
87-
pubfnwrap(&mutself,lower_bound:isize){
87+
pubfnwrap(&mutself,lower_bound:i32){
8888
self.dims.insert(0,
8989
Dimension{
9090
len:1,
@@ -128,7 +128,7 @@ impl<T> Array<T>{
128128
.rev()
129129
.fold((0,1), |(acc, stride),(dim, idx)| {
130130
let shifted = dim.shift(idx);
131-
(acc + shifted * stride, dim.len* stride)
131+
(acc + shifted * stride, dim.lenasusize* stride)
132132
})
133133
.0
134134
}

‎src/impls.rs‎

Lines changed: 45 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,33 @@
1-
use std::io::prelude::*;
2-
use std::error;
3-
use byteorder::{ReadBytesExt,WriteBytesExt,BigEndian};
4-
5-
use postgres::{self,Result};
6-
use postgres::error::Error;
7-
use postgres::types::{Type,Kind,ToSql,FromSql,Oid,IsNull,SessionInfo};
1+
use fallible_iterator::FallibleIterator;
2+
use postgres::types::{Type,Kind,ToSql,FromSql,IsNull,SessionInfo};
3+
use postgres_protocol::types;
4+
use postgres_protocol;
5+
use std::error::Error;
86

97
use{Array,Dimension};
108

119
impl<T>FromSqlforArray<T>
1210
whereT:FromSql
1311
{
14-
fnfrom_sql<R:Read>(ty:&Type,raw:&mutR,info:&SessionInfo) -> postgres::Result<Array<T>>{
15-
let element_type = match ty.kind(){
16-
&Kind::Array(ref ty) => ty,
17-
_ => panic!("unexpected type{:?}", ty),
12+
fnfrom_sql(ty:&Type,raw:&[u8],info:&SessionInfo) -> Result<Array<T>,Box<Error + Sync + Send>>{
13+
let element_type = match*ty.kind(){
14+
Kind::Array(ref ty) => ty,
15+
_ => unreachable!(),
1816
};
1917

20-
let ndim = try!(raw.read_u32::<BigEndian>())asusize;
21-
let _has_null = try!(raw.read_i32::<BigEndian>()) == 1;
22-
let _element_type:Oid = try!(raw.read_u32::<BigEndian>());
18+
let array = try!(types::array_from_sql(raw));
2319

24-
letmut dim_info = Vec::with_capacity(ndim);
25-
for _ in0..ndim {
26-
dim_info.push(Dimension{
27-
len: try!(raw.read_u32::<BigEndian>())asusize,
28-
lower_bound: try!(raw.read_i32::<BigEndian>())asisize,
29-
});
30-
}
31-
let nele = if dim_info.len() == 0{
32-
0
33-
}else{
34-
dim_info.iter().fold(1, |product, info| product * info.len)
35-
};
20+
let dimensions = try!(array.dimensions()
21+
.map(|d| {
22+
Dimension{len: d.len,lower_bound: d.lower_bound}
23+
})
24+
.collect());
3625

37-
letmut elements = Vec::with_capacity(nele);
38-
for _ in0..nele {
39-
let len = try!(raw.read_i32::<BigEndian>());
40-
if len < 0{
41-
elements.push(try!(FromSql::from_sql_null(&element_type, info)));
42-
}else{
43-
letmut limit = raw.take(len asu64);
44-
elements.push(try!(FromSql::from_sql(&element_type,&mut limit, info)));
45-
if limit.limit() != 0{
46-
let err:Box<error::Error + Sync + Send> = "from_sql call did not consume all \
47-
data"
48-
.into();
49-
returnErr(Error::Conversion(err));
50-
}
51-
}
52-
}
26+
let elements = try!(array.values()
27+
.and_then(|v| FromSql::from_sql_nullable(element_type, v, info))
28+
.collect());
5329

54-
Ok(Array::from_parts(elements,dim_info))
30+
Ok(Array::from_parts(elements,dimensions))
5531
}
5632

5733
fnaccepts(ty:&Type) -> bool{
@@ -65,44 +41,34 @@ impl<T> FromSql for Array<T>
6541
impl<T>ToSqlforArray<T>
6642
whereT:ToSql
6743
{
68-
fnto_sql<W: ?Sized + Write>(&self,
69-
ty:&Type,
70-
mutw:&mutW,
71-
info:&SessionInfo)
72-
-> postgres::Result<IsNull>{
44+
fnto_sql(&self,ty:&Type,w:&mutVec<u8>,info:&SessionInfo) -> Result<IsNull,Box<Error + Sync + Send>>{
7345
let element_type = match ty.kind(){
7446
&Kind::Array(ref ty) => ty,
75-
_ => panic!("unexpected type{:?}", ty),
47+
_ => unreachable!(),
7648
};
7749

78-
try!(w.write_i32::<BigEndian>(try!(downcast(self.dimensions().len()))));
79-
try!(w.write_i32::<BigEndian>(1));
80-
try!(w.write_u32::<BigEndian>(element_type.oid()));
81-
82-
for info inself.dimensions(){
83-
try!(w.write_i32::<BigEndian>(try!(downcast(info.len))));
84-
85-
let bound = if info.lower_bound > i32::max_value()asisize ||
86-
info.lower_bound < i32::min_value()asisize{
87-
let err:Box<error::Error + Sync + Send> = "value too large to transmit".into();
88-
returnErr(Error::Conversion(err));
89-
}else{
90-
info.lower_boundasi32
91-
};
92-
try!(w.write_i32::<BigEndian>(bound));
93-
}
94-
95-
letmut inner_buf = vec![];
96-
for v inself{
97-
match try!(v.to_sql(element_type,&mut inner_buf, info)){
98-
IsNull::Yes => try!(w.write_i32::<BigEndian>(-1)),
99-
IsNull::No => {
100-
try!(w.write_i32::<BigEndian>(try!(downcast(inner_buf.len()))));
101-
try!(w.write_all(&inner_buf));
50+
let dimensions = self.dimensions()
51+
.iter()
52+
.map(|d| {
53+
types::ArrayDimension{
54+
len: d.len,
55+
lower_bound: d.lower_bound,
10256
}
103-
}
104-
inner_buf.clear();
105-
}
57+
});
58+
let elements = self.iter();
59+
60+
try!(types::array_to_sql(dimensions,
61+
true,
62+
element_type.oid(),
63+
elements,
64+
|v, w| {
65+
match v.to_sql(element_type, w, info){
66+
Ok(IsNull::Yes) => Ok(postgres_protocol::IsNull::Yes),
67+
Ok(IsNull::No) => Ok(postgres_protocol::IsNull::No),
68+
Err(e) => Err(e),
69+
}
70+
},
71+
w));
10672

10773
Ok(IsNull::No)
10874
}
@@ -117,26 +83,17 @@ impl<T> ToSql for Array<T>
11783
to_sql_checked!();
11884
}
11985

120-
fndowncast(len:usize) -> Result<i32>{
121-
if len > i32::max_value()asusize{
122-
let err:Box<error::Error + Sync + Send> = "value too large to transmit".into();
123-
Err(Error::Conversion(err))
124-
}else{
125-
Ok(len asi32)
126-
}
127-
}
128-
12986
#[cfg(test)]
13087
mod test {
13188
use std::fmt;
13289

133-
use postgres::{Connection,SslMode};
90+
use postgres::{Connection,TlsMode};
13491
use postgres::types::{FromSql,ToSql};
13592
useArray;
13693

13794
fntest_type<T:PartialEq + FromSql + ToSql,S: fmt::Display>(sql_type:&str,
13895
checks:&[(T,S)]){
139-
let conn = Connection::connect("postgres://postgres@localhost",SslMode::None).unwrap();
96+
let conn = Connection::connect("postgres://postgres@localhost",TlsMode::None).unwrap();
14097
for&(ref val,ref repr)in checks.iter(){
14198
let stmt = conn.prepare(&format!("SELECT{}::{}",*repr, sql_type)).unwrap();
14299
let result = stmt.query(&[]).unwrap().iter().next().unwrap().get(0);
@@ -256,7 +213,7 @@ mod test{
256213

257214
#[test]
258215
fntest_empty_array(){
259-
let conn = Connection::connect("postgres://postgres@localhost",SslMode::None).unwrap();
216+
let conn = Connection::connect("postgres://postgres@localhost",TlsMode::None).unwrap();
260217
let stmt = conn.prepare("SELECT '{}'::INT4[]").unwrap();
261218
stmt.query(&[]).unwrap().iter().next().unwrap().get::<_,Array<i32>>(0);
262219
}

‎src/lib.rs‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! Multi-dimensional arrays with per-dimension specifiable lower bounds
22
#![doc(html_root_url="https://sfackler.github.io/rust-postgres-array/doc/v0.6.2")]
33

4-
#[macro_use(to_sql_checked)]
4+
externcrate fallible_iterator;
5+
#[macro_use]
56
externcrate postgres;
6-
externcratebyteorder;
7+
externcratepostgres_protocol;
78

89
#[doc(inline)]
910
pubuse array::Array;
@@ -15,19 +16,19 @@ mod impls;
1516
#[derive(Debug,Clone,Copy,PartialEq,Eq)]
1617
pubstructDimension{
1718
/// The length of the dimension.
18-
publen:usize,
19+
publen:i32,
1920
/// The index of the first element of the dimension.
20-
publower_bound:isize,
21+
publower_bound:i32,
2122
}
2223

2324
implDimension{
2425
fnshift(&self,idx:isize) -> usize{
25-
let offset = self.lower_bound;
26+
let offset = self.lower_boundasisize;
2627
assert!(idx >= offset,"out of bounds array access");
2728
assert!(offset >= 0 || idx <= 0 || usize::max_value() - (-offset)asusize >= idx asusize,
2829
"out of bounds array access");
2930
let shifted = idx.wrapping_sub(offset)asusize;
30-
assert!(shifted < self.len,"out of bounds array access");
31+
assert!(shifted < self.lenasusize,"out of bounds array access");
3132
shifted
3233
}
3334
}

0 commit comments

Comments
(0)