mirror of
https://github.com/isar/rusqlite.git
synced 2025-03-31 19:12:58 +08:00
63 lines
2.1 KiB
Rust
63 lines
2.1 KiB
Rust
//! Automatic extension loading
|
|
use super::ffi;
|
|
use crate::error::{check, to_sqlite_error};
|
|
use crate::{Connection, Error, Result};
|
|
use std::os::raw::{c_char, c_int};
|
|
use std::panic::catch_unwind;
|
|
|
|
/// Automatic extension initialization routine
|
|
pub type AutoExtension = fn(Connection) -> Result<()>;
|
|
|
|
/// Raw automatic extension initialization routine
|
|
pub type RawAutoExtension = unsafe extern "C" fn(
|
|
db: *mut ffi::sqlite3,
|
|
pz_err_msg: *mut *mut c_char,
|
|
_: *const ffi::sqlite3_api_routines,
|
|
) -> c_int;
|
|
|
|
/// Bridge between `RawAutoExtension` and `AutoExtension`
|
|
///
|
|
/// # Safety
|
|
/// * Opening a database from an auto-extension handler will lead to
|
|
/// an endless recursion of the auto-handler triggering itself
|
|
/// indirectly for each newly-opened database.
|
|
/// * Results are undefined if the given db is closed by an auto-extension.
|
|
/// * The list of auto-extensions should not be manipulated from an auto-extension.
|
|
pub unsafe fn init_auto_extension(
|
|
db: *mut ffi::sqlite3,
|
|
pz_err_msg: *mut *mut c_char,
|
|
ax: AutoExtension,
|
|
) -> c_int {
|
|
let r = catch_unwind(|| {
|
|
let c = Connection::from_handle(db);
|
|
c.and_then(ax)
|
|
})
|
|
.unwrap_or_else(|_| Err(Error::UnwindingPanic));
|
|
match r {
|
|
Err(e) => to_sqlite_error(&e, pz_err_msg),
|
|
_ => ffi::SQLITE_OK,
|
|
}
|
|
}
|
|
|
|
/// Register au auto-extension
|
|
///
|
|
/// # Safety
|
|
/// * Opening a database from an auto-extension handler will lead to
|
|
/// an endless recursion of the auto-handler triggering itself
|
|
/// indirectly for each newly-opened database.
|
|
/// * Results are undefined if the given db is closed by an auto-extension.
|
|
/// * The list of auto-extensions should not be manipulated from an auto-extension.
|
|
pub unsafe fn register_auto_extension(ax: RawAutoExtension) -> Result<()> {
|
|
check(ffi::sqlite3_auto_extension(Some(ax)))
|
|
}
|
|
|
|
/// Unregister the initialization routine
|
|
pub fn cancel_auto_extension(ax: RawAutoExtension) -> bool {
|
|
unsafe { ffi::sqlite3_cancel_auto_extension(Some(ax)) == 1 }
|
|
}
|
|
|
|
/// Disable all automatic extensions previously registered
|
|
pub fn reset_auto_extension() {
|
|
unsafe { ffi::sqlite3_reset_auto_extension() }
|
|
}
|