diff options
Diffstat (limited to 'third_party/rust/rusqlite/examples')
-rw-r--r-- | third_party/rust/rusqlite/examples/load_extension.rs | 22 | ||||
-rw-r--r-- | third_party/rust/rusqlite/examples/loadable_extension.rs | 50 |
2 files changed, 72 insertions, 0 deletions
diff --git a/third_party/rust/rusqlite/examples/load_extension.rs b/third_party/rust/rusqlite/examples/load_extension.rs new file mode 100644 index 0000000000..9e52bb202f --- /dev/null +++ b/third_party/rust/rusqlite/examples/load_extension.rs @@ -0,0 +1,22 @@ +//! Ensure loadable_extension.rs works. + +use rusqlite::{Connection, Result}; + +fn main() -> Result<()> { + let db = Connection::open_in_memory()?; + + unsafe { + db.load_extension_enable()?; + #[cfg(not(windows))] + db.load_extension("target/debug/examples/libloadable_extension", None)?; + #[cfg(windows)] + db.load_extension("target/debug/examples/loadable_extension", None)?; + db.load_extension_disable()?; + } + + let str = db.query_row("SELECT rusqlite_test_function()", [], |row| { + row.get::<_, String>(0) + })?; + assert_eq!(&str, "Rusqlite extension loaded correctly!"); + Ok(()) +} diff --git a/third_party/rust/rusqlite/examples/loadable_extension.rs b/third_party/rust/rusqlite/examples/loadable_extension.rs new file mode 100644 index 0000000000..e913240573 --- /dev/null +++ b/third_party/rust/rusqlite/examples/loadable_extension.rs @@ -0,0 +1,50 @@ +//! Adaptation of https://sqlite.org/loadext.html#programming_loadable_extensions +use std::os::raw::{c_char, c_int}; + +use rusqlite::ffi; +use rusqlite::functions::FunctionFlags; +use rusqlite::types::{ToSqlOutput, Value}; +use rusqlite::{to_sqlite_error, Connection, Result}; + +/// # build +/// ```sh +/// cargo build --example loadable_extension --features "loadable_extension modern_sqlite functions vtab trace" +/// ``` +/// # test +/// ```sh +/// sqlite> .log on +/// sqlite> .load target/debug/examples/libloadable_extension.so +/// (28) Rusqlite extension initialized +/// sqlite> SELECT rusqlite_test_function(); +/// Rusqlite extension loaded correctly! +/// ``` +#[allow(clippy::not_unsafe_ptr_arg_deref)] +#[no_mangle] +pub extern "C" fn sqlite3_extension_init( + db: *mut ffi::sqlite3, + pz_err_msg: *mut *mut c_char, + p_api: *mut ffi::sqlite3_api_routines, +) -> c_int { + if p_api.is_null() { + return ffi::SQLITE_ERROR; + } else if let Err(err) = extension_init(db, p_api) { + return unsafe { to_sqlite_error(&err, pz_err_msg) }; + } + ffi::SQLITE_OK +} + +fn extension_init(db: *mut ffi::sqlite3, p_api: *mut ffi::sqlite3_api_routines) -> Result<()> { + let db = unsafe { Connection::extension_init2(db, p_api)? }; + db.create_scalar_function( + "rusqlite_test_function", + 0, + FunctionFlags::SQLITE_DETERMINISTIC, + |_ctx| { + Ok(ToSqlOutput::Owned(Value::Text( + "Rusqlite extension loaded correctly!".to_string(), + ))) + }, + )?; + rusqlite::trace::log(ffi::SQLITE_WARNING, "Rusqlite extension initialized"); + Ok(()) +} |