11use std:: cell:: Cell ;
2+ use std:: c_str:: { ToCStr , CString } ;
23use std:: str;
34use std:: ptr;
45use std:: libc:: { c_void, c_char, c_int} ;
@@ -97,7 +98,7 @@ impl<'self> PostgresConnection<'self> {
9798impl < ' self > PostgresConnection < ' self > {
9899 pub fn new ( uri : & str ) -> Result < ~PostgresConnection , ~str > {
99100 unsafe {
100- let conn = ~PostgresConnection { conn : do uri. as_c_str |c_uri| {
101+ let conn = ~PostgresConnection { conn : do uri. with_c_str |c_uri| {
101102 ffi:: PQconnectdb ( c_uri)
102103 } , next_stmt_id : Cell :: new ( 0 ) , notice_handler : log_notice_handler} ;
103104 let arg: * PostgresConnection = & * conn;
@@ -122,8 +123,8 @@ impl<'self> PostgresConnection<'self> {
122123 self . next_stmt_id . put_back ( id + 1 ) ;
123124
124125 let mut res = unsafe {
125- let raw_res = do query. as_c_str |c_query| {
126- do name. as_c_str |c_name| {
126+ let raw_res = do query. with_c_str |c_query| {
127+ do name. with_c_str |c_name| {
127128 ffi:: PQprepare ( self . conn , c_name, c_query,
128129 0 , ptr:: null ( ) )
129130 }
@@ -136,7 +137,7 @@ impl<'self> PostgresConnection<'self> {
136137 }
137138
138139 res = unsafe {
139- let raw_res = do name. as_c_str |c_name| {
140+ let raw_res = do name. with_c_str |c_name| {
140141 ffi:: PQdescribePrepared ( self . conn , c_name)
141142 } ;
142143 PostgresResult { result : raw_res}
@@ -198,7 +199,7 @@ impl<'self> Drop for PostgresStatement<'self> {
198199 // We can't do self.conn.update(...) since that will create a statement
199200 let query = fmt ! ( "DEALLOCATE %s" , self . name) ;
200201 unsafe {
201- do query. as_c_str |c_query| {
202+ do query. with_c_str |c_query| {
202203 ffi:: PQclear ( ffi:: PQexec ( self . conn . conn , c_query) ) ;
203204 }
204205 }
@@ -212,8 +213,8 @@ impl<'self> PostgresStatement<'self> {
212213 }
213214
214215 let res = unsafe {
215- let raw_res = do self . name . as_c_str |c_name| {
216- do as_c_str_array ( params) |c_params| {
216+ let raw_res = do self . name . with_c_str |c_name| {
217+ do with_c_str_array ( params) |c_params| {
217218 ffi:: PQexecPrepared ( self . conn . conn , c_name,
218219 self . num_params as c_int ,
219220 c_params, ptr:: null ( ) , ptr:: null ( ) ,
@@ -244,12 +245,13 @@ impl<'self> PostgresStatement<'self> {
244245 }
245246}
246247
247- fn as_c_str_array < T > ( array : & [ ~str ] , blk : & fn ( * * c_char ) -> T ) -> T {
248- let mut c_array: ~[ * c_char ] = vec:: with_capacity ( array. len ( ) + 1 ) ;
248+ fn with_c_str_array < T > ( array : & [ ~str ] , blk : & fn ( * * c_char ) -> T ) -> T {
249+ let mut cstrs: ~[ CString ] = ~[ ] ;
250+ let mut c_array: ~[ * c_char ] = ~[ ] ;
249251 for s in array. iter ( ) {
250- // DANGER, WILL ROBINSON
251- do s . as_c_str |c_s | {
252- c_array. push ( c_s ) ;
252+ cstrs . push ( s . to_c_str ( ) ) ;
253+ do cstrs . last ( ) . with_ref |c_str | {
254+ c_array. push ( c_str ) ;
253255 }
254256 }
255257 c_array. push ( ptr:: null ( ) ) ;
@@ -290,18 +292,17 @@ impl PostgresResult {
290292 unsafe { ffi:: PQnparams ( self . result ) as uint }
291293 }
292294
293- fn is_null ( & self , row : uint , col : uint ) -> bool {
295+ fn get_value ( & self , row : uint , col : uint ) -> Option < ~ str > {
294296 unsafe {
295- ffi:: PQgetisnull ( self . result , row as c_int , col as c_int ) == 1
296- }
297- }
298-
299- fn get_value ( & self , row : uint , col : uint ) -> ~str {
300- unsafe {
301- let raw_s = ffi:: PQgetvalue ( self . result ,
302- row as c_int ,
303- col as c_int ) ;
304- str:: raw:: from_c_str ( raw_s)
297+ match ffi:: PQgetisnull ( self . result , row as c_int , col as c_int ) {
298+ 0 => {
299+ let raw_s = ffi:: PQgetvalue ( self . result ,
300+ row as c_int ,
301+ col as c_int ) ;
302+ Some ( str:: raw:: from_c_str ( raw_s) )
303+ }
304+ _ => None
305+ }
305306 }
306307 }
307308}
@@ -322,7 +323,7 @@ impl PostgresResult {
322323 fail ! ( "Out of bounds access" ) ;
323324 }
324325
325- self . iter ( ) . idx ( idx) . get ( )
326+ self . iter ( ) . idx ( idx) . unwrap ( )
326327 }
327328}
328329
@@ -381,11 +382,7 @@ impl<'self, T: FromSql> Index<uint, T> for PostgresRow<'self> {
381382}
382383
383384impl < ' self > PostgresRow < ' self > {
384- fn is_null ( & self , col : uint ) -> bool {
385- self . result . is_null ( self . row , col)
386- }
387-
388- fn get_value ( & self , col : uint ) -> ~str {
385+ fn get_value ( & self , col : uint ) -> Option < ~str > {
389386 self . result . get_value ( self . row , col)
390387 }
391388}
@@ -403,55 +400,58 @@ pub trait FromSql {
403400 fn from_sql ( row : & PostgresRow , idx : uint ) -> Self ;
404401}
405402
406- macro_rules! from_str_impl (
403+ macro_rules! from_opt_impl (
407404 ( $t: ty) => (
408405 impl FromSql for $t {
409406 fn from_sql( row: & PostgresRow , idx: uint) -> $t {
410- if row. is_null( idx) {
411- fail!( "Row is NULL" ) ;
412- }
413- FromStr :: from_str( row. get_value( idx) ) . get( )
407+ FromSql :: from_sql:: <Option <$t>>( row, idx) . unwrap( )
414408 }
415409 }
416410 )
417411)
418412
419- macro_rules! option_impl (
413+ macro_rules! from_str_opt_impl (
420414 ( $t: ty) => (
421415 impl FromSql for Option <$t> {
422416 fn from_sql( row: & PostgresRow , idx: uint) -> Option <$t> {
423- match row. is_null( idx) {
424- true => None ,
425- false => Some ( FromSql :: from_sql( row, idx) )
417+ do row. get_value( idx) . chain |s| {
418+ Some ( FromStr :: from_str( s) . unwrap( ) )
426419 }
427420 }
428421 }
429422 )
430423)
431424
432- from_str_impl ! ( int)
433- option_impl ! ( int)
434- from_str_impl ! ( i8 )
435- option_impl ! ( i8 )
436- from_str_impl ! ( i16 )
437- option_impl ! ( i16 )
438- from_str_impl ! ( i32 )
439- option_impl ! ( i32 )
440- from_str_impl ! ( i64 )
441- option_impl ! ( i64 )
442- from_str_impl ! ( uint)
443- option_impl ! ( uint)
444- from_str_impl ! ( u8 )
445- option_impl ! ( u8 )
446- from_str_impl ! ( u16 )
447- option_impl ! ( u16 )
448- from_str_impl ! ( u32 )
449- option_impl ! ( u32 )
450- from_str_impl ! ( u64 )
451- option_impl ! ( u64 )
452- from_str_impl ! ( float)
453- option_impl ! ( float)
454- from_str_impl ! ( f32 )
455- option_impl ! ( f32 )
456- from_str_impl ! ( f64 )
457- option_impl ! ( f64 )
425+ from_opt_impl ! ( int)
426+ from_str_opt_impl ! ( int)
427+ from_opt_impl ! ( i8 )
428+ from_str_opt_impl ! ( i8 )
429+ from_opt_impl ! ( i16 )
430+ from_str_opt_impl ! ( i16 )
431+ from_opt_impl ! ( i32 )
432+ from_str_opt_impl ! ( i32 )
433+ from_opt_impl ! ( i64 )
434+ from_str_opt_impl ! ( i64 )
435+ from_opt_impl ! ( uint)
436+ from_str_opt_impl ! ( uint)
437+ from_opt_impl ! ( u8 )
438+ from_str_opt_impl ! ( u8 )
439+ from_opt_impl ! ( u16 )
440+ from_str_opt_impl ! ( u16 )
441+ from_opt_impl ! ( u32 )
442+ from_str_opt_impl ! ( u32 )
443+ from_opt_impl ! ( u64 )
444+ from_str_opt_impl ! ( u64 )
445+ from_opt_impl ! ( float)
446+ from_str_opt_impl ! ( float)
447+ from_opt_impl ! ( f32 )
448+ from_str_opt_impl ! ( f32 )
449+ from_opt_impl ! ( f64 )
450+ from_str_opt_impl ! ( f64 )
451+
452+ impl FromSql for Option < ~str > {
453+ fn from_sql ( row : & PostgresRow , idx : uint ) -> Option < ~str > {
454+ row. get_value ( idx)
455+ }
456+ }
457+ from_opt_impl ! ( ~str )
0 commit comments