diff --git a/Cargo.toml b/Cargo.toml index 6da1bce..2d510a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "exasol" -version = "0.2.3" +version = "0.2.4" edition = "2021" authors = ["bobozaur"] description = "Exasol client library implemented in Rust." diff --git a/src/connection.rs b/src/connection.rs index 186df63..4dd7b37 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -207,10 +207,9 @@ impl Connection { /// prepared_stmt.execute(vec_data).unwrap(); /// ``` /// - /// String literals resembling a parameter can be escaped, if, for any reason, needed: - /// (Exasol doesn't really seem to like combining parameters with literals in prepared statements) + /// String literals resembling a parameter can be escaped, if needed: /// - /// ``` should_panic + /// ``` /// # use exasol::{connect, QueryResult, PreparedStatement}; /// # use exasol::error::Result; /// # use serde_json::json; diff --git a/src/query.rs b/src/query.rs index 4a9054e..ae4147e 100644 --- a/src/query.rs +++ b/src/query.rs @@ -389,6 +389,7 @@ impl PreparedStatement { /// ["a", "b", 1, "x"], /// ["c", "d", 2, "x"], /// ["e", "f", 3, "x"], + /// ["g", "h", 4, "x"] /// ] /// ); /// @@ -422,13 +423,14 @@ impl PreparedStatement { .map(|c| c.as_str()) .collect::>(); - let col_major_data = to_col_major(&col_names, data).map_err(DriverError::DataError)?; + let (col_major_data, num_rows) = + to_col_major(&col_names, data).map_err(DriverError::DataError)?; let payload = json!({ "command": "executePreparedStatement", "statementHandle": &self.statement_handle, "numColumns": num_columns, - "numRows": col_major_data.len(), + "numRows": num_rows, "columns": columns, "data": col_major_data }); diff --git a/src/row.rs b/src/row.rs index d1ffc1c..58a15df 100644 --- a/src/row.rs +++ b/src/row.rs @@ -337,17 +337,19 @@ fn col_major_seq_data() { struct SomeRow(String, String); let row = SomeRow("val1".to_owned(), "val2".to_owned()); - let row_major_data = vec![row.clone(), row.clone()]; + let row_major_data = vec![row.clone(), row.clone(), row.clone()]; let columns = &["col1", "col2"]; - let col_major_data = to_col_major(columns, row_major_data).unwrap(); + let (col_major_data, num_rows) = to_col_major(columns, row_major_data).unwrap(); assert_eq!( col_major_data, vec![ - vec!["val1".to_owned(), "val1".to_owned()], - vec!["val2".to_owned(), "val2".to_owned()] + vec!["val1".to_owned(), "val1".to_owned(), "val1".to_owned()], + vec!["val2".to_owned(), "val2".to_owned(), "val2".to_owned()] ] - ) + ); + + assert_eq!(num_rows, 3); } #[test] @@ -363,17 +365,19 @@ fn col_major_map_data() { col2: "val2".to_owned(), }; - let row_major_data = vec![row.clone(), row.clone()]; + let row_major_data = vec![row.clone(), row.clone(), row.clone()]; let columns = &["col2", "col1"]; - let col_major_data = to_col_major(columns, row_major_data).unwrap(); + let (col_major_data, num_rows) = to_col_major(columns, row_major_data).unwrap(); assert_eq!( col_major_data, vec![ - vec!["val2".to_owned(), "val2".to_owned()], - vec!["val1".to_owned(), "val1".to_owned()] + vec!["val2".to_owned(), "val2".to_owned(), "val2".to_owned()], + vec!["val1".to_owned(), "val1".to_owned(), "val1".to_owned()] ] - ) + ); + + assert_eq!(num_rows, 3); } /// Function used to transpose data from an iterator or serializable types, @@ -383,18 +387,23 @@ fn col_major_map_data() { /// Sequence-like data is processed as such, and the columns are merely used to assert length. /// Map-like data though requires columns so the data is processed in the expected order. Also, /// duplicate columns are not supported, as column values from the map get consumed. -pub(crate) fn to_col_major(columns: &[&C], data: T) -> DataResult>> +pub(crate) fn to_col_major(columns: &[&C], data: T) -> DataResult<(Vec>, usize)> where S: Serialize, C: ?Sized + Hash + Ord + Display, String: Borrow, T: IntoIterator, { + let mut num_rows = 0usize; let iter_data = data .into_iter() - .map(|s| to_seq_iter(s, columns).map(IntoIterator::into_iter)) + .map(|s| { + num_rows += 1; + to_seq_iter(s, columns).map(IntoIterator::into_iter) + }) .collect::>>>()?; - Ok(ColumnMajorIterator(iter_data).collect::>>()) + let col_major_data = ColumnMajorIterator(iter_data).collect::>>(); + Ok((col_major_data, num_rows)) } #[inline]