Trait odbc_api::Cursor

source ·
pub trait Cursor: ResultSetMetadata {
    fn bind_buffer<B>(
        self,
        row_set_buffer: B
    ) -> Result<BlockCursor<Self, B>, Error>
    where
        Self: Sized,
        B: RowSetBuffer
; fn next_row(&mut self) -> Result<Option<CursorRow<'_>>, Error> { ... } }
Expand description

Cursors are used to process and iterate the result sets returned by executing queries.

Example: Fetching result in batches

use odbc_api::{Cursor, buffers::{BufferDescription, BufferKind, ColumnarAnyBuffer}, Error};

/// Fetches all values from the first column of the cursor as i32 in batches of 100 and stores
/// them in a vector.
fn fetch_all_ints(cursor: impl Cursor) -> Result<Vec<i32>, Error> {
    let mut all_ints = Vec::new();
    // Batch size determines how many values we fetch at once.
    let batch_size = 100;
    // We expect the first column to hold INTEGERs (or a type convertible to INTEGER). Use
    // the metadata on the result set, if you want to investige the types of the columns at
    // runtime.
    let description = BufferDescription {
        kind: BufferKind::I32,
        nullable: false,
    };
    // This is the buffer we bind to the driver, and repeatedly use to fetch each batch
    let buffer = ColumnarAnyBuffer::from_description(batch_size, [description]);
    // Bind buffer to cursor
    let mut row_set_buffer = cursor.bind_buffer(buffer)?;
    // Fetch data batch by batch
    while let Some(batch) = row_set_buffer.fetch()? {
        all_ints.extend_from_slice(batch.column(0).as_slice().unwrap())
    }
    Ok(all_ints)
}

Required Methods§

Binds this cursor to a buffer holding a row set.

Provided Methods§

Advances the cursor to the next row in the result set. This is Slow. Bind buffers instead, for good performance.

While this method is very convenient due to the fact that the application does not have to declare and bind specific buffers it is also in many situations extremely slow. Concrete performance depends on the ODBC driver in question, but it is likely it performs a roundtrip to the datasource for each individual row. It is also likely an extra conversion is performed then requesting individual fields, since the C buffer type is not known to the driver in advance. Consider binding a buffer to the cursor first using Self::bind_buffer.

Implementors§