Introduce to_sqlite_error

643c0f699f
One small step to support creating loadable extension
This commit is contained in:
gwenn 2023-06-08 20:01:17 +02:00
parent 38bf316601
commit 687aeef3b0
5 changed files with 36 additions and 33 deletions

View File

@ -443,3 +443,25 @@ pub fn check(code: c_int) -> Result<()> {
Ok(()) Ok(())
} }
} }
/// Transform Rust error to SQLite error (message and code).
/// # Safety
/// This function is unsafe because it uses raw pointer
pub unsafe fn to_sqlite_error(
e: &Error,
err_msg: *mut *mut std::os::raw::c_char,
) -> std::os::raw::c_int {
use crate::util::alloc;
match e {
Error::SqliteFailure(err, s) => {
if let Some(s) = s {
*err_msg = alloc(&s);
}
err.extended_code
}
err => {
*err_msg = alloc(&err.to_string());
ffi::SQLITE_ERROR
}
}
}

View File

@ -75,7 +75,7 @@ use crate::types::ValueRef;
pub use crate::cache::CachedStatement; pub use crate::cache::CachedStatement;
pub use crate::column::Column; pub use crate::column::Column;
pub use crate::error::Error; pub use crate::error::{to_sqlite_error, Error};
pub use crate::ffi::ErrorCode; pub use crate::ffi::ErrorCode;
#[cfg(feature = "load_extension")] #[cfg(feature = "load_extension")]
pub use crate::load_extension_guard::LoadExtensionGuard; pub use crate::load_extension_guard::LoadExtensionGuard;

View File

@ -6,4 +6,4 @@ pub(crate) use small_cstr::SmallCString;
// Doesn't use any modern features or vtab stuff, but is only used by them. // Doesn't use any modern features or vtab stuff, but is only used by them.
mod sqlite_string; mod sqlite_string;
pub(crate) use sqlite_string::SqliteMallocString; pub(crate) use sqlite_string::{alloc, SqliteMallocString};

View File

@ -7,6 +7,12 @@ use std::marker::PhantomData;
use std::os::raw::{c_char, c_int}; use std::os::raw::{c_char, c_int};
use std::ptr::NonNull; use std::ptr::NonNull;
// Space to hold this string must be obtained
// from an SQLite memory allocation function
pub(crate) fn alloc(s: &str) -> *mut c_char {
SqliteMallocString::from_str(s).into_raw()
}
/// A string we own that's allocated on the SQLite heap. Automatically calls /// A string we own that's allocated on the SQLite heap. Automatically calls
/// `sqlite3_free` when dropped, unless `into_raw` (or `into_inner`) is called /// `sqlite3_free` when dropped, unless `into_raw` (or `into_inner`) is called
/// on it. If constructed from a rust string, `sqlite3_malloc` is used. /// on it. If constructed from a rust string, `sqlite3_malloc` is used.

View File

@ -17,10 +17,11 @@ use std::ptr;
use std::slice; use std::slice;
use crate::context::set_result; use crate::context::set_result;
use crate::error::error_from_sqlite_code; use crate::error::{error_from_sqlite_code, to_sqlite_error};
use crate::ffi; use crate::ffi;
pub use crate::ffi::{sqlite3_vtab, sqlite3_vtab_cursor}; pub use crate::ffi::{sqlite3_vtab, sqlite3_vtab_cursor};
use crate::types::{FromSql, FromSqlError, ToSql, ValueRef}; use crate::types::{FromSql, FromSqlError, ToSql, ValueRef};
use crate::util::alloc;
use crate::{str_to_cstring, Connection, Error, InnerConnection, Result}; use crate::{str_to_cstring, Connection, Error, InnerConnection, Result};
// let conn: Connection = ...; // let conn: Connection = ...;
@ -964,8 +965,7 @@ where
ffi::SQLITE_OK ffi::SQLITE_OK
} else { } else {
let err = error_from_sqlite_code(rc, None); let err = error_from_sqlite_code(rc, None);
*err_msg = alloc(&err.to_string()); to_sqlite_error(&err, err_msg)
rc
} }
} }
Err(err) => { Err(err) => {
@ -973,16 +973,7 @@ where
ffi::SQLITE_ERROR ffi::SQLITE_ERROR
} }
}, },
Err(Error::SqliteFailure(err, s)) => { Err(err) => to_sqlite_error(&err, err_msg),
if let Some(s) = s {
*err_msg = alloc(&s);
}
err.extended_code
}
Err(err) => {
*err_msg = alloc(&err.to_string());
ffi::SQLITE_ERROR
}
} }
} }
@ -1016,8 +1007,7 @@ where
ffi::SQLITE_OK ffi::SQLITE_OK
} else { } else {
let err = error_from_sqlite_code(rc, None); let err = error_from_sqlite_code(rc, None);
*err_msg = alloc(&err.to_string()); to_sqlite_error(&err, err_msg)
rc
} }
} }
Err(err) => { Err(err) => {
@ -1025,16 +1015,7 @@ where
ffi::SQLITE_ERROR ffi::SQLITE_ERROR
} }
}, },
Err(Error::SqliteFailure(err, s)) => { Err(err) => to_sqlite_error(&err, err_msg),
if let Some(s) = s {
*err_msg = alloc(&s);
}
err.extended_code
}
Err(err) => {
*err_msg = alloc(&err.to_string());
ffi::SQLITE_ERROR
}
} }
} }
@ -1311,12 +1292,6 @@ unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) ->
} }
} }
// Space to hold this string must be obtained
// from an SQLite memory allocation function
fn alloc(s: &str) -> *mut c_char {
crate::util::SqliteMallocString::from_str(s).into_raw()
}
#[cfg(feature = "array")] #[cfg(feature = "array")]
#[cfg_attr(docsrs, doc(cfg(feature = "array")))] #[cfg_attr(docsrs, doc(cfg(feature = "array")))]
pub mod array; pub mod array;