11use futures:: sync:: mpsc;
2+ use postgres_protocol;
23use postgres_protocol:: message:: backend:: Message ;
34use postgres_protocol:: message:: frontend;
45
56use disconnected;
6- use error:: Error ;
7+ use error:: { self , Error } ;
78use proto:: connection:: Request ;
9+ use proto:: execute:: ExecuteFuture ;
810use proto:: prepare:: PrepareFuture ;
9- use types:: Type ;
11+ use proto:: statement:: Statement ;
12+ use types:: { IsNull , ToSql , Type } ;
1013
1114pub struct PendingRequest {
1215 sender : mpsc:: UnboundedSender < Request > ,
13- messages : Vec < u8 > ,
16+ messages : Result < Vec < u8 > , Error > ,
1417}
1518
1619impl PendingRequest {
1720 pub fn send ( self ) -> Result < mpsc:: Receiver < Message > , Error > {
21+ let messages = self . messages ?;
1822 let ( sender, receiver) = mpsc:: channel ( 0 ) ;
1923 self . sender
20- . unbounded_send ( Request {
21- messages : self . messages ,
22- sender,
23- } )
24+ . unbounded_send ( Request { messages, sender } )
2425 . map ( |_| receiver)
2526 . map_err ( |_| disconnected ( ) )
2627 }
@@ -36,16 +37,52 @@ impl Client {
3637 }
3738
3839 pub fn prepare ( & mut self , name : String , query : & str , param_types : & [ Type ] ) -> PrepareFuture {
40+ let pending = self . pending ( |buf| {
41+ frontend:: parse ( & name, query, param_types. iter ( ) . map ( |t| t. oid ( ) ) , buf) ?;
42+ frontend:: describe ( b'S' , & name, buf) ?;
43+ frontend:: sync ( buf) ;
44+ Ok ( ( ) )
45+ } ) ;
46+
47+ PrepareFuture :: new ( pending, self . sender . clone ( ) , name)
48+ }
49+
50+ pub fn execute ( & mut self , statement : & Statement , params : & [ & ToSql ] ) -> ExecuteFuture {
51+ let pending = self . pending ( |buf| {
52+ let r = frontend:: bind (
53+ "" ,
54+ statement. name ( ) ,
55+ Some ( 1 ) ,
56+ params. iter ( ) . zip ( statement. params ( ) ) ,
57+ |( param, ty) , buf| match param. to_sql_checked ( ty, buf) {
58+ Ok ( IsNull :: No ) => Ok ( postgres_protocol:: IsNull :: No ) ,
59+ Ok ( IsNull :: Yes ) => Ok ( postgres_protocol:: IsNull :: Yes ) ,
60+ Err ( e) => Err ( e) ,
61+ } ,
62+ Some ( 1 ) ,
63+ buf,
64+ ) ;
65+ match r {
66+ Ok ( ( ) ) => { }
67+ Err ( frontend:: BindError :: Conversion ( e) ) => return Err ( error:: conversion ( e) ) ,
68+ Err ( frontend:: BindError :: Serialization ( e) ) => return Err ( Error :: from ( e) ) ,
69+ }
70+ frontend:: execute ( "" , 0 , buf) ?;
71+ frontend:: sync ( buf) ;
72+ Ok ( ( ) )
73+ } ) ;
74+
75+ ExecuteFuture :: new ( pending, statement. clone ( ) )
76+ }
77+
78+ fn pending < F > ( & self , messages : F ) -> PendingRequest
79+ where
80+ F : FnOnce ( & mut Vec < u8 > ) -> Result < ( ) , Error > ,
81+ {
3982 let mut buf = vec ! [ ] ;
40- let request = frontend:: parse ( & name, query, param_types. iter ( ) . map ( |t| t. oid ( ) ) , & mut buf)
41- . and_then ( |( ) | frontend:: describe ( b'S' , & name, & mut buf) )
42- . and_then ( |( ) | Ok ( frontend:: sync ( & mut buf) ) )
43- . map ( |( ) | PendingRequest {
44- sender : self . sender . clone ( ) ,
45- messages : buf,
46- } )
47- . map_err ( Into :: into) ;
48-
49- PrepareFuture :: new ( request, self . sender . clone ( ) , name)
83+ PendingRequest {
84+ sender : self . sender . clone ( ) ,
85+ messages : messages ( & mut buf) . map ( |( ) | buf) ,
86+ }
5087 }
5188}
0 commit comments