Merge pull request #1494 from gwenn/register_ext

Improve Connection::extension_init2
This commit is contained in:
gwenn 2024-05-11 09:51:25 +02:00 committed by GitHub
commit 7f93b28705
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 15 deletions

View File

@ -4,7 +4,7 @@ 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};
use rusqlite::{Connection, Result};
/// # build
/// ```sh
@ -20,21 +20,15 @@ use rusqlite::{to_sqlite_error, Connection, Result};
/// ```
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[no_mangle]
pub extern "C" fn sqlite3_extension_init(
pub unsafe 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
Connection::extension_init2(db, pz_err_msg, p_api, extension_init)
}
fn extension_init(db: *mut ffi::sqlite3, p_api: *mut ffi::sqlite3_api_routines) -> Result<()> {
let db = unsafe { Connection::extension_init2(db, p_api)? };
fn extension_init(db: Connection) -> Result<bool> {
db.create_scalar_function(
"rusqlite_test_function",
0,
@ -46,5 +40,5 @@ fn extension_init(db: *mut ffi::sqlite3, p_api: *mut ffi::sqlite3_api_routines)
},
)?;
rusqlite::trace::log(ffi::SQLITE_WARNING, "Rusqlite extension initialized");
Ok(())
Ok(false)
}

View File

@ -952,15 +952,31 @@ impl Connection {
})
}
/// Like SQLITE_EXTENSION_INIT2 macro
/// Helper to register an SQLite extension written in Rust.
/// For [persistent](https://sqlite.org/loadext.html#persistent_loadable_extensions) extension,
/// `init` should returns `Ok(true)`.
/// # Safety
/// * Results are undefined if `init` does not just register features.
#[cfg(feature = "loadable_extension")]
#[cfg_attr(docsrs, doc(cfg(feature = "loadable_extension")))]
pub unsafe fn extension_init2(
db: *mut ffi::sqlite3,
pz_err_msg: *mut *mut c_char,
p_api: *mut ffi::sqlite3_api_routines,
) -> Result<Connection> {
ffi::rusqlite_extension_init2(p_api)?;
Connection::from_handle(db)
init: fn(Connection) -> Result<bool>,
) -> c_int {
if p_api.is_null() {
return ffi::SQLITE_ERROR;
}
match ffi::rusqlite_extension_init2(p_api)
.map_err(Error::from)
.and(Connection::from_handle(db))
.and_then(init)
{
Err(err) => to_sqlite_error(&err, pz_err_msg),
Ok(true) => ffi::SQLITE_OK_LOAD_PERMANENTLY,
_ => ffi::SQLITE_OK,
}
}
/// Create a `Connection` from a raw owned handle.