odbc_api

Struct Prepared

Source
pub struct Prepared<S> { /* private fields */ }
Expand description

A prepared query. Prepared queries are useful if the similar queries should executed more than once. See crate::Connection::prepare.

Implementations§

Source§

impl<S> Prepared<S>

Source

pub fn into_statement(self) -> S

Transfer ownership to the underlying statement handle.

The resulting type is one level of indirection away from the raw pointer of the ODBC API. It no longer has any guarantees about bound buffers, but is still guaranteed to be a valid allocated statement handle. This serves together with crate::handles::StatementImpl::into_sys or crate::handles::Statement::as_sys this serves as an escape hatch to access the functionality provided by crate::sys not yet accessible through safe abstractions.

Source§

impl<S> Prepared<S>
where S: AsStatementRef,

Source

pub fn execute( &mut self, params: impl ParameterCollectionRef, ) -> Result<Option<CursorImpl<StatementRef<'_>>>, Error>

Execute the prepared statement.

  • params: Used to bind these parameters before executing the statement. You can use () to represent no parameters. In regards to binding arrays of parameters: Should params specify a parameter set size of 0, nothing is executed, and Ok(None) is returned. See the crate::parameter module level documentation for more information on how to pass parameters.
Source

pub fn describe_param( &mut self, parameter_number: u16, ) -> Result<ParameterDescription, Error>

Describes parameter marker associated with a prepared SQL statement.

§Parameters
  • parameter_number: Parameter marker number ordered sequentially in increasing parameter order, starting at 1.
Source

pub fn num_params(&mut self) -> Result<u16, Error>

Number of placeholders which must be provided with Self::execute in order to execute this statement. This is equivalent to the number of placeholders used in the SQL string used to prepare the statement.

Source

pub fn parameter_descriptions( &mut self, ) -> Result<impl DoubleEndedIterator<Item = Result<ParameterDescription, Error>> + ExactSizeIterator<Item = Result<ParameterDescription, Error>> + '_, Error>

Number of placeholders which must be provided with Self::execute in order to execute this statement. This is equivalent to the number of placeholders used in the SQL string used to prepare the statement.

use odbc_api::{Connection, Error, handles::ParameterDescription};

fn collect_parameter_descriptions(
    connection: Connection<'_>
) -> Result<Vec<ParameterDescription>, Error>{
    // Note the two `?` used as placeholders for the parameters.
    let sql = "INSERT INTO NationalDrink (country, drink) VALUES (?, ?)";
    let mut prepared = connection.prepare(sql)?;

    let params: Vec<_> = prepared.parameter_descriptions()?.collect::<Result<_,_>>()?;

    Ok(params)
}
Source

pub unsafe fn unchecked_bind_columnar_array_parameters<C>( self, parameter_buffers: Vec<C>, ) -> Result<ColumnarBulkInserter<S, C>, Error>

Unless you want to roll your own column buffer implementation users are encouraged to use Self::into_text_inserter instead.

§Safety
  • Parameters must all be valid for insertion. An example for an invalid parameter would be a text buffer with a cell those indiactor value exceeds the maximum element length. This can happen after when truncation occurs then writing into a buffer.
Source

pub fn into_text_inserter( self, capacity: usize, max_str_len: impl IntoIterator<Item = usize>, ) -> Result<ColumnarBulkInserter<S, TextColumn<u8>>, Error>

Use this to insert rows of string input into the database.

use odbc_api::{Connection, Error};

fn insert_text<'e>(connection: Connection<'e>) -> Result<(), Error>{
    // Insert six rows of text with two columns each into the database in batches of 3. In a
    // real use case you are likely to achieve a better results with a higher batch size.

    // Note the two `?` used as placeholders for the parameters.
    let prepared = connection.prepare("INSERT INTO NationalDrink (country, drink) VALUES (?, ?)")?;
    // We assume both parameter inputs never exceed 50 bytes.
    let mut prebound = prepared.into_text_inserter(3, [50, 50])?;
     
    // A cell is an option to byte. We could use `None` to represent NULL but we have no
    // need to do that in this example.
    let as_cell = |s: &'static str| { Some(s.as_bytes()) } ;

    // First batch of values
    prebound.append(["England", "Tea"].into_iter().map(as_cell))?;
    prebound.append(["Germany", "Beer"].into_iter().map(as_cell))?;
    prebound.append(["Russia", "Vodka"].into_iter().map(as_cell))?;

    // Execute statement using values bound in buffer.
    prebound.execute()?;
    // Clear buffer contents, otherwise the previous values would stay in the buffer.
    prebound.clear();

    // Second batch of values
    prebound.append(["India", "Tea"].into_iter().map(as_cell))?;
    prebound.append(["France", "Wine"].into_iter().map(as_cell))?;
    prebound.append(["USA", "Cola"].into_iter().map(as_cell))?;

    // Send second batch to the database
    prebound.execute()?;

    Ok(())
}
Source

pub fn into_column_inserter( self, capacity: usize, descriptions: impl IntoIterator<Item = BufferDesc>, ) -> Result<ColumnarBulkInserter<S, AnyBuffer>, Error>

A crate::ColumnarBulkInserter which takes ownership of both the statement and the bound array parameter buffers.

use odbc_api::{Connection, Error, IntoParameter, buffers::BufferDesc};

fn insert_birth_years(
    conn: &Connection,
    names: &[&str],
    years: &[i16]
) -> Result<(), Error> {
    // All columns must have equal length.
    assert_eq!(names.len(), years.len());

    let prepared = conn.prepare("INSERT INTO Birthdays (name, year) VALUES (?, ?)")?;

    // Create a columnar buffer which fits the input parameters.
    let buffer_description = [
        BufferDesc::Text { max_str_len: 255 },
        BufferDesc::I16 { nullable: false },
    ];
    // The capacity must be able to hold at least the largest batch. We do everything in one
    // go, so we set it to the length of the input parameters.
    let capacity = names.len();
    // Allocate memory for the array column parameters and bind it to the statement.
    let mut prebound = prepared.into_column_inserter(capacity, buffer_description)?;
    // Length of this batch
    prebound.set_num_rows(capacity);


    // Fill the buffer with values column by column
    let mut col = prebound
        .column_mut(0)
        .as_text_view()
        .expect("We know the name column to hold text.");

    for (index, name) in names.iter().enumerate() {
        col.set_cell(index, Some(name.as_bytes()));
    }

    let col = prebound
        .column_mut(1)
        .as_slice::<i16>()
        .expect("We know the year column to hold i16.");
    col.copy_from_slice(years);

    prebound.execute()?;
    Ok(())
}
Source

pub fn column_inserter( &mut self, capacity: usize, descriptions: impl IntoIterator<Item = BufferDesc>, ) -> Result<ColumnarBulkInserter<StatementRef<'_>, AnyBuffer>, Error>

A crate::ColumnarBulkInserter which has ownership of the bound array parameter buffers and borrows the statement. For most usecases Self::into_column_inserter is what you want to use, yet on some instances you may want to bind new paramater buffers to the same prepared statement. E.g. to grow the capacity dynamically during insertions with several chunks. In such use cases you may only want to borrow the prepared statemnt, so it can be reused with a different set of parameter buffers.

Source

pub fn row_count(&mut self) -> Result<Option<usize>, Error>

Number of rows affected by the last INSERT, UPDATE or DELETE statement. May return None if row count is not available. Some drivers may also allow to use this to determine how many rows have been fetched using SELECT. Most drivers however only know how many rows have been fetched after they have been fetched.

use odbc_api::{Connection, Error, IntoParameter};

/// Deletes all comments for every user in the slice. Returns the number of deleted
/// comments.
pub fn delete_all_comments_from(
    users: &[&str],
    conn: Connection<'_>,
) -> Result<usize, Error>
{
    // Store prepared query for fast repeated execution.
    let mut prepared = conn.prepare("DELETE FROM Comments WHERE user=?")?;
    let mut total_deleted_comments = 0;
    for user in users {
        prepared.execute(&user.into_parameter())?;
        total_deleted_comments += prepared
            .row_count()?
            .expect("Row count must always be available for DELETE statements.");
    }
    Ok(total_deleted_comments)
}

Trait Implementations§

Source§

impl<S> AsStatementRef for Prepared<S>
where S: AsStatementRef,

Source§

fn as_stmt_ref(&mut self) -> StatementRef<'_>

Get an exclusive reference to the underlying statement handle. This method is used to implement other more higher level methods on top of it. It is not intended to be called by users of this crate directly, yet it may serve as an escape hatch for low level use cases.
Source§

impl<S> ResultSetMetadata for Prepared<S>
where S: AsStatementRef,

Source§

fn describe_col( &mut self, column_number: u16, column_description: &mut ColumnDescription, ) -> Result<(), Error>

Fetch a column description using the column index. Read more
Source§

fn num_result_cols(&mut self) -> Result<i16, Error>

Number of columns in result set. Can also be used to see whether executing a prepared Statement (crate::Prepared) would yield a result set, as this would return 0 if it does not. Read more
Source§

fn column_is_unsigned(&mut self, column_number: u16) -> Result<bool, Error>

true if a given column in a result set is unsigned or not a numeric type, false otherwise. Read more
Source§

fn col_octet_length( &mut self, column_number: u16, ) -> Result<Option<NonZeroUsize>, Error>

Size in bytes of the columns. For variable sized types this is the maximum size, excluding a terminating zero. Read more
Source§

fn col_display_size( &mut self, column_number: u16, ) -> Result<Option<NonZeroUsize>, Error>

Maximum number of characters required to display data from the column. If the driver is unable to provide a maximum None is returned. Read more
Source§

fn col_precision(&mut self, column_number: u16) -> Result<isize, Error>

Precision of the column. Read more
Source§

fn col_scale(&mut self, column_number: u16) -> Result<isize, Error>

The applicable scale for a numeric data type. For DECIMAL and NUMERIC data types, this is the defined scale. It is undefined for all other data types.
Source§

fn col_name(&mut self, column_number: u16) -> Result<String, Error>

The column alias, if it applies. If the column alias does not apply, the column name is returned. If there is no column name or a column alias, an empty string is returned.
Source§

fn column_names(&mut self) -> Result<ColumnNamesIt<'_, Self>, Error>

Use this if you want to iterate over all column names and allocate a String for each one. Read more
Source§

fn col_data_type(&mut self, column_number: u16) -> Result<DataType, Error>

Data type of the specified column. Read more

Auto Trait Implementations§

§

impl<S> Freeze for Prepared<S>
where S: Freeze,

§

impl<S> RefUnwindSafe for Prepared<S>
where S: RefUnwindSafe,

§

impl<S> Send for Prepared<S>
where S: Send,

§

impl<S> Sync for Prepared<S>
where S: Sync,

§

impl<S> Unpin for Prepared<S>
where S: Unpin,

§

impl<S> UnwindSafe for Prepared<S>
where S: UnwindSafe,

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> 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, 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<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