11use antidote:: Mutex ;
22use futures:: sync:: mpsc;
3+ use futures:: { AsyncSink , Sink , Stream } ;
34use postgres_protocol;
45use postgres_protocol:: message:: backend:: Message ;
56use postgres_protocol:: message:: frontend;
67use std:: collections:: HashMap ;
8+ use std:: error:: Error as StdError ;
79use std:: sync:: { Arc , Weak } ;
810
911use disconnected;
1012use error:: { self , Error } ;
11- use proto:: connection:: Request ;
13+ use proto:: connection:: { Request , RequestMessages } ;
14+ use proto:: copy_in:: { CopyInFuture , CopyInReceiver , CopyMessage } ;
1215use proto:: copy_out:: CopyOutStream ;
1316use proto:: execute:: ExecuteFuture ;
1417use proto:: prepare:: PrepareFuture ;
@@ -17,7 +20,7 @@ use proto::simple_query::SimpleQueryFuture;
1720use proto:: statement:: Statement ;
1821use types:: { IsNull , Oid , ToSql , Type } ;
1922
20- pub struct PendingRequest ( Result < Vec < u8 > , Error > ) ;
23+ pub struct PendingRequest ( Result < RequestMessages , Error > ) ;
2124
2225pub struct WeakClient ( Weak < Inner > ) ;
2326
@@ -122,17 +125,45 @@ impl Client {
122125 }
123126
124127 pub fn execute ( & self , statement : & Statement , params : & [ & ToSql ] ) -> ExecuteFuture {
125- let pending = self . pending_execute ( statement, params) ;
128+ let pending = PendingRequest (
129+ self . excecute_message ( statement, params)
130+ . map ( RequestMessages :: Single ) ,
131+ ) ;
126132 ExecuteFuture :: new ( self . clone ( ) , pending, statement. clone ( ) )
127133 }
128134
129135 pub fn query ( & self , statement : & Statement , params : & [ & ToSql ] ) -> QueryStream {
130- let pending = self . pending_execute ( statement, params) ;
136+ let pending = PendingRequest (
137+ self . excecute_message ( statement, params)
138+ . map ( RequestMessages :: Single ) ,
139+ ) ;
131140 QueryStream :: new ( self . clone ( ) , pending, statement. clone ( ) )
132141 }
133142
143+ pub fn copy_in < S > ( & self , statement : & Statement , params : & [ & ToSql ] , stream : S ) -> CopyInFuture < S >
144+ where
145+ S : Stream < Item = Vec < u8 > > ,
146+ S :: Error : Into < Box < StdError + Sync + Send > > ,
147+ {
148+ let ( mut sender, receiver) = mpsc:: channel ( 0 ) ;
149+ let pending = PendingRequest ( self . excecute_message ( statement, params) . map ( |buf| {
150+ match sender. start_send ( CopyMessage :: Data ( buf) ) {
151+ Ok ( AsyncSink :: Ready ) => { }
152+ _ => unreachable ! ( "channel should have capacity" ) ,
153+ }
154+ RequestMessages :: CopyIn {
155+ receiver : CopyInReceiver :: new ( receiver) ,
156+ pending_message : None ,
157+ }
158+ } ) ) ;
159+ CopyInFuture :: new ( self . clone ( ) , pending, statement. clone ( ) , stream, sender)
160+ }
161+
134162 pub fn copy_out ( & self , statement : & Statement , params : & [ & ToSql ] ) -> CopyOutStream {
135- let pending = self . pending_execute ( statement, params) ;
163+ let pending = PendingRequest (
164+ self . excecute_message ( statement, params)
165+ . map ( RequestMessages :: Single ) ,
166+ ) ;
136167 CopyOutStream :: new ( self . clone ( ) , pending, statement. clone ( ) )
137168 }
138169
@@ -142,42 +173,41 @@ impl Client {
142173 frontend:: sync ( & mut buf) ;
143174 let ( sender, _) = mpsc:: channel ( 0 ) ;
144175 let _ = self . 0 . sender . unbounded_send ( Request {
145- messages : buf,
176+ messages : RequestMessages :: Single ( buf) ,
146177 sender,
147178 } ) ;
148179 }
149180
150- fn pending_execute ( & self , statement : & Statement , params : & [ & ToSql ] ) -> PendingRequest {
151- self . pending ( |buf| {
152- let r = frontend:: bind (
153- "" ,
154- statement. name ( ) ,
155- Some ( 1 ) ,
156- params. iter ( ) . zip ( statement. params ( ) ) ,
157- |( param, ty) , buf| match param. to_sql_checked ( ty, buf) {
158- Ok ( IsNull :: No ) => Ok ( postgres_protocol:: IsNull :: No ) ,
159- Ok ( IsNull :: Yes ) => Ok ( postgres_protocol:: IsNull :: Yes ) ,
160- Err ( e) => Err ( e) ,
161- } ,
162- Some ( 1 ) ,
163- buf,
164- ) ;
165- match r {
166- Ok ( ( ) ) => { }
167- Err ( frontend:: BindError :: Conversion ( e) ) => return Err ( error:: conversion ( e) ) ,
168- Err ( frontend:: BindError :: Serialization ( e) ) => return Err ( Error :: from ( e) ) ,
169- }
170- frontend:: execute ( "" , 0 , buf) ?;
171- frontend:: sync ( buf) ;
172- Ok ( ( ) )
173- } )
181+ fn excecute_message ( & self , statement : & Statement , params : & [ & ToSql ] ) -> Result < Vec < u8 > , Error > {
182+ let mut buf = vec ! [ ] ;
183+ let r = frontend:: bind (
184+ "" ,
185+ statement. name ( ) ,
186+ Some ( 1 ) ,
187+ params. iter ( ) . zip ( statement. params ( ) ) ,
188+ |( param, ty) , buf| match param. to_sql_checked ( ty, buf) {
189+ Ok ( IsNull :: No ) => Ok ( postgres_protocol:: IsNull :: No ) ,
190+ Ok ( IsNull :: Yes ) => Ok ( postgres_protocol:: IsNull :: Yes ) ,
191+ Err ( e) => Err ( e) ,
192+ } ,
193+ Some ( 1 ) ,
194+ & mut buf,
195+ ) ;
196+ match r {
197+ Ok ( ( ) ) => { }
198+ Err ( frontend:: BindError :: Conversion ( e) ) => return Err ( error:: conversion ( e) ) ,
199+ Err ( frontend:: BindError :: Serialization ( e) ) => return Err ( Error :: from ( e) ) ,
200+ }
201+ frontend:: execute ( "" , 0 , & mut buf) ?;
202+ frontend:: sync ( & mut buf) ;
203+ Ok ( buf)
174204 }
175205
176206 fn pending < F > ( & self , messages : F ) -> PendingRequest
177207 where
178208 F : FnOnce ( & mut Vec < u8 > ) -> Result < ( ) , Error > ,
179209 {
180210 let mut buf = vec ! [ ] ;
181- PendingRequest ( messages ( & mut buf) . map ( |( ) | buf) )
211+ PendingRequest ( messages ( & mut buf) . map ( |( ) | RequestMessages :: Single ( buf) ) )
182212 }
183213}
0 commit comments