Skip to content

Commit b2c7ef3

Browse files
committed
refactor(odbc): update binary data handling in tests
This commit modifies the test for binary data handling to use UTF-8 safe bytes, ensuring compatibility with PostgreSQL. The data fetching logic is simplified by using `fetch_optional` and adjusting the assertion to directly compare the fetched result with the expected binary data.
1 parent e4346d4 commit b2c7ef3

File tree

3 files changed

+33
-38
lines changed

3 files changed

+33
-38
lines changed

sqlx-core/src/odbc/connection/odbc_bridge.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,18 @@ where
472472
nulls.push(!txt.unwrap_or(false));
473473
}
474474

475+
fn push_bit(
476+
cursor_row: &mut odbc_api::CursorRow<'_>,
477+
col_index: u16,
478+
vec: &mut Vec<bool>,
479+
nulls: &mut Vec<bool>,
480+
) {
481+
let mut bit_val = odbc_api::Bit(0);
482+
let result = cursor_row.get_data(col_index, &mut bit_val);
483+
vec.push(bit_val.as_bool());
484+
nulls.push(result.is_err());
485+
}
486+
475487
fn push_from_cursor_row(
476488
cursor_row: &mut odbc_api::CursorRow<'_>,
477489
col_index: u16,
@@ -485,9 +497,7 @@ where
485497
OdbcValueVec::BigInt(v) => push_get_data(cursor_row, col_index, v, nulls),
486498
OdbcValueVec::Real(v) => push_get_data(cursor_row, col_index, v, nulls),
487499
OdbcValueVec::Double(v) => push_get_data(cursor_row, col_index, v, nulls),
488-
OdbcValueVec::Bit(v) => {
489-
push_get_data_with_default(cursor_row, col_index, v, nulls, odbc_api::Bit(0))
490-
}
500+
OdbcValueVec::Bit(v) => push_bit(cursor_row, col_index, v, nulls),
491501
OdbcValueVec::Date(v) => push_get_data(cursor_row, col_index, v, nulls),
492502
OdbcValueVec::Time(v) => push_get_data(cursor_row, col_index, v, nulls),
493503
OdbcValueVec::Timestamp(v) => push_get_data(cursor_row, col_index, v, nulls),

sqlx-core/src/odbc/value.rs

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub enum OdbcValueVec {
2020
Double(Vec<f64>),
2121

2222
// Bit type
23-
Bit(Vec<odbc_api::Bit>),
23+
Bit(Vec<bool>),
2424

2525
// Text types (inherently nullable in ODBC)
2626
Text(Vec<String>),
@@ -245,7 +245,7 @@ pub enum OdbcValueType {
245245
BigInt(i64),
246246
Real(f32),
247247
Double(f64),
248-
Bit(odbc_api::Bit),
248+
Bit(bool),
249249
Text(String),
250250
Binary(Vec<u8>),
251251
Date(odbc_api::sys::Date),
@@ -301,7 +301,10 @@ pub fn convert_any_slice_to_value_vec(slice: AnySlice<'_>) -> (OdbcValueVec, Vec
301301
AnySlice::F64(s) => handle_non_nullable_slice(s, OdbcValueVec::Double),
302302

303303
// Non-nullable other types
304-
AnySlice::Bit(s) => handle_non_nullable_slice(s, OdbcValueVec::Bit),
304+
AnySlice::Bit(s) => {
305+
let vec: Vec<bool> = s.iter().map(|bit| bit.as_bool()).collect();
306+
(OdbcValueVec::Bit(vec), vec![false; s.len()])
307+
}
305308
AnySlice::Date(s) => handle_non_nullable_slice(s, OdbcValueVec::Date),
306309
AnySlice::Time(s) => handle_non_nullable_slice(s, OdbcValueVec::Time),
307310
AnySlice::Timestamp(s) => handle_non_nullable_slice(s, OdbcValueVec::Timestamp),
@@ -320,7 +323,7 @@ pub fn convert_any_slice_to_value_vec(slice: AnySlice<'_>) -> (OdbcValueVec, Vec
320323
OdbcValueVec::Bit(
321324
values
322325
.into_iter()
323-
.map(|opt| opt.unwrap_or(odbc_api::Bit(0)))
326+
.map(|opt| opt.map_or(false, |bit| bit.as_bool()))
324327
.collect(),
325328
),
326329
nulls,
@@ -332,33 +335,17 @@ pub fn convert_any_slice_to_value_vec(slice: AnySlice<'_>) -> (OdbcValueVec, Vec
332335
let mut values = Vec::with_capacity(s.len());
333336
let mut nulls = Vec::with_capacity(s.len());
334337
for bytes_opt in s.iter() {
335-
match bytes_opt {
336-
Some(bytes) => {
337-
values.push(String::from_utf8_lossy(bytes).to_string());
338-
nulls.push(false);
339-
}
340-
None => {
341-
values.push(String::new());
342-
nulls.push(true);
343-
}
344-
}
338+
nulls.push(bytes_opt.is_none());
339+
values.push(String::from_utf8_lossy(bytes_opt.unwrap_or_default()).into_owned());
345340
}
346341
(OdbcValueVec::Text(values), nulls)
347342
}
348343
AnySlice::Binary(s) => {
349344
let mut values = Vec::with_capacity(s.len());
350345
let mut nulls = Vec::with_capacity(s.len());
351346
for bytes_opt in s.iter() {
352-
match bytes_opt {
353-
Some(bytes) => {
354-
values.push(bytes.to_vec());
355-
nulls.push(false);
356-
}
357-
None => {
358-
values.push(Vec::new());
359-
nulls.push(true);
360-
}
361-
}
347+
nulls.push(bytes_opt.is_none());
348+
values.push(bytes_opt.unwrap_or_default().to_vec());
362349
}
363350
(OdbcValueVec::Binary(values), nulls)
364351
}
@@ -444,9 +431,6 @@ macro_rules! impl_int_conversion {
444431
($vec:expr, $row_index:expr, $type:ty) => {
445432
<$type>::try_from(*$vec.get($row_index)?).ok()
446433
};
447-
($vec:expr, $row_index:expr, $type:ty, bit) => {
448-
<$type>::try_from($vec.get($row_index)?.0).ok()
449-
};
450434
($vec:expr, $row_index:expr, $type:ty, text) => {
451435
if let Some(Some(text)) = $vec.get($row_index) {
452436
text.trim().parse().ok()
@@ -465,7 +449,7 @@ fn value_vec_int<T: TryFromInt>(column_data: &ColumnData, row_index: usize) -> O
465449
OdbcValueVec::SmallInt(v) => impl_int_conversion!(v, row_index, T),
466450
OdbcValueVec::Integer(v) => impl_int_conversion!(v, row_index, T),
467451
OdbcValueVec::BigInt(v) => impl_int_conversion!(v, row_index, T),
468-
OdbcValueVec::Bit(v) => impl_int_conversion!(v, row_index, T, bit),
452+
OdbcValueVec::Bit(v) => T::try_from(*v.get(row_index)? as u8).ok(),
469453
OdbcValueVec::Text(v) => v.get(row_index).and_then(|text| text.trim().parse().ok()),
470454
_ => None,
471455
}

tests/odbc/odbc.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -440,16 +440,17 @@ async fn it_handles_binary_data() -> anyhow::Result<()> {
440440
let mut conn = new::<Odbc>().await?;
441441

442442
// Test binary data - use UTF-8 safe bytes for PostgreSQL compatibility
443-
let binary_data = b"ABCDE";
443+
let binary_data = "Héllö world! 😀".as_bytes();
444444
let stmt = conn.prepare("SELECT ? AS binary_data").await?;
445445
let row = stmt
446-
.query()
447-
.bind(&binary_data[..])
448-
.fetch_one(&mut conn)
449-
.await?;
446+
.query_as::<(Vec<u8>,)>()
447+
.bind(binary_data)
448+
.fetch_optional(&mut conn)
449+
.await
450+
.expect("query failed")
451+
.expect("row expected");
450452

451-
let result = row.try_get_raw(0)?.to_owned().decode::<Vec<u8>>();
452-
assert_eq!(result, binary_data);
453+
assert_eq!(row.0, binary_data);
453454
Ok(())
454455
}
455456

0 commit comments

Comments
 (0)