-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
247 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use std::convert::TryInto; | ||
|
||
use crate::{handles::Statement, DataType, Parameter}; | ||
|
||
/// Can stream a sequence of binary batches. Use this to put large data. | ||
/// | ||
/// # Safety | ||
/// | ||
/// Should a size hint be implemented (i.e. `len` returns `Some` value), then it must be correct. | ||
pub unsafe trait BlobInputStream { | ||
/// Fetches the next batch from the stream. The batch may not be valid once the next call to | ||
/// `next` (as enforced by the signature). | ||
fn next(&mut self) -> Option<&[u8]>; | ||
|
||
/// Total length of all batches combined. If available this information will be send to the | ||
/// driver before the first call to next. It depends on the driver wether or not something | ||
/// clever happens with this. | ||
fn len(&self) -> Option<usize>; | ||
|
||
/// SQL Parameter Data Type as which the stream is going to be bound. E.g. | ||
/// [`DataType::LongVarchar`] for narrow text data. | ||
fn data_type(&self) -> DataType; | ||
} | ||
|
||
/// Can bind stream input data at statement execution time. Useful for sending long data to the | ||
/// connected data source. | ||
pub struct BlobInputParameter<B> { | ||
stream: B, | ||
indicator: isize, | ||
} | ||
|
||
impl<B> BlobInputParameter<B> | ||
where | ||
B: BlobInputStream, | ||
{ | ||
/// Create a new blob input parameter from a blob stream. | ||
pub fn new(stream: B) -> Self { | ||
let indicator = if let Some(len) = stream.len() { | ||
odbc_sys::len_data_at_exec(len.try_into().unwrap()) | ||
} else { | ||
odbc_sys::DATA_AT_EXEC | ||
}; | ||
|
||
Self { stream, indicator } | ||
} | ||
} | ||
|
||
unsafe impl<B> Parameter for &mut BlobInputParameter<B> | ||
where | ||
B: BlobInputStream, | ||
{ | ||
unsafe fn bind_parameter( | ||
self, | ||
parameter_number: u16, | ||
stmt: &mut crate::handles::StatementImpl<'_>, | ||
) -> Result<(), crate::Error> { | ||
stmt.bind_input_blob( | ||
parameter_number, | ||
parameter_number as odbc_sys::Pointer, | ||
self.stream.data_type(), | ||
&self.indicator, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,38 @@ | ||
//! Since connection pooling mode is a process level attribute these tests have to run in their own | ||
//! process. | ||
|
||
use lazy_static::lazy_static; | ||
use odbc_api::Environment; | ||
use odbc_sys::{AttrConnectionPooling, AttrCpMatch}; | ||
|
||
const MSSQL_CONNECTION: &str = | ||
"Driver={ODBC Driver 17 for SQL Server};Server=localhost;UID=SA;PWD=<YourStrong@Passw0rd>;"; | ||
|
||
// Rust by default executes tests in parallel. Yet only one environment is allowed at a time. | ||
lazy_static! { | ||
pub static ref ENV: Environment = unsafe { | ||
let _ = env_logger::builder().is_test(true).try_init(); | ||
Environment::set_connection_pooling(AttrConnectionPooling::DriverAware).unwrap(); | ||
let mut env = Environment::new().unwrap(); | ||
env.set_connection_pooling_matching(AttrCpMatch::Strict).unwrap(); | ||
env | ||
}; | ||
} | ||
|
||
#[test] | ||
fn connect() { | ||
// First connection should be created on demand | ||
{ | ||
let conn = ENV.connect_with_connection_string(MSSQL_CONNECTION).unwrap(); | ||
assert!(!conn.is_dead().unwrap()); | ||
} | ||
|
||
// Second connection should be from the pool | ||
let conn = ENV.connect_with_connection_string(MSSQL_CONNECTION).unwrap(); | ||
assert!(!conn.is_dead().unwrap()); | ||
} | ||
//! Since connection pooling mode is a process level attribute these tests have to run in their own | ||
//! process. | ||
|
||
use lazy_static::lazy_static; | ||
use odbc_api::Environment; | ||
use odbc_sys::{AttrConnectionPooling, AttrCpMatch}; | ||
|
||
const MSSQL_CONNECTION: &str = | ||
"Driver={ODBC Driver 17 for SQL Server};Server=localhost;UID=SA;PWD=<YourStrong@Passw0rd>;"; | ||
|
||
// Rust by default executes tests in parallel. Yet only one environment is allowed at a time. | ||
lazy_static! { | ||
pub static ref ENV: Environment = unsafe { | ||
let _ = env_logger::builder().is_test(true).try_init(); | ||
Environment::set_connection_pooling(AttrConnectionPooling::DriverAware).unwrap(); | ||
let mut env = Environment::new().unwrap(); | ||
env.set_connection_pooling_matching(AttrCpMatch::Strict) | ||
.unwrap(); | ||
env | ||
}; | ||
} | ||
|
||
#[test] | ||
fn connect() { | ||
// First connection should be created on demand | ||
{ | ||
let conn = ENV | ||
.connect_with_connection_string(MSSQL_CONNECTION) | ||
.unwrap(); | ||
assert!(!conn.is_dead().unwrap()); | ||
} | ||
|
||
// Second connection should be from the pool | ||
let conn = ENV | ||
.connect_with_connection_string(MSSQL_CONNECTION) | ||
.unwrap(); | ||
assert!(!conn.is_dead().unwrap()); | ||
} |
Oops, something went wrong.