@@ -2,7 +2,7 @@ use crate::client::{InnerClient, Responses};
2
2
use crate :: codec:: FrontendMessage ;
3
3
use crate :: connection:: RequestMessages ;
4
4
use crate :: types:: { IsNull , ToSql } ;
5
- use crate :: { Error , Row , Statement } ;
5
+ use crate :: { Error , Portal , Row , Statement } ;
6
6
use futures:: { ready, Stream , TryFutureExt } ;
7
7
use postgres_protocol:: message:: backend:: Message ;
8
8
use postgres_protocol:: message:: frontend;
@@ -23,6 +23,27 @@ pub fn query(
23
23
. try_flatten_stream ( )
24
24
}
25
25
26
+ pub fn query_portal (
27
+ client : Arc < InnerClient > ,
28
+ portal : Portal ,
29
+ max_rows : i32 ,
30
+ ) -> impl Stream < Item = Result < Row , Error > > {
31
+ let start = async move {
32
+ let mut buf = vec ! [ ] ;
33
+ frontend:: execute ( portal. name ( ) , max_rows, & mut buf) . map_err ( Error :: encode) ?;
34
+ frontend:: sync ( & mut buf) ;
35
+
36
+ let responses = client. send ( RequestMessages :: Single ( FrontendMessage :: Raw ( buf) ) ) ?;
37
+
38
+ Ok ( Query {
39
+ statement : portal. statement ( ) . clone ( ) ,
40
+ responses,
41
+ } )
42
+ } ;
43
+
44
+ start. try_flatten_stream ( )
45
+ }
46
+
26
47
pub async fn execute ( client : Arc < InnerClient > , buf : Result < Vec < u8 > , Error > ) -> Result < u64 , Error > {
27
48
let mut responses = start ( client, buf) . await ?;
28
49
@@ -59,6 +80,18 @@ async fn start(client: Arc<InnerClient>, buf: Result<Vec<u8>, Error>) -> Result<
59
80
}
60
81
61
82
pub fn encode < ' a , I > ( statement : & Statement , params : I ) -> Result < Vec < u8 > , Error >
83
+ where
84
+ I : IntoIterator < Item = & ' a dyn ToSql > ,
85
+ I :: IntoIter : ExactSizeIterator ,
86
+ {
87
+ let mut buf = encode_bind ( statement, params, "" ) ?;
88
+ frontend:: execute ( "" , 0 , & mut buf) . map_err ( Error :: encode) ?;
89
+ frontend:: sync ( & mut buf) ;
90
+
91
+ Ok ( buf)
92
+ }
93
+
94
+ pub fn encode_bind < ' a , I > ( statement : & Statement , params : I , portal : & str ) -> Result < Vec < u8 > , Error >
62
95
where
63
96
I : IntoIterator < Item = & ' a dyn ToSql > ,
64
97
I :: IntoIter : ExactSizeIterator ,
76
109
77
110
let mut error_idx = 0 ;
78
111
let r = frontend:: bind (
79
- "" ,
112
+ portal ,
80
113
statement. name ( ) ,
81
114
Some ( 1 ) ,
82
115
params. zip ( statement. params ( ) ) . enumerate ( ) ,
@@ -92,15 +125,10 @@ where
92
125
& mut buf,
93
126
) ;
94
127
match r {
95
- Ok ( ( ) ) => { }
128
+ Ok ( ( ) ) => Ok ( buf ) ,
96
129
Err ( frontend:: BindError :: Conversion ( e) ) => return Err ( Error :: to_sql ( e, error_idx) ) ,
97
130
Err ( frontend:: BindError :: Serialization ( e) ) => return Err ( Error :: encode ( e) ) ,
98
131
}
99
-
100
- frontend:: execute ( "" , 0 , & mut buf) . map_err ( Error :: encode) ?;
101
- frontend:: sync ( & mut buf) ;
102
-
103
- Ok ( buf)
104
132
}
105
133
106
134
struct Query {
@@ -116,7 +144,9 @@ impl Stream for Query {
116
144
Message :: DataRow ( body) => {
117
145
Poll :: Ready ( Some ( Ok ( Row :: new ( self . statement . clone ( ) , body) ?) ) )
118
146
}
119
- Message :: EmptyQueryResponse | Message :: CommandComplete ( _) => Poll :: Ready ( None ) ,
147
+ Message :: EmptyQueryResponse
148
+ | Message :: CommandComplete ( _)
149
+ | Message :: PortalSuspended => Poll :: Ready ( None ) ,
120
150
Message :: ErrorResponse ( body) => Poll :: Ready ( Some ( Err ( Error :: db ( body) ) ) ) ,
121
151
_ => Poll :: Ready ( Some ( Err ( Error :: unexpected_message ( ) ) ) ) ,
122
152
}
0 commit comments