Skip to content

Commit a1ae1c7

Browse files
committed
refactor(odbc): enhance buffer settings handling in tests
This commit introduces a new helper function to streamline testing with different OdbcBufferSettings configurations. It updates existing tests to utilize this function, improving code clarity and maintainability while ensuring robust handling of binary and text data in ODBC connections. Additionally, the Docker command in the test script is modified for interactive mode, and the Postgres service configuration is updated to include detailed logging.
1 parent 22c8728 commit a1ae1c7

File tree

4 files changed

+86
-46
lines changed

4 files changed

+86
-46
lines changed

sqlx-core/src/odbc/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ pub fn convert_any_slice_to_value_vec(slice: AnySlice<'_>) -> (OdbcValueVec, Vec
323323
OdbcValueVec::Bit(
324324
values
325325
.into_iter()
326-
.map(|opt| opt.map_or(false, |bit| bit.as_bool()))
326+
.map(|opt| opt.is_some_and(|bit| bit.as_bool()))
327327
.collect(),
328328
),
329329
nulls,

test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ DATABASE_URL='sqlite://./tests/sqlite/sqlite.db' cargo test --features any,sqlit
1313

1414
# Copy odbc config from tests/odbc.ini to ~/.odbc.ini and run ODBC tests against Postgres
1515
cp tests/odbc.ini ~/.odbc.ini
16-
docker compose -f tests/docker-compose.yml run -p 5432:5432 --name postgres_16_no_ssl postgres_16_no_ssl
16+
docker compose -f tests/docker-compose.yml run -p 5432:5432 --name postgres_16_no_ssl -it postgres_16_no_ssl
1717
DATABASE_URL='DSN=SNOWFLAKE' cargo test --no-default-features --features any,odbc,all-types,macros,runtime-tokio-rustls

tests/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ services:
208208
volumes:
209209
- "./postgres/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
210210
command: >
211-
-c ssl=off
211+
-c ssl=off -c log_statement=all
212212
#
213213
# Microsoft SQL Server (MSSQL)
214214
# https://hub.docker.com/_/microsoft-mssql-server

tests/odbc/odbc.rs

Lines changed: 83 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use futures::TryStreamExt;
2-
use sqlx_oldapi::odbc::{Odbc, OdbcConnectOptions, OdbcConnection};
2+
use sqlx_oldapi::odbc::{Odbc, OdbcBufferSettings, OdbcConnectOptions, OdbcConnection};
33
use sqlx_oldapi::Column;
44
use sqlx_oldapi::Connection;
55
use sqlx_oldapi::Executor;
@@ -435,42 +435,89 @@ async fn it_handles_large_strings() -> anyhow::Result<()> {
435435
Ok(())
436436
}
437437

438+
async fn test_with_buffer_settings<F, T>(
439+
buffer_settings: &[OdbcBufferSettings],
440+
test_fn: F,
441+
) -> anyhow::Result<()>
442+
where
443+
F: Fn(OdbcConnection) -> T,
444+
T: std::future::Future<Output = anyhow::Result<()>>,
445+
{
446+
use sqlx_oldapi::odbc::OdbcConnectOptions;
447+
448+
for &buf_settings in buffer_settings {
449+
let database_url = std::env::var("DATABASE_URL").unwrap();
450+
let mut opts = OdbcConnectOptions::from_str(&database_url)?;
451+
opts.buffer_settings(buf_settings);
452+
453+
let conn = OdbcConnection::connect_with(&opts).await?;
454+
test_fn(conn).await?;
455+
}
456+
Ok(())
457+
}
458+
438459
#[tokio::test]
439460
async fn it_handles_binary_data() -> anyhow::Result<()> {
440-
let mut conn = new::<Odbc>().await?;
441-
442461
// Test binary data - use UTF-8 safe bytes for PostgreSQL compatibility
443462
let binary_data = "Héllö world! 😀".as_bytes();
444-
let stmt = conn.prepare("SELECT ? AS binary_data").await?;
445-
let row = stmt
446-
.query_as::<(Vec<u8>,)>()
447-
.bind(binary_data)
448-
.fetch_optional(&mut conn)
449-
.await
450-
.expect("query failed")
451-
.expect("row expected");
452463

453-
assert_eq!(row.0, binary_data);
454-
Ok(())
464+
let buffer_settings = [
465+
OdbcBufferSettings {
466+
batch_size: 1,
467+
max_column_size: None,
468+
},
469+
OdbcBufferSettings {
470+
batch_size: 1,
471+
max_column_size: Some(450),
472+
},
473+
];
474+
475+
test_with_buffer_settings(&buffer_settings, |mut conn| async move {
476+
let stmt = conn.prepare("SELECT ? AS binary_data").await?;
477+
let row = stmt
478+
.query_as::<(Vec<u8>,)>()
479+
.bind(binary_data)
480+
.fetch_optional(&mut conn)
481+
.await
482+
.expect("query failed")
483+
.expect("row expected");
484+
485+
assert_eq!(row.0, binary_data);
486+
Ok(())
487+
})
488+
.await
455489
}
456490

457491
#[tokio::test]
458492
async fn it_handles_text_as_utf8_binary() -> anyhow::Result<()> {
459-
let mut conn = new::<Odbc>().await?;
460-
461493
// Test binary data - use UTF-8 safe bytes for PostgreSQL compatibility
462494
let text = "Héllö world! 😀";
463-
let stmt = conn.prepare("SELECT ? AS text_data").await?;
464-
let row = stmt
465-
.query_as::<(Vec<u8>,)>()
466-
.bind(text)
467-
.fetch_optional(&mut conn)
468-
.await
469-
.expect("query failed")
470-
.expect("row expected");
471495

472-
assert_eq!(row.0, text.as_bytes());
473-
Ok(())
496+
let buffer_settings = [
497+
OdbcBufferSettings {
498+
batch_size: 1,
499+
max_column_size: None,
500+
},
501+
OdbcBufferSettings {
502+
batch_size: 1,
503+
max_column_size: Some(450),
504+
},
505+
];
506+
507+
test_with_buffer_settings(&buffer_settings, |mut conn| async move {
508+
let stmt = conn.prepare("SELECT ? AS text_data").await?;
509+
let row = stmt
510+
.query_as::<(Vec<u8>,)>()
511+
.bind(text)
512+
.fetch_optional(&mut conn)
513+
.await
514+
.expect("query failed")
515+
.expect("row expected");
516+
517+
assert_eq!(row.0, text.as_bytes());
518+
Ok(())
519+
})
520+
.await
474521
}
475522

476523
#[tokio::test]
@@ -1058,20 +1105,9 @@ async fn it_handles_prepared_statement_with_wrong_parameters() -> anyhow::Result
10581105

10591106
#[tokio::test]
10601107
async fn it_works_with_buffered_and_unbuffered_mode() -> anyhow::Result<()> {
1061-
use sqlx_oldapi::odbc::{OdbcBufferSettings, OdbcConnectOptions};
1062-
1063-
// Create connection with unbuffered settings
1064-
let database_url = std::env::var("DATABASE_URL").unwrap();
1065-
let mut opts = OdbcConnectOptions::from_str(&database_url)?;
1066-
10671108
let count = 450;
10681109

1069-
let select = (0..count)
1070-
.map(|i| format!("SELECT {i} AS n, '{}' as aas", "a".repeat(i)))
1071-
.collect::<Vec<_>>()
1072-
.join(" UNION ALL ");
1073-
1074-
for buf_settings in [
1110+
let buffer_settings = [
10751111
OdbcBufferSettings {
10761112
batch_size: 1,
10771113
max_column_size: None,
@@ -1092,14 +1128,17 @@ async fn it_works_with_buffered_and_unbuffered_mode() -> anyhow::Result<()> {
10921128
batch_size: 10000,
10931129
max_column_size: Some(450),
10941130
},
1095-
] {
1096-
opts.buffer_settings(buf_settings);
1131+
];
10971132

1098-
let mut conn = OdbcConnection::connect_with(&opts).await?;
1133+
test_with_buffer_settings(&buffer_settings, |mut conn| async move {
1134+
let select = (0..count)
1135+
.map(|i| format!("SELECT {i} AS n, '{}' as aas", "a".repeat(i)))
1136+
.collect::<Vec<_>>()
1137+
.join(" UNION ALL ");
10991138

11001139
// Test that unbuffered mode works correctly
11011140
let s = conn
1102-
.prepare(&select)
1141+
.prepare(select.as_str())
11031142
.await?
11041143
.query()
11051144
.fetch_all(&mut conn)
@@ -1122,6 +1161,7 @@ async fn it_works_with_buffered_and_unbuffered_mode() -> anyhow::Result<()> {
11221161
.expect("SELECT aas should be a string");
11231162
assert_eq!(aas, "a".repeat(i));
11241163
}
1125-
}
1126-
Ok(())
1164+
Ok(())
1165+
})
1166+
.await
11271167
}

0 commit comments

Comments
 (0)