pub struct Preallocated<S> { /* private fields */ }Expand description
A preallocated SQL statement handle intended for sequential execution of different queries. See
crate::Connection::preallocate.
§Example
use odbc_api::{Connection, Error};
use std::io::{self, stdin, Read};
fn interactive(conn: &Connection<'_>) -> io::Result<()>{
let mut statement = conn.preallocate().unwrap();
let mut query = String::new();
stdin().read_line(&mut query)?;
while !query.is_empty() {
match statement.execute(&query, ()) {
Err(e) => println!("{}", e),
Ok(None) => println!("No results set generated."),
Ok(Some(cursor)) => {
// ...print cursor contents...
},
}
stdin().read_line(&mut query)?;
}
Ok(())
}Implementations§
Source§impl<S> Preallocated<S>where
S: AsStatementRef,
impl<S> Preallocated<S>where
S: AsStatementRef,
Sourcepub unsafe fn new(statement: S) -> Self
pub unsafe fn new(statement: S) -> Self
Users which intend to write their application in safe Rust should prefer using
crate::Connection::preallocate as opposed to this constructor.
§Safety
statement must be an allocated handled with no pointers bound for either results or
arguments. The statement must not be prepared, but in the state of a “freshly” allocated
handle.
Sourcepub fn execute(
&mut self,
query: &str,
params: impl ParameterCollectionRef,
) -> Result<Option<CursorImpl<StatementRef<'_>>>, Error>
pub fn execute( &mut self, query: &str, params: impl ParameterCollectionRef, ) -> Result<Option<CursorImpl<StatementRef<'_>>>, Error>
Executes a statement. This is the fastest way to sequentially execute different SQL Statements.
This method produces a cursor which borrowes the statement handle. If you want to take
ownership you can use the sibling Self::into_cursor.
§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. Check thecrate::parametermodule level documentation for more information on how to pass parameters.
§Return
Returns Some if a cursor is created. If None is returned no cursor has been created (
e.g. the query came back empty). Note that an empty query may also create a cursor with zero
rows. Since we want to reuse the statement handle a returned cursor will not take ownership
of it and instead borrow it.
§Example
use odbc_api::{Connection, Error};
use std::io::{self, stdin, Read};
fn interactive(conn: &Connection) -> io::Result<()>{
let mut statement = conn.preallocate().unwrap();
let mut query = String::new();
stdin().read_line(&mut query)?;
while !query.is_empty() {
match statement.execute(&query, ()) {
Err(e) => println!("{}", e),
Ok(None) => println!("No results set generated."),
Ok(Some(cursor)) => {
// ...print cursor contents...
},
}
stdin().read_line(&mut query)?;
}
Ok(())
}Sourcepub fn into_cursor(
self,
query: &str,
params: impl ParameterCollectionRef,
) -> Result<Option<CursorImpl<S>>, Error>
pub fn into_cursor( self, query: &str, params: impl ParameterCollectionRef, ) -> Result<Option<CursorImpl<S>>, Error>
Similar to Self::execute, but transfers ownership of the statement handle to the
resulting cursor if any is created. This makes this method not suitable to repeatedly
execute statements. In most situations you may want to call crate::Connection::execute
instead of this method, yet this method is useful if you have some time in your application
until the query is known, and once you have it want to execute it as fast as possible.
Sourcepub fn into_handle(self) -> S
pub fn into_handle(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.
Sourcepub fn tables_cursor(
&mut self,
catalog_name: &str,
schema_name: &str,
table_name: &str,
table_type: &str,
) -> Result<CursorImpl<StatementRef<'_>>, Error>
pub fn tables_cursor( &mut self, catalog_name: &str, schema_name: &str, table_name: &str, table_type: &str, ) -> Result<CursorImpl<StatementRef<'_>>, Error>
List tables, schemas, views and catalogs of a datasource.
§Parameters
catalog_name: Filter result by catalog name. Accept search patterns. Use%to match any number of characters. Use_to match exactly on character. Use\to escape characeters.schema_name: Filter result by schema. Accepts patterns in the same way ascatalog_name.table_name: Filter result by table. Accepts patterns in the same way ascatalog_name.table_type: Filters results by table type. E.g: ‘TABLE’, ‘VIEW’. This argument accepts a comma separeted list of table types. Omit it to not filter the result by table type at all.
Sourcepub fn into_tables_cursor(
self,
catalog_name: &str,
schema_name: &str,
table_name: &str,
table_type: &str,
) -> Result<CursorImpl<S>, Error>
pub fn into_tables_cursor( self, catalog_name: &str, schema_name: &str, table_name: &str, table_type: &str, ) -> Result<CursorImpl<S>, Error>
Same as Self::tables_cursor but the cursor takes ownership of the statement handle.
Sourcepub fn columns_cursor(
&mut self,
catalog_name: &str,
schema_name: &str,
table_name: &str,
column_name: &str,
) -> Result<CursorImpl<StatementRef<'_>>, Error>
pub fn columns_cursor( &mut self, catalog_name: &str, schema_name: &str, table_name: &str, column_name: &str, ) -> Result<CursorImpl<StatementRef<'_>>, Error>
A cursor describing columns of all tables matching the patterns. Patterns support as
placeholder % for multiple characters or _ for a single character. Use \ to escape.The
returned cursor has the columns:
TABLE_CAT, TABLE_SCHEM, TABLE_NAME, COLUMN_NAME, DATA_TYPE, TYPE_NAME,
COLUMN_SIZE, BUFFER_LENGTH, DECIMAL_DIGITS, NUM_PREC_RADIX, NULLABLE,
REMARKS, COLUMN_DEF, SQL_DATA_TYPE, SQL_DATETIME_SUB, CHAR_OCTET_LENGTH,
ORDINAL_POSITION, IS_NULLABLE.
In addition to that there may be a number of columns specific to the data source.
Sourcepub fn into_columns_cursor(
self,
catalog_name: &str,
schema_name: &str,
table_name: &str,
column_name: &str,
) -> Result<CursorImpl<S>, Error>
pub fn into_columns_cursor( self, catalog_name: &str, schema_name: &str, table_name: &str, column_name: &str, ) -> Result<CursorImpl<S>, Error>
Same as Self::columns_cursor, but the cursor takes ownership of the statement handle.
Sourcepub fn primary_keys_cursor(
&mut self,
catalog_name: Option<&str>,
schema_name: Option<&str>,
table_name: &str,
) -> Result<CursorImpl<StatementRef<'_>>, Error>
pub fn primary_keys_cursor( &mut self, catalog_name: Option<&str>, schema_name: Option<&str>, table_name: &str, ) -> Result<CursorImpl<StatementRef<'_>>, Error>
Create a result set which contains the column names that make up the primary key for the
table. Same as Self::into_primary_keys_cursor but the cursor borrowes the statement
handle instead of taking ownership of it. This allows you to reuse the statement handle for
multiple calls to Self::primary_keys_cursor or other queries, without the need to ask
the driver for repeated allocations of new handles.
§Parameters
catalog_name: Catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data from different DBMSs, an empty string (“”) denotes those tables that do not have catalogs.catalog_namemust not contain a string search pattern.schema_name: Schema name. If a driver supports schemas for some tables but not for others, such as when the driver retrieves data from different DBMSs, an empty string (“”) denotes those tables that do not have schemas.schema_namemust not contain a string search pattern.table_name: Table name.table_namemust not contain a string search pattern.
The resulting result set contains the following columns:
TABLE_CAT: Primary key table catalog name. NULL if not applicable to the data source. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data from different DBMSs, it returns an empty string (“”) for those tables that do not have catalogs.VARCHARTABLE_SCHEM: Primary key table schema name; NULL if not applicable to the data source. If a driver supports schemas for some tables but not for others, such as when the driver retrieves data from different DBMSs, it returns an empty string (“”) for those tables that do not have schemas.VARCHARTABLE_NAME: Primary key table name.VARCHAR NOT NULLCOLUMN_NAME: Primary key column name. The driver returns an empty string for a column that does not have a name.VARCHAR NOT NULLKEY_SEQ: Column sequence number in key (starting with 1).SMALLINT NOT NULLPK_NAME: Primary key name. NULL if not applicable to the data source.VARCHAR
The maximum length of the VARCHAR columns is driver specific.
If crate::sys::StatementAttribute::MetadataId statement attribute is set to true,
catalog, schema and table name parameters are treated as an identifiers and their case is
not significant. If it is false, they are ordinary arguments. As such they treated literally
and their case is significant.
See: https://learn.microsoft.com/sql/odbc/reference/syntax/sqlprimarykeys-function
Sourcepub fn primary_keys(
&mut self,
catalog_name: Option<&str>,
schema_name: Option<&str>,
table_name: &str,
) -> Result<BlockCursorIterator<CursorImpl<StatementRef<'_>>, PrimaryKeysRow>, Error>
pub fn primary_keys( &mut self, catalog_name: Option<&str>, schema_name: Option<&str>, table_name: &str, ) -> Result<BlockCursorIterator<CursorImpl<StatementRef<'_>>, PrimaryKeysRow>, Error>
An iterator whose items contains the column names that make up the primary key for the
table. Same as Self::into_primary_keys but the cursor borrowes the statement handle
instead of taking ownership of it. This allows you to reuse the statement handle for
multiple calls to Self::primary_keys or other queries, without the need to ask the
driver for repeated allocations of new handles.
§Parameters
catalog_name: Catalog name. If a driver supports catalogs for some tables but not for others, such as when the driver retrieves data from different DBMSs, an empty string (“”) denotes those tables that do not have catalogs.catalog_namemust not contain a string search pattern.schema_name: Schema name. If a driver supports schemas for some tables but not for others, such as when the driver retrieves data from different DBMSs, an empty string (“”) denotes those tables that do not have schemas.schema_namemust not contain a string search pattern.table_name: Table name.table_namemust not contain a string search pattern.
If crate::sys::StatementAttribute::MetadataId statement attribute is set to true,
catalog, schema and table name parameters are treated as an identifiers and their case is
not significant. If it is false, they are ordinary arguments. As such they treated literally
and their case is significant.
See: https://learn.microsoft.com/sql/odbc/reference/syntax/sqlprimarykeys-function
Sourcepub fn into_primary_keys_cursor(
self,
catalog_name: Option<&str>,
schema_name: Option<&str>,
table_name: &str,
) -> Result<CursorImpl<S>, Error>
pub fn into_primary_keys_cursor( self, catalog_name: Option<&str>, schema_name: Option<&str>, table_name: &str, ) -> Result<CursorImpl<S>, Error>
Same as Self::primary_keys_cursor but the cursor takes ownership of the statement handle.
Sourcepub fn into_primary_keys(
self,
catalog_name: Option<&str>,
schema_name: Option<&str>,
table_name: &str,
) -> Result<BlockCursorIterator<CursorImpl<S>, PrimaryKeysRow>, Error>
pub fn into_primary_keys( self, catalog_name: Option<&str>, schema_name: Option<&str>, table_name: &str, ) -> Result<BlockCursorIterator<CursorImpl<S>, PrimaryKeysRow>, Error>
Same as Self::primary_keys but the cursor takes ownership of the statement handle.
Sourcepub fn foreign_keys_cursor(
&mut self,
pk_catalog_name: &str,
pk_schema_name: &str,
pk_table_name: &str,
fk_catalog_name: &str,
fk_schema_name: &str,
fk_table_name: &str,
) -> Result<CursorImpl<StatementRef<'_>>, Error>
pub fn foreign_keys_cursor( &mut self, pk_catalog_name: &str, pk_schema_name: &str, pk_table_name: &str, fk_catalog_name: &str, fk_schema_name: &str, fk_table_name: &str, ) -> Result<CursorImpl<StatementRef<'_>>, Error>
This can be used to retrieve either a list of foreign keys in the specified table or a list of foreign keys in other table that refer to the primary key of the specified table.
See: https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function
Sourcepub fn into_foreign_keys_cursor(
self,
pk_catalog_name: &str,
pk_schema_name: &str,
pk_table_name: &str,
fk_catalog_name: &str,
fk_schema_name: &str,
fk_table_name: &str,
) -> Result<CursorImpl<S>, Error>
pub fn into_foreign_keys_cursor( self, pk_catalog_name: &str, pk_schema_name: &str, pk_table_name: &str, fk_catalog_name: &str, fk_schema_name: &str, fk_table_name: &str, ) -> Result<CursorImpl<S>, Error>
This can be used to retrieve either a list of foreign keys in the specified table or a list of foreign keys in other table that refer to the primary key of the specified table.
See: https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlforeignkeys-function
Sourcepub fn row_count(&mut self) -> Result<Option<usize>, Error>
pub fn row_count(&mut self) -> Result<Option<usize>, Error>
Number of rows affected by the last INSERT, UPDATE or DELETE statment. 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};
/// Make everyone rich and return how many colleagues are happy now.
fn raise_minimum_salary(
conn: &Connection<'_>,
new_min_salary: i32
) -> Result<usize, Error> {
// We won't use conn.execute directly, because we need a handle to ask about the number
// of changed rows. So let's allocate the statement explicitly.
let mut stmt = conn.preallocate()?;
stmt.execute(
"UPDATE Employees SET salary = ? WHERE salary < ?",
(&new_min_salary, &new_min_salary),
)?;
let number_of_updated_rows = stmt
.row_count()?
.expect("For UPDATE statements row count must always be available.");
Ok(number_of_updated_rows)
}Sourcepub fn set_query_timeout_sec(&mut self, timeout_sec: usize) -> Result<(), Error>
pub fn set_query_timeout_sec(&mut self, timeout_sec: usize) -> Result<(), Error>
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. You can specify 0, to deactivate the timeout, this is the default. For
this to work the driver must support this feature. E.g. PostgreSQL, and Microsoft SQL Server
do, but SQLite or MariaDB do not.
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
Sourcepub fn query_timeout_sec(&mut self) -> Result<usize, Error>
pub fn query_timeout_sec(&mut self) -> Result<usize, Error>
The number of seconds to wait for a SQL statement to execute before returning to the
application. If timeout_sec is equal to 0 (default), there is no timeout.
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
Sourcepub fn into_polling(self) -> Result<PreallocatedPolling<S>, Error>
pub fn into_polling(self) -> Result<PreallocatedPolling<S>, Error>
Call this method to enable asynchronous polling mode on the statement.
⚠️Attention⚠️: Please read Asynchronous execution using polling mode