Skip to main content

PostgresRdbcItemReader

Struct PostgresRdbcItemReader 

Source
pub struct PostgresRdbcItemReader<'a, I>
where for<'r> I: FromRow<'r, PgRow> + Send + Unpin + Clone,
{ /* private fields */ }
Available on crate feature rdbc only.
Expand description

PostgreSQL RDBC Item Reader for batch processing

This reader provides efficient reading of database records with optional pagination to manage memory usage. It implements the ItemReader trait for integration with Spring Batch processing patterns and is specifically optimized for PostgreSQL databases.

§Design

  • Uses SQLx’s PostgreSQL-specific driver for optimal performance
  • Supports automatic deserialization using the FromRow trait
  • Implements pagination with LIMIT/OFFSET for memory-efficient processing
  • Maintains an internal buffer to minimize database round trips
  • Uses interior mutability (Cell/RefCell) for state management in single-threaded contexts

§Memory Management

  • Uses internal buffering with configurable page sizes
  • Automatically handles pagination with LIMIT/OFFSET SQL clauses
  • Clears buffer between pages to minimize memory footprint
  • Pre-allocates buffer capacity when page size is known

§Thread Safety

  • Uses Cell and RefCell for interior mutability in single-threaded contexts
  • Not thread-safe - should be used within a single thread
  • Designed for use in Spring Batch’s single-threaded step execution model

§How Pagination Works

When page_size is provided:

  • Data is loaded in batches of page_size items using SQL LIMIT/OFFSET
  • When all items in a batch have been read, a new batch is automatically loaded
  • The offset tracks both the SQL OFFSET clause and position within the buffer
  • Buffer is cleared and refilled for each new page to manage memory

When page_size is not provided:

  • All data is loaded in one query without LIMIT/OFFSET
  • The offset only tracks the current position in the buffer
  • Suitable for smaller datasets that fit comfortably in memory

§Type Parameters

  • I - The item type that must implement:
    • FromRow<PgRow> for automatic deserialization from PostgreSQL rows
    • Send + Unpin for async compatibility
    • Clone for efficient item retrieval from the buffer

§Construction

This reader can only be created through RdbcItemReaderBuilder. Direct construction is not available to ensure proper configuration.

Implementations§

Source§

impl<'a, I> PostgresRdbcItemReader<'a, I>
where for<'r> I: FromRow<'r, PgRow> + Send + Unpin + Clone,

Source

pub fn new(pool: Pool<Postgres>, query: &'a str, page_size: Option<i32>) -> Self

Creates a new PostgresRdbcItemReader with the specified parameters

This constructor is only accessible within the crate to enforce the use of RdbcItemReaderBuilder for creating reader instances.

§Arguments
  • pool - PostgreSQL connection pool for database operations
  • query - SQL query to execute (without LIMIT/OFFSET)
  • page_size - Optional page size for pagination. None means read all at once.
§Returns

A new PostgresRdbcItemReader instance ready for use.

Trait Implementations§

Source§

impl<I> ItemReader<I> for PostgresRdbcItemReader<'_, I>
where for<'r> I: FromRow<'r, PgRow> + Send + Unpin + Clone,

Implementation of ItemReader trait for PostgresRdbcItemReader.

This implementation provides a way to read items from a PostgreSQL database with support for pagination. It uses an internal buffer to store the results of database queries and keeps track of the current offset to determine when a new page of data needs to be fetched.

The implementation handles both paginated and non-paginated reading modes transparently, making it suitable for various batch processing scenarios.

Source§

fn read(&self) -> ItemReaderResult<I>

Reads the next item from the PostgreSQL database

This method implements the ItemReader trait and provides the core reading logic with automatic pagination management:

  1. Index Calculation: Determines the current position within the current page
  2. Page Loading: Loads a new page if we’re at the beginning of a page
  3. Item Retrieval: Returns the item at the current position from the buffer
  4. Offset Management: Advances the offset for the next read operation
§Pagination Logic

For paginated reading (when page_size is Some):

  • index = offset % page_size gives position within current page
  • When index == 0, we’re at the start of a new page and need to load data
  • Buffer contains only the current page’s items

For non-paginated reading (when page_size is None):

  • index = offset gives absolute position in the full result set
  • Data is loaded only once when index == 0 (first read)
  • Buffer contains all items from the query
§Returns
  • Ok(Some(item)) if an item was successfully read
  • Ok(None) if there are no more items to read (end of result set)
  • Err(BatchError::ItemReader) if a database error occurred
§Examples
use spring_batch_rs::core::item::ItemReader;

let reader = PostgresRdbcItemReader::<User>::new(
    pool,
    "SELECT id, name FROM users ORDER BY id",
    Some(100)
);

// Read items one by one
let mut count = 0;
while let Some(user) = reader.read()? {
    println!("User: {} - {}", user.id, user.name);
    count += 1;
}
println!("Processed {} users", count);

Auto Trait Implementations§

§

impl<'a, I> !Freeze for PostgresRdbcItemReader<'a, I>

§

impl<'a, I> !RefUnwindSafe for PostgresRdbcItemReader<'a, I>

§

impl<'a, I> Send for PostgresRdbcItemReader<'a, I>

§

impl<'a, I> !Sync for PostgresRdbcItemReader<'a, I>

§

impl<'a, I> Unpin for PostgresRdbcItemReader<'a, I>

§

impl<'a, I> UnsafeUnpin for PostgresRdbcItemReader<'a, I>

§

impl<'a, I> !UnwindSafe for PostgresRdbcItemReader<'a, I>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Fake for T

Source§

fn fake<U>(&self) -> U
where Self: FakeBase<U>,

Source§

fn fake_with_rng<U, R>(&self, rng: &mut R) -> U
where R: RngExt + ?Sized, Self: FakeBase<U>,

Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more