1
1
use std:: io:: prelude:: * ;
2
+ use std:: error;
2
3
use byteorder:: { ReadBytesExt , WriteBytesExt , BigEndian } ;
3
4
4
- use postgres:: { self , Error , Type , Kind , ToSql , FromSql , Oid } ;
5
- use postgres:: types:: { IsNull } ;
5
+ use postgres;
6
+ use postgres:: error:: Error ;
7
+ use postgres:: types:: { Type , Kind , ToSql , FromSql , Oid , IsNull , SessionInfo } ;
6
8
7
9
use { Array , Dimension } ;
8
10
9
11
impl < T > FromSql for Array < Option < T > > where T : FromSql {
10
- fn from_sql < R : Read > ( ty : & Type , raw : & mut R ) -> postgres:: Result < Array < Option < T > > > {
12
+ fn from_sql < R : Read > ( ty : & Type , raw : & mut R , info : & SessionInfo )
13
+ -> postgres:: Result < Array < Option < T > > > {
11
14
let element_type = match ty. kind ( ) {
12
15
& Kind :: Array ( ref ty) => ty,
13
16
_ => panic ! ( "unexpected type {:?}" , ty) ,
@@ -37,9 +40,11 @@ impl<T> FromSql for Array<Option<T>> where T: FromSql {
37
40
elements. push ( None ) ;
38
41
} else {
39
42
let mut limit = raw. take ( len as u64 ) ;
40
- elements. push ( Some ( try!( FromSql :: from_sql ( & element_type, & mut limit) ) ) ) ;
43
+ elements. push ( Some ( try!( FromSql :: from_sql ( & element_type, & mut limit, info ) ) ) ) ;
41
44
if limit. limit ( ) != 0 {
42
- return Err ( Error :: BadResponse ) ;
45
+ let err: Box < error:: Error +Sync +Send > =
46
+ "from_sql call did not consume all data" . into ( ) ;
47
+ return Err ( Error :: Conversion ( err) ) ;
43
48
}
44
49
}
45
50
}
@@ -56,15 +61,16 @@ impl<T> FromSql for Array<Option<T>> where T: FromSql {
56
61
}
57
62
58
63
impl < T > ToSql for Array < T > where T : ToSql {
59
- fn to_sql < W : ?Sized +Write > ( & self , ty : & Type , mut w : & mut W ) -> postgres:: Result < IsNull > {
64
+ fn to_sql < W : ?Sized +Write > ( & self , ty : & Type , mut w : & mut W , info : & SessionInfo )
65
+ -> postgres:: Result < IsNull > {
60
66
let element_type = match ty. kind ( ) {
61
67
& Kind :: Array ( ref ty) => ty,
62
68
_ => panic ! ( "unexpected type {:?}" , ty) ,
63
69
} ;
64
70
65
71
try!( w. write_u32 :: < BigEndian > ( self . dimensions ( ) . len ( ) as u32 ) ) ;
66
72
try!( w. write_i32 :: < BigEndian > ( 1 ) ) ;
67
- try!( w. write_u32 :: < BigEndian > ( element_type. to_oid ( ) ) ) ;
73
+ try!( w. write_u32 :: < BigEndian > ( element_type. oid ( ) ) ) ;
68
74
69
75
for info in self . dimensions ( ) {
70
76
try!( w. write_u32 :: < BigEndian > ( info. len as u32 ) ) ;
@@ -73,7 +79,7 @@ impl<T> ToSql for Array<T> where T: ToSql {
73
79
74
80
let mut inner_buf = vec ! [ ] ;
75
81
for v in self {
76
- match try!( v. to_sql ( element_type, & mut inner_buf) ) {
82
+ match try!( v. to_sql ( element_type, & mut inner_buf, info ) ) {
77
83
IsNull :: Yes => try!( w. write_i32 :: < BigEndian > ( -1 ) ) ,
78
84
IsNull :: No => {
79
85
try!( w. write_i32 :: < BigEndian > ( inner_buf. len ( ) as i32 ) ) ;
@@ -100,7 +106,8 @@ impl<T> ToSql for Array<T> where T: ToSql {
100
106
mod test {
101
107
use std:: fmt;
102
108
103
- use postgres:: { Connection , SslMode , FromSql , ToSql } ;
109
+ use postgres:: { Connection , SslMode } ;
110
+ use postgres:: types:: { FromSql , ToSql } ;
104
111
use Array ;
105
112
106
113
fn test_type < T : PartialEq +FromSql +ToSql , S : fmt:: Display > ( sql_type : & str , checks : & [ ( T , S ) ] ) {
0 commit comments