Skip to content

Commit

Permalink
introduce derive feature
Browse files Browse the repository at this point in the history
  • Loading branch information
pacman82 committed Apr 28, 2024
1 parent 6f5a5de commit 100fc7d
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 23 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ jobs:

- name: Test
run: |
cargo test --release -- --skip postgresql --skip maria_db
cargo test --features narrow --release -- --skip postgresql --skip maria_db
cargo test --release -- --skip postgresql --skip maria_db --features derive
cargo test --features narrow,derive --release -- --skip postgresql --skip maria_db
win32:
name: Build Win32
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ WORKDIR /workspace
COPY . .
RUN cp odbcsv/tests/list-drivers-linux.txt odbcsv/tests/list-drivers.txt

CMD ~/.cargo/bin/cargo test --release --features narrow
CMD ~/.cargo/bin/cargo test --release --features narrow,derive
5 changes: 0 additions & 5 deletions derive/tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,3 @@ struct MyRow {
a: i64,
b: VarCharArray<50>
}

#[test]
fn fetch_rowise_derive_integration() {

}
4 changes: 4 additions & 0 deletions odbc-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ pub use self::{
/// crate.
pub use odbc_sys as sys;
pub use widestring::{U16Str, U16String};

// Reexport fetch if derive feature is enabled
#[cfg(feature="derive")]
pub use odbc_api_derive::Fetch;
37 changes: 35 additions & 2 deletions odbc-api/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use lazy_static::lazy_static;
use odbc_api::{
buffers,
handles::{CDataMut, Statement, StatementRef},
Connection, ConnectionOptions, Cursor, Environment, Error, RowSetBuffer, TruncationInfo,
Connection, ConnectionOptions, Cursor, Environment, Error, RowSetBuffer,
TruncationInfo,
};

// Rust by default executes tests in parallel. Yet only one environment is allowed at a time.
Expand All @@ -19,6 +20,8 @@ pub struct Given<'a> {
table_name: &'a str,
column_types: &'a [&'a str],
column_names: &'a [&'a str],
/// String representation of values to be inserted into table in column wise order.
values: &'a [&'a [Option<&'a str>]],
}

impl<'a> Given<'a> {
Expand All @@ -27,6 +30,7 @@ impl<'a> Given<'a> {
table_name,
column_types: &[],
column_names: &["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"],
values: &[],
}
}

Expand All @@ -40,11 +44,40 @@ impl<'a> Given<'a> {
self
}

/// String representation of values to be filled into test table in column wise order.
pub fn values_by_column(&mut self, values: &'a [&'a [Option<&'a str>]]) -> &mut Self {
self.values = values;
self
}

pub fn build(
&self,
profile: &Profile,
) -> Result<(Connection<'static>, Table<'a>), odbc_api::Error> {
profile.create_table(self.table_name, self.column_types, self.column_names)
let (conn, table) =
profile.create_table(self.table_name, self.column_types, self.column_names)?;
if !self.values.is_empty() {
let num_rows = self.values[0].len();
let max_str_len = self.values.iter().map(|vals| {
vals.iter()
.map(|text| text.unwrap_or("").len())
.max()
.expect("Columns may not be empty")
});
let mut inserter = conn
.prepare(&table.sql_insert())?
.into_text_inserter(num_rows, max_str_len)?;
inserter.set_num_rows(num_rows);
for r in 0..num_rows {
for c in 0..self.values.len() {
inserter
.column_mut(c)
.set_cell(r, self.values[c][r].map(|text| text.as_bytes()))
}
}
inserter.execute()?;
}
Ok((conn, table))
}
}

Expand Down
61 changes: 48 additions & 13 deletions odbc-api/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use odbc_api::{
DataType, Error, InOut, IntoParameter, Narrow, Nullability, Nullable, Out, Preallocated,
ResultSetMetadata, RowSetBuffer, TruncationInfo, U16Str, U16String,
};
#[cfg(feature="derive")]
use odbc_api::Fetch;

use std::{
ffi::CString,
io::{self, Write},
Expand Down Expand Up @@ -4644,23 +4647,17 @@ async fn async_bulk_fetch(profile: &Profile) {
#[test_case(MARIADB; "Maria DB")]
#[test_case(SQLITE_3; "SQLite 3")]
#[test_case(POSTGRES; "PostgreSQL")]
fn row_wise_bulk_query(profile: &Profile) {
fn row_wise_bulk_query_using_tuple(profile: &Profile) {
// Given a cursor
let table_name = table_name!();
let (conn, table) = Given::new(&table_name)
.column_types(&["INTEGER", "VARCHAR(50)"])
.values_by_column(&[
&[Some("42"), Some("5")],
&[Some("Hello, World!"), Some("Hallo, Welt!")],
])
.build(profile)
.unwrap();
conn.execute(
&table.sql_insert(),
(&42.into_parameter(), &"Hello, World!".into_parameter()),
)
.unwrap();
conn.execute(
&table.sql_insert(),
(&5.into_parameter(), &"Hallo, Welt!".into_parameter()),
)
.unwrap();
let cursor = conn
.execute(&table.sql_all_ordered_by_id(), ())
.unwrap()
Expand All @@ -4679,6 +4676,45 @@ fn row_wise_bulk_query(profile: &Profile) {
assert_eq!("Hallo, Welt!", batch[1].1.as_str().unwrap().unwrap());
}

#[cfg(feature="derive")]
#[test_case(MSSQL; "Microsoft SQL Server")]
#[test_case(MARIADB; "Maria DB")]
#[test_case(SQLITE_3; "SQLite 3")]
#[test_case(POSTGRES; "PostgreSQL")]
fn row_wise_bulk_query_using_custom_row(profile: &Profile) {
// Given a cursor
let table_name = table_name!();
let (conn, table) = Given::new(&table_name)
.column_types(&["INTEGER", "VARCHAR(50)"])
.values_by_column(&[
&[Some("42"), Some("5")],
&[Some("Hello, World!"), Some("Hallo, Welt!")],
])
.build(profile)
.unwrap();
let cursor = conn
.execute(&table.sql_all_ordered_by_id(), ())
.unwrap()
.unwrap();

// When
#[derive(Clone, Copy, Default, Fetch)]
struct MyRow {
a: i32,
b: VarCharArray<50>,
}
let row_set_buffer = RowVec::<MyRow>::new(10);
let mut block_cursor = cursor.bind_buffer(row_set_buffer).unwrap();
let batch = block_cursor.fetch().unwrap().unwrap();

// Then
assert_eq!(2, batch.num_rows());
assert_eq!(42, batch[0].a);
assert_eq!("Hello, World!", batch[0].b.as_str().unwrap().unwrap());
assert_eq!(5, batch[1].a);
assert_eq!("Hallo, Welt!", batch[1].b.as_str().unwrap().unwrap());
}

#[test_case(MSSQL; "Microsoft SQL Server")]
#[test_case(MARIADB; "Maria DB")]
#[test_case(SQLITE_3; "SQLite 3")]
Expand All @@ -4688,10 +4724,9 @@ fn truncation_in_row_wise_bulk_buffer(profile: &Profile) {
let table_name = table_name!();
let (conn, table) = Given::new(&table_name)
.column_types(&["VARCHAR(50)"])
.values_by_column(&[&[Some("Hello, World!")]])
.build(profile)
.unwrap();
conn.execute(&table.sql_insert(), &"Hello, World!".into_parameter())
.unwrap();
let cursor = conn
.execute(&table.sql_all_ordered_by_id(), ())
.unwrap()
Expand Down

0 comments on commit 100fc7d

Please sign in to comment.