Skip to content

Commit

Permalink
Merge pull request #3236 from weiznich/row_by_row_cleanup
Browse files Browse the repository at this point in the history
Minor cleanup for #3213
  • Loading branch information
weiznich authored Jul 18, 2022
2 parents 53a4157 + 999ab8d commit 6cf2ac7
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 11 deletions.
17 changes: 9 additions & 8 deletions diesel/src/pg/connection/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl Iterator for Cursor {
/// Acts as an iterator over `T`.
#[allow(missing_debug_implementations)]
pub struct RowByRowCursor<'a> {
current_row: usize,
first_row: bool,
db_result: Rc<PgResult>,
conn: &'a mut super::ConnectionAndTransactionManager,
}
Expand All @@ -72,7 +72,7 @@ impl<'a> RowByRowCursor<'a> {
conn: &'a mut super::ConnectionAndTransactionManager,
) -> Self {
RowByRowCursor {
current_row: 0,
first_row: true,
db_result: Rc::new(db_result),
conn,
}
Expand All @@ -83,30 +83,31 @@ impl Iterator for RowByRowCursor<'_> {
type Item = crate::QueryResult<PgRow>;

fn next(&mut self) -> Option<Self::Item> {
if self.current_row > 0 {
if !self.first_row {
let get_next_result = super::update_transaction_manager_status(
self.conn.raw_connection.get_next_result(),
self.conn,
);
match get_next_result {
Ok(Some(res)) => {
// we try to reuse the existing allocation here
if let Some(old_res) = Rc::get_mut(&mut self.db_result) {
*old_res = res;
} else {
self.db_result = Rc::new(res);
}
self.current_row = 0;
}
Ok(None) => {
return None;
}
Err(e) => return Some(Err(e)),
}
}
if self.current_row < self.db_result.num_rows() {
let row = self.db_result.clone().get_row(self.current_row);
self.current_row += 1;
Some(Ok(row))
// This contains either 1 (for a row containing data) or 0 (for the last one) rows
if self.db_result.num_rows() > 0 {
debug_assert_eq!(self.db_result.num_rows(), 1);
self.first_row = false;
Some(Ok(self.db_result.clone().get_row(0)))
} else {
None
}
Expand Down
8 changes: 5 additions & 3 deletions diesel/src/pg/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use std::os::raw as libc;
///
/// Due to the fact that `PgConnection` supports multiple loading modes
/// it is **required** to always specify the used loading mode
/// when calling [`RunQueryDsl::load_iter`] or [`LoadConnection::load`].
/// when calling [`RunQueryDsl::load_iter`]
///
/// ## `DefaultLoadingMode`
///
Expand Down Expand Up @@ -241,7 +241,9 @@ fn update_transaction_manager_status<T>(
) -> QueryResult<T> {
if let Err(Error::DatabaseError { .. }) = query_result {
/// avoid monomorphizing for every result type - this part will not be inlined
fn non_generic_inner(raw_conn: &mut RawConnection, tm: &mut AnsiTransactionManager) {
fn non_generic_inner(conn: &mut ConnectionAndTransactionManager) {
let raw_conn: &mut RawConnection = &mut conn.raw_connection;
let tm: &mut AnsiTransactionManager = &mut conn.transaction_state;
if tm.status.is_not_broken_and_in_transaction() {
// libpq keeps track of the transaction status internally, and that is accessible
// via `transaction_status`. We can use that to update the AnsiTransactionManager
Expand All @@ -266,7 +268,7 @@ fn update_transaction_manager_status<T>(
}
}
}
non_generic_inner(&mut conn.raw_connection, &mut conn.transaction_state)
non_generic_inner(conn)
}
query_result
}
Expand Down

0 comments on commit 6cf2ac7

Please sign in to comment.