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§
Sourcetype StatementParent: StatementParent
type StatementParent: StatementParent
The type passed to crate::handles::StatementConnection to express ownership of the connection.
Required Methods§
Sourcefn into_cursor(
self,
query: &str,
params: impl ParameterCollectionRef,
query_timeout_sec: Option<usize>,
) -> Result<Option<CursorImpl<StatementConnection<Self::StatementParent>>>, FailedStateTransition<Self>>
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 thecrate::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 atNone
. Only reason to specify0
is if for some reason your datasource does not have0
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
Sourcefn into_prepared(
self,
query: &str,
) -> Result<Prepared<StatementConnection<Self::StatementParent>>, Error>
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)
}
Sourcefn into_preallocated(
self,
) -> Result<Preallocated<StatementConnection<Self::StatementParent>>, Error>
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.