Skip to content
This repository has been archived by the owner on Sep 3, 2023. It is now read-only.

Commit

Permalink
Fixed tests and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bobozaur committed Apr 21, 2022
1 parent cc4db17 commit 018170d
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 51 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/target
Cargo.lock
.idea
env_setup.ps1
env_setup.ps1
test_data.csv
10 changes: 3 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,9 @@ __rustls = {version = "0.20.4", optional = true , package = "rustls"}
flate2 = { version = "1.0.22", optional = true }

[features]
native-tls-basic = ["rcgen", "__native_tls", "tungstenite/native-tls"]
rustls_dangerous = ["__rustls/dangerous_configuration"]
rustls = ["rcgen", "__rustls", "tungstenite/__rustls-tls"]
native-tls-basic = ["rcgen", "__native_tls", "tungstenite/native-tls"] # meant for internal use
rustls = ["rcgen", "__rustls", "tungstenite/__rustls-tls"] # meant for internal use
native-tls = ["tungstenite/native-tls", "native-tls-basic"]
native-tls-vendored = ["tungstenite/native-tls-vendored", "native-tls-basic"]
rustls-tls-webpki-roots = ["tungstenite/rustls-tls-webpki-roots", "rustls"]
rustls-tls-native-roots = ["tungstenite/rustls-tls-native-roots", "rustls"]

[dev-dependencies]
exasol = { path = ".", features = ["native-tls", "rustls-tls-webpki-roots", "rustls_dangerous", "flate2"] }
rustls-tls-native-roots = ["tungstenite/rustls-tls-native-roots", "rustls"]
5 changes: 2 additions & 3 deletions src/con_opts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ type ConResult<T> = std::result::Result<T, ConnectionError>;
/// autocommit: true
///
/// ```
/// use exasol::ConOpts;
/// use exasol::{ConOpts, LoginKind, Credentials};
///
/// let mut opts = ConOpts::new(); // calls default() under the hood
/// opts.set_dsn("test_dsn");
/// opts.set_user("test_user");
/// opts.set_password("test_password");
/// opts.set_login_kind(LoginKind::Credentials(Credentials::new("test_user", "test_password")));
/// opts.set_schema(Some("test_schema"));
/// opts.set_autocommit(false);
/// ```
Expand Down
2 changes: 1 addition & 1 deletion src/connection/http_transport/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crossbeam::channel::{IntoIter, Receiver};
use std::io::Read;

/// HTTP Transport reader that can be used
/// in custom closures in [Connection::export_to_closure].
/// in custom closures in [Connection::export_to_closure](crate::Connection).
pub struct ExaReader {
receiver: IntoIter<Vec<u8>>,
buf: Vec<u8>,
Expand Down
2 changes: 1 addition & 1 deletion src/connection/http_transport/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crossbeam::channel::Sender;
use std::io::{Error, ErrorKind, Write};

/// HTTP Transport writer that can be used
/// in custom closures in [Connection::import_from_closure].
/// in custom closures in [Connection::import_from_closure](crate::Connection).
pub struct ExaWriter {
sender: Sender<Vec<u8>>,
buf: Vec<u8>,
Expand Down
36 changes: 18 additions & 18 deletions src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ where
///
/// As a best practice, though, put some effort into manually closing the results and
/// prepared statements created so as not to bloat the connection.
#[doc(hidden)]
pub struct Connection {
driver_attr: DriverAttributes,
ws: ExaWebSocket,
Expand Down Expand Up @@ -146,7 +145,7 @@ impl Connection {
/// an error is returned.
/// ```
/// use std::env;
/// use exasol::{ConOpts, Connection};
/// use exasol::*;
///
/// let dsn = env::var("EXA_DSN").unwrap();
/// let schema = env::var("EXA_SCHEMA").unwrap();
Expand All @@ -155,8 +154,7 @@ impl Connection {
///
/// let mut opts = ConOpts::new();
/// opts.set_dsn(dsn);
/// opts.set_user(user);
/// opts.set_password(password);
/// opts.set_login_kind(LoginKind::Credentials(Credentials::new(user, password)));
/// opts.set_schema(None::<String>);
///
/// let mut exa_con = Connection::new(opts).unwrap();
Expand Down Expand Up @@ -223,7 +221,7 @@ impl Connection {
self.driver_attr.fetch_size
}

/// Sets the fetch size in bytes when retrieving [ResultSet](crate::query::ResultSet) chunks
/// Sets the fetch size in bytes when retrieving [ResultSet] chunks.
///
/// ```
/// # use exasol::connect;
Expand Down Expand Up @@ -261,8 +259,7 @@ impl Connection {
self.driver_attr.lowercase_columns
}

/// Sets whether the [ResultSet](crate::query::ResultSet) [Column](crate::response::Column)
/// names will be implicitly cast to lowercase
/// Sets whether the [ResultSet] [Column] names will be implicitly cast to lowercase.
///
/// ```
/// # use exasol::connect;
Expand Down Expand Up @@ -513,10 +510,7 @@ impl Connection {
/// #
/// let mut exa_con = connect(&dsn, &schema, &user, &password).unwrap();
/// let mut result = exa_con.execute("SELECT '1', '2', '3' UNION ALL SELECT '4', '5', '6'").unwrap();
/// let data: Vec<Vec<String>> = exa_con.iter_result(&mut result).unwrap();
///
/// let mut result2 = exa_con.execute("SELECT '1', '2', '3' UNION ALL SELECT '4', '5', '6'").unwrap();
/// let data2 = exa_con.iter_result(&mut result2).collect::<Result<Vec<Vec<String>>>>().unwrap();
/// let data = exa_con.iter_result(&mut result).collect::<Result<Vec<Vec<String>>>>().unwrap();
/// assert_eq!(data.len(), 2);
/// ```
pub fn iter_result<'a, T: DeserializeOwned>(
Expand All @@ -531,7 +525,7 @@ impl Connection {

/// HTTP Transport export with a closure that deserializes rows into a `Vec`.
/// ```
/// # use exasol::{connect, QueryResult};
/// # use exasol::{connect, ExportOpts, QueryResult};
/// # use exasol::error::Result;
/// # use serde_json::Value;
/// # use std::env;
Expand All @@ -541,7 +535,9 @@ impl Connection {
/// # let user = env::var("EXA_USER").unwrap();
/// # let password = env::var("EXA_PASSWORD").unwrap();
/// let mut exa_con = connect(&dsn, &schema, &user, &password).unwrap();
/// let result = exa_con.export_to_vec("SELECT * FROM EXA_RUST_TEST LIMIT 1000", None).unwrap();
/// let mut opts = ExportOpts::new();
/// opts.set_query("SELECT 'a', 'b', 1 UNION ALL SELECT 'c', 'd', 2;");
/// let result = exa_con.export_to_vec(opts).unwrap();
///
/// result.into_iter().take(5).for_each(|v: (String, String, u32)| println!("{:?}", v))
/// ```
Expand Down Expand Up @@ -609,7 +605,7 @@ impl Connection {
}

/// HTTP Transport export implementation that can take any closure and an instance
/// of [ExportOpts]. The closure must make use of a reader implementing [Read].
/// of [ExportOpts]. The closure must make use of a reader implementing [Read](std::io::Read).
/// For examples check [Connection::export_to_file] and [Connection::export_to_vec].
pub fn export_to_closure<F, T>(&mut self, callback: F, opts: ExportOpts) -> Result<T>
where
Expand All @@ -626,7 +622,7 @@ impl Connection {
/// HTTP Transport import with a closure that serializes rows from a type implementing
/// [IntoIterator].
/// ```
/// # use exasol::{connect, QueryResult};
/// # use exasol::*;
/// # use exasol::error::Result;
/// # use serde_json::Value;
/// # use std::env;
Expand All @@ -636,8 +632,12 @@ impl Connection {
/// # let user = env::var("EXA_USER").unwrap();
/// # let password = env::var("EXA_PASSWORD").unwrap();
/// let mut exa_con = connect(&dsn, &schema, &user, &password).unwrap();
/// let result: Vec<(String, String, u32)> = exa_con.export_to_vec("SELECT * FROM EXA_RUST_TEST LIMIT 1000", None).unwrap();
/// exa_con.import_from_iter("EXA_RUST_TEST", result, None).unwrap();
/// let mut export_opts = ExportOpts::new();
/// export_opts.set_query("SELECT 'a', 'b', 1 UNION ALL SELECT 'c', 'd', 2;");
/// let result: Vec<(String, String, u32)> = exa_con.export_to_vec(export_opts).unwrap();
/// let mut import_opts = ImportOpts::new();
/// import_opts.set_table_name("EXA_RUST_TEST");
/// exa_con.import_from_iter(result, import_opts).unwrap();
/// ```
pub fn import_from_iter<I, T>(&mut self, iter: I, mut opts: ImportOpts) -> Result<()>
where
Expand Down Expand Up @@ -708,7 +708,7 @@ impl Connection {
}

/// HTTP Transport import implementation that can take any closure and an instance
/// of [ImportOpts]. The closure must make use of a writer implementing [Write].
/// of [ImportOpts]. The closure must make use of a writer implementing [Write](std::io::Write).
/// For examples check [Connection::import_from_file] and [Connection::import_from_iter].
pub fn import_from_closure<F, T>(&mut self, callback: F, opts: ImportOpts) -> Result<T>
where
Expand Down
6 changes: 3 additions & 3 deletions src/connection/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,16 +441,16 @@ impl serde::Serialize for ColumnIteratorAdapter {
/// SomeVar4(SomeRow2)
/// }
///
/// let data: Vec<SomeRow1> = exa_con.fetch(&mut result1, 1).unwrap();
/// let data: Vec<SomeRow1> = exa_con.iter_result(&mut result1).take(1).collect::<Result<_>>().unwrap();
/// // Due to the unsupported external tagging
/// // deserialization this will error out:
/// // let data: Vec<Val1> = exa_con.fetch(&mut result1, 1).unwrap();
///
/// // But internal tagging works
/// let data: Vec<SomeRow2> = exa_con.fetch(&mut result2, 1).unwrap();
/// let data: Vec<SomeRow2> = exa_con.iter_result(&mut result2).take(1).collect::<Result<_>>().unwrap();
///
/// // And so does untagged deserialization
/// let data: Vec<SomeRow3> = exa_con.fetch(&mut result3, 1).unwrap();
/// let data: Vec<SomeRow3> = exa_con.iter_result(&mut result3).take(1).collect::<Result<_>>().unwrap();
/// ```
pub fn deserialize_as_seq<'de, D, F>(deserializer: D) -> std::result::Result<F, D::Error>
where
Expand Down
20 changes: 9 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
//!
//! // Retrieving data associated with the result set.
//! // A Vec of rows is returned, and the row type in this case will be Vec<String>.
//! let data: Vec<Vec<String>> = exa_con.iter_result(&mut result).unwrap();
//! let data = exa_con.iter_result(&mut result).collect::<Result<Vec<Vec<String>>>>().unwrap();
//! ```
//!
//! The [Connection::iter_result] method returns a lazy iterator over a result's rows. Only a given
Expand Down Expand Up @@ -66,7 +66,7 @@
//! // Only enough calls necessary to retrieve 100 rows will be made to the database.
//! // Any leftover data in the chunk will still be present in the ResultSet buffer.
//! // and can be used in later retrievals.
//! let data: Vec<(String, String, u16)> = exa_con.fetch(&mut result, 100).unwrap();
//! let data: Vec<(String, String, u16)> = exa_con.iter_result(&mut result).take(100).collect::<Result<_>>().unwrap();
//! // do stuff with data
//!
//! counter += 1;
Expand Down Expand Up @@ -111,13 +111,13 @@
//! let mut result = exa_con.execute("SELECT 1, 2 UNION ALL SELECT 1, 2;").unwrap();
//!
//! // Change the expected row type with the turbofish notation
//! let mut data = exa_con.fetch::<[u8; 2]>(&mut result, 1).unwrap();
//! let mut data: Vec<[u8; 2]> = exa_con.iter_result(&mut result).collect::<Result<_>>().unwrap();
//! let row1 = data[0];
//!
//! // You can also rely on type inference.
//! // Nothing stops you from changing row types
//! // on the same result set.
//! let mut data: Vec<Vec<u8>> = exa_con.fetch(&mut result, 1).unwrap();;
//! let mut data: Vec<Vec<u8>> = exa_con.iter_result(&mut result).collect::<Result<_>>().unwrap();;
//! let row2 = data.pop();
//!
//! let mut result = exa_con.execute("SELECT 1 as col1, 2 as col2, 3 as col3 \
Expand All @@ -131,7 +131,7 @@
//! col3: u8,
//! }
//!
//! let data = exa_con.iter_result::<Test>(&mut result).unwrap();
//! let data = exa_con.iter_result::<Test>(&mut result).collect::<Result<Vec<_>>>().unwrap();
//! for row in data {
//! // do stuff with row
//! }
Expand Down Expand Up @@ -184,7 +184,7 @@
//! The [Connection] struct can be directly instantiated with the use of [ConOpts].
//!
//! ```
//! use exasol::{ConOpts, Connection};
//! use exasol::*;
//! use std::env;
//!
//! let dsn = env::var("EXA_DSN").unwrap();
Expand All @@ -195,8 +195,7 @@
//! // Only providing fields for which we want custom values
//! let mut opts = ConOpts::new();
//! opts.set_dsn(dsn);
//! opts.set_user(user);
//! opts.set_password(password);
//! opts.set_login_kind(LoginKind::Credentials(Credentials::new(user, password)));
//! opts.set_schema(Some(schema));
//!
//! let exa_con = Connection::new(opts).unwrap();
Expand All @@ -216,7 +215,7 @@
//! Attempting to use these methods without their respective features enabled results in panics.
//!
//! ``` should_panic
//! # use exasol::{ConOpts, Connection};
//! # use exasol::*;
//! # use std::env;
//! #
//! # let dsn = env::var("EXA_DSN").unwrap();
Expand All @@ -227,8 +226,7 @@
//! let mut opts = ConOpts::new();
//!
//! opts.set_dsn(dsn);
//! opts.set_user(user);
//! opts.set_password(password);
//! opts.set_login_kind(LoginKind::Credentials(Credentials::new(user, password)));
//! opts.set_schema(Some(schema));
//!
//! opts.set_encryption(true);
Expand Down
60 changes: 60 additions & 0 deletions tests/basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//! Basic IMPORT/EXPORT tests.
#[cfg(test)]
#[allow(unused)]
mod tests {
use exasol::error::Result;
use exasol::*;
use std::env;

#[test]
#[allow(unused)]
fn http_transport_tests() {
let dsn = env::var("EXA_DSN").unwrap();
let schema = env::var("EXA_SCHEMA").unwrap();
let user = env::var("EXA_USER").unwrap();
let password = env::var("EXA_PASSWORD").unwrap();

let mut opts = ConOpts::new();
opts.set_login_kind(LoginKind::Credentials(Credentials::new(user, password)));
opts.set_dsn(dsn);

let mut exa_con = Connection::new(opts).unwrap();
let mut result = exa_con
.execute("SELECT * FROM RUST.EXA_RUST_TEST LIMIT 2001;")
.unwrap();

let rows: Vec<(String, String, u16)> = exa_con
.iter_result(&mut result)
.collect::<Result<_>>()
.unwrap();

let mut http_opts = ExportOpts::new();
http_opts.set_encryption(false);
http_opts.set_compression(false);
http_opts.set_query("SELECT * FROM RUST.EXA_RUST_TEST LIMIT 2001");
let data: Vec<(String, String, u16)> = exa_con.export_to_vec(http_opts).unwrap();

let mut http_opts = ImportOpts::new();
http_opts.set_encryption(false);
http_opts.set_compression(false);
http_opts.set_table_name("RUST.EXA_RUST_TEST");
exa_con.import_from_iter(data, http_opts).unwrap();

let mut http_opts = ExportOpts::new();
http_opts.set_encryption(false);
http_opts.set_compression(false);
http_opts.set_column_separator(b'|');
http_opts.set_query("SELECT * FROM RUST.EXA_RUST_TEST LIMIT 2001");
exa_con.export_to_file("test_data.csv", http_opts).unwrap();

let mut http_opts = ImportOpts::new();
http_opts.set_encryption(false);
http_opts.set_compression(false);
http_opts.set_column_separator(b'|');
http_opts.set_table_name("RUST.EXA_RUST_TEST");
exa_con
.import_from_file("test_data.csv", http_opts)
.unwrap();
}
}
32 changes: 30 additions & 2 deletions tests/encrypted_compression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! We'll also include a fingerprint in the DSN
#[cfg(test)]
#[cfg(all(feature = "native-tls-basic", feature = "flate2"))]
#[allow(unused)]
mod tests {
use __native_tls::TlsConnector;
Expand All @@ -19,10 +20,11 @@ mod tests {
let password = env::var("EXA_PASSWORD").unwrap();

let mut opts = ConOpts::new();
opts.set_user(user);
opts.set_password(password);
opts.set_login_kind(LoginKind::Credentials(Credentials::new(user, password)));
opts.set_dsn(dsn);
opts.set_schema(Some(schema));
opts.set_compression(true);
println!("Default encryption with flags: {}", opts.encryption());

let mut config = TlsConnector::builder()
.danger_accept_invalid_certs(true)
Expand All @@ -46,5 +48,31 @@ mod tests {
http_opts.set_compression(true);
http_opts.set_table_name("RUST.EXA_RUST_TEST");
exa_con.import_from_iter(data, http_opts).unwrap();

let mut http_opts = ExportOpts::new();
http_opts.set_encryption(false);
http_opts.set_compression(true);
http_opts.set_query("SELECT * FROM RUST.EXA_RUST_TEST LIMIT 2001");
let data: Vec<(String, String, u16)> = exa_con.export_to_vec(http_opts).unwrap();

let mut http_opts = ImportOpts::new();
http_opts.set_encryption(false);
http_opts.set_compression(true);
http_opts.set_table_name("RUST.EXA_RUST_TEST");
exa_con.import_from_iter(data, http_opts).unwrap();

let mut http_opts = ExportOpts::new();
http_opts.set_encryption(true);
http_opts.set_compression(true);
http_opts.set_query("SELECT * FROM RUST.EXA_RUST_TEST LIMIT 2001");
exa_con.export_to_file("test_data.csv", http_opts).unwrap();

let mut http_opts = ImportOpts::new();
http_opts.set_encryption(true);
http_opts.set_compression(true);
http_opts.set_table_name("RUST.EXA_RUST_TEST");
exa_con
.import_from_file("test_data.csv", http_opts)
.unwrap();
}
}
Loading

0 comments on commit 018170d

Please sign in to comment.