Make tests return Result

This commit is contained in:
gwenn 2020-11-05 22:14:00 +01:00
parent 65c38bf813
commit da94f8eba6
30 changed files with 1040 additions and 1179 deletions

View File

@ -310,96 +310,84 @@ impl Drop for Backup<'_, '_> {
#[cfg(test)]
mod test {
use super::Backup;
use crate::{Connection, DatabaseName};
use crate::{Connection, DatabaseName, Result};
use std::time::Duration;
#[test]
fn test_backup() {
let src = Connection::open_in_memory().unwrap();
fn test_backup() -> Result<()> {
let src = Connection::open_in_memory()?;
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER);
INSERT INTO foo VALUES(42);
END;";
src.execute_batch(sql).unwrap();
src.execute_batch(sql)?;
let mut dst = Connection::open_in_memory().unwrap();
let mut dst = Connection::open_in_memory()?;
{
let backup = Backup::new(&src, &mut dst).unwrap();
backup.step(-1).unwrap();
let backup = Backup::new(&src, &mut dst)?;
backup.step(-1)?;
}
let the_answer: i64 = dst
.query_row("SELECT x FROM foo", [], |r| r.get(0))
.unwrap();
let the_answer: i64 = dst.query_row("SELECT x FROM foo", [], |r| r.get(0))?;
assert_eq!(42, the_answer);
src.execute_batch("INSERT INTO foo VALUES(43)").unwrap();
src.execute_batch("INSERT INTO foo VALUES(43)")?;
{
let backup = Backup::new(&src, &mut dst).unwrap();
backup
.run_to_completion(5, Duration::from_millis(250), None)
.unwrap();
let backup = Backup::new(&src, &mut dst)?;
backup.run_to_completion(5, Duration::from_millis(250), None)?;
}
let the_answer: i64 = dst
.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap();
let the_answer: i64 = dst.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
assert_eq!(42 + 43, the_answer);
Ok(())
}
#[test]
fn test_backup_temp() {
let src = Connection::open_in_memory().unwrap();
fn test_backup_temp() -> Result<()> {
let src = Connection::open_in_memory()?;
let sql = "BEGIN;
CREATE TEMPORARY TABLE foo(x INTEGER);
INSERT INTO foo VALUES(42);
END;";
src.execute_batch(sql).unwrap();
src.execute_batch(sql)?;
let mut dst = Connection::open_in_memory().unwrap();
let mut dst = Connection::open_in_memory()?;
{
let backup =
Backup::new_with_names(&src, DatabaseName::Temp, &mut dst, DatabaseName::Main)
.unwrap();
backup.step(-1).unwrap();
Backup::new_with_names(&src, DatabaseName::Temp, &mut dst, DatabaseName::Main)?;
backup.step(-1)?;
}
let the_answer: i64 = dst
.query_row("SELECT x FROM foo", [], |r| r.get(0))
.unwrap();
let the_answer: i64 = dst.query_row("SELECT x FROM foo", [], |r| r.get(0))?;
assert_eq!(42, the_answer);
src.execute_batch("INSERT INTO foo VALUES(43)").unwrap();
src.execute_batch("INSERT INTO foo VALUES(43)")?;
{
let backup =
Backup::new_with_names(&src, DatabaseName::Temp, &mut dst, DatabaseName::Main)
.unwrap();
backup
.run_to_completion(5, Duration::from_millis(250), None)
.unwrap();
Backup::new_with_names(&src, DatabaseName::Temp, &mut dst, DatabaseName::Main)?;
backup.run_to_completion(5, Duration::from_millis(250), None)?;
}
let the_answer: i64 = dst
.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap();
let the_answer: i64 = dst.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
assert_eq!(42 + 43, the_answer);
Ok(())
}
#[test]
fn test_backup_attached() {
let src = Connection::open_in_memory().unwrap();
fn test_backup_attached() -> Result<()> {
let src = Connection::open_in_memory()?;
let sql = "ATTACH DATABASE ':memory:' AS my_attached;
BEGIN;
CREATE TABLE my_attached.foo(x INTEGER);
INSERT INTO my_attached.foo VALUES(42);
END;";
src.execute_batch(sql).unwrap();
src.execute_batch(sql)?;
let mut dst = Connection::open_in_memory().unwrap();
let mut dst = Connection::open_in_memory()?;
{
let backup = Backup::new_with_names(
@ -407,17 +395,14 @@ mod test {
DatabaseName::Attached("my_attached"),
&mut dst,
DatabaseName::Main,
)
.unwrap();
backup.step(-1).unwrap();
)?;
backup.step(-1)?;
}
let the_answer: i64 = dst
.query_row("SELECT x FROM foo", [], |r| r.get(0))
.unwrap();
let the_answer: i64 = dst.query_row("SELECT x FROM foo", [], |r| r.get(0))?;
assert_eq!(42, the_answer);
src.execute_batch("INSERT INTO foo VALUES(43)").unwrap();
src.execute_batch("INSERT INTO foo VALUES(43)")?;
{
let backup = Backup::new_with_names(
@ -425,16 +410,12 @@ mod test {
DatabaseName::Attached("my_attached"),
&mut dst,
DatabaseName::Main,
)
.unwrap();
backup
.run_to_completion(5, Duration::from_millis(250), None)
.unwrap();
)?;
backup.run_to_completion(5, Duration::from_millis(250), None)?;
}
let the_answer: i64 = dst
.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap();
let the_answer: i64 = dst.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
assert_eq!(42 + 43, the_answer);
Ok(())
}
}

View File

@ -434,22 +434,18 @@ mod test {
}
#[test]
fn test_blob() {
let (db, rowid) = db_with_test_blob().unwrap();
fn test_blob() -> Result<()> {
let (db, rowid) = db_with_test_blob()?;
let mut blob = db
.blob_open(DatabaseName::Main, "test", "content", rowid, false)
.unwrap();
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)?;
assert_eq!(4, blob.write(b"Clob").unwrap());
assert_eq!(6, blob.write(b"567890xxxxxx").unwrap()); // cannot write past 10
assert_eq!(0, blob.write(b"5678").unwrap()); // still cannot write past 10
blob.reopen(rowid).unwrap();
blob.close().unwrap();
blob.reopen(rowid)?;
blob.close()?;
blob = db
.blob_open(DatabaseName::Main, "test", "content", rowid, true)
.unwrap();
blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, true)?;
let mut bytes = [0u8; 5];
assert_eq!(5, blob.read(&mut bytes[..]).unwrap());
assert_eq!(&bytes, b"Clob5");
@ -470,7 +466,7 @@ mod test {
assert_eq!(5, blob.read(&mut bytes[..]).unwrap());
assert_eq!(&bytes, b"56789");
blob.reopen(rowid).unwrap();
blob.reopen(rowid)?;
assert_eq!(5, blob.read(&mut bytes[..]).unwrap());
assert_eq!(&bytes, b"Clob5");
@ -481,20 +477,19 @@ mod test {
// write_all should detect when we return Ok(0) because there is no space left,
// and return a write error
blob.reopen(rowid).unwrap();
blob.reopen(rowid)?;
assert!(blob.write_all(b"0123456789x").is_err());
Ok(())
}
#[test]
fn test_blob_in_bufreader() {
let (db, rowid) = db_with_test_blob().unwrap();
fn test_blob_in_bufreader() -> Result<()> {
let (db, rowid) = db_with_test_blob()?;
let mut blob = db
.blob_open(DatabaseName::Main, "test", "content", rowid, false)
.unwrap();
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)?;
assert_eq!(8, blob.write(b"one\ntwo\n").unwrap());
blob.reopen(rowid).unwrap();
blob.reopen(rowid)?;
let mut reader = BufReader::new(blob);
let mut line = String::new();
@ -508,16 +503,15 @@ mod test {
line.truncate(0);
assert_eq!(2, reader.read_line(&mut line).unwrap());
assert_eq!("\0\0", line);
Ok(())
}
#[test]
fn test_blob_in_bufwriter() {
let (db, rowid) = db_with_test_blob().unwrap();
fn test_blob_in_bufwriter() -> Result<()> {
let (db, rowid) = db_with_test_blob()?;
{
let blob = db
.blob_open(DatabaseName::Main, "test", "content", rowid, false)
.unwrap();
let blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)?;
let mut writer = BufWriter::new(blob);
// trying to write too much and then flush should fail
@ -528,18 +522,14 @@ mod test {
{
// ... but it should've written the first 10 bytes
let mut blob = db
.blob_open(DatabaseName::Main, "test", "content", rowid, false)
.unwrap();
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)?;
let mut bytes = [0u8; 10];
assert_eq!(10, blob.read(&mut bytes[..]).unwrap());
assert_eq!(b"0123456701", &bytes);
}
{
let blob = db
.blob_open(DatabaseName::Main, "test", "content", rowid, false)
.unwrap();
let blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)?;
let mut writer = BufWriter::new(blob);
// trying to write_all too much should fail
@ -549,12 +539,11 @@ mod test {
{
// ... but it should've written the first 10 bytes
let mut blob = db
.blob_open(DatabaseName::Main, "test", "content", rowid, false)
.unwrap();
let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false)?;
let mut bytes = [0u8; 10];
assert_eq!(10, blob.read(&mut bytes[..]).unwrap());
assert_eq!(b"aaaaaaaaaa", &bytes);
Ok(())
}
}
}

View File

@ -194,22 +194,18 @@ impl<'conn> Blob<'conn> {
#[cfg(test)]
mod test {
use crate::{Connection, DatabaseName};
use crate::{Connection, DatabaseName, Result};
// to ensure we don't modify seek pos
use std::io::Seek as _;
#[test]
fn test_pos_io() {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE test_table(content BLOB);")
.unwrap();
db.execute("INSERT INTO test_table(content) VALUES (ZEROBLOB(10))", [])
.unwrap();
fn test_pos_io() -> Result<()> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE test_table(content BLOB);")?;
db.execute("INSERT INTO test_table(content) VALUES (ZEROBLOB(10))", [])?;
let rowid = db.last_insert_rowid();
let mut blob = db
.blob_open(DatabaseName::Main, "test_table", "content", rowid, false)
.unwrap();
let mut blob = db.blob_open(DatabaseName::Main, "test_table", "content", rowid, false)?;
// modify the seek pos to ensure we aren't using it or modifying it.
blob.seek(std::io::SeekFrom::Start(1)).unwrap();
@ -274,5 +270,6 @@ mod test {
let end_pos = blob.seek(std::io::SeekFrom::Current(0)).unwrap();
assert_eq!(end_pos, 1);
Ok(())
}
}

View File

@ -86,15 +86,13 @@ mod test {
use crate::{Connection, Error, ErrorCode, Result, TransactionBehavior};
#[test]
fn test_default_busy() {
fn test_default_busy() -> Result<()> {
let temp_dir = tempfile::tempdir().unwrap();
let path = temp_dir.path().join("test.db3");
let mut db1 = Connection::open(&path).unwrap();
let tx1 = db1
.transaction_with_behavior(TransactionBehavior::Exclusive)
.unwrap();
let db2 = Connection::open(&path).unwrap();
let mut db1 = Connection::open(&path)?;
let tx1 = db1.transaction_with_behavior(TransactionBehavior::Exclusive)?;
let db2 = Connection::open(&path)?;
let r: Result<()> = db2.query_row("PRAGMA schema_version", [], |_| unreachable!());
match r.unwrap_err() {
Error::SqliteFailure(err, _) => {
@ -102,7 +100,7 @@ mod test {
}
err => panic!("Unexpected error {}", err),
}
tx1.rollback().unwrap();
tx1.rollback()
}
#[test]

View File

@ -175,7 +175,7 @@ impl StatementCache {
#[cfg(test)]
mod test {
use super::StatementCache;
use crate::Connection;
use crate::{Connection, Result};
use fallible_iterator::FallibleIterator;
impl StatementCache {
@ -193,8 +193,8 @@ mod test {
}
#[test]
fn test_cache() {
let db = Connection::open_in_memory().unwrap();
fn test_cache() -> Result<()> {
let db = Connection::open_in_memory()?;
let cache = &db.cache;
let initial_capacity = cache.capacity();
assert_eq!(0, cache.len());
@ -202,34 +202,35 @@ mod test {
let sql = "PRAGMA schema_version";
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
}
assert_eq!(1, cache.len());
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
}
assert_eq!(1, cache.len());
cache.clear();
assert_eq!(0, cache.len());
assert_eq!(initial_capacity, cache.capacity());
Ok(())
}
#[test]
fn test_set_capacity() {
let db = Connection::open_in_memory().unwrap();
fn test_set_capacity() -> Result<()> {
let db = Connection::open_in_memory()?;
let cache = &db.cache;
let sql = "PRAGMA schema_version";
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
}
assert_eq!(1, cache.len());
@ -237,55 +238,53 @@ mod test {
assert_eq!(0, cache.len());
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
}
assert_eq!(0, cache.len());
db.set_prepared_statement_cache_capacity(8);
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
}
assert_eq!(1, cache.len());
Ok(())
}
#[test]
fn test_discard() {
let db = Connection::open_in_memory().unwrap();
fn test_discard() -> Result<()> {
let db = Connection::open_in_memory()?;
let cache = &db.cache;
let sql = "PRAGMA schema_version";
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
stmt.discard();
}
assert_eq!(0, cache.len());
Ok(())
}
#[test]
fn test_ddl() {
let db = Connection::open_in_memory().unwrap();
fn test_ddl() -> Result<()> {
let db = Connection::open_in_memory()?;
db.execute_batch(
r#"
CREATE TABLE foo (x INT);
INSERT INTO foo VALUES (1);
"#,
)
.unwrap();
)?;
let sql = "SELECT * FROM foo";
{
let mut stmt = db.prepare_cached(sql).unwrap();
assert_eq!(
Ok(Some(1i32)),
stmt.query([]).unwrap().map(|r| r.get(0)).next()
);
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(Ok(Some(1i32)), stmt.query([])?.map(|r| r.get(0)).next());
}
db.execute_batch(
@ -293,55 +292,55 @@ mod test {
ALTER TABLE foo ADD COLUMN y INT;
UPDATE foo SET y = 2;
"#,
)
.unwrap();
)?;
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(
Ok(Some((1i32, 2i32))),
stmt.query([])
.unwrap()
.map(|r| Ok((r.get(0)?, r.get(1)?)))
.next()
stmt.query([])?.map(|r| Ok((r.get(0)?, r.get(1)?))).next()
);
}
Ok(())
}
#[test]
fn test_connection_close() {
let conn = Connection::open_in_memory().unwrap();
conn.prepare_cached("SELECT * FROM sqlite_master;").unwrap();
fn test_connection_close() -> Result<()> {
let conn = Connection::open_in_memory()?;
conn.prepare_cached("SELECT * FROM sqlite_master;")?;
conn.close().expect("connection not closed");
Ok(())
}
#[test]
fn test_cache_key() {
let db = Connection::open_in_memory().unwrap();
fn test_cache_key() -> Result<()> {
let db = Connection::open_in_memory()?;
let cache = &db.cache;
assert_eq!(0, cache.len());
//let sql = " PRAGMA schema_version; -- comment";
let sql = "PRAGMA schema_version; ";
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
}
assert_eq!(1, cache.len());
{
let mut stmt = db.prepare_cached(sql).unwrap();
let mut stmt = db.prepare_cached(sql)?;
assert_eq!(0, cache.len());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0)).unwrap());
assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?);
}
assert_eq!(1, cache.len());
Ok(())
}
#[test]
fn test_empty_stmt() {
let conn = Connection::open_in_memory().unwrap();
conn.prepare_cached("").unwrap();
fn test_empty_stmt() -> Result<()> {
let conn = Connection::open_in_memory()?;
conn.prepare_cached("")?;
Ok(())
}
}

View File

@ -171,26 +171,24 @@ mod test {
}
#[test]
fn test_unicase() {
let db = Connection::open_in_memory().unwrap();
fn test_unicase() -> Result<()> {
let db = Connection::open_in_memory()?;
db.create_collation("unicase", unicase_compare).unwrap();
db.create_collation("unicase", unicase_compare)?;
collate(db);
collate(db)
}
fn collate(db: Connection) {
fn collate(db: Connection) -> Result<()> {
db.execute_batch(
"CREATE TABLE foo (bar);
INSERT INTO foo (bar) VALUES ('Maße');
INSERT INTO foo (bar) VALUES ('MASSE');",
)
.unwrap();
let mut stmt = db
.prepare("SELECT DISTINCT bar COLLATE unicase FROM foo ORDER BY 1")
.unwrap();
let rows = stmt.query([]).unwrap();
assert_eq!(rows.count().unwrap(), 1);
)?;
let mut stmt = db.prepare("SELECT DISTINCT bar COLLATE unicase FROM foo ORDER BY 1")?;
let rows = stmt.query([])?;
assert_eq!(rows.count()?, 1);
Ok(())
}
fn collation_needed(db: &Connection, collation_name: &str) -> Result<()> {
@ -202,9 +200,9 @@ mod test {
}
#[test]
fn test_collation_needed() {
let db = Connection::open_in_memory().unwrap();
db.collation_needed(collation_needed).unwrap();
collate(db);
fn test_collation_needed() -> Result<()> {
let db = Connection::open_in_memory()?;
db.collation_needed(collation_needed)?;
collate(db)
}
}

View File

@ -176,15 +176,15 @@ impl<'stmt> Row<'stmt> {
#[cfg(test)]
mod test {
use crate::Connection;
use crate::{Connection, Result};
#[test]
#[cfg(feature = "column_decltype")]
fn test_columns() {
fn test_columns() -> Result<()> {
use super::Column;
let db = Connection::open_in_memory().unwrap();
let query = db.prepare("SELECT * FROM sqlite_master").unwrap();
let db = Connection::open_in_memory()?;
let query = db.prepare("SELECT * FROM sqlite_master")?;
let columns = query.columns();
let column_names: Vec<&str> = columns.iter().map(Column::name).collect();
assert_eq!(
@ -196,22 +196,22 @@ mod test {
&column_types[..3],
&[Some("text"), Some("text"), Some("text"),]
);
Ok(())
}
#[test]
fn test_column_name_in_error() {
fn test_column_name_in_error() -> Result<()> {
use crate::{types::Type, Error};
let db = Connection::open_in_memory().unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch(
"BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
INSERT INTO foo VALUES(4, NULL);
END;",
)
.unwrap();
let mut stmt = db.prepare("SELECT x as renamed, y FROM foo").unwrap();
let mut rows = stmt.query([]).unwrap();
let row = rows.next().unwrap().unwrap();
)?;
let mut stmt = db.prepare("SELECT x as renamed, y FROM foo")?;
let mut rows = stmt.query([])?;
let row = rows.next()?.unwrap();
match row.get::<_, String>(0).unwrap_err() {
Error::InvalidColumnType(idx, name, ty) => {
assert_eq!(idx, 0);
@ -232,5 +232,6 @@ mod test {
panic!("Unexpected error type: {:?}", e);
}
}
Ok(())
}
}

View File

@ -122,13 +122,13 @@ impl Connection {
#[cfg(test)]
mod test {
use super::DbConfig;
use crate::Connection;
use crate::{Connection, Result};
#[test]
fn test_db_config() {
let db = Connection::open_in_memory().unwrap();
fn test_db_config() -> Result<()> {
let db = Connection::open_in_memory()?;
let opposite = !db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY).unwrap();
let opposite = !db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY)?;
assert_eq!(
db.set_db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY, opposite),
Ok(opposite)
@ -138,9 +138,7 @@ mod test {
Ok(opposite)
);
let opposite = !db
.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER)
.unwrap();
let opposite = !db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER)?;
assert_eq!(
db.set_db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER, opposite),
Ok(opposite)
@ -149,5 +147,6 @@ mod test {
db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER),
Ok(opposite)
);
Ok(())
}
}

View File

@ -761,36 +761,36 @@ mod test {
}
#[test]
fn test_function_half() {
let db = Connection::open_in_memory().unwrap();
fn test_function_half() -> Result<()> {
let db = Connection::open_in_memory()?;
db.create_scalar_function(
"half",
1,
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
half,
)
.unwrap();
)?;
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
assert!((3f64 - result.unwrap()).abs() < EPSILON);
assert!((3f64 - result?).abs() < EPSILON);
Ok(())
}
#[test]
fn test_remove_function() {
let db = Connection::open_in_memory().unwrap();
fn test_remove_function() -> Result<()> {
let db = Connection::open_in_memory()?;
db.create_scalar_function(
"half",
1,
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
half,
)
.unwrap();
)?;
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
assert!((3f64 - result.unwrap()).abs() < EPSILON);
assert!((3f64 - result?).abs() < EPSILON);
db.remove_function("half", 1).unwrap();
db.remove_function("half", 1)?;
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
assert!(result.is_err());
Ok(())
}
// This implementation of a regexp scalar function uses SQLite's auxilliary data
@ -817,8 +817,8 @@ mod test {
}
#[test]
fn test_function_regexp_with_auxilliary() {
let db = Connection::open_in_memory().unwrap();
fn test_function_regexp_with_auxilliary() -> Result<()> {
let db = Connection::open_in_memory()?;
db.execute_batch(
"BEGIN;
CREATE TABLE foo (x string);
@ -826,20 +826,18 @@ mod test {
INSERT INTO foo VALUES ('lXsi');
INSERT INTO foo VALUES ('lisX');
END;",
)
.unwrap();
)?;
db.create_scalar_function(
"regexp",
2,
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
regexp_with_auxilliary,
)
.unwrap();
)?;
let result: Result<bool> =
db.query_row("SELECT regexp('l.s[aeiouy]', 'lisa')", [], |r| r.get(0));
assert_eq!(true, result.unwrap());
assert_eq!(true, result?);
let result: Result<i64> = db.query_row(
"SELECT COUNT(*) FROM foo WHERE regexp('l.s[aeiouy]', x) == 1",
@ -847,12 +845,13 @@ mod test {
|r| r.get(0),
);
assert_eq!(2, result.unwrap());
assert_eq!(2, result?);
Ok(())
}
#[test]
fn test_varargs_function() {
let db = Connection::open_in_memory().unwrap();
fn test_varargs_function() -> Result<()> {
let db = Connection::open_in_memory()?;
db.create_scalar_function(
"my_concat",
-1,
@ -867,42 +866,40 @@ mod test {
Ok(ret)
},
)
.unwrap();
)?;
for &(expected, query) in &[
("", "SELECT my_concat()"),
("onetwo", "SELECT my_concat('one', 'two')"),
("abc", "SELECT my_concat('a', 'b', 'c')"),
] {
let result: String = db.query_row(query, [], |r| r.get(0)).unwrap();
let result: String = db.query_row(query, [], |r| r.get(0))?;
assert_eq!(expected, result);
}
Ok(())
}
#[test]
fn test_get_aux_type_checking() {
let db = Connection::open_in_memory().unwrap();
fn test_get_aux_type_checking() -> Result<()> {
let db = Connection::open_in_memory()?;
db.create_scalar_function("example", 2, FunctionFlags::default(), |ctx| {
if !ctx.get::<bool>(1)? {
ctx.set_aux::<i64>(0, 100)?;
} else {
assert_eq!(ctx.get_aux::<String>(0), Err(Error::GetAuxWrongType));
assert_eq!(*ctx.get_aux::<i64>(0).unwrap().unwrap(), 100);
assert_eq!(*ctx.get_aux::<i64>(0)?.unwrap(), 100);
}
Ok(true)
})
.unwrap();
})?;
let res: bool = db
.query_row(
"SELECT example(0, i) FROM (SELECT 0 as i UNION SELECT 1)",
[],
|r| r.get(0),
)
.unwrap();
let res: bool = db.query_row(
"SELECT example(0, i) FROM (SELECT 0 as i UNION SELECT 1)",
[],
|r| r.get(0),
)?;
// Doesn't actually matter, we'll assert in the function if there's a problem.
assert!(res);
Ok(())
}
struct Sum;
@ -939,52 +936,50 @@ mod test {
}
#[test]
fn test_sum() {
let db = Connection::open_in_memory().unwrap();
fn test_sum() -> Result<()> {
let db = Connection::open_in_memory()?;
db.create_aggregate_function(
"my_sum",
1,
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
Sum,
)
.unwrap();
)?;
// sum should return NULL when given no columns (contrast with count below)
let no_result = "SELECT my_sum(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
let result: Option<i64> = db.query_row(no_result, [], |r| r.get(0)).unwrap();
let result: Option<i64> = db.query_row(no_result, [], |r| r.get(0))?;
assert!(result.is_none());
let single_sum = "SELECT my_sum(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
let result: i64 = db.query_row(single_sum, [], |r| r.get(0)).unwrap();
let result: i64 = db.query_row(single_sum, [], |r| r.get(0))?;
assert_eq!(4, result);
let dual_sum = "SELECT my_sum(i), my_sum(j) FROM (SELECT 2 AS i, 1 AS j UNION ALL SELECT \
2, 1)";
let result: (i64, i64) = db
.query_row(dual_sum, [], |r| Ok((r.get(0)?, r.get(1)?)))
.unwrap();
let result: (i64, i64) = db.query_row(dual_sum, [], |r| Ok((r.get(0)?, r.get(1)?)))?;
assert_eq!((4, 2), result);
Ok(())
}
#[test]
fn test_count() {
let db = Connection::open_in_memory().unwrap();
fn test_count() -> Result<()> {
let db = Connection::open_in_memory()?;
db.create_aggregate_function(
"my_count",
-1,
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
Count,
)
.unwrap();
)?;
// count should return 0 when given no columns (contrast with sum above)
let no_result = "SELECT my_count(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
let result: i64 = db.query_row(no_result, [], |r| r.get(0)).unwrap();
let result: i64 = db.query_row(no_result, [], |r| r.get(0))?;
assert_eq!(result, 0);
let single_sum = "SELECT my_count(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
let result: i64 = db.query_row(single_sum, [], |r| r.get(0)).unwrap();
let result: i64 = db.query_row(single_sum, [], |r| r.get(0))?;
assert_eq!(2, result);
Ok(())
}
#[cfg(feature = "window")]
@ -1001,17 +996,16 @@ mod test {
#[test]
#[cfg(feature = "window")]
fn test_window() {
fn test_window() -> Result<()> {
use fallible_iterator::FallibleIterator;
let db = Connection::open_in_memory().unwrap();
let db = Connection::open_in_memory()?;
db.create_window_function(
"sumint",
1,
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
Sum,
)
.unwrap();
)?;
db.execute_batch(
"CREATE TABLE t3(x, y);
INSERT INTO t3 VALUES('a', 4),
@ -1019,24 +1013,19 @@ mod test {
('c', 3),
('d', 8),
('e', 1);",
)
.unwrap();
)?;
let mut stmt = db
.prepare(
"SELECT x, sumint(y) OVER (
let mut stmt = db.prepare(
"SELECT x, sumint(y) OVER (
ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
) AS sum_y
FROM t3 ORDER BY x;",
)
.unwrap();
)?;
let results: Vec<(String, i64)> = stmt
.query([])
.unwrap()
.query([])?
.map(|row| Ok((row.get("x")?, row.get("sum_y")?)))
.collect()
.unwrap();
.collect()?;
let expected = vec![
("a".to_owned(), 9),
("b".to_owned(), 12),
@ -1045,5 +1034,6 @@ mod test {
("e".to_owned(), 9),
];
assert_eq!(expected, results);
Ok(())
}
}

View File

@ -305,26 +305,26 @@ unsafe fn free_boxed_hook<F>(p: *mut c_void) {
#[cfg(test)]
mod test {
use super::Action;
use crate::Connection;
use crate::{Connection, Result};
use std::sync::atomic::{AtomicBool, Ordering};
#[test]
fn test_commit_hook() {
let db = Connection::open_in_memory().unwrap();
fn test_commit_hook() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut called = false;
db.commit_hook(Some(|| {
called = true;
false
}));
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")
.unwrap();
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")?;
assert!(called);
Ok(())
}
#[test]
fn test_fn_commit_hook() {
let db = Connection::open_in_memory().unwrap();
fn test_fn_commit_hook() -> Result<()> {
let db = Connection::open_in_memory()?;
fn hook() -> bool {
true
@ -333,24 +333,25 @@ mod test {
db.commit_hook(Some(hook));
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")
.unwrap_err();
Ok(())
}
#[test]
fn test_rollback_hook() {
let db = Connection::open_in_memory().unwrap();
fn test_rollback_hook() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut called = false;
db.rollback_hook(Some(|| {
called = true;
}));
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); ROLLBACK;")
.unwrap();
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); ROLLBACK;")?;
assert!(called);
Ok(())
}
#[test]
fn test_update_hook() {
let db = Connection::open_in_memory().unwrap();
fn test_update_hook() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut called = false;
db.update_hook(Some(|action, db: &str, tbl: &str, row_id| {
@ -360,14 +361,15 @@ mod test {
assert_eq!(1, row_id);
called = true;
}));
db.execute_batch("CREATE TABLE foo (t TEXT)").unwrap();
db.execute_batch("INSERT INTO foo VALUES ('lisa')").unwrap();
db.execute_batch("CREATE TABLE foo (t TEXT)")?;
db.execute_batch("INSERT INTO foo VALUES ('lisa')")?;
assert!(called);
Ok(())
}
#[test]
fn test_progress_handler() {
let db = Connection::open_in_memory().unwrap();
fn test_progress_handler() -> Result<()> {
let db = Connection::open_in_memory()?;
static CALLED: AtomicBool = AtomicBool::new(false);
db.progress_handler(
@ -377,14 +379,14 @@ mod test {
false
}),
);
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")
.unwrap();
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")?;
assert!(CALLED.load(Ordering::Relaxed));
Ok(())
}
#[test]
fn test_progress_handler_interrupt() {
let db = Connection::open_in_memory().unwrap();
fn test_progress_handler_interrupt() -> Result<()> {
let db = Connection::open_in_memory()?;
fn handler() -> bool {
true
@ -393,5 +395,6 @@ mod test {
db.progress_handler(1, Some(handler));
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")
.unwrap_err();
Ok(())
}
}

View File

@ -1060,38 +1060,32 @@ mod test {
}
#[test]
fn test_concurrent_transactions_busy_commit() {
fn test_concurrent_transactions_busy_commit() -> Result<()> {
use std::time::Duration;
let tmp = tempfile::tempdir().unwrap();
let path = tmp.path().join("transactions.db3");
Connection::open(&path)
.expect("create temp db")
.execute_batch(
"
Connection::open(&path)?.execute_batch(
"
BEGIN; CREATE TABLE foo(x INTEGER);
INSERT INTO foo VALUES(42); END;",
)
.expect("create temp db");
)?;
let mut db1 =
Connection::open_with_flags(&path, OpenFlags::SQLITE_OPEN_READ_WRITE).unwrap();
let mut db2 = Connection::open_with_flags(&path, OpenFlags::SQLITE_OPEN_READ_ONLY).unwrap();
let mut db1 = Connection::open_with_flags(&path, OpenFlags::SQLITE_OPEN_READ_WRITE)?;
let mut db2 = Connection::open_with_flags(&path, OpenFlags::SQLITE_OPEN_READ_ONLY)?;
db1.busy_timeout(Duration::from_millis(0)).unwrap();
db2.busy_timeout(Duration::from_millis(0)).unwrap();
db1.busy_timeout(Duration::from_millis(0))?;
db2.busy_timeout(Duration::from_millis(0))?;
{
let tx1 = db1.transaction().unwrap();
let tx2 = db2.transaction().unwrap();
let tx1 = db1.transaction()?;
let tx2 = db2.transaction()?;
// SELECT first makes sqlite lock with a shared lock
tx1.query_row("SELECT x FROM foo LIMIT 1", [], |_| Ok(()))
.unwrap();
tx2.query_row("SELECT x FROM foo LIMIT 1", [], |_| Ok(()))
.unwrap();
tx1.query_row("SELECT x FROM foo LIMIT 1", [], |_| Ok(()))?;
tx2.query_row("SELECT x FROM foo LIMIT 1", [], |_| Ok(()))?;
tx1.execute("INSERT INTO foo VALUES(?1)", &[&1]).unwrap();
tx1.execute("INSERT INTO foo VALUES(?1)", &[&1])?;
let _ = tx2.execute("INSERT INTO foo VALUES(?1)", [2]);
let _ = tx1.commit();
@ -1104,27 +1098,29 @@ mod test {
let _ = db2
.transaction()
.expect("commit should have closed transaction");
Ok(())
}
#[test]
fn test_persistence() {
fn test_persistence() -> Result<()> {
let temp_dir = tempfile::tempdir().unwrap();
let path = temp_dir.path().join("test.db3");
{
let db = Connection::open(&path).unwrap();
let db = Connection::open(&path)?;
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER);
INSERT INTO foo VALUES(42);
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
}
let path_string = path.to_str().unwrap();
let db = Connection::open(&path_string).unwrap();
let db = Connection::open(&path_string)?;
let the_answer: Result<i64> = db.query_row("SELECT x FROM foo", [], |r| r.get(0));
assert_eq!(42i64, the_answer.unwrap());
assert_eq!(42i64, the_answer?);
Ok(())
}
#[test]
@ -1157,7 +1153,7 @@ mod test {
#[cfg(unix)]
#[test]
fn test_invalid_unicode_file_names() {
fn test_invalid_unicode_file_names() -> Result<()> {
use std::ffi::OsStr;
use std::fs::File;
use std::os::unix::ffi::OsStrExt;
@ -1166,26 +1162,27 @@ mod test {
let path = temp_dir.path();
if File::create(path.join(OsStr::from_bytes(&[0xFE]))).is_err() {
// Skip test, filesystem doesn't support invalid Unicode
return;
return Ok(());
}
let db_path = path.join(OsStr::from_bytes(&[0xFF]));
{
let db = Connection::open(&db_path).unwrap();
let db = Connection::open(&db_path)?;
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER);
INSERT INTO foo VALUES(42);
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
}
let db = Connection::open(&db_path).unwrap();
let db = Connection::open(&db_path)?;
let the_answer: Result<i64> = db.query_row("SELECT x FROM foo", [], |r| r.get(0));
assert_eq!(42i64, the_answer.unwrap());
assert_eq!(42i64, the_answer?);
Ok(())
}
#[test]
fn test_close_retry() {
fn test_close_retry() -> Result<()> {
let db = checked_memory_handle();
// force the DB to be busy by preparing a statement; this must be done at the
@ -1199,7 +1196,7 @@ mod test {
let raw_db = db.db.borrow_mut().db;
let sql = "SELECT 1";
let mut raw_stmt: *mut ffi::sqlite3_stmt = ptr::null_mut();
let cstring = str_to_cstring(sql).unwrap();
let cstring = str_to_cstring(sql)?;
let rc = unsafe {
ffi::sqlite3_prepare_v2(
raw_db,
@ -1223,6 +1220,7 @@ mod test {
assert_eq!(ffi::SQLITE_OK, unsafe { ffi::sqlite3_finalize(raw_stmt) });
db.close().unwrap();
Ok(())
}
#[test]
@ -1237,7 +1235,7 @@ mod test {
}
#[test]
fn test_execute_batch() {
fn test_execute_batch() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER);
@ -1246,33 +1244,27 @@ mod test {
INSERT INTO foo VALUES(3);
INSERT INTO foo VALUES(4);
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
db.execute_batch("UPDATE foo SET x = 3 WHERE x < 3")
.unwrap();
db.execute_batch("UPDATE foo SET x = 3 WHERE x < 3")?;
assert!(db.execute_batch("INVALID SQL").is_err());
Ok(())
}
#[test]
fn test_execute() {
fn test_execute() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER)")?;
assert_eq!(
1,
db.execute("INSERT INTO foo(x) VALUES (?)", [1i32]).unwrap()
);
assert_eq!(
1,
db.execute("INSERT INTO foo(x) VALUES (?)", [2i32]).unwrap()
);
assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?)", [1i32])?);
assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?)", [2i32])?);
assert_eq!(
3i32,
db.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap()
db.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
);
Ok(())
}
#[test]
@ -1302,77 +1294,78 @@ mod test {
}
#[test]
fn test_prepare_column_names() {
fn test_prepare_column_names() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER);").unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
let stmt = db.prepare("SELECT * FROM foo").unwrap();
let stmt = db.prepare("SELECT * FROM foo")?;
assert_eq!(stmt.column_count(), 1);
assert_eq!(stmt.column_names(), vec!["x"]);
let stmt = db.prepare("SELECT x AS a, x AS b FROM foo").unwrap();
let stmt = db.prepare("SELECT x AS a, x AS b FROM foo")?;
assert_eq!(stmt.column_count(), 2);
assert_eq!(stmt.column_names(), vec!["a", "b"]);
Ok(())
}
#[test]
fn test_prepare_execute() {
fn test_prepare_execute() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER);").unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)").unwrap();
assert_eq!(insert_stmt.execute([1i32]).unwrap(), 1);
assert_eq!(insert_stmt.execute([2i32]).unwrap(), 1);
assert_eq!(insert_stmt.execute([3i32]).unwrap(), 1);
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)")?;
assert_eq!(insert_stmt.execute([1i32])?, 1);
assert_eq!(insert_stmt.execute([2i32])?, 1);
assert_eq!(insert_stmt.execute([3i32])?, 1);
assert_eq!(insert_stmt.execute(["hello".to_string()]).unwrap(), 1);
assert_eq!(insert_stmt.execute(["goodbye".to_string()]).unwrap(), 1);
assert_eq!(insert_stmt.execute([types::Null]).unwrap(), 1);
assert_eq!(insert_stmt.execute(["hello".to_string()])?, 1);
assert_eq!(insert_stmt.execute(["goodbye".to_string()])?, 1);
assert_eq!(insert_stmt.execute([types::Null])?, 1);
let mut update_stmt = db.prepare("UPDATE foo SET x=? WHERE x<?").unwrap();
assert_eq!(update_stmt.execute([3i32, 3i32]).unwrap(), 2);
assert_eq!(update_stmt.execute([3i32, 3i32]).unwrap(), 0);
assert_eq!(update_stmt.execute([8i32, 8i32]).unwrap(), 3);
let mut update_stmt = db.prepare("UPDATE foo SET x=? WHERE x<?")?;
assert_eq!(update_stmt.execute([3i32, 3i32])?, 2);
assert_eq!(update_stmt.execute([3i32, 3i32])?, 0);
assert_eq!(update_stmt.execute([8i32, 8i32])?, 3);
Ok(())
}
#[test]
fn test_prepare_query() {
fn test_prepare_query() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER);").unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)").unwrap();
assert_eq!(insert_stmt.execute([1i32]).unwrap(), 1);
assert_eq!(insert_stmt.execute([2i32]).unwrap(), 1);
assert_eq!(insert_stmt.execute([3i32]).unwrap(), 1);
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)")?;
assert_eq!(insert_stmt.execute([1i32])?, 1);
assert_eq!(insert_stmt.execute([2i32])?, 1);
assert_eq!(insert_stmt.execute([3i32])?, 1);
let mut query = db
.prepare("SELECT x FROM foo WHERE x < ? ORDER BY x DESC")
.unwrap();
let mut query = db.prepare("SELECT x FROM foo WHERE x < ? ORDER BY x DESC")?;
{
let mut rows = query.query([4i32]).unwrap();
let mut rows = query.query([4i32])?;
let mut v = Vec::<i32>::new();
while let Some(row) = rows.next().unwrap() {
v.push(row.get(0).unwrap());
while let Some(row) = rows.next()? {
v.push(row.get(0)?);
}
assert_eq!(v, [3i32, 2, 1]);
}
{
let mut rows = query.query([3i32]).unwrap();
let mut rows = query.query([3i32])?;
let mut v = Vec::<i32>::new();
while let Some(row) = rows.next().unwrap() {
v.push(row.get(0).unwrap());
while let Some(row) = rows.next()? {
v.push(row.get(0)?);
}
assert_eq!(v, [2i32, 1]);
}
Ok(())
}
#[test]
fn test_query_map() {
fn test_query_map() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
@ -1381,16 +1374,17 @@ mod test {
INSERT INTO foo VALUES(2, \"world\");
INSERT INTO foo VALUES(1, \"!\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let results: Result<Vec<String>> = query.query([]).unwrap().map(|row| row.get(1)).collect();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
let results: Result<Vec<String>> = query.query([])?.map(|row| row.get(1)).collect();
assert_eq!(results.unwrap().concat(), "hello, world!");
assert_eq!(results?.concat(), "hello, world!");
Ok(())
}
#[test]
fn test_query_row() {
fn test_query_row() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER);
@ -1399,12 +1393,11 @@ mod test {
INSERT INTO foo VALUES(3);
INSERT INTO foo VALUES(4);
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
assert_eq!(
10i64,
db.query_row::<i64, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap()
db.query_row::<i64, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
);
let result: Result<i64> = db.query_row("SELECT x FROM foo WHERE x > 5", [], |r| r.get(0));
@ -1416,22 +1409,23 @@ mod test {
let bad_query_result = db.query_row("NOT A PROPER QUERY; test123", [], |_| Ok(()));
assert!(bad_query_result.is_err());
Ok(())
}
#[test]
fn test_optional() {
fn test_optional() -> Result<()> {
let db = checked_memory_handle();
let result: Result<i64> = db.query_row("SELECT 1 WHERE 0 <> 0", [], |r| r.get(0));
let result = result.optional();
match result.unwrap() {
match result? {
None => (),
_ => panic!("Unexpected result"),
}
let result: Result<i64> = db.query_row("SELECT 1 WHERE 0 == 0", [], |r| r.get(0));
let result = result.optional();
match result.unwrap() {
match result? {
Some(1) => (),
_ => panic!("Unexpected result"),
}
@ -1439,47 +1433,48 @@ mod test {
let bad_query_result: Result<i64> = db.query_row("NOT A PROPER QUERY", [], |r| r.get(0));
let bad_query_result = bad_query_result.optional();
assert!(bad_query_result.is_err());
Ok(())
}
#[test]
fn test_pragma_query_row() {
fn test_pragma_query_row() -> Result<()> {
let db = checked_memory_handle();
assert_eq!(
"memory",
db.query_row::<String, _, _>("PRAGMA journal_mode", [], |r| r.get(0))
.unwrap()
db.query_row::<String, _, _>("PRAGMA journal_mode", [], |r| r.get(0))?
);
assert_eq!(
"off",
db.query_row::<String, _, _>("PRAGMA journal_mode=off", [], |r| r.get(0))
.unwrap()
db.query_row::<String, _, _>("PRAGMA journal_mode=off", [], |r| r.get(0))?
);
Ok(())
}
#[test]
fn test_prepare_failures() {
fn test_prepare_failures() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER);").unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
let err = db.prepare("SELECT * FROM does_not_exist").unwrap_err();
assert!(format!("{}", err).contains("does_not_exist"));
Ok(())
}
#[test]
fn test_last_insert_rowid() {
fn test_last_insert_rowid() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)")
.unwrap();
db.execute_batch("INSERT INTO foo DEFAULT VALUES").unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)")?;
db.execute_batch("INSERT INTO foo DEFAULT VALUES")?;
assert_eq!(db.last_insert_rowid(), 1);
let mut stmt = db.prepare("INSERT INTO foo DEFAULT VALUES").unwrap();
let mut stmt = db.prepare("INSERT INTO foo DEFAULT VALUES")?;
for _ in 0i32..9 {
stmt.execute([]).unwrap();
stmt.execute([])?;
}
assert_eq!(db.last_insert_rowid(), 10);
Ok(())
}
#[test]
@ -1493,32 +1488,34 @@ mod test {
#[test]
#[cfg(feature = "modern_sqlite")]
fn test_is_busy() {
fn test_is_busy() -> Result<()> {
let db = checked_memory_handle();
assert!(!db.is_busy());
let mut stmt = db.prepare("PRAGMA schema_version").unwrap();
let mut stmt = db.prepare("PRAGMA schema_version")?;
assert!(!db.is_busy());
{
let mut rows = stmt.query([]).unwrap();
let mut rows = stmt.query([])?;
assert!(!db.is_busy());
let row = rows.next().unwrap();
let row = rows.next()?;
assert!(db.is_busy());
assert!(row.is_some());
}
assert!(!db.is_busy());
Ok(())
}
#[test]
fn test_statement_debugging() {
fn test_statement_debugging() -> Result<()> {
let db = checked_memory_handle();
let query = "SELECT 12345";
let stmt = db.prepare(query).unwrap();
let stmt = db.prepare(query)?;
assert!(format!("{:?}", stmt).contains(query));
Ok(())
}
#[test]
fn test_notnull_constraint_error() {
fn test_notnull_constraint_error() -> Result<()> {
// extended error codes for constraints were added in SQLite 3.7.16; if we're
// running on our bundled version, we know the extended error code exists.
#[cfg(feature = "modern_sqlite")]
@ -1529,7 +1526,7 @@ mod test {
fn check_extended_code(_extended_code: c_int) {}
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x NOT NULL)").unwrap();
db.execute_batch("CREATE TABLE foo(x NOT NULL)")?;
let result = db.execute("INSERT INTO foo (x) VALUES (NULL)", []);
assert!(result.is_err());
@ -1541,6 +1538,7 @@ mod test {
}
err => panic!("Unexpected error {}", err),
}
Ok(())
}
#[test]
@ -1555,7 +1553,7 @@ mod test {
#[test]
#[cfg(feature = "functions")]
fn test_interrupt() {
fn test_interrupt() -> Result<()> {
let db = checked_memory_handle();
let interrupt_handle = db.get_interrupt_handle();
@ -1568,14 +1566,12 @@ mod test {
interrupt_handle.interrupt();
Ok(0)
},
)
.unwrap();
)?;
let mut stmt = db
.prepare("SELECT interrupt() FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)")
.unwrap();
let mut stmt =
db.prepare("SELECT interrupt() FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)")?;
let result: Result<Vec<i32>> = stmt.query([]).unwrap().map(|r| r.get(0)).collect();
let result: Result<Vec<i32>> = stmt.query([])?.map(|r| r.get(0)).collect();
match result.unwrap_err() {
Error::SqliteFailure(err, _) => {
@ -1585,6 +1581,7 @@ mod test {
panic!("Unexpected error {}", err);
}
}
Ok(())
}
#[test]
@ -1604,36 +1601,38 @@ mod test {
}
#[test]
fn test_get_raw() {
fn test_get_raw() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(i, x);").unwrap();
db.execute_batch("CREATE TABLE foo(i, x);")?;
let vals = ["foobar", "1234", "qwerty"];
let mut insert_stmt = db.prepare("INSERT INTO foo(i, x) VALUES(?, ?)").unwrap();
let mut insert_stmt = db.prepare("INSERT INTO foo(i, x) VALUES(?, ?)")?;
for (i, v) in vals.iter().enumerate() {
let i_to_insert = i as i64;
assert_eq!(insert_stmt.execute(params![i_to_insert, v]).unwrap(), 1);
assert_eq!(insert_stmt.execute(params![i_to_insert, v])?, 1);
}
let mut query = db.prepare("SELECT i, x FROM foo").unwrap();
let mut rows = query.query([]).unwrap();
let mut query = db.prepare("SELECT i, x FROM foo")?;
let mut rows = query.query([])?;
while let Some(row) = rows.next().unwrap() {
let i = row.get_raw(0).as_i64().unwrap();
while let Some(row) = rows.next()? {
let i = row.get_raw(0).as_i64()?;
let expect = vals[i as usize];
let x = row.get_raw("x").as_str().unwrap();
let x = row.get_raw("x").as_str()?;
assert_eq!(x, expect);
}
Ok(())
}
#[test]
fn test_from_handle() {
fn test_from_handle() -> Result<()> {
let db = checked_memory_handle();
let handle = unsafe { db.handle() };
{
let db = unsafe { Connection::from_handle(handle) }.unwrap();
db.execute_batch("PRAGMA VACUUM").unwrap();
let db = unsafe { Connection::from_handle(handle) }?;
db.execute_batch("PRAGMA VACUUM")?;
}
db.close().unwrap();
Ok(())
}
mod query_and_then_tests {
@ -1677,7 +1676,7 @@ mod test {
type CustomResult<T> = Result<T, CustomError>;
#[test]
fn test_query_and_then() {
fn test_query_and_then() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
@ -1686,19 +1685,18 @@ mod test {
INSERT INTO foo VALUES(2, \"world\");
INSERT INTO foo VALUES(1, \"!\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let results: Result<Vec<String>> = query
.query_and_then([], |row| row.get(1))
.unwrap()
.collect();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
let results: Result<Vec<String>> =
query.query_and_then([], |row| row.get(1))?.collect();
assert_eq!(results.unwrap().concat(), "hello, world!");
assert_eq!(results?.concat(), "hello, world!");
Ok(())
}
#[test]
fn test_query_and_then_fails() {
fn test_query_and_then_fails() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
@ -1707,32 +1705,28 @@ mod test {
INSERT INTO foo VALUES(2, \"world\");
INSERT INTO foo VALUES(1, \"!\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let bad_type: Result<Vec<f64>> = query
.query_and_then([], |row| row.get(1))
.unwrap()
.collect();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
let bad_type: Result<Vec<f64>> = query.query_and_then([], |row| row.get(1))?.collect();
match bad_type.unwrap_err() {
Error::InvalidColumnType(..) => (),
err => panic!("Unexpected error {}", err),
}
let bad_idx: Result<Vec<String>> = query
.query_and_then([], |row| row.get(3))
.unwrap()
.collect();
let bad_idx: Result<Vec<String>> =
query.query_and_then([], |row| row.get(3))?.collect();
match bad_idx.unwrap_err() {
Error::InvalidColumnIndex(_) => (),
err => panic!("Unexpected error {}", err),
}
Ok(())
}
#[test]
fn test_query_and_then_custom_error() {
fn test_query_and_then_custom_error() -> CustomResult<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
@ -1741,19 +1735,19 @@ mod test {
INSERT INTO foo VALUES(2, \"world\");
INSERT INTO foo VALUES(1, \"!\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
let results: CustomResult<Vec<String>> = query
.query_and_then([], |row| row.get(1).map_err(CustomError::Sqlite))
.unwrap()
.query_and_then([], |row| row.get(1).map_err(CustomError::Sqlite))?
.collect();
assert_eq!(results.unwrap().concat(), "hello, world!");
assert_eq!(results?.concat(), "hello, world!");
Ok(())
}
#[test]
fn test_query_and_then_custom_error_fails() {
fn test_query_and_then_custom_error_fails() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
@ -1762,12 +1756,11 @@ mod test {
INSERT INTO foo VALUES(2, \"world\");
INSERT INTO foo VALUES(1, \"!\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
let bad_type: CustomResult<Vec<f64>> = query
.query_and_then([], |row| row.get(1).map_err(CustomError::Sqlite))
.unwrap()
.query_and_then([], |row| row.get(1).map_err(CustomError::Sqlite))?
.collect();
match bad_type.unwrap_err() {
@ -1776,8 +1769,7 @@ mod test {
}
let bad_idx: CustomResult<Vec<String>> = query
.query_and_then([], |row| row.get(3).map_err(CustomError::Sqlite))
.unwrap()
.query_and_then([], |row| row.get(3).map_err(CustomError::Sqlite))?
.collect();
match bad_idx.unwrap_err() {
@ -1786,40 +1778,41 @@ mod test {
}
let non_sqlite_err: CustomResult<Vec<String>> = query
.query_and_then([], |_| Err(CustomError::SomeError))
.unwrap()
.query_and_then([], |_| Err(CustomError::SomeError))?
.collect();
match non_sqlite_err.unwrap_err() {
CustomError::SomeError => (),
err => panic!("Unexpected error {}", err),
}
Ok(())
}
#[test]
fn test_query_row_and_then_custom_error() {
fn test_query_row_and_then_custom_error() -> CustomResult<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
INSERT INTO foo VALUES(4, \"hello\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let query = "SELECT x, y FROM foo ORDER BY x DESC";
let results: CustomResult<String> =
db.query_row_and_then(query, [], |row| row.get(1).map_err(CustomError::Sqlite));
assert_eq!(results.unwrap(), "hello");
assert_eq!(results?, "hello");
Ok(())
}
#[test]
fn test_query_row_and_then_custom_error_fails() {
fn test_query_row_and_then_custom_error_fails() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
INSERT INTO foo VALUES(4, \"hello\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let query = "SELECT x, y FROM foo ORDER BY x DESC";
let bad_type: CustomResult<f64> =
@ -1845,39 +1838,38 @@ mod test {
CustomError::SomeError => (),
err => panic!("Unexpected error {}", err),
}
Ok(())
}
}
#[test]
fn test_dynamic() {
fn test_dynamic() -> Result<()> {
let db = checked_memory_handle();
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y TEXT);
INSERT INTO foo VALUES(4, \"hello\");
END;";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
db.query_row("SELECT * FROM foo", [], |r| {
assert_eq!(2, r.column_count());
Ok(())
})
.unwrap();
}
#[test]
fn test_dyn_box() {
fn test_dyn_box() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER);").unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
let b: Box<dyn ToSql> = Box::new(5);
db.execute("INSERT INTO foo VALUES(?)", [b]).unwrap();
db.execute("INSERT INTO foo VALUES(?)", [b])?;
db.query_row("SELECT x FROM foo", [], |r| {
assert_eq!(5, r.get_unwrap::<_, i32>(0));
Ok(())
})
.unwrap();
}
#[test]
fn test_params() {
fn test_params() -> Result<()> {
let db = checked_memory_handle();
db.query_row(
"SELECT
@ -1894,20 +1886,19 @@ mod test {
Ok(())
},
)
.unwrap();
}
#[test]
#[cfg(not(feature = "extra_check"))]
fn test_alter_table() {
fn test_alter_table() -> Result<()> {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE x(t);").unwrap();
db.execute_batch("CREATE TABLE x(t);")?;
// `execute_batch` should be used but `execute` should also work
db.execute("ALTER TABLE x RENAME TO y;", []).unwrap();
db.execute("ALTER TABLE x RENAME TO y;", [])
}
#[test]
fn test_batch() {
fn test_batch() -> Result<()> {
let db = checked_memory_handle();
let sql = r"
CREATE TABLE tbl1 (col);
@ -1915,8 +1906,9 @@ mod test {
";
let batch = Batch::new(&db, sql);
for stmt in batch {
let mut stmt = stmt.unwrap();
stmt.execute([]).unwrap();
let mut stmt = stmt?;
stmt.execute([])?;
}
Ok(())
}
}

View File

@ -27,11 +27,11 @@ impl Connection {
#[cfg(test)]
mod test {
use crate::ffi::Limit;
use crate::Connection;
use crate::{Connection, Result};
#[test]
fn test_limit() {
let db = Connection::open_in_memory().unwrap();
fn test_limit() -> Result<()> {
let db = Connection::open_in_memory()?;
db.set_limit(Limit::SQLITE_LIMIT_LENGTH, 1024);
assert_eq!(1024, db.limit(Limit::SQLITE_LIMIT_LENGTH));
@ -70,5 +70,6 @@ mod test {
db.set_limit(Limit::SQLITE_LIMIT_WORKER_THREADS, 2);
assert_eq!(2, db.limit(Limit::SQLITE_LIMIT_WORKER_THREADS));
}
Ok(())
}
}

View File

@ -314,95 +314,95 @@ fn is_identifier_continue(c: char) -> bool {
mod test {
use super::Sql;
use crate::pragma;
use crate::{Connection, DatabaseName};
use crate::{Connection, DatabaseName, Result};
#[test]
fn pragma_query_value() {
let db = Connection::open_in_memory().unwrap();
let user_version: i32 = db
.pragma_query_value(None, "user_version", |row| row.get(0))
.unwrap();
fn pragma_query_value() -> Result<()> {
let db = Connection::open_in_memory()?;
let user_version: i32 = db.pragma_query_value(None, "user_version", |row| row.get(0))?;
assert_eq!(0, user_version);
Ok(())
}
#[test]
#[cfg(feature = "modern_sqlite")]
fn pragma_func_query_value() {
let db = Connection::open_in_memory().unwrap();
let user_version: i32 = db
.query_row("SELECT user_version FROM pragma_user_version", [], |row| {
fn pragma_func_query_value() -> Result<()> {
let db = Connection::open_in_memory()?;
let user_version: i32 =
db.query_row("SELECT user_version FROM pragma_user_version", [], |row| {
row.get(0)
})
.unwrap();
})?;
assert_eq!(0, user_version);
Ok(())
}
#[test]
fn pragma_query_no_schema() {
let db = Connection::open_in_memory().unwrap();
fn pragma_query_no_schema() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut user_version = -1;
db.pragma_query(None, "user_version", |row| {
user_version = row.get(0)?;
Ok(())
})
.unwrap();
})?;
assert_eq!(0, user_version);
Ok(())
}
#[test]
fn pragma_query_with_schema() {
let db = Connection::open_in_memory().unwrap();
fn pragma_query_with_schema() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut user_version = -1;
db.pragma_query(Some(DatabaseName::Main), "user_version", |row| {
user_version = row.get(0)?;
Ok(())
})
.unwrap();
})?;
assert_eq!(0, user_version);
Ok(())
}
#[test]
fn pragma() {
let db = Connection::open_in_memory().unwrap();
fn pragma() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut columns = Vec::new();
db.pragma(None, "table_info", &"sqlite_master", |row| {
let column: String = row.get(1)?;
columns.push(column);
Ok(())
})
.unwrap();
})?;
assert_eq!(5, columns.len());
Ok(())
}
#[test]
#[cfg(feature = "modern_sqlite")]
fn pragma_func() {
let db = Connection::open_in_memory().unwrap();
let mut table_info = db.prepare("SELECT * FROM pragma_table_info(?)").unwrap();
fn pragma_func() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut table_info = db.prepare("SELECT * FROM pragma_table_info(?)")?;
let mut columns = Vec::new();
let mut rows = table_info.query(&["sqlite_master"]).unwrap();
let mut rows = table_info.query(&["sqlite_master"])?;
while let Some(row) = rows.next().unwrap() {
while let Some(row) = rows.next()? {
let row = row;
let column: String = row.get(1).unwrap();
let column: String = row.get(1)?;
columns.push(column);
}
assert_eq!(5, columns.len());
Ok(())
}
#[test]
fn pragma_update() {
let db = Connection::open_in_memory().unwrap();
db.pragma_update(None, "user_version", &1).unwrap();
fn pragma_update() -> Result<()> {
let db = Connection::open_in_memory()?;
db.pragma_update(None, "user_version", &1)
}
#[test]
fn pragma_update_and_check() {
let db = Connection::open_in_memory().unwrap();
let journal_mode: String = db
.pragma_update_and_check(None, "journal_mode", &"OFF", |row| row.get(0))
.unwrap();
fn pragma_update_and_check() -> Result<()> {
let db = Connection::open_in_memory()?;
let journal_mode: String =
db.pragma_update_and_check(None, "journal_mode", &"OFF", |row| row.get(0))?;
assert_eq!("off", &journal_mode);
Ok(())
}
#[test]
@ -428,13 +428,14 @@ mod test {
}
#[test]
fn locking_mode() {
let db = Connection::open_in_memory().unwrap();
fn locking_mode() -> Result<()> {
let db = Connection::open_in_memory()?;
let r = db.pragma_update(None, "locking_mode", &"exclusive");
if cfg!(feature = "extra_check") {
r.unwrap_err();
} else {
r.unwrap();
r?;
}
Ok(())
}
}

View File

@ -413,53 +413,46 @@ tuples_try_from_row!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
#[cfg(test)]
mod tests {
#![allow(clippy::redundant_closure)] // false positives due to lifetime issues; clippy issue #5594
use crate::{Connection, Result};
#[test]
fn test_try_from_row_for_tuple_1() {
use crate::{Connection, ToSql};
fn test_try_from_row_for_tuple_1() -> Result<()> {
use crate::ToSql;
use std::convert::TryFrom;
let conn = Connection::open_in_memory().expect("failed to create in-memoory database");
let conn = Connection::open_in_memory()?;
conn.execute(
"CREATE TABLE test (a INTEGER)",
crate::params_from_iter(std::iter::empty::<&dyn ToSql>()),
)
.expect("failed to create table");
conn.execute("INSERT INTO test VALUES (42)", [])
.expect("failed to insert value");
let val = conn
.query_row("SELECT a FROM test", [], |row| <(u32,)>::try_from(row))
.expect("failed to query row");
)?;
conn.execute("INSERT INTO test VALUES (42)", [])?;
let val = conn.query_row("SELECT a FROM test", [], |row| <(u32,)>::try_from(row))?;
assert_eq!(val, (42,));
let fail = conn.query_row("SELECT a FROM test", [], |row| <(u32, u32)>::try_from(row));
assert!(fail.is_err());
Ok(())
}
#[test]
fn test_try_from_row_for_tuple_2() {
use crate::Connection;
fn test_try_from_row_for_tuple_2() -> Result<()> {
use std::convert::TryFrom;
let conn = Connection::open_in_memory().expect("failed to create in-memoory database");
conn.execute("CREATE TABLE test (a INTEGER, b INTEGER)", [])
.expect("failed to create table");
conn.execute("INSERT INTO test VALUES (42, 47)", [])
.expect("failed to insert value");
let val = conn
.query_row("SELECT a, b FROM test", [], |row| {
<(u32, u32)>::try_from(row)
})
.expect("failed to query row");
let conn = Connection::open_in_memory()?;
conn.execute("CREATE TABLE test (a INTEGER, b INTEGER)", [])?;
conn.execute("INSERT INTO test VALUES (42, 47)", [])?;
let val = conn.query_row("SELECT a, b FROM test", [], |row| {
<(u32, u32)>::try_from(row)
})?;
assert_eq!(val, (42, 47));
let fail = conn.query_row("SELECT a, b FROM test", [], |row| {
<(u32, u32, u32)>::try_from(row)
});
assert!(fail.is_err());
Ok(())
}
#[test]
fn test_try_from_row_for_tuple_16() {
use crate::Connection;
fn test_try_from_row_for_tuple_16() -> Result<()> {
use std::convert::TryFrom;
let create_table = "CREATE TABLE test (
@ -519,14 +512,10 @@ mod tests {
u32,
);
let conn = Connection::open_in_memory().expect("failed to create in-memoory database");
conn.execute(create_table, [])
.expect("failed to create table");
conn.execute(insert_values, [])
.expect("failed to insert value");
let val = conn
.query_row("SELECT * FROM test", [], |row| BigTuple::try_from(row))
.expect("failed to query row");
let conn = Connection::open_in_memory()?;
conn.execute(create_table, [])?;
conn.execute(insert_values, [])?;
let val = conn.query_row("SELECT * FROM test", [], |row| BigTuple::try_from(row))?;
// Debug is not implemented for tuples of 16
assert_eq!(val.0, 0);
assert_eq!(val.1, 1);
@ -546,5 +535,6 @@ mod tests {
assert_eq!(val.15, 15);
// We don't test one bigger because it's unimplemented
Ok(())
}
}

View File

@ -781,80 +781,77 @@ mod test {
use super::{Changeset, ChangesetIter, ConflictAction, ConflictType, Session};
use crate::hooks::Action;
use crate::Connection;
use crate::{Connection, Result};
fn one_changeset() -> Changeset {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")
.unwrap();
fn one_changeset() -> Result<Changeset> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?;
let mut session = Session::new(&db).unwrap();
let mut session = Session::new(&db)?;
assert!(session.is_empty());
session.attach(None).unwrap();
db.execute("INSERT INTO foo (t) VALUES (?);", &["bar"])
.unwrap();
session.attach(None)?;
db.execute("INSERT INTO foo (t) VALUES (?);", &["bar"])?;
session.changeset().unwrap()
session.changeset()
}
fn one_changeset_strm() -> Vec<u8> {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")
.unwrap();
fn one_changeset_strm() -> Result<Vec<u8>> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?;
let mut session = Session::new(&db).unwrap();
let mut session = Session::new(&db)?;
assert!(session.is_empty());
session.attach(None).unwrap();
db.execute("INSERT INTO foo (t) VALUES (?);", &["bar"])
.unwrap();
session.attach(None)?;
db.execute("INSERT INTO foo (t) VALUES (?);", &["bar"])?;
let mut output = Vec::new();
session.changeset_strm(&mut output).unwrap();
output
session.changeset_strm(&mut output)?;
Ok(output)
}
#[test]
fn test_changeset() {
let changeset = one_changeset();
let mut iter = changeset.iter().unwrap();
let item = iter.next().unwrap();
fn test_changeset() -> Result<()> {
let changeset = one_changeset()?;
let mut iter = changeset.iter()?;
let item = iter.next()?;
assert!(item.is_some());
let item = item.unwrap();
let op = item.op().unwrap();
let op = item.op()?;
assert_eq!("foo", op.table_name());
assert_eq!(1, op.number_of_columns());
assert_eq!(Action::SQLITE_INSERT, op.code());
assert_eq!(false, op.indirect());
let pk = item.pk().unwrap();
let pk = item.pk()?;
assert_eq!(&[1], pk);
let new_value = item.new_value(0).unwrap();
let new_value = item.new_value(0)?;
assert_eq!(Ok("bar"), new_value.as_str());
Ok(())
}
#[test]
fn test_changeset_strm() {
let output = one_changeset_strm();
fn test_changeset_strm() -> Result<()> {
let output = one_changeset_strm()?;
assert!(!output.is_empty());
assert_eq!(14, output.len());
let input: &mut dyn Read = &mut output.as_slice();
let mut iter = ChangesetIter::start_strm(&input).unwrap();
let item = iter.next().unwrap();
let mut iter = ChangesetIter::start_strm(&input)?;
let item = iter.next()?;
assert!(item.is_some());
Ok(())
}
#[test]
fn test_changeset_apply() {
let changeset = one_changeset();
fn test_changeset_apply() -> Result<()> {
let changeset = one_changeset()?;
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")
.unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?;
static CALLED: AtomicBool = AtomicBool::new(false);
db.apply(
@ -864,15 +861,12 @@ mod test {
CALLED.store(true, Ordering::Relaxed);
ConflictAction::SQLITE_CHANGESET_OMIT
},
)
.unwrap();
)?;
assert!(!CALLED.load(Ordering::Relaxed));
let check = db
.query_row("SELECT 1 FROM foo WHERE t = ?", &["bar"], |row| {
row.get::<_, i32>(0)
})
.unwrap();
let check = db.query_row("SELECT 1 FROM foo WHERE t = ?", &["bar"], |row| {
row.get::<_, i32>(0)
})?;
assert_eq!(1, check);
// conflict expected when same changeset applied again on the same db
@ -886,68 +880,66 @@ mod test {
assert_eq!(Ok("bar"), conflict.as_str());
ConflictAction::SQLITE_CHANGESET_OMIT
},
)
.unwrap();
)?;
assert!(CALLED.load(Ordering::Relaxed));
Ok(())
}
#[test]
fn test_changeset_apply_strm() {
let output = one_changeset_strm();
fn test_changeset_apply_strm() -> Result<()> {
let output = one_changeset_strm()?;
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")
.unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?;
let mut input = output.as_slice();
db.apply_strm(
&mut input,
None::<fn(&str) -> bool>,
|_conflict_type, _item| ConflictAction::SQLITE_CHANGESET_OMIT,
)
.unwrap();
)?;
let check = db
.query_row("SELECT 1 FROM foo WHERE t = ?", &["bar"], |row| {
row.get::<_, i32>(0)
})
.unwrap();
let check = db.query_row("SELECT 1 FROM foo WHERE t = ?", &["bar"], |row| {
row.get::<_, i32>(0)
})?;
assert_eq!(1, check);
Ok(())
}
#[test]
fn test_session_empty() {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")
.unwrap();
fn test_session_empty() -> Result<()> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(t TEXT PRIMARY KEY NOT NULL);")?;
let mut session = Session::new(&db).unwrap();
let mut session = Session::new(&db)?;
assert!(session.is_empty());
session.attach(None).unwrap();
db.execute("INSERT INTO foo (t) VALUES (?);", &["bar"])
.unwrap();
session.attach(None)?;
db.execute("INSERT INTO foo (t) VALUES (?);", &["bar"])?;
assert!(!session.is_empty());
Ok(())
}
#[test]
fn test_session_set_enabled() {
let db = Connection::open_in_memory().unwrap();
fn test_session_set_enabled() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut session = Session::new(&db).unwrap();
let mut session = Session::new(&db)?;
assert!(session.is_enabled());
session.set_enabled(false);
assert!(!session.is_enabled());
Ok(())
}
#[test]
fn test_session_set_indirect() {
let db = Connection::open_in_memory().unwrap();
fn test_session_set_indirect() -> Result<()> {
let db = Connection::open_in_memory()?;
let mut session = Session::new(&db).unwrap();
let mut session = Session::new(&db)?;
assert!(!session.is_indirect());
session.set_indirect(true);
assert!(session.is_indirect());
Ok(())
}
}

View File

@ -940,26 +940,23 @@ mod test {
#[test]
#[allow(deprecated)]
fn test_execute_named() {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap();
fn test_execute_named() -> Result<()> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(x INTEGER)")?;
assert_eq!(
db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &1i32)])
.unwrap(),
db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &1i32)])?,
1
);
assert_eq!(
db.execute("INSERT INTO foo(x) VALUES (:x)", &[(":x", &2i32)])
.unwrap(),
db.execute("INSERT INTO foo(x) VALUES (:x)", &[(":x", &2i32)])?,
1
);
assert_eq!(
db.execute(
"INSERT INTO foo(x) VALUES (:x)",
crate::named_params! {":x": 3i32}
)
.unwrap(),
)?,
1
);
@ -969,8 +966,7 @@ mod test {
"SELECT SUM(x) FROM foo WHERE x > :x",
&[(":x", &0i32)],
|r| r.get(0)
)
.unwrap()
)?
);
assert_eq!(
5i32,
@ -978,133 +974,118 @@ mod test {
"SELECT SUM(x) FROM foo WHERE x > :x",
&[(":x", &1i32)],
|r| r.get(0)
)
.unwrap()
)?
);
Ok(())
}
#[test]
#[allow(deprecated)]
fn test_stmt_execute_named() {
let db = Connection::open_in_memory().unwrap();
fn test_stmt_execute_named() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = "CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag \
INTEGER)";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut stmt = db
.prepare("INSERT INTO test (name) VALUES (:name)")
.unwrap();
stmt.execute_named(&[(":name", &"one")]).unwrap();
let mut stmt = db.prepare("INSERT INTO test (name) VALUES (:name)")?;
stmt.execute_named(&[(":name", &"one")])?;
let mut stmt = db
.prepare("SELECT COUNT(*) FROM test WHERE name = :name")
.unwrap();
let mut stmt = db.prepare("SELECT COUNT(*) FROM test WHERE name = :name")?;
assert_eq!(
1i32,
stmt.query_row_named::<i32, _>(&[(":name", &"one")], |r| r.get(0))
.unwrap()
stmt.query_row_named::<i32, _>(&[(":name", &"one")], |r| r.get(0))?
);
assert_eq!(
1i32,
stmt.query_row::<i32, _, _>(&[(":name", &"one")], |r| r.get(0))
.unwrap()
stmt.query_row::<i32, _, _>(&[(":name", &"one")], |r| r.get(0))?
);
Ok(())
}
#[test]
#[allow(deprecated)]
fn test_query_named() {
let db = Connection::open_in_memory().unwrap();
fn test_query_named() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = r#"
CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
INSERT INTO test(id, name) VALUES (1, "one");
"#;
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut stmt = db
.prepare("SELECT id FROM test where name = :name")
.unwrap();
let mut stmt = db.prepare("SELECT id FROM test where name = :name")?;
// legacy `_named` api
{
let mut rows = stmt.query_named(&[(":name", &"one")]).unwrap();
let id: Result<i32> = rows.next().unwrap().unwrap().get(0);
let mut rows = stmt.query_named(&[(":name", &"one")])?;
let id: Result<i32> = rows.next()?.unwrap().get(0);
assert_eq!(Ok(1), id);
}
// plain api
{
let mut rows = stmt.query(&[(":name", &"one")]).unwrap();
let id: Result<i32> = rows.next().unwrap().unwrap().get(0);
let mut rows = stmt.query(&[(":name", &"one")])?;
let id: Result<i32> = rows.next()?.unwrap().get(0);
assert_eq!(Ok(1), id);
}
Ok(())
}
#[test]
#[allow(deprecated)]
fn test_query_map_named() {
let db = Connection::open_in_memory().unwrap();
fn test_query_map_named() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = r#"
CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
INSERT INTO test(id, name) VALUES (1, "one");
"#;
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut stmt = db
.prepare("SELECT id FROM test where name = :name")
.unwrap();
let mut stmt = db.prepare("SELECT id FROM test where name = :name")?;
// legacy `_named` api
{
let mut rows = stmt
.query_map_named(&[(":name", &"one")], |row| {
let id: Result<i32> = row.get(0);
id.map(|i| 2 * i)
})
.unwrap();
let mut rows = stmt.query_map_named(&[(":name", &"one")], |row| {
let id: Result<i32> = row.get(0);
id.map(|i| 2 * i)
})?;
let doubled_id: i32 = rows.next().unwrap().unwrap();
let doubled_id: i32 = rows.next().unwrap()?;
assert_eq!(2, doubled_id);
}
// plain api
{
let mut rows = stmt
.query_map(&[(":name", &"one")], |row| {
let id: Result<i32> = row.get(0);
id.map(|i| 2 * i)
})
.unwrap();
let mut rows = stmt.query_map(&[(":name", &"one")], |row| {
let id: Result<i32> = row.get(0);
id.map(|i| 2 * i)
})?;
let doubled_id: i32 = rows.next().unwrap().unwrap();
let doubled_id: i32 = rows.next().unwrap()?;
assert_eq!(2, doubled_id);
}
Ok(())
}
#[test]
#[allow(deprecated)]
fn test_query_and_then_named() {
let db = Connection::open_in_memory().unwrap();
fn test_query_and_then_named() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = r#"
CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
INSERT INTO test(id, name) VALUES (1, "one");
INSERT INTO test(id, name) VALUES (2, "one");
"#;
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut stmt = db
.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")
.unwrap();
let mut rows = stmt
.query_and_then_named(&[(":name", &"one")], |row| {
let id: i32 = row.get(0)?;
if id == 1 {
Ok(id)
} else {
Err(Error::SqliteSingleThreadedMode)
}
})
.unwrap();
let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")?;
let mut rows = stmt.query_and_then_named(&[(":name", &"one")], |row| {
let id: i32 = row.get(0)?;
if id == 1 {
Ok(id)
} else {
Err(Error::SqliteSingleThreadedMode)
}
})?;
// first row should be Ok
let doubled_id: i32 = rows.next().unwrap().unwrap();
let doubled_id: i32 = rows.next().unwrap()?;
assert_eq!(1, doubled_id);
// second row should be Err
@ -1114,34 +1095,31 @@ mod test {
Err(Error::SqliteSingleThreadedMode) => (),
Err(_) => panic!("invalid Err"),
}
Ok(())
}
#[test]
fn test_query_and_then_by_name() {
let db = Connection::open_in_memory().unwrap();
fn test_query_and_then_by_name() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = r#"
CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
INSERT INTO test(id, name) VALUES (1, "one");
INSERT INTO test(id, name) VALUES (2, "one");
"#;
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut stmt = db
.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")
.unwrap();
let mut rows = stmt
.query_and_then(&[(":name", &"one")], |row| {
let id: i32 = row.get(0)?;
if id == 1 {
Ok(id)
} else {
Err(Error::SqliteSingleThreadedMode)
}
})
.unwrap();
let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")?;
let mut rows = stmt.query_and_then(&[(":name", &"one")], |row| {
let id: i32 = row.get(0)?;
if id == 1 {
Ok(id)
} else {
Err(Error::SqliteSingleThreadedMode)
}
})?;
// first row should be Ok
let doubled_id: i32 = rows.next().unwrap().unwrap();
let doubled_id: i32 = rows.next().unwrap()?;
assert_eq!(1, doubled_id);
// second row should be Err
@ -1151,29 +1129,28 @@ mod test {
Err(Error::SqliteSingleThreadedMode) => (),
Err(_) => panic!("invalid Err"),
}
Ok(())
}
#[test]
#[allow(deprecated)]
fn test_unbound_parameters_are_null() {
let db = Connection::open_in_memory().unwrap();
fn test_unbound_parameters_are_null() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = "CREATE TABLE test (x TEXT, y TEXT)";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut stmt = db
.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")
.unwrap();
stmt.execute_named(&[(":x", &"one")]).unwrap();
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
stmt.execute_named(&[(":x", &"one")])?;
let result: Option<String> = db
.query_row("SELECT y FROM test WHERE x = 'one'", [], |row| row.get(0))
.unwrap();
let result: Option<String> =
db.query_row("SELECT y FROM test WHERE x = 'one'", [], |row| row.get(0))?;
assert!(result.is_none());
Ok(())
}
#[test]
fn test_raw_binding() -> Result<()> {
let db = Connection::open_in_memory().unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE test (name TEXT, value INTEGER)")?;
{
let mut stmt = db.prepare("INSERT INTO test (name, value) VALUES (:name, ?3)")?;
@ -1203,164 +1180,147 @@ mod test {
}
#[test]
fn test_unbound_parameters_are_reused() {
let db = Connection::open_in_memory().unwrap();
fn test_unbound_parameters_are_reused() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = "CREATE TABLE test (x TEXT, y TEXT)";
db.execute_batch(sql).unwrap();
db.execute_batch(sql)?;
let mut stmt = db
.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")
.unwrap();
stmt.execute(&[(":x", &"one")]).unwrap();
stmt.execute(&[(":y", &"two")]).unwrap();
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
stmt.execute(&[(":x", &"one")])?;
stmt.execute(&[(":y", &"two")])?;
let result: String = db
.query_row("SELECT x FROM test WHERE y = 'two'", [], |row| row.get(0))
.unwrap();
let result: String =
db.query_row("SELECT x FROM test WHERE y = 'two'", [], |row| row.get(0))?;
assert_eq!(result, "one");
Ok(())
}
#[test]
fn test_insert() {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)")
.unwrap();
let mut stmt = db
.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?)")
.unwrap();
assert_eq!(stmt.insert(&[&1i32]).unwrap(), 1);
assert_eq!(stmt.insert(&[&2i32]).unwrap(), 2);
fn test_insert() -> Result<()> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)")?;
let mut stmt = db.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?)")?;
assert_eq!(stmt.insert(&[&1i32])?, 1);
assert_eq!(stmt.insert(&[&2i32])?, 2);
match stmt.insert(&[&1i32]).unwrap_err() {
Error::StatementChangedRows(0) => (),
err => panic!("Unexpected error {}", err),
}
let mut multi = db
.prepare("INSERT INTO foo (x) SELECT 3 UNION ALL SELECT 4")
.unwrap();
let mut multi = db.prepare("INSERT INTO foo (x) SELECT 3 UNION ALL SELECT 4")?;
match multi.insert([]).unwrap_err() {
Error::StatementChangedRows(2) => (),
err => panic!("Unexpected error {}", err),
}
Ok(())
}
#[test]
fn test_insert_different_tables() {
fn test_insert_different_tables() -> Result<()> {
// Test for https://github.com/rusqlite/rusqlite/issues/171
let db = Connection::open_in_memory().unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch(
r"
CREATE TABLE foo(x INTEGER);
CREATE TABLE bar(x INTEGER);
",
)
.unwrap();
)?;
assert_eq!(
db.prepare("INSERT INTO foo VALUES (10)")
.unwrap()
.insert([])
.unwrap(),
1
);
assert_eq!(
db.prepare("INSERT INTO bar VALUES (10)")
.unwrap()
.insert([])
.unwrap(),
1
);
assert_eq!(db.prepare("INSERT INTO foo VALUES (10)")?.insert([])?, 1);
assert_eq!(db.prepare("INSERT INTO bar VALUES (10)")?.insert([])?, 1);
Ok(())
}
#[test]
fn test_exists() {
let db = Connection::open_in_memory().unwrap();
fn test_exists() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER);
INSERT INTO foo VALUES(1);
INSERT INTO foo VALUES(2);
END;";
db.execute_batch(sql).unwrap();
let mut stmt = db.prepare("SELECT 1 FROM foo WHERE x = ?").unwrap();
assert!(stmt.exists([1i32]).unwrap());
assert!(stmt.exists(&[&2i32]).unwrap());
assert!(!stmt.exists([&0i32]).unwrap());
db.execute_batch(sql)?;
let mut stmt = db.prepare("SELECT 1 FROM foo WHERE x = ?")?;
assert!(stmt.exists([1i32])?);
assert!(stmt.exists(&[&2i32])?);
assert!(!stmt.exists([&0i32])?);
Ok(())
}
#[test]
fn test_query_row() {
let db = Connection::open_in_memory().unwrap();
fn test_query_row() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y INTEGER);
INSERT INTO foo VALUES(1, 3);
INSERT INTO foo VALUES(2, 4);
END;";
db.execute_batch(sql).unwrap();
let mut stmt = db.prepare("SELECT y FROM foo WHERE x = ?").unwrap();
db.execute_batch(sql)?;
let mut stmt = db.prepare("SELECT y FROM foo WHERE x = ?")?;
let y: Result<i64> = stmt.query_row([1i32], |r| r.get(0));
assert_eq!(3i64, y.unwrap());
assert_eq!(3i64, y?);
Ok(())
}
#[test]
fn test_query_by_column_name() {
let db = Connection::open_in_memory().unwrap();
fn test_query_by_column_name() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y INTEGER);
INSERT INTO foo VALUES(1, 3);
END;";
db.execute_batch(sql).unwrap();
let mut stmt = db.prepare("SELECT y FROM foo").unwrap();
db.execute_batch(sql)?;
let mut stmt = db.prepare("SELECT y FROM foo")?;
let y: Result<i64> = stmt.query_row([], |r| r.get("y"));
assert_eq!(3i64, y.unwrap());
assert_eq!(3i64, y?);
Ok(())
}
#[test]
fn test_query_by_column_name_ignore_case() {
let db = Connection::open_in_memory().unwrap();
fn test_query_by_column_name_ignore_case() -> Result<()> {
let db = Connection::open_in_memory()?;
let sql = "BEGIN;
CREATE TABLE foo(x INTEGER, y INTEGER);
INSERT INTO foo VALUES(1, 3);
END;";
db.execute_batch(sql).unwrap();
let mut stmt = db.prepare("SELECT y as Y FROM foo").unwrap();
db.execute_batch(sql)?;
let mut stmt = db.prepare("SELECT y as Y FROM foo")?;
let y: Result<i64> = stmt.query_row([], |r| r.get("y"));
assert_eq!(3i64, y.unwrap());
assert_eq!(3i64, y?);
Ok(())
}
#[test]
#[cfg(feature = "modern_sqlite")]
fn test_expanded_sql() {
let db = Connection::open_in_memory().unwrap();
let stmt = db.prepare("SELECT ?").unwrap();
stmt.bind_parameter(&1, 1).unwrap();
fn test_expanded_sql() -> Result<()> {
let db = Connection::open_in_memory()?;
let stmt = db.prepare("SELECT ?")?;
stmt.bind_parameter(&1, 1)?;
assert_eq!(Some("SELECT 1".to_owned()), stmt.expanded_sql());
Ok(())
}
#[test]
fn test_bind_parameters() {
let db = Connection::open_in_memory().unwrap();
fn test_bind_parameters() -> Result<()> {
let db = Connection::open_in_memory()?;
// dynamic slice:
db.query_row(
"SELECT ?1, ?2, ?3",
&[&1u8 as &dyn ToSql, &"one", &Some("one")],
|row| row.get::<_, u8>(0),
)
.unwrap();
)?;
// existing collection:
let data = vec![1, 2, 3];
db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
row.get::<_, u8>(0)
})
.unwrap();
})?;
db.query_row(
"SELECT ?1, ?2, ?3",
params_from_iter(data.as_slice()),
|row| row.get::<_, u8>(0),
)
.unwrap();
)?;
db.query_row("SELECT ?1, ?2, ?3", params_from_iter(data), |row| {
row.get::<_, u8>(0)
})
.unwrap();
})?;
use std::collections::BTreeSet;
let data: BTreeSet<String> = ["one", "two", "three"]
@ -1369,76 +1329,73 @@ mod test {
.collect();
db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
row.get::<_, String>(0)
})
.unwrap();
})?;
let data = [0; 3];
db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
row.get::<_, u8>(0)
})
.unwrap();
})?;
db.query_row("SELECT ?1, ?2, ?3", params_from_iter(data.iter()), |row| {
row.get::<_, u8>(0)
})
.unwrap();
})?;
Ok(())
}
#[test]
fn test_empty_stmt() {
let conn = Connection::open_in_memory().unwrap();
let mut stmt = conn.prepare("").unwrap();
fn test_empty_stmt() -> Result<()> {
let conn = Connection::open_in_memory()?;
let mut stmt = conn.prepare("")?;
assert_eq!(0, stmt.column_count());
assert!(stmt.parameter_index("test").is_ok());
assert!(stmt.step().is_err());
stmt.reset();
assert!(stmt.execute([]).is_err());
Ok(())
}
#[test]
fn test_comment_stmt() {
let conn = Connection::open_in_memory().unwrap();
conn.prepare("/*SELECT 1;*/").unwrap();
fn test_comment_stmt() -> Result<()> {
let conn = Connection::open_in_memory()?;
conn.prepare("/*SELECT 1;*/")?;
Ok(())
}
#[test]
fn test_comment_and_sql_stmt() {
let conn = Connection::open_in_memory().unwrap();
let stmt = conn.prepare("/*...*/ SELECT 1;").unwrap();
fn test_comment_and_sql_stmt() -> Result<()> {
let conn = Connection::open_in_memory()?;
let stmt = conn.prepare("/*...*/ SELECT 1;")?;
assert_eq!(1, stmt.column_count());
Ok(())
}
#[test]
fn test_semi_colon_stmt() {
let conn = Connection::open_in_memory().unwrap();
let stmt = conn.prepare(";").unwrap();
fn test_semi_colon_stmt() -> Result<()> {
let conn = Connection::open_in_memory()?;
let stmt = conn.prepare(";")?;
assert_eq!(0, stmt.column_count());
Ok(())
}
#[test]
fn test_utf16_conversion() {
let db = Connection::open_in_memory().unwrap();
db.pragma_update(None, "encoding", &"UTF-16le").unwrap();
let encoding: String = db
.pragma_query_value(None, "encoding", |row| row.get(0))
.unwrap();
fn test_utf16_conversion() -> Result<()> {
let db = Connection::open_in_memory()?;
db.pragma_update(None, "encoding", &"UTF-16le")?;
let encoding: String = db.pragma_query_value(None, "encoding", |row| row.get(0))?;
assert_eq!("UTF-16le", encoding);
db.execute_batch("CREATE TABLE foo(x TEXT)").unwrap();
db.execute_batch("CREATE TABLE foo(x TEXT)")?;
let expected = "テスト";
db.execute("INSERT INTO foo(x) VALUES (?)", &[&expected])
.unwrap();
let actual: String = db
.query_row("SELECT x FROM foo", [], |row| row.get(0))
.unwrap();
db.execute("INSERT INTO foo(x) VALUES (?)", &[&expected])?;
let actual: String = db.query_row("SELECT x FROM foo", [], |row| row.get(0))?;
assert_eq!(expected, actual);
Ok(())
}
#[test]
fn test_nul_byte() {
let db = Connection::open_in_memory().unwrap();
fn test_nul_byte() -> Result<()> {
let db = Connection::open_in_memory()?;
let expected = "a\x00b";
let actual: String = db
.query_row("SELECT ?", [expected], |row| row.get(0))
.unwrap();
let actual: String = db.query_row("SELECT ?", [expected], |row| row.get(0))?;
assert_eq!(expected, actual);
Ok(())
}
}

View File

@ -128,10 +128,10 @@ mod test {
use std::sync::Mutex;
use std::time::Duration;
use crate::Connection;
use crate::{Connection, Result};
#[test]
fn test_trace() {
fn test_trace() -> Result<()> {
lazy_static! {
static ref TRACED_STMTS: Mutex<Vec<String>> = Mutex::new(Vec::new());
}
@ -140,7 +140,7 @@ mod test {
traced_stmts.push(s.to_owned());
}
let mut db = Connection::open_in_memory().unwrap();
let mut db = Connection::open_in_memory()?;
db.trace(Some(tracer));
{
let _ = db.query_row("SELECT ?", &[&1i32], |_| Ok(()));
@ -156,10 +156,11 @@ mod test {
assert_eq!(traced_stmts.len(), 2);
assert_eq!(traced_stmts[0], "SELECT 1");
assert_eq!(traced_stmts[1], "SELECT 'hello'");
Ok(())
}
#[test]
fn test_profile() {
fn test_profile() -> Result<()> {
lazy_static! {
static ref PROFILED: Mutex<Vec<(String, Duration)>> = Mutex::new(Vec::new());
}
@ -168,14 +169,15 @@ mod test {
profiled.push((s.to_owned(), d));
}
let mut db = Connection::open_in_memory().unwrap();
let mut db = Connection::open_in_memory()?;
db.profile(Some(profiler));
db.execute_batch("PRAGMA application_id = 1").unwrap();
db.execute_batch("PRAGMA application_id = 1")?;
db.profile(None);
db.execute_batch("PRAGMA application_id = 2").unwrap();
db.execute_batch("PRAGMA application_id = 2")?;
let profiled = PROFILED.lock().unwrap();
assert_eq!(profiled.len(), 1);
assert_eq!(profiled[0].0, "PRAGMA application_id = 1");
Ok(())
}
}

View File

@ -500,35 +500,35 @@ impl Connection {
#[cfg(test)]
mod test {
use super::DropBehavior;
use crate::{Connection, Error};
use crate::{Connection, Error, Result};
fn checked_memory_handle() -> Connection {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (x INTEGER)").unwrap();
db
fn checked_memory_handle() -> Result<Connection> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (x INTEGER)")?;
Ok(db)
}
#[test]
fn test_drop() {
let mut db = checked_memory_handle();
fn test_drop() -> Result<()> {
let mut db = checked_memory_handle()?;
{
let tx = db.transaction().unwrap();
tx.execute_batch("INSERT INTO foo VALUES(1)").unwrap();
let tx = db.transaction()?;
tx.execute_batch("INSERT INTO foo VALUES(1)")?;
// default: rollback
}
{
let mut tx = db.transaction().unwrap();
tx.execute_batch("INSERT INTO foo VALUES(2)").unwrap();
let mut tx = db.transaction()?;
tx.execute_batch("INSERT INTO foo VALUES(2)")?;
tx.set_drop_behavior(DropBehavior::Commit)
}
{
let tx = db.transaction().unwrap();
let tx = db.transaction()?;
assert_eq!(
2i32,
tx.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap()
tx.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
);
}
Ok(())
}
fn assert_nested_tx_error(e: crate::Error) {
if let Error::SqliteFailure(e, Some(m)) = &e {
@ -542,165 +542,168 @@ mod test {
}
#[test]
fn test_unchecked_nesting() {
let db = checked_memory_handle();
fn test_unchecked_nesting() -> Result<()> {
let db = checked_memory_handle()?;
{
let tx = db.unchecked_transaction().unwrap();
let tx = db.unchecked_transaction()?;
let e = tx.unchecked_transaction().unwrap_err();
assert_nested_tx_error(e);
// default: rollback
}
{
let tx = db.unchecked_transaction().unwrap();
tx.execute_batch("INSERT INTO foo VALUES(1)").unwrap();
let tx = db.unchecked_transaction()?;
tx.execute_batch("INSERT INTO foo VALUES(1)")?;
// Ensure this doesn't interfere with ongoing transaction
let e = tx.unchecked_transaction().unwrap_err();
assert_nested_tx_error(e);
tx.execute_batch("INSERT INTO foo VALUES(1)").unwrap();
tx.commit().unwrap();
tx.execute_batch("INSERT INTO foo VALUES(1)")?;
tx.commit()?;
}
assert_eq!(
2i32,
db.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap()
db.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
);
Ok(())
}
#[test]
fn test_explicit_rollback_commit() {
let mut db = checked_memory_handle();
fn test_explicit_rollback_commit() -> Result<()> {
let mut db = checked_memory_handle()?;
{
let mut tx = db.transaction().unwrap();
let mut tx = db.transaction()?;
{
let mut sp = tx.savepoint().unwrap();
sp.execute_batch("INSERT INTO foo VALUES(1)").unwrap();
sp.rollback().unwrap();
sp.execute_batch("INSERT INTO foo VALUES(2)").unwrap();
sp.commit().unwrap();
let mut sp = tx.savepoint()?;
sp.execute_batch("INSERT INTO foo VALUES(1)")?;
sp.rollback()?;
sp.execute_batch("INSERT INTO foo VALUES(2)")?;
sp.commit()?;
}
tx.commit().unwrap();
tx.commit()?;
}
{
let tx = db.transaction().unwrap();
tx.execute_batch("INSERT INTO foo VALUES(4)").unwrap();
tx.commit().unwrap();
let tx = db.transaction()?;
tx.execute_batch("INSERT INTO foo VALUES(4)")?;
tx.commit()?;
}
{
let tx = db.transaction().unwrap();
let tx = db.transaction()?;
assert_eq!(
6i32,
tx.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap()
tx.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
);
}
Ok(())
}
#[test]
fn test_savepoint() {
let mut db = checked_memory_handle();
fn test_savepoint() -> Result<()> {
let mut db = checked_memory_handle()?;
{
let mut tx = db.transaction().unwrap();
tx.execute_batch("INSERT INTO foo VALUES(1)").unwrap();
assert_current_sum(1, &tx);
let mut tx = db.transaction()?;
tx.execute_batch("INSERT INTO foo VALUES(1)")?;
assert_current_sum(1, &tx)?;
tx.set_drop_behavior(DropBehavior::Commit);
{
let mut sp1 = tx.savepoint().unwrap();
sp1.execute_batch("INSERT INTO foo VALUES(2)").unwrap();
assert_current_sum(3, &sp1);
let mut sp1 = tx.savepoint()?;
sp1.execute_batch("INSERT INTO foo VALUES(2)")?;
assert_current_sum(3, &sp1)?;
// will rollback sp1
{
let mut sp2 = sp1.savepoint().unwrap();
sp2.execute_batch("INSERT INTO foo VALUES(4)").unwrap();
assert_current_sum(7, &sp2);
let mut sp2 = sp1.savepoint()?;
sp2.execute_batch("INSERT INTO foo VALUES(4)")?;
assert_current_sum(7, &sp2)?;
// will rollback sp2
{
let sp3 = sp2.savepoint().unwrap();
sp3.execute_batch("INSERT INTO foo VALUES(8)").unwrap();
assert_current_sum(15, &sp3);
sp3.commit().unwrap();
let sp3 = sp2.savepoint()?;
sp3.execute_batch("INSERT INTO foo VALUES(8)")?;
assert_current_sum(15, &sp3)?;
sp3.commit()?;
// committed sp3, but will be erased by sp2 rollback
}
assert_current_sum(15, &sp2);
assert_current_sum(15, &sp2)?;
}
assert_current_sum(3, &sp1);
assert_current_sum(3, &sp1)?;
}
assert_current_sum(1, &tx);
assert_current_sum(1, &tx)?;
}
assert_current_sum(1, &db);
assert_current_sum(1, &db)?;
Ok(())
}
#[test]
fn test_ignore_drop_behavior() {
let mut db = checked_memory_handle();
fn test_ignore_drop_behavior() -> Result<()> {
let mut db = checked_memory_handle()?;
let mut tx = db.transaction().unwrap();
let mut tx = db.transaction()?;
{
let mut sp1 = tx.savepoint().unwrap();
insert(1, &sp1);
sp1.rollback().unwrap();
insert(2, &sp1);
let mut sp1 = tx.savepoint()?;
insert(1, &sp1)?;
sp1.rollback()?;
insert(2, &sp1)?;
{
let mut sp2 = sp1.savepoint().unwrap();
let mut sp2 = sp1.savepoint()?;
sp2.set_drop_behavior(DropBehavior::Ignore);
insert(4, &sp2);
insert(4, &sp2)?;
}
assert_current_sum(6, &sp1);
sp1.commit().unwrap();
assert_current_sum(6, &sp1)?;
sp1.commit()?;
}
assert_current_sum(6, &tx);
assert_current_sum(6, &tx)?;
Ok(())
}
#[test]
fn test_savepoint_names() {
let mut db = checked_memory_handle();
fn test_savepoint_names() -> Result<()> {
let mut db = checked_memory_handle()?;
{
let mut sp1 = db.savepoint_with_name("my_sp").unwrap();
insert(1, &sp1);
assert_current_sum(1, &sp1);
let mut sp1 = db.savepoint_with_name("my_sp")?;
insert(1, &sp1)?;
assert_current_sum(1, &sp1)?;
{
let mut sp2 = sp1.savepoint_with_name("my_sp").unwrap();
let mut sp2 = sp1.savepoint_with_name("my_sp")?;
sp2.set_drop_behavior(DropBehavior::Commit);
insert(2, &sp2);
assert_current_sum(3, &sp2);
sp2.rollback().unwrap();
assert_current_sum(1, &sp2);
insert(4, &sp2);
insert(2, &sp2)?;
assert_current_sum(3, &sp2)?;
sp2.rollback()?;
assert_current_sum(1, &sp2)?;
insert(4, &sp2)?;
}
assert_current_sum(5, &sp1);
sp1.rollback().unwrap();
assert_current_sum(5, &sp1)?;
sp1.rollback()?;
{
let mut sp2 = sp1.savepoint_with_name("my_sp").unwrap();
let mut sp2 = sp1.savepoint_with_name("my_sp")?;
sp2.set_drop_behavior(DropBehavior::Ignore);
insert(8, &sp2);
insert(8, &sp2)?;
}
assert_current_sum(8, &sp1);
sp1.commit().unwrap();
assert_current_sum(8, &sp1)?;
sp1.commit()?;
}
assert_current_sum(8, &db);
assert_current_sum(8, &db)?;
Ok(())
}
#[test]
fn test_rc() {
fn test_rc() -> Result<()> {
use std::rc::Rc;
let mut conn = Connection::open_in_memory().unwrap();
let rc_txn = Rc::new(conn.transaction().unwrap());
let mut conn = Connection::open_in_memory()?;
let rc_txn = Rc::new(conn.transaction()?);
// This will compile only if Transaction is Debug
Rc::try_unwrap(rc_txn).unwrap();
Ok(())
}
fn insert(x: i32, conn: &Connection) {
conn.execute("INSERT INTO foo VALUES(?)", [x]).unwrap();
fn insert(x: i32, conn: &Connection) -> Result<usize> {
conn.execute("INSERT INTO foo VALUES(?)", [x])
}
fn assert_current_sum(x: i32, conn: &Connection) {
let i = conn
.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))
.unwrap();
fn assert_current_sum(x: i32, conn: &Connection) -> Result<()> {
let i = conn.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
assert_eq!(x, i);
Ok(())
}
}

View File

@ -137,114 +137,109 @@ mod test {
use crate::{Connection, Result};
use chrono::{DateTime, Duration, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
fn checked_memory_handle() -> Connection {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT, b BLOB)")
.unwrap();
db
fn checked_memory_handle() -> Result<Connection> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT, b BLOB)")?;
Ok(db)
}
#[test]
fn test_naive_date() {
let db = checked_memory_handle();
fn test_naive_date() -> Result<()> {
let db = checked_memory_handle()?;
let date = NaiveDate::from_ymd(2016, 2, 23);
db.execute("INSERT INTO foo (t) VALUES (?)", &[&date])
.unwrap();
db.execute("INSERT INTO foo (t) VALUES (?)", &[&date])?;
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!("2016-02-23", s);
let t: NaiveDate = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let t: NaiveDate = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(date, t);
Ok(())
}
#[test]
fn test_naive_time() {
let db = checked_memory_handle();
fn test_naive_time() -> Result<()> {
let db = checked_memory_handle()?;
let time = NaiveTime::from_hms(23, 56, 4);
db.execute("INSERT INTO foo (t) VALUES (?)", &[&time])
.unwrap();
db.execute("INSERT INTO foo (t) VALUES (?)", &[&time])?;
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!("23:56:04", s);
let v: NaiveTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let v: NaiveTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(time, v);
Ok(())
}
#[test]
fn test_naive_date_time() {
let db = checked_memory_handle();
fn test_naive_date_time() -> Result<()> {
let db = checked_memory_handle()?;
let date = NaiveDate::from_ymd(2016, 2, 23);
let time = NaiveTime::from_hms(23, 56, 4);
let dt = NaiveDateTime::new(date, time);
db.execute("INSERT INTO foo (t) VALUES (?)", &[&dt])
.unwrap();
db.execute("INSERT INTO foo (t) VALUES (?)", &[&dt])?;
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!("2016-02-23T23:56:04", s);
let v: NaiveDateTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let v: NaiveDateTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(dt, v);
db.execute("UPDATE foo set b = datetime(t)", []).unwrap(); // "YYYY-MM-DD HH:MM:SS"
let hms: NaiveDateTime = db.query_row("SELECT b FROM foo", [], |r| r.get(0)).unwrap();
db.execute("UPDATE foo set b = datetime(t)", [])?; // "YYYY-MM-DD HH:MM:SS"
let hms: NaiveDateTime = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
assert_eq!(dt, hms);
Ok(())
}
#[test]
fn test_date_time_utc() {
let db = checked_memory_handle();
fn test_date_time_utc() -> Result<()> {
let db = checked_memory_handle()?;
let date = NaiveDate::from_ymd(2016, 2, 23);
let time = NaiveTime::from_hms_milli(23, 56, 4, 789);
let dt = NaiveDateTime::new(date, time);
let utc = Utc.from_utc_datetime(&dt);
db.execute("INSERT INTO foo (t) VALUES (?)", &[&utc])
.unwrap();
db.execute("INSERT INTO foo (t) VALUES (?)", &[&utc])?;
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!("2016-02-23T23:56:04.789+00:00", s);
let v1: DateTime<Utc> = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let v1: DateTime<Utc> = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(utc, v1);
let v2: DateTime<Utc> = db
.query_row("SELECT '2016-02-23 23:56:04.789'", [], |r| r.get(0))
.unwrap();
let v2: DateTime<Utc> =
db.query_row("SELECT '2016-02-23 23:56:04.789'", [], |r| r.get(0))?;
assert_eq!(utc, v2);
let v3: DateTime<Utc> = db
.query_row("SELECT '2016-02-23 23:56:04'", [], |r| r.get(0))
.unwrap();
let v3: DateTime<Utc> = db.query_row("SELECT '2016-02-23 23:56:04'", [], |r| r.get(0))?;
assert_eq!(utc - Duration::milliseconds(789), v3);
let v4: DateTime<Utc> = db
.query_row("SELECT '2016-02-23 23:56:04.789+00:00'", [], |r| r.get(0))
.unwrap();
let v4: DateTime<Utc> =
db.query_row("SELECT '2016-02-23 23:56:04.789+00:00'", [], |r| r.get(0))?;
assert_eq!(utc, v4);
Ok(())
}
#[test]
fn test_date_time_local() {
let db = checked_memory_handle();
fn test_date_time_local() -> Result<()> {
let db = checked_memory_handle()?;
let date = NaiveDate::from_ymd(2016, 2, 23);
let time = NaiveTime::from_hms_milli(23, 56, 4, 789);
let dt = NaiveDateTime::new(date, time);
let local = Local.from_local_datetime(&dt).single().unwrap();
db.execute("INSERT INTO foo (t) VALUES (?)", &[&local])
.unwrap();
db.execute("INSERT INTO foo (t) VALUES (?)", &[&local])?;
// Stored string should be in UTC
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert!(s.ends_with("+00:00"));
let v: DateTime<Local> = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let v: DateTime<Local> = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(local, v);
Ok(())
}
#[test]
fn test_sqlite_functions() {
let db = checked_memory_handle();
fn test_sqlite_functions() -> Result<()> {
let db = checked_memory_handle()?;
let result: Result<NaiveTime> = db.query_row("SELECT CURRENT_TIME", [], |r| r.get(0));
assert!(result.is_ok());
let result: Result<NaiveDate> = db.query_row("SELECT CURRENT_DATE", [], |r| r.get(0));
@ -255,5 +250,6 @@ mod test {
let result: Result<DateTime<Utc>> =
db.query_row("SELECT CURRENT_TIMESTAMP", [], |r| r.get(0));
assert!(result.is_ok());
Ok(())
}
}

View File

@ -235,15 +235,11 @@ impl FromSql for Value {
#[cfg(test)]
mod test {
use super::FromSql;
use crate::{Connection, Error};
fn checked_memory_handle() -> Connection {
Connection::open_in_memory().unwrap()
}
use crate::{Connection, Error, Result};
#[test]
fn test_integral_ranges() {
let db = checked_memory_handle();
fn test_integral_ranges() -> Result<()> {
let db = Connection::open_in_memory()?;
fn check_ranges<T>(db: &Connection, out_of_range: &[i64], in_range: &[i64])
where
@ -278,5 +274,6 @@ mod test {
check_ranges::<u8>(&db, &[-2, -1, 256], &[0, 1, 255]);
check_ranges::<u16>(&db, &[-2, -1, 65536], &[0, 1, 65535]);
check_ranges::<u32>(&db, &[-2, -1, 4_294_967_296], &[0, 1, 4_294_967_295]);
Ok(())
}
}

View File

@ -131,95 +131,92 @@ impl fmt::Display for Type {
#[cfg(test)]
mod test {
use super::Value;
use crate::{params, Connection, Error, Statement};
use crate::{params, Connection, Error, Result, Statement};
use std::f64::EPSILON;
use std::os::raw::{c_double, c_int};
fn checked_memory_handle() -> Connection {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (b BLOB, t TEXT, i INTEGER, f FLOAT, n)")
.unwrap();
db
fn checked_memory_handle() -> Result<Connection> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (b BLOB, t TEXT, i INTEGER, f FLOAT, n)")?;
Ok(db)
}
#[test]
fn test_blob() {
let db = checked_memory_handle();
fn test_blob() -> Result<()> {
let db = checked_memory_handle()?;
let v1234 = vec![1u8, 2, 3, 4];
db.execute("INSERT INTO foo(b) VALUES (?)", &[&v1234])
.unwrap();
db.execute("INSERT INTO foo(b) VALUES (?)", &[&v1234])?;
let v: Vec<u8> = db.query_row("SELECT b FROM foo", [], |r| r.get(0)).unwrap();
let v: Vec<u8> = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
assert_eq!(v, v1234);
Ok(())
}
#[test]
fn test_empty_blob() {
let db = checked_memory_handle();
fn test_empty_blob() -> Result<()> {
let db = checked_memory_handle()?;
let empty = vec![];
db.execute("INSERT INTO foo(b) VALUES (?)", &[&empty])
.unwrap();
db.execute("INSERT INTO foo(b) VALUES (?)", &[&empty])?;
let v: Vec<u8> = db.query_row("SELECT b FROM foo", [], |r| r.get(0)).unwrap();
let v: Vec<u8> = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
assert_eq!(v, empty);
Ok(())
}
#[test]
fn test_str() {
let db = checked_memory_handle();
fn test_str() -> Result<()> {
let db = checked_memory_handle()?;
let s = "hello, world!";
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s]).unwrap();
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s])?;
let from: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let from: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(from, s);
Ok(())
}
#[test]
fn test_string() {
let db = checked_memory_handle();
fn test_string() -> Result<()> {
let db = checked_memory_handle()?;
let s = "hello, world!";
db.execute("INSERT INTO foo(t) VALUES (?)", [s.to_owned()])
.unwrap();
db.execute("INSERT INTO foo(t) VALUES (?)", [s.to_owned()])?;
let from: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let from: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(from, s);
Ok(())
}
#[test]
fn test_value() {
let db = checked_memory_handle();
fn test_value() -> Result<()> {
let db = checked_memory_handle()?;
db.execute("INSERT INTO foo(i) VALUES (?)", [Value::Integer(10)])
.unwrap();
db.execute("INSERT INTO foo(i) VALUES (?)", [Value::Integer(10)])?;
assert_eq!(
10i64,
db.query_row::<i64, _, _>("SELECT i FROM foo", [], |r| r.get(0))
.unwrap()
db.query_row::<i64, _, _>("SELECT i FROM foo", [], |r| r.get(0))?
);
Ok(())
}
#[test]
fn test_option() {
let db = checked_memory_handle();
fn test_option() -> Result<()> {
let db = checked_memory_handle()?;
let s = Some("hello, world!");
let b = Some(vec![1u8, 2, 3, 4]);
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s]).unwrap();
db.execute("INSERT INTO foo(b) VALUES (?)", &[&b]).unwrap();
db.execute("INSERT INTO foo(t) VALUES (?)", &[&s])?;
db.execute("INSERT INTO foo(b) VALUES (?)", &[&b])?;
let mut stmt = db
.prepare("SELECT t, b FROM foo ORDER BY ROWID ASC")
.unwrap();
let mut rows = stmt.query([]).unwrap();
let mut stmt = db.prepare("SELECT t, b FROM foo ORDER BY ROWID ASC")?;
let mut rows = stmt.query([])?;
{
let row1 = rows.next().unwrap().unwrap();
let row1 = rows.next()?.unwrap();
let s1: Option<String> = row1.get_unwrap(0);
let b1: Option<Vec<u8>> = row1.get_unwrap(1);
assert_eq!(s.unwrap(), s1.unwrap());
@ -227,42 +224,42 @@ mod test {
}
{
let row2 = rows.next().unwrap().unwrap();
let row2 = rows.next()?.unwrap();
let s2: Option<String> = row2.get_unwrap(0);
let b2: Option<Vec<u8>> = row2.get_unwrap(1);
assert!(s2.is_none());
assert_eq!(b, b2);
}
Ok(())
}
#[test]
#[allow(clippy::cognitive_complexity)]
fn test_mismatched_types() {
fn test_mismatched_types() -> Result<()> {
fn is_invalid_column_type(err: Error) -> bool {
matches!(err, Error::InvalidColumnType(..))
}
let db = checked_memory_handle();
let db = checked_memory_handle()?;
db.execute(
"INSERT INTO foo(b, t, i, f) VALUES (X'0102', 'text', 1, 1.5)",
[],
)
.unwrap();
)?;
let mut stmt = db.prepare("SELECT b, t, i, f, n FROM foo").unwrap();
let mut rows = stmt.query([]).unwrap();
let mut stmt = db.prepare("SELECT b, t, i, f, n FROM foo")?;
let mut rows = stmt.query([])?;
let row = rows.next().unwrap().unwrap();
let row = rows.next()?.unwrap();
// check the correct types come back as expected
assert_eq!(vec![1, 2], row.get::<_, Vec<u8>>(0).unwrap());
assert_eq!("text", row.get::<_, String>(1).unwrap());
assert_eq!(1, row.get::<_, c_int>(2).unwrap());
assert!((1.5 - row.get::<_, c_double>(3).unwrap()).abs() < EPSILON);
assert_eq!(row.get::<_, Option<c_int>>(4).unwrap(), None);
assert_eq!(row.get::<_, Option<c_double>>(4).unwrap(), None);
assert_eq!(row.get::<_, Option<String>>(4).unwrap(), None);
assert_eq!(vec![1, 2], row.get::<_, Vec<u8>>(0)?);
assert_eq!("text", row.get::<_, String>(1)?);
assert_eq!(1, row.get::<_, c_int>(2)?);
assert!((1.5 - row.get::<_, c_double>(3)?).abs() < EPSILON);
assert_eq!(row.get::<_, Option<c_int>>(4)?, None);
assert_eq!(row.get::<_, Option<c_double>>(4)?, None);
assert_eq!(row.get::<_, Option<String>>(4)?, None);
// check some invalid types
@ -347,58 +344,50 @@ mod test {
assert!(is_invalid_column_type(
row.get::<_, time::OffsetDateTime>(4).err().unwrap()
));
Ok(())
}
#[test]
fn test_dynamic_type() {
fn test_dynamic_type() -> Result<()> {
use super::Value;
let db = checked_memory_handle();
let db = checked_memory_handle()?;
db.execute(
"INSERT INTO foo(b, t, i, f) VALUES (X'0102', 'text', 1, 1.5)",
[],
)
.unwrap();
)?;
let mut stmt = db.prepare("SELECT b, t, i, f, n FROM foo").unwrap();
let mut rows = stmt.query([]).unwrap();
let mut stmt = db.prepare("SELECT b, t, i, f, n FROM foo")?;
let mut rows = stmt.query([])?;
let row = rows.next().unwrap().unwrap();
assert_eq!(Value::Blob(vec![1, 2]), row.get::<_, Value>(0).unwrap());
assert_eq!(
Value::Text(String::from("text")),
row.get::<_, Value>(1).unwrap()
);
assert_eq!(Value::Integer(1), row.get::<_, Value>(2).unwrap());
match row.get::<_, Value>(3).unwrap() {
let row = rows.next()?.unwrap();
assert_eq!(Value::Blob(vec![1, 2]), row.get::<_, Value>(0)?);
assert_eq!(Value::Text(String::from("text")), row.get::<_, Value>(1)?);
assert_eq!(Value::Integer(1), row.get::<_, Value>(2)?);
match row.get::<_, Value>(3)? {
Value::Real(val) => assert!((1.5 - val).abs() < EPSILON),
x => panic!("Invalid Value {:?}", x),
}
assert_eq!(Value::Null, row.get::<_, Value>(4).unwrap());
assert_eq!(Value::Null, row.get::<_, Value>(4)?);
Ok(())
}
macro_rules! test_conversion {
($db_etc:ident, $insert_value:expr, $get_type:ty,expect $expected_value:expr) => {
$db_etc
.insert_statement
.execute(params![$insert_value])
.unwrap();
$db_etc.insert_statement.execute(params![$insert_value])?;
let res = $db_etc
.query_statement
.query_row([], |row| row.get::<_, $get_type>(0));
assert_eq!(res.unwrap(), $expected_value);
$db_etc.delete_statement.execute([]).unwrap();
assert_eq!(res?, $expected_value);
$db_etc.delete_statement.execute([])?;
};
($db_etc:ident, $insert_value:expr, $get_type:ty,expect_from_sql_error) => {
$db_etc
.insert_statement
.execute(params![$insert_value])
.unwrap();
$db_etc.insert_statement.execute(params![$insert_value])?;
let res = $db_etc
.query_statement
.query_row([], |row| row.get::<_, $get_type>(0));
res.unwrap_err();
$db_etc.delete_statement.execute([]).unwrap();
$db_etc.delete_statement.execute([])?;
};
($db_etc:ident, $insert_value:expr, $get_type:ty,expect_to_sql_error) => {
$db_etc
@ -409,12 +398,12 @@ mod test {
}
#[test]
fn test_numeric_conversions() {
fn test_numeric_conversions() -> Result<()> {
#![allow(clippy::float_cmp)]
// Test what happens when we store an f32 and retrieve an i32 etc.
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (x)").unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (x)")?;
// SQLite actually ignores the column types, so we just need to test
// different numeric values.
@ -426,9 +415,9 @@ mod test {
}
let mut db_etc = DbEtc {
insert_statement: db.prepare("INSERT INTO foo VALUES (?1)").unwrap(),
query_statement: db.prepare("SELECT x FROM foo").unwrap(),
delete_statement: db.prepare("DELETE FROM foo").unwrap(),
insert_statement: db.prepare("INSERT INTO foo VALUES (?1)")?,
query_statement: db.prepare("SELECT x FROM foo")?,
delete_statement: db.prepare("DELETE FROM foo")?,
};
// Basic non-converting test.
@ -466,5 +455,6 @@ mod test {
// FromSql float to int conversion, never works even if the actual value
// is an integer.
test_conversion!(db_etc, 0f64, i64, expect_from_sql_error);
Ok(())
}
}

View File

@ -29,30 +29,29 @@ impl FromSql for Value {
#[cfg(test)]
mod test {
use crate::types::ToSql;
use crate::Connection;
use crate::{Connection, Result};
fn checked_memory_handle() -> Connection {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (t TEXT, b BLOB)")
.unwrap();
db
fn checked_memory_handle() -> Result<Connection> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (t TEXT, b BLOB)")?;
Ok(db)
}
#[test]
fn test_json_value() {
let db = checked_memory_handle();
fn test_json_value() -> Result<()> {
let db = checked_memory_handle()?;
let json = r#"{"foo": 13, "bar": "baz"}"#;
let data: serde_json::Value = serde_json::from_str(json).unwrap();
db.execute(
"INSERT INTO foo (t, b) VALUES (?, ?)",
&[&data as &dyn ToSql, &json.as_bytes()],
)
.unwrap();
)?;
let t: serde_json::Value = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let t: serde_json::Value = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
assert_eq!(data, t);
let b: serde_json::Value = db.query_row("SELECT b FROM foo", [], |r| r.get(0)).unwrap();
let b: serde_json::Value = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
assert_eq!(data, b);
Ok(())
}
}

View File

@ -37,16 +37,15 @@ mod test {
use std::time::Duration;
use time::OffsetDateTime;
fn checked_memory_handle() -> Connection {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT)")
.unwrap();
db
fn checked_memory_handle() -> Result<Connection> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT)")?;
Ok(db)
}
#[test]
fn test_offset_date_time() {
let db = checked_memory_handle();
fn test_offset_date_time() -> Result<()> {
let db = checked_memory_handle()?;
let mut ts_vec = vec![];
@ -61,21 +60,23 @@ mod test {
ts_vec.push(make_datetime(10_000_000_000, 0)); //November 20, 2286
for ts in ts_vec {
db.execute("INSERT INTO foo(t) VALUES (?)", &[&ts]).unwrap();
db.execute("INSERT INTO foo(t) VALUES (?)", &[&ts])?;
let from: OffsetDateTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0)).unwrap();
let from: OffsetDateTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
db.execute("DELETE FROM foo", []).unwrap();
db.execute("DELETE FROM foo", [])?;
assert_eq!(from, ts);
}
Ok(())
}
#[test]
fn test_sqlite_functions() {
let db = checked_memory_handle();
fn test_sqlite_functions() -> Result<()> {
let db = checked_memory_handle()?;
let result: Result<OffsetDateTime> =
db.query_row("SELECT CURRENT_TIMESTAMP", [], |r| r.get(0));
assert!(result.is_ok());
Ok(())
}
}

View File

@ -245,6 +245,7 @@ impl<T: ToSql> ToSql for Option<T> {
#[cfg(test)]
mod test {
use super::ToSql;
use crate::Result;
fn is_to_sql<T: ToSql>() {}
@ -339,12 +340,11 @@ mod test {
#[cfg(feature = "i128_blob")]
#[test]
fn test_i128() {
fn test_i128() -> Result<()> {
use crate::Connection;
use std::i128;
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (i128 BLOB, desc TEXT)")
.unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (i128 BLOB, desc TEXT)")?;
db.execute(
"
INSERT INTO foo(i128, desc) VALUES
@ -353,20 +353,15 @@ mod test {
(?, 'pos one'), (?, 'pos two'),
(?, 'min'), (?, 'max')",
[0i128, -1i128, -2i128, 1i128, 2i128, i128::MIN, i128::MAX],
)
.unwrap();
)?;
let mut stmt = db
.prepare("SELECT i128, desc FROM foo ORDER BY i128 ASC")
.unwrap();
let mut stmt = db.prepare("SELECT i128, desc FROM foo ORDER BY i128 ASC")?;
let res = stmt
.query_map([], |row| {
Ok((row.get::<_, i128>(0)?, row.get::<_, String>(1)?))
})
.unwrap()
.collect::<Result<Vec<_>, _>>()
.unwrap();
})?
.collect::<Result<Vec<_>, _>>()?;
assert_eq!(
res,
@ -380,37 +375,35 @@ mod test {
(i128::MAX, "max".to_owned()),
]
);
Ok(())
}
#[cfg(feature = "uuid")]
#[test]
fn test_uuid() {
fn test_uuid() -> Result<()> {
use crate::{params, Connection};
use uuid::Uuid;
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE foo (id BLOB CHECK(length(id) = 16), label TEXT);")
.unwrap();
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo (id BLOB CHECK(length(id) = 16), label TEXT);")?;
let id = Uuid::new_v4();
db.execute(
"INSERT INTO foo (id, label) VALUES (?, ?)",
params![id, "target"],
)
.unwrap();
)?;
let mut stmt = db
.prepare("SELECT id, label FROM foo WHERE id = ?")
.unwrap();
let mut stmt = db.prepare("SELECT id, label FROM foo WHERE id = ?")?;
let mut rows = stmt.query(params![id]).unwrap();
let row = rows.next().unwrap().unwrap();
let mut rows = stmt.query(params![id])?;
let row = rows.next()?.unwrap();
let found_id: Uuid = row.get_unwrap(0);
let found_label: String = row.get_unwrap(1);
assert_eq!(found_id, id);
assert_eq!(found_label, "target");
Ok(())
}
}

View File

@ -30,11 +30,10 @@ mod test {
use crate::{params, Connection, Error, Result};
use url::{ParseError, Url};
fn checked_memory_handle() -> Connection {
let db = Connection::open_in_memory().unwrap();
db.execute_batch("CREATE TABLE urls (i INTEGER, v TEXT)")
.unwrap();
db
fn checked_memory_handle() -> Result<Connection> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE urls (i INTEGER, v TEXT)")?;
Ok(db)
}
fn get_url(db: &Connection, id: i64) -> Result<Url> {
@ -42,8 +41,8 @@ mod test {
}
#[test]
fn test_sql_url() {
let db = &checked_memory_handle();
fn test_sql_url() -> Result<()> {
let db = &checked_memory_handle()?;
let url0 = Url::parse("http://www.example1.com").unwrap();
let url1 = Url::parse("http://www.example1.com/👌").unwrap();
@ -54,16 +53,15 @@ mod test {
// also insert a non-hex encoded url (which might be present if it was
// inserted separately)
params![url0, url1, url2, "illegal"],
)
.unwrap();
)?;
assert_eq!(get_url(db, 0).unwrap(), url0);
assert_eq!(get_url(db, 0)?, url0);
assert_eq!(get_url(db, 1).unwrap(), url1);
assert_eq!(get_url(db, 1)?, url1);
// Should successfully read it, even though it wasn't inserted as an
// escaped url.
let out_url2: Url = get_url(db, 2).unwrap();
let out_url2: Url = get_url(db, 2)?;
assert_eq!(out_url2, Url::parse(url2).unwrap());
// Make sure the conversion error comes through correctly.
@ -79,5 +77,6 @@ mod test {
panic!("Expected conversion failure, got {}", e);
}
}
Ok(())
}
}

View File

@ -106,11 +106,11 @@ mod test {
use std::time;
#[test]
fn test_unlock_notify() {
fn test_unlock_notify() -> Result<()> {
let url = "file::memory:?cache=shared";
let flags = OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_URI;
let db1 = Connection::open_with_flags(url, flags).unwrap();
db1.execute_batch("CREATE TABLE foo (x)").unwrap();
let db1 = Connection::open_with_flags(url, flags)?;
db1.execute_batch("CREATE TABLE foo (x)")?;
let (rx, tx) = sync_channel(0);
let child = thread::spawn(move || {
let mut db2 = Connection::open_with_flags(url, flags).unwrap();
@ -123,7 +123,8 @@ mod test {
});
assert_eq!(tx.recv().unwrap(), 1);
let the_answer: Result<i64> = db1.query_row("SELECT x FROM foo", [], |r| r.get(0));
assert_eq!(42i64, the_answer.unwrap());
assert_eq!(42i64, the_answer?);
child.join().unwrap();
Ok(())
}
}

View File

@ -197,29 +197,30 @@ unsafe impl VTabCursor for ArrayTabCursor<'_> {
mod test {
use crate::types::Value;
use crate::vtab::array;
use crate::Connection;
use crate::{Connection, Result};
use std::rc::Rc;
#[test]
fn test_array_module() {
let db = Connection::open_in_memory().unwrap();
array::load_module(&db).unwrap();
fn test_array_module() -> Result<()> {
let db = Connection::open_in_memory()?;
array::load_module(&db)?;
let v = vec![1i64, 2, 3, 4];
let values: Vec<Value> = v.into_iter().map(Value::from).collect();
let ptr = Rc::new(values);
{
let mut stmt = db.prepare("SELECT value from rarray(?);").unwrap();
let mut stmt = db.prepare("SELECT value from rarray(?);")?;
let rows = stmt.query_map(&[&ptr], |row| row.get::<_, i64>(0)).unwrap();
let rows = stmt.query_map(&[&ptr], |row| row.get::<_, i64>(0))?;
assert_eq!(2, Rc::strong_count(&ptr));
let mut count = 0;
for (i, value) in rows.enumerate() {
assert_eq!(i as i64, value.unwrap() - 1);
assert_eq!(i as i64, value? - 1);
count += 1;
}
assert_eq!(4, count);
}
assert_eq!(1, Rc::strong_count(&ptr));
Ok(())
}
}

View File

@ -367,49 +367,41 @@ mod test {
use fallible_iterator::FallibleIterator;
#[test]
fn test_csv_module() {
let db = Connection::open_in_memory().unwrap();
csvtab::load_module(&db).unwrap();
db.execute_batch("CREATE VIRTUAL TABLE vtab USING csv(filename='test.csv', header=yes)")
.unwrap();
fn test_csv_module() -> Result<()> {
let db = Connection::open_in_memory()?;
csvtab::load_module(&db)?;
db.execute_batch("CREATE VIRTUAL TABLE vtab USING csv(filename='test.csv', header=yes)")?;
{
let mut s = db.prepare("SELECT rowid, * FROM vtab").unwrap();
let mut s = db.prepare("SELECT rowid, * FROM vtab")?;
{
let headers = s.column_names();
assert_eq!(vec!["rowid", "colA", "colB", "colC"], headers);
}
let ids: Result<Vec<i32>> = s
.query([])
.unwrap()
.map(|row| row.get::<_, i32>(0))
.collect();
let sum = ids.unwrap().iter().sum::<i32>();
let ids: Result<Vec<i32>> = s.query([])?.map(|row| row.get::<_, i32>(0)).collect();
let sum = ids?.iter().sum::<i32>();
assert_eq!(sum, 15);
}
db.execute_batch("DROP TABLE vtab").unwrap();
db.execute_batch("DROP TABLE vtab")
}
#[test]
fn test_csv_cursor() {
let db = Connection::open_in_memory().unwrap();
csvtab::load_module(&db).unwrap();
db.execute_batch("CREATE VIRTUAL TABLE vtab USING csv(filename='test.csv', header=yes)")
.unwrap();
fn test_csv_cursor() -> Result<()> {
let db = Connection::open_in_memory()?;
csvtab::load_module(&db)?;
db.execute_batch("CREATE VIRTUAL TABLE vtab USING csv(filename='test.csv', header=yes)")?;
{
let mut s = db
.prepare(
"SELECT v1.rowid, v1.* FROM vtab v1 NATURAL JOIN vtab v2 WHERE \
let mut s = db.prepare(
"SELECT v1.rowid, v1.* FROM vtab v1 NATURAL JOIN vtab v2 WHERE \
v1.rowid < v2.rowid",
)
.unwrap();
)?;
let mut rows = s.query([]).unwrap();
let row = rows.next().unwrap().unwrap();
let mut rows = s.query([])?;
let row = rows.next()?.unwrap();
assert_eq!(row.get_unwrap::<_, i32>(0), 2);
}
db.execute_batch("DROP TABLE vtab").unwrap();
db.execute_batch("DROP TABLE vtab")
}
}

View File

@ -273,26 +273,27 @@ unsafe impl VTabCursor for SeriesTabCursor<'_> {
mod test {
use crate::ffi;
use crate::vtab::series;
use crate::Connection;
use crate::{Connection, Result};
#[test]
fn test_series_module() {
fn test_series_module() -> Result<()> {
let version = unsafe { ffi::sqlite3_libversion_number() };
if version < 3_008_012 {
return;
return Ok(());
}
let db = Connection::open_in_memory().unwrap();
series::load_module(&db).unwrap();
let db = Connection::open_in_memory()?;
series::load_module(&db)?;
let mut s = db.prepare("SELECT * FROM generate_series(0,20,5)").unwrap();
let mut s = db.prepare("SELECT * FROM generate_series(0,20,5)")?;
let series = s.query_map([], |row| row.get::<_, i32>(0)).unwrap();
let series = s.query_map([], |row| row.get::<_, i32>(0))?;
let mut expected = 0;
for value in series {
assert_eq!(expected, value.unwrap());
assert_eq!(expected, value?);
expected += 5;
}
Ok(())
}
}

View File

@ -2,7 +2,7 @@
#[cfg(feature = "vtab")]
#[test]
fn test_dummy_module() {
fn test_dummy_module() -> rusqlite::Result<()> {
use rusqlite::types::ToSql;
use rusqlite::vtab::{
eponymous_only_module, sqlite3_vtab, sqlite3_vtab_cursor, Context, IndexInfo, VTab,
@ -84,20 +84,18 @@ fn test_dummy_module() {
}
}
let db = Connection::open_in_memory().unwrap();
let db = Connection::open_in_memory()?;
db.create_module::<DummyTab>("dummy", &module, None)
.unwrap();
db.create_module::<DummyTab>("dummy", &module, None)?;
let version = version_number();
if version < 3_008_012 {
return;
return Ok(());
}
let mut s = db.prepare("SELECT * FROM dummy()").unwrap();
let mut s = db.prepare("SELECT * FROM dummy()")?;
let dummy = s
.query_row(&[] as &[&dyn ToSql], |row| row.get::<_, i32>(0))
.unwrap();
let dummy = s.query_row(&[] as &[&dyn ToSql], |row| row.get::<_, i32>(0))?;
assert_eq!(1, dummy);
Ok(())
}