Skip to content

Commit 7243455

Browse files
committed
Proper error/row description handling for batch_execute
1 parent 4b6eee5 commit 7243455

File tree

2 files changed

+38
-26
lines changed

2 files changed

+38
-26
lines changed

postgres-tokio/src/lib.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use futures::{Future, IntoFuture, BoxFuture, Stream, Sink, Poll, StartSend};
1111
use futures::future::Either;
1212
use postgres_protocol::authentication;
1313
use postgres_protocol::message::{backend, frontend};
14-
use postgres_protocol::message::backend::ErrorFields;
14+
use postgres_protocol::message::backend::{ErrorResponseBody, ErrorFields};
1515
use postgres_shared::RowData;
1616
use std::collections::HashMap;
1717
use std::fmt;
@@ -263,25 +263,22 @@ impl Connection {
263263
.and_then(|(m, s)| {
264264
match m {
265265
backend::Message::ReadyForQuery(_) => {
266-
Either::A(Ok((rows, Connection(s))).into_future())
266+
Ok((rows, Connection(s))).into_future().boxed()
267267
}
268268
backend::Message::DataRow(body) => {
269269
match body.values().collect() {
270270
Ok(row) => {
271271
rows.push(row);
272-
Either::B(Connection(s).simple_read_rows(rows))
272+
Connection(s).simple_read_rows(rows)
273273
}
274-
Err(e) => Either::A(Err(Error::Io(e)).into_future()),
274+
Err(e) => Err(Error::Io(e)).into_future().boxed(),
275275
}
276276
}
277277
backend::Message::EmptyQueryResponse |
278-
backend::Message::CommandComplete(_) => {
279-
Either::B(Connection(s).simple_read_rows(rows))
280-
}
281-
backend::Message::ErrorResponse(body) => {
282-
Either::A(Err(err(&mut body.fields(), Connection(s))).into_future())
283-
}
284-
_ => Either::A(Err(bad_message()).into_future()),
278+
backend::Message::CommandComplete(_) |
279+
backend::Message::RowDescription(_) => Connection(s).simple_read_rows(rows),
280+
backend::Message::ErrorResponse(body) => Connection(s).ready_err(body),
281+
_ => Err(bad_message()).into_future().boxed(),
285282
}
286283
})
287284
.boxed()
@@ -293,22 +290,18 @@ impl Connection {
293290
.and_then(|(m, s)| {
294291
match m {
295292
backend::Message::EmptyQueryResponse |
296-
backend::Message::CommandComplete(_) => {
297-
Either::B(Connection(s).ready(rows))
298-
},
293+
backend::Message::CommandComplete(_) => Connection(s).ready(rows).boxed(),
299294
backend::Message::DataRow(body) => {
300295
match body.values().collect() {
301296
Ok(row) => {
302297
rows.push(row);
303-
Either::B(Connection(s).read_rows(rows))
298+
Connection(s).read_rows(rows)
304299
}
305-
Err(e) => Either::A(Err(Error::Io(e)).into_future()),
300+
Err(e) => Err(Error::Io(e)).into_future().boxed(),
306301
}
307302
}
308-
backend::Message::ErrorResponse(body) => {
309-
Either::A(Err(err(&mut body.fields(), Connection(s))).into_future())
310-
}
311-
_ => Either::A(Err(bad_message()).into_future()),
303+
backend::Message::ErrorResponse(body) => Connection(s).ready_err(body),
304+
_ => Err(bad_message()).into_future().boxed(),
312305
}
313306
})
314307
.boxed()
@@ -328,6 +321,19 @@ impl Connection {
328321
.boxed()
329322
}
330323

324+
fn ready_err<T>(self, body: ErrorResponseBody<Vec<u8>>) -> BoxFuture<T, Error>
325+
where T: 'static + Send
326+
{
327+
self.ready(DbError::new(&mut body.fields()))
328+
.and_then(|(e, s)| {
329+
match e {
330+
Ok(e) => Err(Error::Db(Box::new(e), s)),
331+
Err(e) => Err(Error::Io(e)),
332+
}
333+
})
334+
.boxed()
335+
}
336+
331337
pub fn batch_execute(self, query: &str) -> BoxFuture<Connection, Error> {
332338
self.simple_query(query).map(|r| r.1).boxed()
333339
}

postgres-tokio/src/test.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,16 @@ fn batch_execute_err() {
9191
let done = Connection::connect("postgres://postgres@localhost", &l.handle())
9292
.then(|r| r.unwrap().batch_execute("CREATE TEMPORARY TABLE foo (id SERIAL); \
9393
INSERT INTO foo DEFAULT VALUES;"))
94-
.and_then(|c| c.batch_execute("SELECT * FROM bogo"));
95-
match l.run(done) {
96-
Err(Error::Db(ref e, _)) if e.code == SqlState::UndefinedTable => {}
97-
Err(e) => panic!("unexpected error: {}", e),
98-
Ok(_) => panic!("unexpected success"),
99-
}
94+
.and_then(|c| c.batch_execute("SELECT * FROM bogo"))
95+
.then(|r| {
96+
match r {
97+
Err(Error::Db(e, s)) => {
98+
assert!(e.code == SqlState::UndefinedTable);
99+
s.batch_execute("SELECT * FROM foo")
100+
}
101+
Err(e) => panic!("unexpected error: {}", e),
102+
Ok(_) => panic!("unexpected success"),
103+
}
104+
});
105+
l.run(done).unwrap();
100106
}

0 commit comments

Comments
 (0)