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)
|
(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
|
/// Like SQLITE_EXTENSION_INIT2 macro
|
||||||
pub unsafe fn rusqlite_extension_init2(
|
pub unsafe fn rusqlite_extension_init2(
|
||||||
p_api: *mut sqlite3_api_routines,
|
p_api: *mut sqlite3_api_routines,
|
||||||
) -> ::std::result::Result<(), InitError> {
|
) -> ::std::result::Result<(), crate::InitError> {
|
||||||
if p_api.is_null() {
|
if p_api.is_null() {
|
||||||
return Err(InitError::NullApiPointer);
|
return Err(crate::InitError::NullApiPointer);
|
||||||
}
|
}
|
||||||
if let Some(fun) = (*p_api).libversion_number {
|
if let Some(fun) = (*p_api).libversion_number {
|
||||||
let version = fun();
|
let version = fun();
|
||||||
if SQLITE_VERSION_NUMBER > version {
|
if SQLITE_VERSION_NUMBER > version {
|
||||||
return Err(InitError::VersionMismatch {
|
return Err(crate::InitError::VersionMismatch {
|
||||||
compile_time: SQLITE_VERSION_NUMBER,
|
compile_time: SQLITE_VERSION_NUMBER,
|
||||||
runtime: version,
|
runtime: version,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(InitError::NullFunctionPointer);
|
return Err(crate::InitError::NullFunctionPointer);
|
||||||
}
|
}
|
||||||
__SQLITE3_AGGREGATE_CONTEXT
|
__SQLITE3_AGGREGATE_CONTEXT
|
||||||
.store((*p_api).aggregate_context, ::atomic::Ordering::Release);
|
.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
|
// (3) generate rust code similar to SQLITE_EXTENSION_INIT2 macro
|
||||||
let tokens = quote::quote! {
|
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
|
/// 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() {
|
if #p_api.is_null() {
|
||||||
return Err(InitError::NullApiPointer);
|
return Err(crate::InitError::NullApiPointer);
|
||||||
}
|
}
|
||||||
if let Some(fun) = (*#p_api).libversion_number {
|
if let Some(fun) = (*#p_api).libversion_number {
|
||||||
let version = fun();
|
let version = fun();
|
||||||
if SQLITE_VERSION_NUMBER > version {
|
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 {
|
} else {
|
||||||
return Err(InitError::NullFunctionPointer);
|
return Err(crate::InitError::NullFunctionPointer);
|
||||||
}
|
}
|
||||||
#(#stores)*
|
#(#stores)*
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -7459,49 +7459,23 @@ pub unsafe fn sqlite3_is_interrupted(arg1: *mut sqlite3) -> ::std::os::raw::c_in
|
|||||||
(fun)(arg1)
|
(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
|
/// Like SQLITE_EXTENSION_INIT2 macro
|
||||||
pub unsafe fn rusqlite_extension_init2(
|
pub unsafe fn rusqlite_extension_init2(
|
||||||
p_api: *mut sqlite3_api_routines,
|
p_api: *mut sqlite3_api_routines,
|
||||||
) -> ::std::result::Result<(), InitError> {
|
) -> ::std::result::Result<(), crate::InitError> {
|
||||||
if p_api.is_null() {
|
if p_api.is_null() {
|
||||||
return Err(InitError::NullApiPointer);
|
return Err(crate::InitError::NullApiPointer);
|
||||||
}
|
}
|
||||||
if let Some(fun) = (*p_api).libversion_number {
|
if let Some(fun) = (*p_api).libversion_number {
|
||||||
let version = fun();
|
let version = fun();
|
||||||
if SQLITE_VERSION_NUMBER > version {
|
if SQLITE_VERSION_NUMBER > version {
|
||||||
return Err(InitError::VersionMismatch {
|
return Err(crate::InitError::VersionMismatch {
|
||||||
compile_time: SQLITE_VERSION_NUMBER,
|
compile_time: SQLITE_VERSION_NUMBER,
|
||||||
runtime: version,
|
runtime: version,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(InitError::NullFunctionPointer);
|
return Err(crate::InitError::NullFunctionPointer);
|
||||||
}
|
}
|
||||||
__SQLITE3_AGGREGATE_CONTEXT
|
__SQLITE3_AGGREGATE_CONTEXT
|
||||||
.store((*p_api).aggregate_context, ::atomic::Ordering::Release);
|
.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",
|
_ => "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
|
/// byte offset of the start of invalid token
|
||||||
offset: c_int,
|
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 {
|
impl PartialEq for Error {
|
||||||
@ -200,6 +204,8 @@ impl PartialEq for Error {
|
|||||||
offset: o2,
|
offset: o2,
|
||||||
},
|
},
|
||||||
) => e1 == e2 && m1 == m2 && s1 == s2 && o1 == o2,
|
) => e1 == e2 && m1 == m2 && s1 == s2 && o1 == o2,
|
||||||
|
#[cfg(feature = "loadable_extension")]
|
||||||
|
(Error::InitError(e1), Error::InitError(e2)) => e1 == e2,
|
||||||
(..) => false,
|
(..) => 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 {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
@ -311,6 +325,8 @@ impl fmt::Display for Error {
|
|||||||
ref sql,
|
ref sql,
|
||||||
..
|
..
|
||||||
} => write!(f, "{msg} in {sql} at offset {offset}"),
|
} => 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,
|
Error::BlobSizeError => None,
|
||||||
#[cfg(feature = "modern_sqlite")]
|
#[cfg(feature = "modern_sqlite")]
|
||||||
Error::SqlInputError { ref error, .. } => Some(error),
|
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.
|
/// Create a `Connection` from a raw owned handle.
|
||||||
///
|
///
|
||||||
/// The returned connection will attempt to close the inner connection
|
/// The returned connection will attempt to close the inner connection
|
||||||
|
Loading…
Reference in New Issue
Block a user