Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wip-get-wide-text #432

Merged
merged 2 commits into from Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 16 additions & 3 deletions odbc-api/src/cursor.rs
Expand Up @@ -4,7 +4,7 @@ use crate::{
buffers::Indicator,
error::ExtendResult,
handles::{AsStatementRef, CDataMut, SqlResult, State, Statement, StatementRef},
parameter::{Binary, CElement, Text, VarCell, VarKind},
parameter::{Binary, CElement, Text, VarCell, VarKind, WideText},
sleep::{wait_for, Sleep},
Error, ResultSetMetadata,
};
Expand Down Expand Up @@ -120,7 +120,9 @@ impl<'s> CursorRow<'s> {
}

/// Retrieves arbitrary large character data from the row and stores it in the buffer. Column
/// index starts at `1`.
/// index starts at `1`. The used encoding is accordig to the ODBC standard determined by your
/// system local. Ultimatly the choice is up to the implementation of your ODBC driver, which
/// often defaults to always UTF-8.
///
/// # Return
///
Expand All @@ -130,6 +132,17 @@ impl<'s> CursorRow<'s> {
self.get_variadic::<Text>(col_or_param_num, buf)
}

/// Retrieves arbitrary large character data from the row and stores it in the buffer. Column
/// index starts at `1`. The used encoding is UTF-16.
///
/// # Return
///
/// `true` indicates that the value has not been `NULL` and the value has been placed in `buf`.
/// `false` indicates that the value is `NULL`. The buffer is cleared in that case.
pub fn get_wide_text(&mut self, col_or_param_num: u16, buf: &mut Vec<u16>) -> Result<bool, Error> {
self.get_variadic::<WideText>(col_or_param_num, buf)
}

/// Retrieves arbitrary large binary data from the row and stores it in the buffer. Column index
/// starts at `1`.
///
Expand Down Expand Up @@ -186,7 +199,7 @@ impl<'s> CursorRow<'s> {
// Use an exponential strategy for increasing buffer size.
buf.resize(old_len * 2, K::ZERO);
let buf_extend =
&mut buf[(old_len - K::TERMINATING_ZEROES * size_of::<K::Element>())..];
&mut buf[(old_len - K::TERMINATING_ZEROES)..];
target = VarCell::<&mut [K::Element], K>::from_buffer(
buf_extend,
Indicator::NoTotal,
Expand Down
2 changes: 1 addition & 1 deletion odbc-api/src/parameter.rs
Expand Up @@ -343,7 +343,7 @@ pub use self::{
varcell::{
Binary, Text, VarBinary, VarBinaryArray, VarBinaryBox, VarBinarySlice, VarBinarySliceMut,
VarCell, VarChar, VarCharArray, VarCharBox, VarCharSlice, VarCharSliceMut, VarKind,
VarWCharArray, VarWCharBox, VarWCharSlice, VarWCharSliceMut,
VarWCharArray, VarWCharBox, VarWCharSlice, VarWCharSliceMut, WideText,
},
};

Expand Down
27 changes: 27 additions & 0 deletions odbc-api/tests/integration.rs
Expand Up @@ -2294,6 +2294,33 @@ fn get_text(profile: &Profile) {
assert_eq!(&b"Hello, World!"[..], &actual);
}

/// Use get_text to retrieve a string. Use a buffer which is one terminating zero short to get the
/// entire value.
#[test_case(MSSQL; "Microsoft SQL Server")]
#[test_case(MARIADB; "Maria DB")]
#[test_case(SQLITE_3; "SQLite 3")]
#[test_case(POSTGRES; "PostgreSQL")]
fn get_wide_text(profile: &Profile) {
let table_name = table_name!();
let (conn, table) = profile.given(&table_name, &["Varchar(50)"]).unwrap();
conn.execute(&table.sql_insert(), &"Hello, World!".into_parameter())
.unwrap();
let mut cursor = conn
.execute(&format!("SELECT a FROM {table_name} ORDER BY id"), ())
.unwrap()
.unwrap();

let mut row = cursor.next_row().unwrap().unwrap();
// We want to hit an edge case there there has been a sign error then calculating buffer size
// with terminating zero.
let mut actual = Vec::with_capacity("Hello, World!".len() - 1);
let is_not_null = row.get_wide_text(1, &mut actual).unwrap();

let actual = U16String::from_vec(actual).to_string().unwrap();
assert!(is_not_null);
assert_eq!("Hello, World!", &actual);
}

/// Use get_data to retrieve a binary data
#[test_case(MSSQL; "Microsoft SQL Server")]
#[test_case(MARIADB; "Maria DB")]
Expand Down