2018-10-31 03:13:41 +08:00
|
|
|
use crate::types::Type;
|
|
|
|
use crate::{errmsg_to_string, ffi};
|
2015-12-13 14:04:09 +08:00
|
|
|
use std::error;
|
|
|
|
use std::fmt;
|
2018-08-11 18:48:21 +08:00
|
|
|
use std::os::raw::c_int;
|
2015-12-13 14:04:09 +08:00
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::str;
|
|
|
|
|
2015-12-17 12:46:39 +08:00
|
|
|
/// Enum listing possible errors from rusqlite.
|
2015-12-13 14:04:09 +08:00
|
|
|
#[derive(Debug)]
|
2016-08-08 21:23:55 +08:00
|
|
|
#[allow(enum_variant_names)]
|
2015-12-13 14:04:09 +08:00
|
|
|
pub enum Error {
|
2015-12-17 12:46:39 +08:00
|
|
|
/// An error from an underlying SQLite call.
|
2015-12-13 14:04:09 +08:00
|
|
|
SqliteFailure(ffi::Error, Option<String>),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error reported when attempting to open a connection when SQLite was
|
|
|
|
/// configured to allow single-threaded use only.
|
2015-12-17 12:33:56 +08:00
|
|
|
SqliteSingleThreadedMode,
|
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when the value of a particular column is requested, but it cannot
|
|
|
|
/// be converted to the requested Rust type.
|
2016-06-03 03:03:25 +08:00
|
|
|
FromSqlConversionFailure(usize, Type, Box<error::Error + Send + Sync>),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when SQLite gives us an integral value outside the range of the
|
|
|
|
/// requested type (e.g., trying to get the value 1000 into a `u8`).
|
|
|
|
/// The associated `usize` is the column index,
|
|
|
|
/// and the associated `i64` is the value returned by SQLite.
|
2018-05-24 03:04:13 +08:00
|
|
|
IntegralValueOutOfRange(usize, i64),
|
2017-01-23 08:26:19 +08:00
|
|
|
|
2015-12-17 12:46:39 +08:00
|
|
|
/// Error converting a string to UTF-8.
|
2015-12-13 14:04:09 +08:00
|
|
|
Utf8Error(str::Utf8Error),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error converting a string to a C-compatible string because it contained
|
|
|
|
/// an embedded nul.
|
2015-12-13 14:04:09 +08:00
|
|
|
NulError(::std::ffi::NulError),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when using SQL named parameters and passing a parameter name not
|
|
|
|
/// present in the SQL.
|
2015-12-13 14:04:09 +08:00
|
|
|
InvalidParameterName(String),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
|
|
|
/// Error converting a file path to a string.
|
2015-12-13 14:04:09 +08:00
|
|
|
InvalidPath(PathBuf),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2016-01-08 00:36:01 +08:00
|
|
|
/// Error returned when an `execute` call returns rows.
|
2015-12-13 14:04:09 +08:00
|
|
|
ExecuteReturnedResults,
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when a query that was expected to return at least one row (e.g.,
|
|
|
|
/// for `query_row`) did not return any.
|
2015-12-13 14:04:09 +08:00
|
|
|
QueryReturnedNoRows,
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when the value of a particular column is requested, but the index
|
|
|
|
/// is out of range for the statement.
|
2018-05-24 03:04:13 +08:00
|
|
|
InvalidColumnIndex(usize),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when the value of a named column is requested, but no column
|
|
|
|
/// matches the name for the statement.
|
2016-01-02 19:13:37 +08:00
|
|
|
InvalidColumnName(String),
|
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when the value of a particular column is requested, but the type
|
|
|
|
/// of the result in that column cannot be converted to the requested
|
|
|
|
/// Rust type.
|
2018-05-24 03:04:13 +08:00
|
|
|
InvalidColumnType(usize, Type),
|
2015-12-13 14:04:09 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error when a query that was expected to insert one row did not insert
|
|
|
|
/// any or insert many.
|
2018-05-24 03:23:28 +08:00
|
|
|
StatementChangedRows(usize),
|
2016-05-17 00:15:07 +08:00
|
|
|
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error returned by `functions::Context::get` when the function argument
|
|
|
|
/// cannot be converted to the requested type.
|
2015-12-13 14:04:09 +08:00
|
|
|
#[cfg(feature = "functions")]
|
2016-05-31 02:35:56 +08:00
|
|
|
InvalidFunctionParameterType(usize, Type),
|
2018-08-17 00:29:46 +08:00
|
|
|
/// Error returned by `vtab::Values::get` when the filter argument cannot
|
|
|
|
/// be converted to the requested type.
|
2018-05-13 17:28:56 +08:00
|
|
|
#[cfg(feature = "vtab")]
|
|
|
|
InvalidFilterParameterType(usize, Type),
|
2015-12-17 12:46:39 +08:00
|
|
|
|
|
|
|
/// An error case available for implementors of custom user functions (e.g.,
|
|
|
|
/// `create_scalar_function`).
|
2015-12-13 14:04:09 +08:00
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
#[allow(dead_code)]
|
2015-12-16 03:34:42 +08:00
|
|
|
UserFunctionError(Box<error::Error + Send + Sync>),
|
2016-02-09 01:06:11 +08:00
|
|
|
|
2017-05-31 07:22:14 +08:00
|
|
|
/// Error available for the implementors of the `ToSql` trait.
|
|
|
|
ToSqlConversionFailure(Box<error::Error + Send + Sync>),
|
2018-01-20 19:29:07 +08:00
|
|
|
|
2018-08-11 02:48:13 +08:00
|
|
|
/// Error when the SQL is not a `SELECT`, is not read-only.
|
|
|
|
InvalidQuery,
|
2018-08-11 19:37:56 +08:00
|
|
|
|
2016-02-09 01:06:11 +08:00
|
|
|
/// An error case available for implementors of custom modules (e.g.,
|
|
|
|
/// `create_module`).
|
|
|
|
#[cfg(feature = "vtab")]
|
|
|
|
#[allow(dead_code)]
|
|
|
|
ModuleError(String),
|
2015-12-13 14:04:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<str::Utf8Error> for Error {
|
|
|
|
fn from(err: str::Utf8Error) -> Error {
|
|
|
|
Error::Utf8Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<::std::ffi::NulError> for Error {
|
|
|
|
fn from(err: ::std::ffi::NulError) -> Error {
|
|
|
|
Error::NulError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2016-02-14 23:11:59 +08:00
|
|
|
match *self {
|
|
|
|
Error::SqliteFailure(ref err, None) => err.fmt(f),
|
|
|
|
Error::SqliteFailure(_, Some(ref s)) => write!(f, "{}", s),
|
2018-08-11 18:48:21 +08:00
|
|
|
Error::SqliteSingleThreadedMode => write!(
|
|
|
|
f,
|
|
|
|
"SQLite was compiled or configured for single-threaded use only"
|
|
|
|
),
|
|
|
|
Error::FromSqlConversionFailure(i, ref t, ref err) => write!(
|
|
|
|
f,
|
|
|
|
"Conversion error from type {} at index: {}, {}",
|
|
|
|
t, i, err
|
|
|
|
),
|
2017-01-23 08:26:19 +08:00
|
|
|
Error::IntegralValueOutOfRange(col, val) => {
|
|
|
|
write!(f, "Integer {} out of range at index {}", val, col)
|
|
|
|
}
|
2016-02-14 23:11:59 +08:00
|
|
|
Error::Utf8Error(ref err) => err.fmt(f),
|
|
|
|
Error::NulError(ref err) => err.fmt(f),
|
|
|
|
Error::InvalidParameterName(ref name) => write!(f, "Invalid parameter name: {}", name),
|
|
|
|
Error::InvalidPath(ref p) => write!(f, "Invalid path: {}", p.to_string_lossy()),
|
|
|
|
Error::ExecuteReturnedResults => {
|
2016-02-03 02:12:00 +08:00
|
|
|
write!(f, "Execute returned results - did you mean to call query?")
|
|
|
|
}
|
2016-02-14 23:11:59 +08:00
|
|
|
Error::QueryReturnedNoRows => write!(f, "Query returned no rows"),
|
|
|
|
Error::InvalidColumnIndex(i) => write!(f, "Invalid column index: {}", i),
|
|
|
|
Error::InvalidColumnName(ref name) => write!(f, "Invalid column name: {}", name),
|
2016-05-27 03:03:05 +08:00
|
|
|
Error::InvalidColumnType(i, ref t) => {
|
|
|
|
write!(f, "Invalid column type {} at index: {}", t, i)
|
|
|
|
}
|
2016-05-17 00:15:07 +08:00
|
|
|
Error::StatementChangedRows(i) => write!(f, "Query changed {} rows", i),
|
2015-12-13 14:04:09 +08:00
|
|
|
|
|
|
|
#[cfg(feature = "functions")]
|
2016-05-27 03:03:05 +08:00
|
|
|
Error::InvalidFunctionParameterType(i, ref t) => {
|
|
|
|
write!(f, "Invalid function parameter type {} at index {}", t, i)
|
|
|
|
}
|
2018-05-13 17:28:56 +08:00
|
|
|
#[cfg(feature = "vtab")]
|
|
|
|
Error::InvalidFilterParameterType(i, ref t) => {
|
|
|
|
write!(f, "Invalid filter parameter type {} at index {}", t, i)
|
|
|
|
}
|
2015-12-13 14:04:09 +08:00
|
|
|
#[cfg(feature = "functions")]
|
2016-02-14 23:11:59 +08:00
|
|
|
Error::UserFunctionError(ref err) => err.fmt(f),
|
2017-05-31 07:22:14 +08:00
|
|
|
Error::ToSqlConversionFailure(ref err) => err.fmt(f),
|
2018-08-11 02:48:13 +08:00
|
|
|
Error::InvalidQuery => write!(f, "Query is not read-only"),
|
2016-02-09 01:06:11 +08:00
|
|
|
#[cfg(feature = "vtab")]
|
2016-03-31 00:26:26 +08:00
|
|
|
Error::ModuleError(ref desc) => write!(f, "{}", desc),
|
2015-12-13 14:04:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl error::Error for Error {
|
|
|
|
fn description(&self) -> &str {
|
2016-02-14 23:11:59 +08:00
|
|
|
match *self {
|
|
|
|
Error::SqliteFailure(ref err, None) => err.description(),
|
|
|
|
Error::SqliteFailure(_, Some(ref s)) => s,
|
2018-08-11 18:48:21 +08:00
|
|
|
Error::SqliteSingleThreadedMode => {
|
|
|
|
"SQLite was compiled or configured for single-threaded use only"
|
|
|
|
}
|
2016-06-03 03:03:25 +08:00
|
|
|
Error::FromSqlConversionFailure(_, _, ref err) => err.description(),
|
2017-02-09 04:11:15 +08:00
|
|
|
Error::IntegralValueOutOfRange(_, _) => "integral value out of range of requested type",
|
2016-02-14 23:11:59 +08:00
|
|
|
Error::Utf8Error(ref err) => err.description(),
|
|
|
|
Error::InvalidParameterName(_) => "invalid parameter name",
|
|
|
|
Error::NulError(ref err) => err.description(),
|
|
|
|
Error::InvalidPath(_) => "invalid path",
|
2018-08-11 18:48:21 +08:00
|
|
|
Error::ExecuteReturnedResults => {
|
|
|
|
"execute returned results - did you mean to call query?"
|
|
|
|
}
|
2016-02-14 23:11:59 +08:00
|
|
|
Error::QueryReturnedNoRows => "query returned no rows",
|
|
|
|
Error::InvalidColumnIndex(_) => "invalid column index",
|
|
|
|
Error::InvalidColumnName(_) => "invalid column name",
|
2016-05-27 03:03:05 +08:00
|
|
|
Error::InvalidColumnType(_, _) => "invalid column type",
|
2016-05-17 00:15:07 +08:00
|
|
|
Error::StatementChangedRows(_) => "query inserted zero or more than one row",
|
2015-12-13 14:04:09 +08:00
|
|
|
|
|
|
|
#[cfg(feature = "functions")]
|
2016-05-27 03:03:05 +08:00
|
|
|
Error::InvalidFunctionParameterType(_, _) => "invalid function parameter type",
|
2018-05-13 17:28:56 +08:00
|
|
|
#[cfg(feature = "vtab")]
|
|
|
|
Error::InvalidFilterParameterType(_, _) => "invalid filter parameter type",
|
2015-12-13 14:04:09 +08:00
|
|
|
#[cfg(feature = "functions")]
|
2016-02-14 23:11:59 +08:00
|
|
|
Error::UserFunctionError(ref err) => err.description(),
|
2017-05-31 07:22:14 +08:00
|
|
|
Error::ToSqlConversionFailure(ref err) => err.description(),
|
2018-08-11 02:48:13 +08:00
|
|
|
Error::InvalidQuery => "query is not read-only",
|
2016-02-09 01:06:11 +08:00
|
|
|
#[cfg(feature = "vtab")]
|
2016-03-31 00:26:26 +08:00
|
|
|
Error::ModuleError(ref desc) => desc,
|
2015-12-13 14:04:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn cause(&self) -> Option<&error::Error> {
|
2016-02-14 23:11:59 +08:00
|
|
|
match *self {
|
|
|
|
Error::SqliteFailure(ref err, _) => Some(err),
|
|
|
|
Error::Utf8Error(ref err) => Some(err),
|
|
|
|
Error::NulError(ref err) => Some(err),
|
2016-03-29 23:54:02 +08:00
|
|
|
|
2018-08-11 18:48:21 +08:00
|
|
|
Error::IntegralValueOutOfRange(_, _)
|
|
|
|
| Error::SqliteSingleThreadedMode
|
|
|
|
| Error::InvalidParameterName(_)
|
|
|
|
| Error::ExecuteReturnedResults
|
|
|
|
| Error::QueryReturnedNoRows
|
|
|
|
| Error::InvalidColumnIndex(_)
|
|
|
|
| Error::InvalidColumnName(_)
|
|
|
|
| Error::InvalidColumnType(_, _)
|
|
|
|
| Error::InvalidPath(_)
|
|
|
|
| Error::StatementChangedRows(_)
|
|
|
|
| Error::InvalidQuery => None,
|
2015-12-13 14:04:09 +08:00
|
|
|
|
|
|
|
#[cfg(feature = "functions")]
|
2016-05-27 03:03:05 +08:00
|
|
|
Error::InvalidFunctionParameterType(_, _) => None,
|
2018-05-13 17:28:56 +08:00
|
|
|
#[cfg(feature = "vtab")]
|
|
|
|
Error::InvalidFilterParameterType(_, _) => None,
|
2016-03-30 02:18:56 +08:00
|
|
|
|
2015-12-13 14:04:09 +08:00
|
|
|
#[cfg(feature = "functions")]
|
2016-02-14 23:11:59 +08:00
|
|
|
Error::UserFunctionError(ref err) => Some(&**err),
|
2017-11-18 02:37:23 +08:00
|
|
|
|
2018-08-11 18:48:21 +08:00
|
|
|
Error::FromSqlConversionFailure(_, _, ref err)
|
|
|
|
| Error::ToSqlConversionFailure(ref err) => Some(&**err),
|
2018-08-11 19:37:56 +08:00
|
|
|
|
2016-02-09 01:06:11 +08:00
|
|
|
#[cfg(feature = "vtab")]
|
2016-03-31 00:26:26 +08:00
|
|
|
Error::ModuleError(_) => None,
|
2015-12-13 14:04:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-15 00:47:52 +08:00
|
|
|
// These are public but not re-exported by lib.rs, so only visible within crate.
|
|
|
|
|
2015-12-13 14:04:09 +08:00
|
|
|
pub fn error_from_sqlite_code(code: c_int, message: Option<String>) -> Error {
|
|
|
|
Error::SqliteFailure(ffi::Error::new(code), message)
|
|
|
|
}
|
|
|
|
|
2017-02-08 10:09:20 +08:00
|
|
|
pub fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error {
|
2015-12-13 14:04:09 +08:00
|
|
|
let message = if db.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(unsafe { errmsg_to_string(ffi::sqlite3_errmsg(db)) })
|
|
|
|
};
|
|
|
|
error_from_sqlite_code(code, message)
|
|
|
|
}
|