mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-25 02:21:37 +08:00
Add Connection::extension_init2
This commit is contained in:
parent
92c536b622
commit
81585a75cb
@ -6263,49 +6263,23 @@ pub unsafe fn sqlite3_expanded_sql(
|
||||
(fun)(arg1)
|
||||
}
|
||||
|
||||
/// Loadable extension initialization error
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub enum InitError {
|
||||
/// Invalid sqlite3_api_routines pointer
|
||||
NullApiPointer,
|
||||
/// Version mismatch between the extension and the SQLite3 library
|
||||
VersionMismatch { compile_time: i32, runtime: i32 },
|
||||
/// Invalid function pointer in one of sqlite3_api_routines fields
|
||||
NullFunctionPointer,
|
||||
}
|
||||
impl ::std::fmt::Display for InitError {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
InitError::NullApiPointer => {
|
||||
write!(f, "Invalid sqlite3_api_routines pointer")
|
||||
}
|
||||
InitError::VersionMismatch { compile_time, runtime } => {
|
||||
write!(f, "SQLite version mismatch: {runtime} < {compile_time}")
|
||||
}
|
||||
InitError::NullFunctionPointer => {
|
||||
write!(f, "Some sqlite3_api_routines fields are null")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Like SQLITE_EXTENSION_INIT2 macro
|
||||
pub unsafe fn rusqlite_extension_init2(
|
||||
p_api: *mut sqlite3_api_routines,
|
||||
) -> ::std::result::Result<(), InitError> {
|
||||
) -> ::std::result::Result<(), crate::InitError> {
|
||||
if p_api.is_null() {
|
||||
return Err(InitError::NullApiPointer);
|
||||
return Err(crate::InitError::NullApiPointer);
|
||||
}
|
||||
if let Some(fun) = (*p_api).libversion_number {
|
||||
let version = fun();
|
||||
if SQLITE_VERSION_NUMBER > version {
|
||||
return Err(InitError::VersionMismatch {
|
||||
return Err(crate::InitError::VersionMismatch {
|
||||
compile_time: SQLITE_VERSION_NUMBER,
|
||||
runtime: version,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return Err(InitError::NullFunctionPointer);
|
||||
return Err(crate::InitError::NullFunctionPointer);
|
||||
}
|
||||
__SQLITE3_AGGREGATE_CONTEXT
|
||||
.store((*p_api).aggregate_context, ::atomic::Ordering::Release);
|
||||
|
@ -773,38 +773,18 @@ mod loadable_extension {
|
||||
}
|
||||
// (3) generate rust code similar to SQLITE_EXTENSION_INIT2 macro
|
||||
let tokens = quote::quote! {
|
||||
/// Loadable extension initialization error
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub enum InitError {
|
||||
/// Invalid sqlite3_api_routines pointer
|
||||
NullApiPointer,
|
||||
/// Version mismatch between the extension and the SQLite3 library
|
||||
VersionMismatch{compile_time: i32, runtime: i32},
|
||||
/// Invalid function pointer in one of sqlite3_api_routines fields
|
||||
NullFunctionPointer,
|
||||
}
|
||||
impl ::std::fmt::Display for InitError {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
InitError::NullApiPointer => write!(f, "Invalid sqlite3_api_routines pointer"),
|
||||
InitError::VersionMismatch{compile_time, runtime} => write!(f, "SQLite version mismatch: {runtime} < {compile_time}"),
|
||||
InitError::NullFunctionPointer => write!(f, "Some sqlite3_api_routines fields are null"),
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Like SQLITE_EXTENSION_INIT2 macro
|
||||
pub unsafe fn rusqlite_extension_init2(#p_api: *mut #sqlite3_api_routines_ident) -> ::std::result::Result<(),InitError> {
|
||||
pub unsafe fn rusqlite_extension_init2(#p_api: *mut #sqlite3_api_routines_ident) -> ::std::result::Result<(),crate::InitError> {
|
||||
if #p_api.is_null() {
|
||||
return Err(InitError::NullApiPointer);
|
||||
return Err(crate::InitError::NullApiPointer);
|
||||
}
|
||||
if let Some(fun) = (*#p_api).libversion_number {
|
||||
let version = fun();
|
||||
if SQLITE_VERSION_NUMBER > version {
|
||||
return Err(InitError::VersionMismatch{compile_time: SQLITE_VERSION_NUMBER, runtime: version});
|
||||
return Err(crate::InitError::VersionMismatch{compile_time: SQLITE_VERSION_NUMBER, runtime: version});
|
||||
}
|
||||
} else {
|
||||
return Err(InitError::NullFunctionPointer);
|
||||
return Err(crate::InitError::NullFunctionPointer);
|
||||
}
|
||||
#(#stores)*
|
||||
Ok(())
|
||||
|
@ -7459,49 +7459,23 @@ pub unsafe fn sqlite3_is_interrupted(arg1: *mut sqlite3) -> ::std::os::raw::c_in
|
||||
(fun)(arg1)
|
||||
}
|
||||
|
||||
/// Loadable extension initialization error
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub enum InitError {
|
||||
/// Invalid sqlite3_api_routines pointer
|
||||
NullApiPointer,
|
||||
/// Version mismatch between the extension and the SQLite3 library
|
||||
VersionMismatch { compile_time: i32, runtime: i32 },
|
||||
/// Invalid function pointer in one of sqlite3_api_routines fields
|
||||
NullFunctionPointer,
|
||||
}
|
||||
impl ::std::fmt::Display for InitError {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
InitError::NullApiPointer => {
|
||||
write!(f, "Invalid sqlite3_api_routines pointer")
|
||||
}
|
||||
InitError::VersionMismatch { compile_time, runtime } => {
|
||||
write!(f, "SQLite version mismatch: {runtime} < {compile_time}")
|
||||
}
|
||||
InitError::NullFunctionPointer => {
|
||||
write!(f, "Some sqlite3_api_routines fields are null")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Like SQLITE_EXTENSION_INIT2 macro
|
||||
pub unsafe fn rusqlite_extension_init2(
|
||||
p_api: *mut sqlite3_api_routines,
|
||||
) -> ::std::result::Result<(), InitError> {
|
||||
) -> ::std::result::Result<(), crate::InitError> {
|
||||
if p_api.is_null() {
|
||||
return Err(InitError::NullApiPointer);
|
||||
return Err(crate::InitError::NullApiPointer);
|
||||
}
|
||||
if let Some(fun) = (*p_api).libversion_number {
|
||||
let version = fun();
|
||||
if SQLITE_VERSION_NUMBER > version {
|
||||
return Err(InitError::VersionMismatch {
|
||||
return Err(crate::InitError::VersionMismatch {
|
||||
compile_time: SQLITE_VERSION_NUMBER,
|
||||
runtime: version,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return Err(InitError::NullFunctionPointer);
|
||||
return Err(crate::InitError::NullFunctionPointer);
|
||||
}
|
||||
__SQLITE3_AGGREGATE_CONTEXT
|
||||
.store((*p_api).aggregate_context, ::atomic::Ordering::Release);
|
||||
|
@ -269,3 +269,37 @@ pub fn code_to_str(code: c_int) -> &'static str {
|
||||
_ => "Unknown error code",
|
||||
}
|
||||
}
|
||||
|
||||
/// Loadable extension initialization error
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[non_exhaustive]
|
||||
pub enum InitError {
|
||||
/// Invalid sqlite3_api_routines pointer
|
||||
NullApiPointer,
|
||||
/// Version mismatch between the extension and the SQLite3 library
|
||||
VersionMismatch { compile_time: i32, runtime: i32 },
|
||||
/// Invalid function pointer in one of sqlite3_api_routines fields
|
||||
NullFunctionPointer,
|
||||
}
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
impl ::std::fmt::Display for InitError {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
InitError::NullApiPointer => {
|
||||
write!(f, "Invalid sqlite3_api_routines pointer")
|
||||
}
|
||||
InitError::VersionMismatch {
|
||||
compile_time,
|
||||
runtime,
|
||||
} => {
|
||||
write!(f, "SQLite version mismatch: {runtime} < {compile_time}")
|
||||
}
|
||||
InitError::NullFunctionPointer => {
|
||||
write!(f, "Some sqlite3_api_routines fields are null")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
impl error::Error for InitError {}
|
||||
|
18
src/error.rs
18
src/error.rs
@ -141,6 +141,10 @@ pub enum Error {
|
||||
/// byte offset of the start of invalid token
|
||||
offset: c_int,
|
||||
},
|
||||
/// Loadable extension initialization error
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "loadable_extension")))]
|
||||
InitError(ffi::InitError),
|
||||
}
|
||||
|
||||
impl PartialEq for Error {
|
||||
@ -200,6 +204,8 @@ impl PartialEq for Error {
|
||||
offset: o2,
|
||||
},
|
||||
) => e1 == e2 && m1 == m2 && s1 == s2 && o1 == o2,
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
(Error::InitError(e1), Error::InitError(e2)) => e1 == e2,
|
||||
(..) => false,
|
||||
}
|
||||
}
|
||||
@ -241,6 +247,14 @@ impl From<FromSqlError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
impl From<ffi::InitError> for Error {
|
||||
#[cold]
|
||||
fn from(err: ffi::InitError) -> Error {
|
||||
Error::InitError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
@ -311,6 +325,8 @@ impl fmt::Display for Error {
|
||||
ref sql,
|
||||
..
|
||||
} => write!(f, "{msg} in {sql} at offset {offset}"),
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
Error::InitError(ref err) => err.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -360,6 +376,8 @@ impl error::Error for Error {
|
||||
Error::BlobSizeError => None,
|
||||
#[cfg(feature = "modern_sqlite")]
|
||||
Error::SqlInputError { ref error, .. } => Some(error),
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
Error::InitError(ref err) => Some(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
src/lib.rs
11
src/lib.rs
@ -898,6 +898,17 @@ impl Connection {
|
||||
})
|
||||
}
|
||||
|
||||
/// Like SQLITE_EXTENSION_INIT2 macro
|
||||
#[cfg(feature = "loadable_extension")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "loadable_extension")))]
|
||||
pub unsafe fn extension_init2(
|
||||
db: *mut ffi::sqlite3,
|
||||
p_api: *mut ffi::sqlite3_api_routines,
|
||||
) -> Result<Connection> {
|
||||
ffi::rusqlite_extension_init2(p_api)?;
|
||||
Connection::from_handle(db)
|
||||
}
|
||||
|
||||
/// Create a `Connection` from a raw owned handle.
|
||||
///
|
||||
/// The returned connection will attempt to close the inner connection
|
||||
|
Loading…
Reference in New Issue
Block a user