Trait ConnectionTransitions

Source
pub trait ConnectionTransitions: Sized {
    type StatementParent: StatementParent;

    // Required methods
    fn into_cursor(
        self,
        query: &str,
        params: impl ParameterCollectionRef,
        query_timeout_sec: Option<usize>,
    ) -> Result<Option<CursorImpl<StatementConnection<Self::StatementParent>>>, FailedStateTransition<Self>>;
    fn into_prepared(
        self,
        query: &str,
    ) -> Result<Prepared<StatementConnection<Self::StatementParent>>, Error>;
    fn into_preallocated(
        self,
    ) -> Result<Preallocated<StatementConnection<Self::StatementParent>>, Error>;
}
Expand description

Ability to transition ownership of the connection to various children which represent statement handles in various states. E.g. crate::Prepared or crate::Cursor. Transfering ownership of the connection could e.g. be useful if you want to clean the connection after you are done with the child.

Having this in a trait rather than directly on Connection allows us to be generic over the type of ownership we express. E.g. we can express shared ownership of a connection by using an Arc<Mutex<Connection>> or Arc<Connection>. Or a still exclusive ownership using a plain Connection.

Required Associated Types§

Source

type StatementParent: StatementParent

The type passed to crate::handles::StatementConnection to express ownership of the connection.

Required Methods§

Source

fn into_cursor( self, query: &str, params: impl ParameterCollectionRef, query_timeout_sec: Option<usize>, ) -> Result<Option<CursorImpl<StatementConnection<Self::StatementParent>>>, FailedStateTransition<Self>>

Similar to crate::Connection::into_cursor, yet it operates on an Arc<Mutex<Connection>>. Arc<Connection> can be used if you want shared ownership of connections. However, Arc<Connection> is not Send due to Connection not being Sync. So sometimes you may want to wrap your Connection into an Arc<Mutex<Connection>> to allow shared ownership of the connection across threads. This function allows you to create a cursor from such a shared which also holds a strong reference to it.

§Parameters
  • query: The text representation of the SQL statement. E.g. “SELECT * FROM my_table;”.

  • params: ? may be used as a placeholder in the statement text. You can use () to represent no parameters. See the crate::parameter module level documentation for more information on how to pass parameters.

  • query_timeout_sec: Use this to limit the time the query is allowed to take, before responding with data to the application. The driver may replace the number of seconds you provide with a minimum or maximum value.

    For the timeout to work the driver must support this feature. E.g. PostgreSQL, and Microsoft SQL Server do, but SQLite or MariaDB do not.

    You can specify 0, to deactivate the timeout, this is the default. So if you want no timeout, just leave it at None. Only reason to specify 0 is if for some reason your datasource does not have 0 as default.

    This corresponds to SQL_ATTR_QUERY_TIMEOUT in the ODBC C API.

    See: https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlsetstmtattr-function

Source

fn into_prepared( self, query: &str, ) -> Result<Prepared<StatementConnection<Self::StatementParent>>, Error>

Prepares an SQL statement which takes ownership of the connection. The advantage over Connection::prepare is, that you do not need to keep track of the lifetime of the connection seperatly and can create types which do own the prepared query and only depend on the lifetime of the environment.

§Parameters
  • query: The text representation of the SQL statement. E.g. “SELECT * FROM my_table;”. ? may be used as a placeholder in the statement text, to be replaced with parameters during execution.
use odbc_api::{
    environment, Error, ColumnarBulkInserter, ConnectionTransitions, Connection,
    handles::StatementConnection, buffers::{BufferDesc, AnyBuffer}, ConnectionOptions,
};

const CONNECTION_STRING: &str =
    "Driver={ODBC Driver 18 for SQL Server};\
    Server=localhost;UID=SA;\
    PWD=My@Test@Password1;";

/// Supports columnar bulk inserts on a heterogenous schema (columns have different types),
/// takes ownership of a connection created using an environment with static lifetime.
type Inserter = ColumnarBulkInserter<StatementConnection<Connection<'static>>, AnyBuffer>;

/// Creates an inserter which can be reused to bulk insert birthyears with static lifetime.
fn make_inserter(query: &str) -> Result<Inserter, Error> {
    let env = environment()?;
    let conn = env.connect_with_connection_string(
        CONNECTION_STRING,
        ConnectionOptions::default()
    )?;
    let prepared = conn.into_prepared("INSERT INTO Birthyear (name, year) VALUES (?, ?)")?;
    let buffers = [
        BufferDesc::Text { max_str_len: 255},
        BufferDesc::I16 { nullable: false },
    ];
    let capacity = 400;
    prepared.into_column_inserter(capacity, buffers)
}
Source

fn into_preallocated( self, ) -> Result<Preallocated<StatementConnection<Self::StatementParent>>, Error>

Creates a preallocated statement handle like Connection::preallocate. Yet the statement also takes ownership of the connection.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<'env> ConnectionTransitions for Arc<Connection<'env>>

Source§

type StatementParent = Arc<Connection<'env>>

Source§

fn into_cursor( self, query: &str, params: impl ParameterCollectionRef, query_timeout_sec: Option<usize>, ) -> Result<Option<CursorImpl<StatementConnection<Self>>>, FailedStateTransition<Self>>

Source§

fn into_prepared( self, query: &str, ) -> Result<Prepared<StatementConnection<Self>>, Error>

Source§

fn into_preallocated( self, ) -> Result<Preallocated<StatementConnection<Self>>, Error>

Implementors§