diff options
Diffstat (limited to 'third_party/rust/rusqlite/tests')
-rw-r--r-- | third_party/rust/rusqlite/tests/config_log.rs | 34 | ||||
-rw-r--r-- | third_party/rust/rusqlite/tests/deny_single_threaded_sqlite_config.rs | 20 | ||||
-rw-r--r-- | third_party/rust/rusqlite/tests/vtab.rs | 100 |
3 files changed, 154 insertions, 0 deletions
diff --git a/third_party/rust/rusqlite/tests/config_log.rs b/third_party/rust/rusqlite/tests/config_log.rs new file mode 100644 index 0000000000..0c28bdf1df --- /dev/null +++ b/third_party/rust/rusqlite/tests/config_log.rs @@ -0,0 +1,34 @@ +//! This file contains unit tests for `rusqlite::trace::config_log`. This +//! function affects SQLite process-wide and so is not safe to run as a normal +//! #[test] in the library. + +#[cfg(feature = "trace")] +fn main() { + use lazy_static::lazy_static; + use std::os::raw::c_int; + use std::sync::Mutex; + + lazy_static! { + static ref LOGS_RECEIVED: Mutex<Vec<(c_int, String)>> = Mutex::new(Vec::new()); + } + + fn log_handler(err: c_int, message: &str) { + let mut logs_received = LOGS_RECEIVED.lock().unwrap(); + logs_received.push((err, message.to_owned())); + } + + use rusqlite::trace; + + unsafe { trace::config_log(Some(log_handler)) }.unwrap(); + trace::log(10, "First message from rusqlite"); + unsafe { trace::config_log(None) }.unwrap(); + trace::log(11, "Second message from rusqlite"); + + let logs_received = LOGS_RECEIVED.lock().unwrap(); + assert_eq!(logs_received.len(), 1); + assert_eq!(logs_received[0].0, 10); + assert_eq!(logs_received[0].1, "First message from rusqlite"); +} + +#[cfg(not(feature = "trace"))] +fn main() {} diff --git a/third_party/rust/rusqlite/tests/deny_single_threaded_sqlite_config.rs b/third_party/rust/rusqlite/tests/deny_single_threaded_sqlite_config.rs new file mode 100644 index 0000000000..adfc8e55ce --- /dev/null +++ b/third_party/rust/rusqlite/tests/deny_single_threaded_sqlite_config.rs @@ -0,0 +1,20 @@ +//! Ensure we reject connections when SQLite is in single-threaded mode, as it +//! would violate safety if multiple Rust threads tried to use connections. + +use rusqlite::ffi; +use rusqlite::Connection; + +#[test] +fn test_error_when_singlethread_mode() { + // put SQLite into single-threaded mode + unsafe { + // Note: macOS system SQLite seems to return an error if you attempt to + // reconfigure to single-threaded mode. + if ffi::sqlite3_config(ffi::SQLITE_CONFIG_SINGLETHREAD) != ffi::SQLITE_OK { + return; + } + assert_eq!(ffi::sqlite3_initialize(), ffi::SQLITE_OK); + } + let res = Connection::open_in_memory(); + assert!(res.is_err()); +} diff --git a/third_party/rust/rusqlite/tests/vtab.rs b/third_party/rust/rusqlite/tests/vtab.rs new file mode 100644 index 0000000000..65582064c9 --- /dev/null +++ b/third_party/rust/rusqlite/tests/vtab.rs @@ -0,0 +1,100 @@ +//! Ensure Virtual tables can be declared outside `rusqlite` crate. + +#[cfg(feature = "vtab")] +#[test] +fn test_dummy_module() -> rusqlite::Result<()> { + use rusqlite::vtab::{ + eponymous_only_module, sqlite3_vtab, sqlite3_vtab_cursor, Context, IndexInfo, VTab, + VTabConnection, VTabCursor, Values, + }; + use rusqlite::{version_number, Connection, Result}; + use std::marker::PhantomData; + use std::os::raw::c_int; + + let module = eponymous_only_module::<DummyTab>(); + + #[repr(C)] + struct DummyTab { + /// Base class. Must be first + base: sqlite3_vtab, + } + + unsafe impl<'vtab> VTab<'vtab> for DummyTab { + type Aux = (); + type Cursor = DummyTabCursor<'vtab>; + + fn connect( + _: &mut VTabConnection, + _aux: Option<&()>, + _args: &[&[u8]], + ) -> Result<(String, DummyTab)> { + let vtab = DummyTab { + base: sqlite3_vtab::default(), + }; + Ok(("CREATE TABLE x(value)".to_owned(), vtab)) + } + + fn best_index(&self, info: &mut IndexInfo) -> Result<()> { + info.set_estimated_cost(1.); + Ok(()) + } + + fn open(&'vtab mut self) -> Result<DummyTabCursor<'vtab>> { + Ok(DummyTabCursor::default()) + } + } + + #[derive(Default)] + #[repr(C)] + struct DummyTabCursor<'vtab> { + /// Base class. Must be first + base: sqlite3_vtab_cursor, + /// The rowid + row_id: i64, + phantom: PhantomData<&'vtab DummyTab>, + } + + unsafe impl VTabCursor for DummyTabCursor<'_> { + fn filter( + &mut self, + _idx_num: c_int, + _idx_str: Option<&str>, + _args: &Values<'_>, + ) -> Result<()> { + self.row_id = 1; + Ok(()) + } + + fn next(&mut self) -> Result<()> { + self.row_id += 1; + Ok(()) + } + + fn eof(&self) -> bool { + self.row_id > 1 + } + + fn column(&self, ctx: &mut Context, _: c_int) -> Result<()> { + ctx.set_result(&self.row_id) + } + + fn rowid(&self) -> Result<i64> { + Ok(self.row_id) + } + } + + let db = Connection::open_in_memory()?; + + db.create_module::<DummyTab>("dummy", module, None)?; + + let version = version_number(); + if version < 3_009_000 { + return Ok(()); + } + + let mut s = db.prepare("SELECT * FROM dummy()")?; + + let dummy = s.query_row([], |row| row.get::<_, i32>(0))?; + assert_eq!(1, dummy); + Ok(()) +} |