1
1
use std:: rt:: io:: Decorator ;
2
- use std:: rt:: io:: extensions:: WriterByteConversions ;
3
- use std:: rt:: io:: mem:: MemWriter ;
2
+ use std:: rt:: io:: extensions:: { WriterByteConversions , ReaderByteConversions } ;
3
+ use std:: rt:: io:: mem:: { MemWriter , MemReader } ;
4
4
use std:: str;
5
- use std:: f32;
6
- use std:: f64;
7
5
8
6
pub type Oid = i32 ;
9
7
10
8
// Values from pg_type.h
11
9
static BOOLOID : Oid = 16 ;
10
+ static BYTEAOID : Oid = 17 ;
12
11
static INT8OID : Oid = 20 ;
13
12
static INT2OID : Oid = 21 ;
14
13
static INT4OID : Oid = 23 ;
@@ -21,20 +20,40 @@ pub enum Format {
21
20
Binary = 1
22
21
}
23
22
23
+ pub fn result_format ( ty : Oid ) -> Format {
24
+ match ty {
25
+ BOOLOID |
26
+ BYTEAOID |
27
+ INT8OID |
28
+ INT2OID |
29
+ INT4OID |
30
+ FLOAT4OID |
31
+ FLOAT8OID => Binary ,
32
+ _ => Text
33
+ }
34
+ }
35
+
36
+ macro_rules! check_oid(
37
+ ( $expected: ident, $actual: ident) => (
38
+ if $expected != $actual {
39
+ fail!( "Expected Oid %? but got Oid %?" , $expected, $actual) ;
40
+ }
41
+ )
42
+ )
43
+
24
44
pub trait FromSql {
25
- fn from_sql ( raw : & Option < ~[ u8 ] > ) -> Self ;
45
+ fn from_sql ( ty : Oid , raw : & Option < ~[ u8 ] > ) -> Self ;
26
46
}
27
47
28
- macro_rules! from_str_impl (
29
- ( $t: ty) => (
48
+ macro_rules! from_conversions_impl (
49
+ ( $oid : ident , $ t: ty, $f : ident ) => (
30
50
impl FromSql for Option <$t> {
31
- fn from_sql( raw: & Option <~[ u8 ] >) -> Option <$t> {
32
- match * raw {
33
- None => None ,
34
- Some ( ref buf) => {
35
- let s = str :: from_bytes_slice( buf. as_slice( ) ) ;
36
- Some ( FromStr :: from_str( s) . unwrap( ) )
37
- }
51
+ fn from_sql( ty: Oid , raw: & Option <~[ u8 ] >) -> Option <$t> {
52
+ check_oid!( $oid, ty)
53
+ do raw. map |buf| {
54
+ // TODO change to BufReader when implemented
55
+ let mut reader = MemReader :: new( buf. to_owned( ) ) ;
56
+ reader. $f( )
38
57
}
39
58
}
40
59
}
@@ -44,109 +63,58 @@ macro_rules! from_str_impl(
44
63
macro_rules! from_option_impl(
45
64
( $t: ty) => (
46
65
impl FromSql for $t {
47
- fn from_sql( raw: & Option <~[ u8 ] >) -> $t {
66
+ fn from_sql( ty : Oid , raw: & Option <~[ u8 ] >) -> $t {
48
67
// FIXME when you can specify Self types properly
49
- let ret: Option <$t> = FromSql :: from_sql( raw) ;
68
+ let ret: Option <$t> = FromSql :: from_sql( ty , raw) ;
50
69
ret. unwrap( )
51
70
}
52
71
}
53
72
)
54
73
)
55
74
56
75
impl FromSql for Option < bool > {
57
- fn from_sql ( raw : & Option < ~[ u8 ] > ) -> Option < bool > {
58
- match * raw {
59
- None => None ,
60
- Some ( ref buf) => {
61
- assert_eq ! ( 1 , buf. len( ) ) ;
62
- match buf[ 0 ] as char {
63
- 't' => Some ( true ) ,
64
- 'f' => Some ( false ) ,
65
- byte => fail ! ( "Invalid byte: %?" , byte)
66
- }
67
- }
76
+ fn from_sql ( ty : Oid , raw : & Option < ~[ u8 ] > ) -> Option < bool > {
77
+ check_oid ! ( BOOLOID , ty)
78
+ do raw. map |buf| {
79
+ buf[ 0 ] != 0
68
80
}
69
81
}
70
82
}
71
83
from_option_impl ! ( bool )
72
84
73
- from_str_impl ! ( int)
74
- from_option_impl ! ( int)
75
- from_str_impl ! ( i8 )
76
- from_option_impl ! ( i8 )
77
- from_str_impl ! ( i16 )
85
+ from_conversions_impl ! ( INT2OID , i16 , read_be_i16_)
78
86
from_option_impl ! ( i16 )
79
- from_str_impl ! ( i32 )
87
+ from_conversions_impl ! ( INT4OID , i32 , read_be_i32_ )
80
88
from_option_impl ! ( i32 )
81
- from_str_impl ! ( i64 )
89
+ from_conversions_impl ! ( INT8OID , i64 , read_be_i64_ )
82
90
from_option_impl ! ( i64 )
83
- from_str_impl ! ( uint)
84
- from_option_impl ! ( uint)
85
- from_str_impl ! ( u8 )
86
- from_option_impl ! ( u8 )
87
- from_str_impl ! ( u16 )
88
- from_option_impl ! ( u16 )
89
- from_str_impl ! ( u32 )
90
- from_option_impl ! ( u32 )
91
- from_str_impl ! ( u64 )
92
- from_option_impl ! ( u64 )
93
-
94
- impl FromSql for Option < f32 > {
95
- fn from_sql ( raw : & Option < ~[ u8 ] > ) -> Option < f32 > {
96
- match * raw {
97
- None => None ,
98
- Some ( ref buf) => {
99
- Some ( match str:: from_bytes_slice ( buf. as_slice ( ) ) {
100
- "NaN" => f32:: NaN ,
101
- "Infinity" => f32:: infinity,
102
- "-Infinity" => f32:: neg_infinity,
103
- str => FromStr :: from_str ( str) . unwrap ( )
104
- } )
105
- }
106
- }
107
- }
108
- }
91
+ from_conversions_impl ! ( FLOAT4OID , f32 , read_be_f32_)
109
92
from_option_impl ! ( f32 )
110
-
111
- impl FromSql for Option < f64 > {
112
- fn from_sql ( raw : & Option < ~[ u8 ] > ) -> Option < f64 > {
113
- match * raw {
114
- None => None ,
115
- Some ( ref buf) => {
116
- Some ( match str:: from_bytes_slice ( buf. as_slice ( ) ) {
117
- "NaN" => f64:: NaN ,
118
- "Infinity" => f64:: infinity,
119
- "-Infinity" => f64:: neg_infinity,
120
- str => FromStr :: from_str ( str) . unwrap ( )
121
- } )
122
- }
123
- }
124
- }
125
- }
93
+ from_conversions_impl ! ( FLOAT8OID , f64 , read_be_f64_)
126
94
from_option_impl ! ( f64 )
127
95
128
96
impl FromSql for Option < ~str > {
129
- fn from_sql ( raw : & Option < ~[ u8 ] > ) -> Option < ~str > {
97
+ fn from_sql ( ty : Oid , raw : & Option < ~[ u8 ] > ) -> Option < ~str > {
98
+ check_oid ! ( VARCHAROID , ty)
130
99
do raw. chain_ref |buf| {
131
100
Some ( str:: from_bytes ( buf. as_slice ( ) ) )
132
101
}
133
102
}
134
103
}
135
104
from_option_impl ! ( ~str )
136
105
106
+ impl FromSql for Option < ~[ u8 ] > {
107
+ fn from_sql ( ty : Oid , raw : & Option < ~[ u8 ] > ) -> Option < ~[ u8 ] > {
108
+ check_oid ! ( BYTEAOID , ty)
109
+ raw. clone ( )
110
+ }
111
+ }
112
+ from_option_impl ! ( ~[ u8 ] )
113
+
137
114
pub trait ToSql {
138
115
fn to_sql ( & self , ty : Oid ) -> ( Format , Option < ~[ u8 ] > ) ;
139
116
}
140
117
141
- macro_rules! check_oid(
142
- ( $expected: ident, $actual: ident) => (
143
- if $expected != $actual {
144
- fail!( "Attempted to bind an invalid type. Expected Oid %? but got \
145
- Oid %?", $expected, $actual) ;
146
- }
147
- )
148
- )
149
-
150
118
macro_rules! to_option_impl(
151
119
( $oid: ident, $t: ty) => (
152
120
impl ToSql for Option <$t> {
@@ -213,3 +181,22 @@ impl<'self> ToSql for Option<&'self str> {
213
181
}
214
182
}
215
183
}
184
+
185
+ impl < ' self > ToSql for & ' self [ u8 ] {
186
+ fn to_sql ( & self , ty : Oid ) -> ( Format , Option < ~[ u8 ] > ) {
187
+ check_oid ! ( BYTEAOID , ty)
188
+ ( Binary , Some ( self . to_owned ( ) ) )
189
+ }
190
+ }
191
+
192
+ to_option_impl ! ( BYTEAOID , ~[ u8 ] )
193
+
194
+ impl < ' self > ToSql for Option < & ' self [ u8 ] > {
195
+ fn to_sql ( & self , ty : Oid ) -> ( Format , Option < ~[ u8 ] > ) {
196
+ check_oid ! ( BYTEAOID , ty)
197
+ match * self {
198
+ None => ( Text , None ) ,
199
+ Some ( val) => val. to_sql ( ty)
200
+ }
201
+ }
202
+ }
0 commit comments