Introduce err macro

This commit is contained in:
gwenn 2024-12-08 17:02:58 +01:00
parent 8081589201
commit e025f283f5
8 changed files with 40 additions and 70 deletions

View File

@ -412,6 +412,21 @@ pub fn error_from_sqlite_code(code: c_int, message: Option<String>) -> Error {
Error::SqliteFailure(ffi::Error::new(code), message) Error::SqliteFailure(ffi::Error::new(code), message)
} }
macro_rules! err {
($code:expr $(,)?) => {
$crate::error::error_from_sqlite_code($code, None)
};
($code:expr, $msg:literal $(,)?) => {
$crate::error::error_from_sqlite_code($code, Some(format!($msg)))
};
($code:expr, $err:expr $(,)?) => {
$crate::error::error_from_sqlite_code($code, Some(format!($err)))
};
($code:expr, $fmt:expr, $($arg:tt)*) => {
$crate::error::error_from_sqlite_code($code, Some(format!($fmt, $($arg)*)))
};
}
#[cold] #[cold]
pub unsafe fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error { pub unsafe fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error {
error_from_sqlite_code(code, error_msg(db, code)) error_from_sqlite_code(code, error_msg(db, code))

View File

@ -90,7 +90,7 @@ impl InnerConnection {
let r = ffi::sqlite3_open_v2(c_path.as_ptr(), &mut db, flags.bits(), z_vfs); let r = ffi::sqlite3_open_v2(c_path.as_ptr(), &mut db, flags.bits(), z_vfs);
if r != ffi::SQLITE_OK { if r != ffi::SQLITE_OK {
let e = if db.is_null() { let e = if db.is_null() {
error_from_sqlite_code(r, Some(c_path.to_string_lossy().to_string())) err!(r, "{}", c_path.to_string_lossy())
} else { } else {
let mut e = error_from_handle(db, r); let mut e = error_from_handle(db, r);
if let Error::SqliteFailure( if let Error::SqliteFailure(
@ -101,10 +101,7 @@ impl InnerConnection {
Some(msg), Some(msg),
) = e ) = e
{ {
e = Error::SqliteFailure( e = err!(r, "{msg}: {}", c_path.to_string_lossy());
ffi::Error::new(r),
Some(format!("{msg}: {}", c_path.to_string_lossy())),
);
} }
ffi::sqlite3_close(db); ffi::sqlite3_close(db);
e e
@ -344,14 +341,11 @@ impl InnerConnection {
match r { match r {
0 => Ok(false), 0 => Ok(false),
1 => Ok(true), 1 => Ok(true),
-1 => Err(Error::SqliteFailure( -1 => Err(err!(
ffi::Error::new(ffi::SQLITE_MISUSE), ffi::SQLITE_MISUSE,
Some(format!("{db_name:?} is not the name of a database")), "{db_name:?} is not the name of a database"
)),
_ => Err(error_from_sqlite_code(
r,
Some("Unexpected result".to_owned()),
)), )),
_ => Err(err!(r, "Unexpected result")),
} }
} }
@ -370,14 +364,11 @@ impl InnerConnection {
0 => Ok(super::transaction::TransactionState::None), 0 => Ok(super::transaction::TransactionState::None),
1 => Ok(super::transaction::TransactionState::Read), 1 => Ok(super::transaction::TransactionState::Read),
2 => Ok(super::transaction::TransactionState::Write), 2 => Ok(super::transaction::TransactionState::Write),
-1 => Err(Error::SqliteFailure( -1 => Err(err!(
ffi::Error::new(ffi::SQLITE_MISUSE), ffi::SQLITE_MISUSE,
Some(format!("{db_name:?} is not the name of a valid schema")), "{db_name:?} is not the name of a valid schema"
)),
_ => Err(error_from_sqlite_code(
r,
Some("Unexpected result".to_owned()),
)), )),
_ => Err(err!(r, "Unexpected result")),
} }
} }

View File

@ -93,6 +93,7 @@ pub use crate::version::*;
#[doc(hidden)] #[doc(hidden)]
pub use rusqlite_macros::__bind; pub use rusqlite_macros::__bind;
#[macro_use]
mod error; mod error;
#[cfg(not(feature = "loadable_extension"))] #[cfg(not(feature = "loadable_extension"))]
@ -321,10 +322,7 @@ fn str_for_sqlite(s: &[u8]) -> Result<(*const c_char, c_int, ffi::sqlite3_destru
// failed. // failed.
fn len_as_c_int(len: usize) -> Result<c_int> { fn len_as_c_int(len: usize) -> Result<c_int> {
if len >= (c_int::MAX as usize) { if len >= (c_int::MAX as usize) {
Err(Error::SqliteFailure( Err(err!(ffi::SQLITE_TOOBIG))
ffi::Error::new(ffi::SQLITE_TOOBIG),
None,
))
} else { } else {
Ok(len as c_int) Ok(len as c_int)
} }

View File

@ -1,6 +1,6 @@
//! Run-Time Limits //! Run-Time Limits
use crate::{ffi, Connection, Error, Result}; use crate::{ffi, Connection, Result};
use std::os::raw::c_int; use std::os::raw::c_int;
/// Run-Time limit categories, for use with [`Connection::limit`] and /// Run-Time limit categories, for use with [`Connection::limit`] and
@ -57,10 +57,7 @@ impl Connection {
let c = self.db.borrow(); let c = self.db.borrow();
let rc = unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, -1) }; let rc = unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, -1) };
if rc < 0 { if rc < 0 {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_RANGE, "{limit:?} is invalid"));
ffi::Error::new(ffi::SQLITE_RANGE),
Some(format!("{limit:?} is invalid")),
));
} }
Ok(rc) Ok(rc)
} }
@ -71,18 +68,12 @@ impl Connection {
#[cfg_attr(docsrs, doc(cfg(feature = "limits")))] #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
pub fn set_limit(&self, limit: Limit, new_val: i32) -> Result<i32> { pub fn set_limit(&self, limit: Limit, new_val: i32) -> Result<i32> {
if new_val < 0 { if new_val < 0 {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_RANGE, "{new_val} is invalid"));
ffi::Error::new(ffi::SQLITE_RANGE),
Some(format!("{new_val} is invalid")),
));
} }
let c = self.db.borrow_mut(); let c = self.db.borrow_mut();
let rc = unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, new_val) }; let rc = unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, new_val) };
if rc < 0 { if rc < 0 {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_RANGE, "{limit:?} is invalid"));
ffi::Error::new(ffi::SQLITE_RANGE),
Some(format!("{limit:?} is invalid")),
));
} }
Ok(rc) Ok(rc)
} }

View File

@ -2,7 +2,6 @@
use std::ops::Deref; use std::ops::Deref;
use crate::error::Error;
use crate::ffi; use crate::ffi;
use crate::types::{ToSql, ToSqlOutput, ValueRef}; use crate::types::{ToSql, ToSqlOutput, ValueRef};
use crate::{Connection, DatabaseName, Result, Row}; use crate::{Connection, DatabaseName, Result, Row};
@ -35,10 +34,7 @@ impl Sql {
self.buf.push_str(keyword); self.buf.push_str(keyword);
Ok(()) Ok(())
} else { } else {
Err(Error::SqliteFailure( Err(err!(ffi::SQLITE_MISUSE, "Invalid keyword \"{keyword}\""))
ffi::Error::new(ffi::SQLITE_MISUSE),
Some(format!("Invalid keyword \"{keyword}\"")),
))
} }
} }
@ -66,24 +62,15 @@ impl Sql {
ToSqlOutput::Owned(ref v) => ValueRef::from(v), ToSqlOutput::Owned(ref v) => ValueRef::from(v),
#[cfg(feature = "blob")] #[cfg(feature = "blob")]
ToSqlOutput::ZeroBlob(_) => { ToSqlOutput::ZeroBlob(_) => {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_MISUSE, "Unsupported value \"{value:?}\""));
ffi::Error::new(ffi::SQLITE_MISUSE),
Some(format!("Unsupported value \"{value:?}\"")),
));
} }
#[cfg(feature = "functions")] #[cfg(feature = "functions")]
ToSqlOutput::Arg(_) => { ToSqlOutput::Arg(_) => {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_MISUSE, "Unsupported value \"{value:?}\""));
ffi::Error::new(ffi::SQLITE_MISUSE),
Some(format!("Unsupported value \"{value:?}\"")),
));
} }
#[cfg(feature = "array")] #[cfg(feature = "array")]
ToSqlOutput::Array(_) => { ToSqlOutput::Array(_) => {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_MISUSE, "Unsupported value \"{value:?}\""));
ffi::Error::new(ffi::SQLITE_MISUSE),
Some(format!("Unsupported value \"{value:?}\"")),
));
} }
}; };
match value { match value {
@ -98,10 +85,7 @@ impl Sql {
self.push_string_literal(s); self.push_string_literal(s);
} }
_ => { _ => {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_MISUSE, "Unsupported value \"{value:?}\""));
ffi::Error::new(ffi::SQLITE_MISUSE),
Some(format!("Unsupported value \"{value:?}\"")),
));
} }
}; };
Ok(()) Ok(())

View File

@ -608,10 +608,7 @@ impl Statement<'_> {
} }
#[cfg(feature = "functions")] #[cfg(feature = "functions")]
ToSqlOutput::Arg(_) => { ToSqlOutput::Arg(_) => {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_MISUSE, "Unsupported value \"{value:?}\""));
ffi::Error::new(ffi::SQLITE_MISUSE),
Some(format!("Unsupported value \"{value:?}\"")),
));
} }
#[cfg(feature = "array")] #[cfg(feature = "array")]
ToSqlOutput::Array(a) => { ToSqlOutput::Array(a) => {

View File

@ -501,10 +501,7 @@ impl IndexInfo {
let idx = constraint_idx as c_int; let idx = constraint_idx as c_int;
let collation = unsafe { ffi::sqlite3_vtab_collation(self.0, idx) }; let collation = unsafe { ffi::sqlite3_vtab_collation(self.0, idx) };
if collation.is_null() { if collation.is_null() {
return Err(Error::SqliteFailure( return Err(err!(ffi::SQLITE_MISUSE, "{constraint_idx} is out of range"));
ffi::Error::new(ffi::SQLITE_MISUSE),
Some(format!("{constraint_idx} is out of range")),
));
} }
Ok(unsafe { CStr::from_ptr(collation) }.to_str()?) Ok(unsafe { CStr::from_ptr(collation) }.to_str()?)
} }

View File

@ -12,7 +12,7 @@ use crate::vtab::{
eponymous_only_module, Context, IndexConstraintOp, IndexInfo, VTab, VTabConfig, VTabConnection, eponymous_only_module, Context, IndexConstraintOp, IndexInfo, VTab, VTabConfig, VTabConnection,
VTabCursor, Values, VTabCursor, Values,
}; };
use crate::{Connection, Error, Result}; use crate::{error::error_from_sqlite_code, Connection, Result};
/// Register the `generate_series` module. /// Register the `generate_series` module.
pub fn load_module(conn: &Connection) -> Result<()> { pub fn load_module(conn: &Connection) -> Result<()> {
@ -108,10 +108,7 @@ unsafe impl<'vtab> VTab<'vtab> for SeriesTab {
debug_assert_eq!(Ok("BINARY"), info.collation(*j)); debug_assert_eq!(Ok("BINARY"), info.collation(*j));
} }
if !(unusable_mask & !idx_num).is_empty() { if !(unusable_mask & !idx_num).is_empty() {
return Err(Error::SqliteFailure( return Err(error_from_sqlite_code(ffi::SQLITE_CONSTRAINT, None));
ffi::Error::new(ffi::SQLITE_CONSTRAINT),
None,
));
} }
if idx_num.contains(QueryPlanFlags::BOTH) { if idx_num.contains(QueryPlanFlags::BOTH) {
// Both start= and stop= boundaries are available. // Both start= and stop= boundaries are available.