Struct odbc_api::buffers::ColumnarBuffer
source · [−]pub struct ColumnarBuffer<C> { /* private fields */ }
Expand description
A columnar buffer intended to be bound with crate::Cursor::bind_buffer in order to obtain results from a cursor.
This buffer is designed to be versatile. It supports a wide variety of usage scenarios. It is efficient in retrieving data, but expensive to allocate, as columns are allocated separately. This is required in order to efficiently allow for rebinding columns, if this buffer is used to provide array input parameters those maximum size is not known in advance.
Most applications should find the overhead negligible, especially if instances are reused.
Implementations
sourceimpl<C: ColumnBuffer> ColumnarBuffer<C>
impl<C: ColumnBuffer> ColumnarBuffer<C>
sourcepub fn new(columns: Vec<(u16, C)>) -> Self
pub fn new(columns: Vec<(u16, C)>) -> Self
Create a new instance from columns with unique indicies. Capacity of the buffer will be the minimum capacity of the columns.
sourcepub unsafe fn new_unchecked(capacity: usize, columns: Vec<(u16, C)>) -> Self
pub unsafe fn new_unchecked(capacity: usize, columns: Vec<(u16, C)>) -> Self
Safety
- Indices must be unique
- Columns all must have enough
capacity
.
sourcepub fn column(&self, buffer_index: usize) -> <C as ColumnProjections<'_>>::View
pub fn column(&self, buffer_index: usize) -> <C as ColumnProjections<'_>>::View
Use this method to gain read access to the actual column data.
Parameters
buffer_index
: Please note that the buffer index is not identical to the ODBC column index. For once it is zero based. It also indexes the buffer bound, and not the columns of the output result set. This is important, because not every column needs to be bound. Some columns may simply be ignored. That being said, if every column of the output is bound in the buffer, in the same order in which they are enumerated in the result set, the relationship between column index and buffer index isbuffer_index = column_index - 1
.
sourcepub fn column_mut(
&mut self,
buffer_index: usize
) -> <C as ColumnProjections<'_>>::ViewMut
pub fn column_mut(
&mut self,
buffer_index: usize
) -> <C as ColumnProjections<'_>>::ViewMut
Use this method to gain write access to the actual column data.
Parameters
buffer_index
: Please note that the buffer index is not identical to the ODBC column index. For once it is zero based. It also indexes the buffer bound, and not the columns of the output result set. This is important, because not every column needs to be bound. Some columns may simply be ignored. That being said, if every column of the output is bound in the buffer, in the same order in which they are enumerated in the result set, the relationship between column index and buffer index isbuffer_index = column_index - 1
.
Example
This method is intend to be called if using ColumnarBuffer
for column wise bulk inserts.
use odbc_api::{
Connection, Error, IntoParameter,
buffers::{BufferDescription, BufferKind, AnyColumnViewMut, buffer_from_description}
};
fn insert_birth_years(conn: &Connection, names: &[&str], years: &[i16])
-> Result<(), Error>
{
// All columns must have equal length.
assert_eq!(names.len(), years.len());
// Create a columnar buffer which fits the input parameters.
let buffer_description = [
BufferDescription {
kind: BufferKind::Text { max_str_len: 255 },
nullable: false,
},
BufferDescription {
kind: BufferKind::I16,
nullable: false,
},
];
let mut buffer = buffer_from_description(
names.len(),
buffer_description.iter().copied()
);
// Fill the buffer with values column by column
match buffer.column_mut(0) {
AnyColumnViewMut::Text(mut col) => {
col.write(names.iter().map(|s| Some(s.as_bytes())))
}
_ => panic!("We know the name column to hold text.")
}
match buffer.column_mut(1) {
AnyColumnViewMut::I16(mut col) => {
col.copy_from_slice(years)
}
_ => panic!("We know the year column to hold i16.")
}
conn.execute(
"INSERT INTO Birthdays (name, year) VALUES (?, ?)",
&buffer
)?;
Ok(())
}
sourcepub fn set_num_rows(&mut self, num_rows: usize)
pub fn set_num_rows(&mut self, num_rows: usize)
Set number of valid rows in the buffer. May not be larger than the batch size. If the specified number should be larger than the number of valid rows currently held by the buffer additional rows with the default value are going to be created.
sourceimpl ColumnarBuffer<TextColumn<u8>>
impl ColumnarBuffer<TextColumn<u8>>
sourcepub fn for_cursor(
batch_size: usize,
cursor: &impl ResultSetMetadata,
max_str_len: Option<usize>
) -> Result<TextRowSet, Error>
pub fn for_cursor(
batch_size: usize,
cursor: &impl ResultSetMetadata,
max_str_len: Option<usize>
) -> Result<TextRowSet, Error>
The resulting text buffer is not in any way tied to the cursor, other than that its buffer sizes a tailor fitted to result set the cursor is iterating over.
Parameters
batch_size
: The maximum number of rows the buffer is able to hold.cursor
: Used to query the display size for each column of the row set. For character data the length in characters is multiplied by 4 in order to have enough space for 4 byte utf-8 characters. This is a pessimization for some data sources (e.g. SQLite 3) which do interpret the size of aVARCHAR(5)
column as 5 bytes rather than 5 characters.max_str_limit
: Some queries make it hard to estimate a sensible upper bound and sometimes drivers are just not that good at it. This argument allows you to specify an upper bound for the length of character data.
sourcepub fn from_max_str_lens(
row_capacity: usize,
max_str_lengths: impl Iterator<Item = usize>
) -> Self
pub fn from_max_str_lens(
row_capacity: usize,
max_str_lengths: impl Iterator<Item = usize>
) -> Self
Creates a text buffer large enough to hold batch_size
rows with one column for each item
max_str_lengths
of respective size.
sourcepub fn at(&self, buffer_index: usize, row_index: usize) -> Option<&[u8]>
pub fn at(&self, buffer_index: usize, row_index: usize) -> Option<&[u8]>
Access the element at the specified position in the row set.
sourcepub fn at_as_str(
&self,
col_index: usize,
row_index: usize
) -> Result<Option<&str>, Utf8Error>
pub fn at_as_str(
&self,
col_index: usize,
row_index: usize
) -> Result<Option<&str>, Utf8Error>
Access the element at the specified position in the row set.
sourcepub fn indicator_at(&self, buf_index: usize, row_index: usize) -> Indicator
pub fn indicator_at(&self, buf_index: usize, row_index: usize) -> Indicator
Indicator value at the specified position. Useful to detect truncation of data.
Example
use odbc_api::buffers::{Indicator, TextRowSet};
fn is_truncated(buffer: &TextRowSet, col_index: usize, row_index: usize) -> bool {
match buffer.indicator_at(col_index, row_index) {
// There is no value, therefore there is no value not fitting in the column buffer.
Indicator::Null => false,
// The value did not fit into the column buffer, we do not even know, by how much.
Indicator::NoTotal => true,
Indicator::Length(total_length) => {
// If the maximum string length is shorter than the values total length, the
// has been truncated to fit into the buffer.
buffer.max_len(col_index) < total_length
}
}
}
sourcepub fn max_len(&self, buf_index: usize) -> usize
pub fn max_len(&self, buf_index: usize) -> usize
Maximum length in bytes of elements in a column.
sourcepub fn append<'a>(&mut self, row: impl Iterator<Item = Option<&'a [u8]>>)
pub fn append<'a>(&mut self, row: impl Iterator<Item = Option<&'a [u8]>>)
Takes one element from the iterator for each internal column buffer and appends it to the
end of the buffer. Should the buffer be not large enough to hold the element, it will be
reallocated with 1.2
times its size.
This method panics if it is tried to insert elements beyond batch size. It will also panic if row does not contain at least one item for each internal column buffer.
Trait Implementations
sourceimpl<C> ParameterRefCollection for &ColumnarBuffer<C> where
C: ColumnBuffer + HasDataType,
impl<C> ParameterRefCollection for &ColumnarBuffer<C> where
C: ColumnBuffer + HasDataType,
sourcefn parameter_set_size(&self) -> usize
fn parameter_set_size(&self) -> usize
Number of values per parameter in the collection. This can be different from the maximum
batch size a buffer may be able to hold. Returning 0
will cause the the query not to be
executed. Read more
sourceimpl<C> RowSetBuffer for ColumnarBuffer<C> where
C: ColumnBuffer,
impl<C> RowSetBuffer for ColumnarBuffer<C> where
C: ColumnBuffer,
sourcefn bind_type(&self) -> usize
fn bind_type(&self) -> usize
Declares the bind type of the Row set buffer. 0
Means a columnar binding is used. Any non
zero number is interpreted as the size of a single row in a row wise binding style. Read more
sourcefn row_array_size(&self) -> usize
fn row_array_size(&self) -> usize
The batch size for bulk cursors, if retrieving many rows at once.
sourcefn mut_num_fetch_rows(&mut self) -> &mut usize
fn mut_num_fetch_rows(&mut self) -> &mut usize
Mutable reference to the number of fetched rows. Read more
Auto Trait Implementations
impl<C> RefUnwindSafe for ColumnarBuffer<C> where
C: RefUnwindSafe,
impl<C> Send for ColumnarBuffer<C> where
C: Send,
impl<C> Sync for ColumnarBuffer<C> where
C: Sync,
impl<C> Unpin for ColumnarBuffer<C> where
C: Unpin,
impl<C> UnwindSafe for ColumnarBuffer<C> where
C: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more