Skip to main content

OrmItemReader

Struct OrmItemReader 

Source
pub struct OrmItemReader<'a, I>
where I: EntityTrait,
{ /* private fields */ }
Available on crate feature orm only.
Expand description

A reader for reading entities from a database using SeaORM.

This reader provides an implementation of the ItemReader trait for SeaORM-based database operations. It supports reading entities from any SeaORM-compatible database with optional pagination for efficient memory usage when dealing with large datasets.

§Generic Parameters

  • I: The SeaORM entity type that implements EntityTrait

§Design Philosophy

This reader follows SeaORM’s conventions and leverages its built-in pagination mechanisms for optimal performance. It provides a bridge between SeaORM’s async API and the batch framework’s synchronous ItemReader trait.

§Memory Management

The reader uses an internal buffer to store entity models from the current page, which helps balance memory usage with query performance. When pagination is enabled, only one page of data is kept in memory at any time.

§Query Flexibility

Accepts any SeaORM Select query, allowing for complex filtering, joins, and ordering. The query is executed as-is, with pagination parameters added when configured.

§State Management

  • offset: Tracks the absolute position across all pages
  • current_page: Tracks which page is currently loaded in the buffer
  • buffer: Holds the current page’s entity models

Implementations§

Source§

impl<'a, I> OrmItemReader<'a, I>

Source

pub fn new() -> Self

Creates a new OrmItemReader with default configuration.

All parameters must be set using the builder methods before use. Use the builder pattern for a more convenient API.

§Returns

A new OrmItemReader instance with default settings.

§Examples
use spring_batch_rs::item::orm::OrmItemReader;
use sea_orm::{Database, EntityTrait};

let db = Database::connect("sqlite::memory:").await?;

// Using direct instantiation (less recommended)
// let reader = OrmItemReader::<MyEntity>::new()
//     .connection(&db)
//     .query(MyEntity::find())
//     .page_size(100);

// Using builder (recommended)
// let reader = OrmItemReaderBuilder::new()
//     .connection(&db)
//     .query(MyEntity::find())
//     .page_size(100)
//     .build();
Source

pub fn connection(self, connection: &'a DatabaseConnection) -> Self

Sets the database connection for the reader.

This is a required parameter that must be set before using the reader.

§Arguments
  • connection - Reference to the SeaORM database connection
§Returns

The updated OrmItemReader instance.

§Examples
use spring_batch_rs::item::orm::OrmItemReader;
use sea_orm::Database;

let db = Database::connect("sqlite::memory:").await?;
let reader = OrmItemReader::<String>::new()
    .connection(&db);
Source

pub fn query(self, query: Select<I>) -> Self

Sets the SeaORM select query for the reader.

This is a required parameter that must be set before using the reader. The query can include filtering, ordering, joins, and other SeaORM operations.

§Arguments
  • query - The SeaORM select query to execute
§Returns

The updated OrmItemReader instance.

§Examples
use spring_batch_rs::item::orm::OrmItemReader;
use sea_orm::EntityTrait;

// Basic query
// let reader = OrmItemReader::<MyEntity>::new()
//     .query(MyEntity::find());

// Filtered query
// let reader = OrmItemReader::<MyEntity>::new()
//     .query(MyEntity::find().filter(my_entity::Column::Active.eq(true)));

// Ordered query
// let reader = OrmItemReader::<MyEntity>::new()
//     .query(MyEntity::find().order_by_asc(my_entity::Column::Id));
Source

pub fn page_size(self, page_size: u64) -> Self

Sets the page size for the reader.

When set, the reader will use pagination to limit memory usage. When not set, all data will be loaded at once.

§Arguments
  • page_size - The number of items to read per page
§Returns

The updated OrmItemReader instance.

§Performance Considerations
  • Larger page sizes reduce the number of database round trips but use more memory
  • Smaller page sizes use less memory but may result in more database queries
  • Consider your dataset size and available memory when choosing a page size
  • Recommended range: 50-1000 items per page for most use cases
§Examples
use spring_batch_rs::item::orm::OrmItemReader;

// Small page size for memory-constrained environments
let reader = OrmItemReader::<String>::new()
    .page_size(50);

// Larger page size for better performance with ample memory
let reader = OrmItemReader::<String>::new()
    .page_size(1000);

Trait Implementations§

Source§

impl<'a, I> Default for OrmItemReader<'a, I>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<I> ItemReader<<I as EntityTrait>::Model> for OrmItemReader<'_, I>

Implementation of ItemReader trait for OrmItemReader.

This implementation provides a way to read items from a database using SeaORM 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.

§Reading Strategy

The reader implements a lazy-loading strategy:

  1. First read: Loads the first page of data
  2. Subsequent reads: Returns items from the buffer
  3. Page boundary: When the buffer is exhausted, loads the next page
  4. End of data: Returns None when no more data is available

§State Management

  • offset: Tracks the absolute position across all pages
  • current_page: Tracks which page we’re currently reading from
  • buffer: Holds the current page’s data

The reader maintains these invariants:

  • offset always represents the next item to be read
  • current_page represents the page currently loaded in the buffer
  • The buffer contains items for the current page only
Source§

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

Reads the next item from the reader.

This method manages pagination internally and provides a simple interface for sequential reading. The complexity of pagination is hidden from the caller.

§Reading Algorithm
  1. Calculate buffer index: Determine where we are within the current page
  2. Check if new page needed: If at the start of a page, load new data
  3. Fetch from buffer: Get the item at the current index
  4. Update counters: Increment offset and page number as needed
  5. Return result: Clone the item or return None if exhausted
§Pagination Logic
  • With pagination: index = offset % page_size
  • Without pagination: index = offset (all data in one “page”)
  • New page trigger: When index == 0, we need to load a new page
  • Page advancement: When we reach the end of a page, increment current_page
§Memory Management

Items are cloned when returned to ensure the caller owns the data. This prevents borrowing issues and allows the buffer to be modified for the next page load.

§Returns
  • Ok(Some(item)) if an item was successfully read
  • Ok(None) if there are no more items to read
  • Err(BatchError) if an error occurred during reading (e.g., database error)
§Examples
use spring_batch_rs::item::orm::OrmItemReaderBuilder;
use spring_batch_rs::core::item::ItemReader;
use sea_orm::FromQueryResult;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, FromQueryResult, Deserialize, Serialize)]
struct Product {
    id: i32,
    name: String,
    price: f64,
}

// Assuming you have a database connection and query set up
// let reader = OrmItemReaderBuilder::new()
//     .connection(&db)
//     .query(products::Entity::find())
//     .page_size(50)
//     .build();

// Read all products
// let mut products = Vec::new();
// while let Some(product) = reader.read()? {
//     products.push(product);
// }

Auto Trait Implementations§

§

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

§

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

§

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

§

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

§

impl<'a, I> Unpin for OrmItemReader<'a, I>
where I: Unpin, <I as EntityTrait>::Model: Unpin,

§

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

§

impl<'a, I> !UnwindSafe for OrmItemReader<'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<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
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