• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Automatic extension loading
2 use super::ffi;
3 use crate::error::{check, to_sqlite_error};
4 use crate::{Connection, Error, Result};
5 use std::os::raw::{c_char, c_int};
6 use std::panic::catch_unwind;
7 
8 /// Automatic extension initialization routine
9 pub type AutoExtension = fn(Connection) -> Result<()>;
10 
11 /// Raw automatic extension initialization routine
12 pub type RawAutoExtension = unsafe extern "C" fn(
13     db: *mut ffi::sqlite3,
14     pz_err_msg: *mut *mut c_char,
15     _: *const ffi::sqlite3_api_routines,
16 ) -> c_int;
17 
18 /// Bridge between `RawAutoExtension` and `AutoExtension`
19 ///
20 /// # Safety
21 /// * Opening a database from an auto-extension handler will lead to
22 ///   an endless recursion of the auto-handler triggering itself
23 ///   indirectly for each newly-opened database.
24 /// * Results are undefined if the given db is closed by an auto-extension.
25 /// * The list of auto-extensions should not be manipulated from an auto-extension.
init_auto_extension( db: *mut ffi::sqlite3, pz_err_msg: *mut *mut c_char, ax: AutoExtension, ) -> c_int26 pub unsafe fn init_auto_extension(
27     db: *mut ffi::sqlite3,
28     pz_err_msg: *mut *mut c_char,
29     ax: AutoExtension,
30 ) -> c_int {
31     let r = catch_unwind(|| {
32         let c = Connection::from_handle(db);
33         c.and_then(ax)
34     })
35     .unwrap_or_else(|_| Err(Error::UnwindingPanic));
36     match r {
37         Err(e) => to_sqlite_error(&e, pz_err_msg),
38         _ => ffi::SQLITE_OK,
39     }
40 }
41 
42 /// Register au auto-extension
43 ///
44 /// # Safety
45 /// * Opening a database from an auto-extension handler will lead to
46 ///   an endless recursion of the auto-handler triggering itself
47 ///   indirectly for each newly-opened database.
48 /// * Results are undefined if the given db is closed by an auto-extension.
49 /// * The list of auto-extensions should not be manipulated from an auto-extension.
register_auto_extension(ax: RawAutoExtension) -> Result<()>50 pub unsafe fn register_auto_extension(ax: RawAutoExtension) -> Result<()> {
51     check(ffi::sqlite3_auto_extension(Some(ax)))
52 }
53 
54 /// Unregister the initialization routine
cancel_auto_extension(ax: RawAutoExtension) -> bool55 pub fn cancel_auto_extension(ax: RawAutoExtension) -> bool {
56     unsafe { ffi::sqlite3_cancel_auto_extension(Some(ax)) == 1 }
57 }
58 
59 /// Disable all automatic extensions previously registered
reset_auto_extension()60 pub fn reset_auto_extension() {
61     unsafe { ffi::sqlite3_reset_auto_extension() }
62 }
63