pub struct TableRowReader<'a, R> { /* private fields */ }Expand description
A lending COPY-text row stream for one selected TABLE DATA entry.
crate::Archive::table_rows constructs this reader after exact byte-oriented
table lookup and table-data representation validation. It composes validated
selected-entry seeking, custom chunk framing, streaming decompression, and
CopyRowReader without buffering the complete entry or table.
When valid COPY column metadata is available, every parsed row is checked against that positional field count before it is returned or passed to a caller predicate. Metadata-unavailable or malformed COPY streams remain positionally readable as documented; this reader does not infer a schema from payload rows.
Rows borrow reusable parser storage. A Row and its field slices remain valid
only until this reader is mutably borrowed again, so this type intentionally does
not implement Iterator. Use OwnedRow when a row must outlive advancement.
A newly created TableRowReader starts at the beginning of the selected table-data
body. After calls to TableRowReader::next_row, searches continue from the current
stream position; they do not rewind the archive.
Any row-reading error makes the composed COPY reader terminal. The original call
returns its existing typed error, while subsequent row-reading or search calls return
Ok(None) and never expose bytes from the rejected record or a later record.
Implementations§
Source§impl<'a, R: Read> TableRowReader<'a, R>
impl<'a, R: Read> TableRowReader<'a, R>
Sourcepub fn columns(&self) -> Result<&[Column], PgDumpError>
pub fn columns(&self) -> Result<&[Column], PgDumpError>
Returns COPY columns in the exact positional order used by parsed rows.
This reads metadata parsed while the archive was opened; it does not scan the
entry body. CopyColumnMetadataUnavailable, MalformedCopyStatement, and
UnsupportedTableDataRepresentation remain distinct errors. Positional row
iteration can still be available for readable COPY data when only the column
metadata is unavailable or malformed.
Sourcepub fn column_index(&self, name: &[u8]) -> Result<Option<usize>, PgDumpError>
pub fn column_index(&self, name: &[u8]) -> Result<Option<usize>, PgDumpError>
Resolves a byte-oriented COPY column name to its zero-based field index.
Ok(Some(index)) means valid metadata contained an exact byte match.
Ok(None) means the metadata was valid but that name was absent. Metadata
unavailable/malformed and unsupported representations are returned as distinct
typed errors rather than being conflated with a missing column.
Sourcepub fn next_row(&mut self) -> Result<Option<Row<'_>>, PgDumpError>
pub fn next_row(&mut self) -> Result<Option<Row<'_>>, PgDumpError>
Parses and lends the next logical row from the selected table-data entry.
A returned row borrows reusable parser storage and remains valid only until the next mutable operation on this reader. Fields are byte-oriented logical COPY values after escape decoding; they are not required to be UTF-8.
When valid COPY column metadata is available, the row is returned only if its
field count matches that metadata. A short or long row returns
PgDumpError::CopyRowFieldCountMismatch with dump ID, row number, expected
count, and actual count before the row is exposed.
Any error makes row iteration terminal because the underlying record may have
been partially consumed. Later next_row and search calls return Ok(None);
the original failing call retains its typed archive, parser, limit, or I/O context.
use pgdumpx::{PgDumpError, TableRowReader};
use std::io::Read;
fn cannot_hold_two_rows<R: Read>(
rows: &mut TableRowReader<'_, R>,
) -> Result<(), PgDumpError> {
let first = rows.next_row()?.unwrap();
let _second = rows.next_row()?;
println!("{first:?}");
Ok(())
}Sourcepub fn find_first<F>(
&mut self,
predicate: F,
) -> Result<Option<OwnedRow>, PgDumpError>
pub fn find_first<F>( &mut self, predicate: F, ) -> Result<Option<OwnedRow>, PgDumpError>
Sequentially scans from the current stream position for the first match.
Non-matching rows reuse lending parser storage. On the first predicate result
of true, only that row is copied into OwnedRow and no later row is read.
Ok(None) means the remaining stream ended without a match.
Valid column metadata is checked before the caller predicate sees each row, so malformed short or long rows return a structural error rather than appearing as a non-match.
This is not an indexed row lookup. A fresh TableRowReader scans from the
beginning of the selected table-data entry; after prior row reads it scans from
the current position. A late or absent match can require processing all remaining
selected data. Use TableRowReader::find_first_with_limits to add an explicit
operation-level work budget.
Sourcepub fn find_first_with_limits<F>(
&mut self,
scan_limits: ScanLimits,
predicate: F,
) -> Result<Option<OwnedRow>, PgDumpError>
pub fn find_first_with_limits<F>( &mut self, scan_limits: ScanLimits, predicate: F, ) -> Result<Option<OwnedRow>, PgDumpError>
Sequentially scans for the first match with operation-level ScanLimits.
The limits are measured from this call’s current stream position. Row limits count complete rows before predicate invocation; a crossing row is not exposed. Byte accounting counts physical decompressed COPY bytes consumed by the parser, including separators and terminators, rather than logical decoded field length or decoder/buffered-reader lookahead. The matching row counts toward the budgets, and the scan stops without consuming rows after a match.
Valid column metadata is checked before predicate is called. A field-count
mismatch terminates this reader and is returned instead of a match/no-match result.
Sourcepub fn find_first_equal(
&mut self,
column: &[u8],
expected: FieldRef<'_>,
) -> Result<ColumnEqualityResult, PgDumpError>
pub fn find_first_equal( &mut self, column: &[u8], expected: FieldRef<'_>, ) -> Result<ColumnEqualityResult, PgDumpError>
Finds the first row whose named column exactly equals one logical COPY value.
The column name is resolved exactly once from already-parsed metadata before any
row is scanned. FieldRef::Bytes compares logical post-unescape bytes exactly;
FieldRef::Null matches only SQL NULL, so empty bytes and literal b"\\N" bytes
remain distinct. No UTF-8 conversion, collation, SQL coercion, or typed comparison
is performed.
This convenience method preserves the same sequential scan, early termination,
reader-wide limits, typed errors, field-count validation, and owned-match behavior
as Self::find_first.
Sourcepub fn find_first_equal_with_limits(
&mut self,
scan_limits: ScanLimits,
column: &[u8],
expected: FieldRef<'_>,
) -> Result<ColumnEqualityResult, PgDumpError>
pub fn find_first_equal_with_limits( &mut self, scan_limits: ScanLimits, column: &[u8], expected: FieldRef<'_>, ) -> Result<ColumnEqualityResult, PgDumpError>
Finds the first exact named-column equality match with operation-level limits.
Column resolution happens before the operation budget starts scanning rows. If the
name is absent, ColumnEqualityResult::ColumnNotFound is returned without row
consumption. Metadata failures remain their existing typed PgDumpError values.
For a valid column, this delegates directly to Self::find_first_with_limits, so
row/decompressed-byte accounting, field-count validation, and early termination are
unchanged.