diff --git a/Cargo.lock b/Cargo.lock index 2634aab3..9ce05f9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1144,9 +1144,9 @@ dependencies = [ [[package]] name = "odbc-sys" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38467959ef8ec6b76e0d98a7da6a270b65b7ab4f22b2209ef81c8a9260633a50" +checksum = "19e3a0f2c6531470f498c7cc5054f6b2a5922b5e82a5151065a257c1eb5ee1cd" dependencies = [ "unix-odbc", ] diff --git a/odbc-api/Cargo.toml b/odbc-api/Cargo.toml index c06a1913..8351c8e2 100644 --- a/odbc-api/Cargo.toml +++ b/odbc-api/Cargo.toml @@ -108,7 +108,7 @@ prompt = ["dep:winit"] [dependencies] # Low level bindings to ODBC API calls into libodbc.so -odbc-sys = { version = "0.31.2", default-features = false, features = ["odbc_version_3_50"] } +odbc-sys = { version = "0.31.3", default-features = false, features = ["odbc_version_3_50"] } # Used to generate code for the error type thiserror = "2.0.18" # Used as a log frontend to emit log messages for applications diff --git a/odbc-api/src/connection.rs b/odbc-api/src/connection.rs index 9c6ca794..5bb85d59 100644 --- a/odbc-api/src/connection.rs +++ b/odbc-api/src/connection.rs @@ -7,6 +7,7 @@ use crate::{ self, KeepConnectionOpen, SqlText, State, Statement, StatementConnection, StatementImpl, slice_to_utf8, }, + sys::TransactionCapable, }; use log::error; use std::{ @@ -488,6 +489,16 @@ impl<'env> Connection<'env> { .into_result(&self.connection) } + /// Level of transaction support offered by the data source. See + /// [`crate::sys::TransactionCapable`] for the possible values. + /// + /// This corresponds to the `SQL_TXN_CAPABLE` information type in the ODBC specification. + pub fn transaction_capable(&self) -> Result { + self.connection + .transaction_capable() + .into_result(&self.connection) + } + /// To commit a transaction in manual-commit mode. pub fn commit(&self) -> Result<(), Error> { self.connection.commit().into_result(&self.connection) diff --git a/odbc-api/src/handles/connection.rs b/odbc-api/src/handles/connection.rs index 912154c2..f09d8747 100644 --- a/odbc-api/src/handles/connection.rs +++ b/odbc-api/src/handles/connection.rs @@ -13,7 +13,7 @@ use super::{ use log::trace; use odbc_sys::{ CompletionType, ConnectionAttribute, DriverConnectOption, HDbc, HEnv, HWnd, Handle, HandleType, - IS_UINTEGER, InfoType, Pointer, SQLAllocHandle, SQLDisconnect, SQLEndTran, + IS_UINTEGER, InfoType, Pointer, SQLAllocHandle, SQLDisconnect, SQLEndTran, TransactionCapable, }; use std::{cmp::max, ffi::c_void, marker::PhantomData, mem::size_of, ptr::null_mut}; @@ -347,6 +347,12 @@ impl Connection<'_> { self.info_u16(InfoType::MaxColumnNameLen) } + /// Level of transaction support of the data source. Corresponds to `SQL_TXN_CAPABLE`. + pub fn transaction_capable(&self) -> SqlResult { + self.info_u16(InfoType::TransactionCapable) + .map(TransactionCapable) + } + /// Fetch the name of the current catalog being used by the connection and store it into the /// provided `buf`. pub fn fetch_current_catalog(&self, buffer: &mut Vec) -> SqlResult<()> { diff --git a/odbc-api/tests/integration/main.rs b/odbc-api/tests/integration/main.rs index ac6dc2b4..ba54d1a9 100644 --- a/odbc-api/tests/integration/main.rs +++ b/odbc-api/tests/integration/main.rs @@ -25,7 +25,7 @@ use odbc_api::{ }, sys::{ CDataType, FetchOrientation, HandleType, Numeric, Pointer, SQLFreeHandle, SQLPrepareW, - SqlDataType, SqlReturn, SsAccessToken, Timestamp, + SqlDataType, SqlReturn, SsAccessToken, Timestamp, TransactionCapable, }, }; @@ -1940,6 +1940,16 @@ fn is_autocommit_is_false_after_disabling_autocommit(profile: &Profile) { assert!(!conn.is_autocommit().unwrap()); } +#[test_case(MSSQL, TransactionCapable::ALL; "Microsoft SQL Server")] +#[test_case(MARIADB, TransactionCapable::DDL_COMMIT; "Maria DB")] +#[test_case(SQLITE_3, TransactionCapable::ALL; "SQLite 3")] +#[test_case(POSTGRES, TransactionCapable::ALL; "PostgreSQL")] +fn transaction_capable(profile: &Profile, expected: TransactionCapable) { + let conn = profile.connection().unwrap(); + + assert_eq!(expected, conn.transaction_capable().unwrap()); +} + /// This test checks the behaviour if a connections goes out of scope with a transaction still /// open. #[test_case(MSSQL; "Microsoft SQL Server")]