@@ -7,7 +7,7 @@ use bytes::{Bytes, BytesMut};
7
7
use futures_util:: { ready, Stream } ;
8
8
use log:: { debug, log_enabled, Level } ;
9
9
use pin_project_lite:: pin_project;
10
- use postgres_protocol:: message:: backend:: Message ;
10
+ use postgres_protocol:: message:: backend:: { CommandCompleteBody , Message } ;
11
11
use postgres_protocol:: message:: frontend;
12
12
use std:: fmt;
13
13
use std:: marker:: PhantomPinned ;
52
52
Ok ( RowStream {
53
53
statement,
54
54
responses,
55
+ rows_affected : None ,
55
56
_p : PhantomPinned ,
56
57
} )
57
58
}
@@ -72,10 +73,24 @@ pub async fn query_portal(
72
73
Ok ( RowStream {
73
74
statement : portal. statement ( ) . clone ( ) ,
74
75
responses,
76
+ rows_affected : None ,
75
77
_p : PhantomPinned ,
76
78
} )
77
79
}
78
80
81
+ /// Extract the number of rows affected from [`CommandCompleteBody`].
82
+ pub fn extract_row_affected ( body : & CommandCompleteBody ) -> Result < u64 , Error > {
83
+ let rows = body
84
+ . tag ( )
85
+ . map_err ( Error :: parse) ?
86
+ . rsplit ( ' ' )
87
+ . next ( )
88
+ . unwrap ( )
89
+ . parse ( )
90
+ . unwrap_or ( 0 ) ;
91
+ Ok ( rows)
92
+ }
93
+
79
94
pub async fn execute < P , I > (
80
95
client : & InnerClient ,
81
96
statement : Statement ,
@@ -104,14 +119,7 @@ where
104
119
match responses. next ( ) . await ? {
105
120
Message :: DataRow ( _) => { }
106
121
Message :: CommandComplete ( body) => {
107
- rows = body
108
- . tag ( )
109
- . map_err ( Error :: parse) ?
110
- . rsplit ( ' ' )
111
- . next ( )
112
- . unwrap ( )
113
- . parse ( )
114
- . unwrap_or ( 0 ) ;
122
+ rows = extract_row_affected ( & body) ?;
115
123
}
116
124
Message :: EmptyQueryResponse => rows = 0 ,
117
125
Message :: ReadyForQuery ( _) => return Ok ( rows) ,
@@ -202,6 +210,7 @@ pin_project! {
202
210
pub struct RowStream {
203
211
statement: Statement ,
204
212
responses: Responses ,
213
+ rows_affected: Option <u64 >,
205
214
#[ pin]
206
215
_p: PhantomPinned ,
207
216
}
@@ -217,12 +226,22 @@ impl Stream for RowStream {
217
226
Message :: DataRow ( body) => {
218
227
return Poll :: Ready ( Some ( Ok ( Row :: new ( this. statement . clone ( ) , body) ?) ) )
219
228
}
220
- Message :: EmptyQueryResponse
221
- | Message :: CommandComplete ( _)
222
- | Message :: PortalSuspended => { }
229
+ Message :: CommandComplete ( body) => {
230
+ * this. rows_affected = Some ( extract_row_affected ( & body) ?) ;
231
+ }
232
+ Message :: EmptyQueryResponse | Message :: PortalSuspended => { }
223
233
Message :: ReadyForQuery ( _) => return Poll :: Ready ( None ) ,
224
234
_ => return Poll :: Ready ( Some ( Err ( Error :: unexpected_message ( ) ) ) ) ,
225
235
}
226
236
}
227
237
}
228
238
}
239
+
240
+ impl RowStream {
241
+ /// Returns the number of rows affected by the query.
242
+ ///
243
+ /// This will be `None` if the information is not available yet.
244
+ pub fn rows_affected ( & self ) -> Option < u64 > {
245
+ self . rows_affected
246
+ }
247
+ }
0 commit comments