• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Adaptation of https://sqlite.org/loadext.html#programming_loadable_extensions
2 use std::os::raw::{c_char, c_int};
3 
4 use rusqlite::ffi;
5 use rusqlite::functions::FunctionFlags;
6 use rusqlite::types::{ToSqlOutput, Value};
7 use rusqlite::{Connection, Result};
8 
9 /// # build
10 /// ```sh
11 /// cargo build --example loadable_extension --features "loadable_extension functions trace"
12 /// ```
13 /// # test
14 /// ```sh
15 /// sqlite> .log on
16 /// sqlite> .load target/debug/examples/libloadable_extension.so
17 /// (28) Rusqlite extension initialized
18 /// sqlite> SELECT rusqlite_test_function();
19 /// Rusqlite extension loaded correctly!
20 /// ```
21 #[allow(clippy::not_unsafe_ptr_arg_deref)]
22 #[no_mangle]
sqlite3_extension_init( db: *mut ffi::sqlite3, pz_err_msg: *mut *mut c_char, p_api: *mut ffi::sqlite3_api_routines, ) -> c_int23 pub unsafe extern "C" fn sqlite3_extension_init(
24     db: *mut ffi::sqlite3,
25     pz_err_msg: *mut *mut c_char,
26     p_api: *mut ffi::sqlite3_api_routines,
27 ) -> c_int {
28     Connection::extension_init2(db, pz_err_msg, p_api, extension_init)
29 }
30 
extension_init(db: Connection) -> Result<bool>31 fn extension_init(db: Connection) -> Result<bool> {
32     db.create_scalar_function(
33         "rusqlite_test_function",
34         0,
35         FunctionFlags::SQLITE_DETERMINISTIC,
36         |_ctx| {
37             Ok(ToSqlOutput::Owned(Value::Text(
38                 "Rusqlite extension loaded correctly!".to_string(),
39             )))
40         },
41     )?;
42     rusqlite::trace::log(ffi::SQLITE_WARNING, "Rusqlite extension initialized");
43     Ok(false)
44 }
45