summaryrefslogtreecommitdiffstats
path: root/third_party/rust/rusqlite/tests
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/rusqlite/tests')
-rw-r--r--third_party/rust/rusqlite/tests/config_log.rs34
-rw-r--r--third_party/rust/rusqlite/tests/deny_single_threaded_sqlite_config.rs20
-rw-r--r--third_party/rust/rusqlite/tests/vtab.rs100
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..aeb7eec317
--- /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.
+
+#[cfg(not(feature = "loadable_extension"))]
+#[test]
+fn test_error_when_singlethread_mode() {
+ use rusqlite::ffi;
+ use rusqlite::Connection;
+ // 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();
+ res.unwrap_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(())
+}