@@ -19,11 +19,12 @@ use std::io;
19
19
use tokio_core:: reactor:: Handle ;
20
20
21
21
#[ doc( inline) ]
22
- pub use postgres_shared:: params;
22
+ pub use postgres_shared:: { params, types } ;
23
23
24
24
use error:: { ConnectError , Error , DbError } ;
25
25
use params:: { ConnectParams , IntoConnectParams } ;
26
26
use stream:: PostgresStream ;
27
+ use types:: { Oid , Type } ;
27
28
28
29
pub mod error;
29
30
mod stream;
@@ -44,23 +45,19 @@ struct InnerConnection {
44
45
}
45
46
46
47
impl InnerConnection {
47
- fn read ( self ) -> BoxFuture < ( backend:: Message < Vec < u8 > > , InnerConnection ) , ( io:: Error , InnerConnection ) > {
48
+ fn read ( self ) -> BoxFuture < ( backend:: Message < Vec < u8 > > , InnerConnection ) , io:: Error > {
48
49
self . into_future ( )
49
- . then ( |r| {
50
- let ( m, mut s) = match r {
51
- Ok ( ( m, s) ) => ( m, s) ,
52
- Err ( ( e, s) ) => return Either :: A ( Err ( ( e, s) ) . into_future ( ) ) ,
53
- } ;
54
-
50
+ . map_err ( |e| e. 0 )
51
+ . and_then ( |( m, mut s) | {
55
52
match m {
56
53
Some ( backend:: Message :: ParameterStatus ( body) ) => {
57
54
let name = match body. name ( ) {
58
55
Ok ( name) => name. to_owned ( ) ,
59
- Err ( e) => return Either :: A ( Err ( ( e , s ) ) . into_future ( ) ) ,
56
+ Err ( e) => return Either :: A ( Err ( e ) . into_future ( ) ) ,
60
57
} ;
61
58
let value = match body. value ( ) {
62
59
Ok ( value) => value. to_owned ( ) ,
63
- Err ( e) => return Either :: A ( Err ( ( e , s ) ) . into_future ( ) ) ,
60
+ Err ( e) => return Either :: A ( Err ( e ) . into_future ( ) ) ,
64
61
} ;
65
62
s. parameters . insert ( name, value) ;
66
63
Either :: B ( s. read ( ) )
@@ -72,7 +69,7 @@ impl InnerConnection {
72
69
Some ( m) => Either :: A ( Ok ( ( m, s) ) . into_future ( ) ) ,
73
70
None => {
74
71
let err = io:: Error :: new ( io:: ErrorKind :: UnexpectedEof , "unexpected EOF" ) ;
75
- Either :: A ( Err ( ( err, s ) ) . into_future ( ) )
72
+ Either :: A ( Err ( err) . into_future ( ) )
76
73
}
77
74
}
78
75
} )
@@ -162,7 +159,7 @@ impl Connection {
162
159
163
160
fn handle_auth ( self , params : ConnectParams ) -> BoxFuture < Connection , ConnectError > {
164
161
self . 0 . read ( )
165
- . map_err ( |e| e . 0 . into ( ) )
162
+ . map_err ( ConnectError :: Io )
166
163
. and_then ( move |( m, s) | {
167
164
let response = match m {
168
165
backend:: Message :: AuthenticationOk => Ok ( None ) ,
@@ -215,7 +212,7 @@ impl Connection {
215
212
fn handle_auth_response ( self , message : Vec < u8 > ) -> BoxFuture < Connection , ConnectError > {
216
213
self . 0 . send ( message)
217
214
. and_then ( |s| s. flush ( ) )
218
- . and_then ( |s| s. read ( ) . map_err ( |e| e . 0 ) )
215
+ . and_then ( |s| s. read ( ) )
219
216
. map_err ( ConnectError :: Io )
220
217
. and_then ( |( m, s) | {
221
218
match m {
@@ -229,7 +226,7 @@ impl Connection {
229
226
230
227
fn finish_startup ( self ) -> BoxFuture < Connection , ConnectError > {
231
228
self . 0 . read ( )
232
- . map_err ( |e| ConnectError :: Io ( e . 0 ) )
229
+ . map_err ( ConnectError :: Io )
233
230
. and_then ( |( m, mut s) | {
234
231
match m {
235
232
backend:: Message :: BackendKeyData ( body) => {
@@ -262,7 +259,7 @@ impl Connection {
262
259
// This has its own read_rows since it will need to handle multiple query completions
263
260
fn simple_read_rows ( self , mut rows : Vec < RowData > ) -> BoxFuture < ( Vec < RowData > , Connection ) , Error > {
264
261
self . 0 . read ( )
265
- . map_err ( |e| Error :: Io ( e . 0 ) )
262
+ . map_err ( Error :: Io )
266
263
. and_then ( |( m, s) | {
267
264
match m {
268
265
backend:: Message :: ReadyForQuery ( _) => {
@@ -287,9 +284,10 @@ impl Connection {
287
284
. boxed ( )
288
285
}
289
286
287
+ #[ allow( dead_code) ]
290
288
fn read_rows ( self , mut rows : Vec < RowData > ) -> BoxFuture < ( Vec < RowData > , Connection ) , Error > {
291
289
self . 0 . read ( )
292
- . map_err ( |e| Error :: Io ( e . 0 ) )
290
+ . map_err ( Error :: Io )
293
291
. and_then ( |( m, s) | {
294
292
match m {
295
293
backend:: Message :: EmptyQueryResponse |
@@ -314,7 +312,7 @@ impl Connection {
314
312
where T : ' static + Send
315
313
{
316
314
self . 0 . read ( )
317
- . map_err ( |e| Error :: Io ( e . 0 ) )
315
+ . map_err ( Error :: Io )
318
316
. and_then ( |( m, s) | {
319
317
match m {
320
318
backend:: Message :: ReadyForQuery ( _) => Ok ( ( t, Connection ( s) ) ) ,
@@ -339,11 +337,117 @@ impl Connection {
339
337
self . simple_query ( query) . map ( |r| r. 1 ) . boxed ( )
340
338
}
341
339
340
+ fn raw_prepare ( self ,
341
+ name : & str ,
342
+ query : & str )
343
+ -> BoxFuture < ( Vec < Type > , Vec < Column > , Connection ) , Error > {
344
+ let mut parse = vec ! [ ] ;
345
+ let mut describe = vec ! [ ] ;
346
+ let mut sync = vec ! [ ] ;
347
+ frontend:: parse ( name, query, None , & mut parse)
348
+ . and_then ( |( ) | frontend:: describe ( b'S' , name, & mut describe) )
349
+ . and_then ( |( ) | Ok ( frontend:: sync ( & mut sync) ) )
350
+ . into_future ( )
351
+ . and_then ( move |( ) | self . 0 . send ( parse) )
352
+ . and_then ( |s| s. send ( describe) )
353
+ . and_then ( |s| s. send ( sync) )
354
+ . and_then ( |s| s. flush ( ) )
355
+ . and_then ( |s| s. read ( ) )
356
+ . map_err ( Error :: Io )
357
+ . boxed ( ) // work around nonlinear trans blowup
358
+ . and_then ( |( m, s) | {
359
+ match m {
360
+ backend:: Message :: ParseComplete => Either :: A ( Ok ( s) . into_future ( ) ) ,
361
+ backend:: Message :: ErrorResponse ( body) => {
362
+ Either :: B ( Connection ( s) . ready_err ( body) )
363
+ }
364
+ _ => Either :: A ( Err ( bad_message ( ) ) . into_future ( ) ) ,
365
+ }
366
+ } )
367
+ . and_then ( |s| s. read ( ) . map_err ( Error :: Io ) )
368
+ . and_then ( |( m, s) | {
369
+ match m {
370
+ backend:: Message :: ParameterDescription ( body) => {
371
+ body. parameters ( ) . collect :: < Vec < _ > > ( )
372
+ . map ( |p| ( p, s) )
373
+ . map_err ( Error :: Io )
374
+ }
375
+ _ => Err ( bad_message ( ) ) ,
376
+ }
377
+ } )
378
+ . and_then ( |( p, s) | s. read ( ) . map ( |( m, s) | ( p, m, s) ) . map_err ( Error :: Io ) )
379
+ . boxed ( ) // work around nonlinear trans blowup
380
+ . and_then ( |( p, m, s) | {
381
+ match m {
382
+ backend:: Message :: RowDescription ( body) => {
383
+ body. fields ( )
384
+ . map ( |f| ( f. name ( ) . to_owned ( ) , f. type_oid ( ) ) )
385
+ . collect :: < Vec < _ > > ( )
386
+ . map ( |d| ( p, d, s) )
387
+ . map_err ( Error :: Io )
388
+ }
389
+ backend:: Message :: NoData => Ok ( ( p, vec ! [ ] , s) ) ,
390
+ _ => Err ( bad_message ( ) ) ,
391
+ }
392
+ } )
393
+ . and_then ( |( p, r, s) | Connection ( s) . ready ( ( p, r) ) )
394
+ . and_then ( |( ( p, r) , s) | {
395
+ s. get_types ( p. into_iter ( ) , vec ! [ ] , |& p| p, |_, t| t)
396
+ . map ( |( p, s) | ( p, r, s) )
397
+ } )
398
+ . and_then ( |( p, r, s) | {
399
+ s. get_types ( r. into_iter ( ) ,
400
+ vec ! [ ] ,
401
+ |f| f. 1 ,
402
+ |f, t| Column { name : f. 0 , type_ : t } )
403
+ . map ( |( r, s) | ( p, r, s) )
404
+ } )
405
+ . boxed ( )
406
+ }
407
+
408
+ fn get_types < T , U , I , F , G > ( self ,
409
+ mut raw : I ,
410
+ mut out : Vec < U > ,
411
+ mut get_oid : F ,
412
+ mut build : G )
413
+ -> BoxFuture < ( Vec < U > , Connection ) , Error >
414
+ where T : ' static + Send ,
415
+ U : ' static + Send ,
416
+ I : ' static + Send + Iterator < Item = T > ,
417
+ F : ' static + Send + FnMut ( & T ) -> Oid ,
418
+ G : ' static + Send + FnMut ( T , Type ) -> U
419
+ {
420
+ match raw. next ( ) {
421
+ Some ( v) => {
422
+ let oid = get_oid ( & v) ;
423
+ self . get_type ( oid)
424
+ . and_then ( move |( ty, s) | {
425
+ out. push ( build ( v, ty) ) ;
426
+ s. get_types ( raw, out, get_oid, build)
427
+ } )
428
+ . boxed ( )
429
+ }
430
+ None => Ok ( ( out, self ) ) . into_future ( ) . boxed ( ) ,
431
+ }
432
+ }
433
+
434
+ fn get_type ( self , oid : Oid ) -> BoxFuture < ( Type , Connection ) , Error > {
435
+ if let Some ( type_) = Type :: from_oid ( oid) {
436
+ return Ok ( ( type_, self ) ) . into_future ( ) . boxed ( ) ;
437
+ } ;
438
+ unimplemented ! ( )
439
+ }
440
+
342
441
pub fn cancel_data ( & self ) -> CancelData {
343
442
self . 0 . cancel_data
344
443
}
345
444
}
346
445
446
+ struct Column {
447
+ name : String ,
448
+ type_ : Type ,
449
+ }
450
+
347
451
fn connect_err ( fields : & mut ErrorFields ) -> ConnectError {
348
452
match DbError :: new ( fields) {
349
453
Ok ( err) => ConnectError :: Db ( Box :: new ( err) ) ,
0 commit comments