2015-12-13 14:04:09 +08:00
|
|
|
use std::error;
|
|
|
|
use std::fmt;
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::str;
|
|
|
|
use libc::c_int;
|
|
|
|
use {ffi, errmsg_to_string};
|
|
|
|
|
|
|
|
/// Old name for `Error`. `SqliteError` is deprecated.
|
|
|
|
pub type SqliteError = Error;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
SqliteFailure(ffi::Error, Option<String>),
|
2015-12-16 03:34:42 +08:00
|
|
|
FromSqlConversionFailure(Box<error::Error + Send + Sync>),
|
2015-12-13 14:04:09 +08:00
|
|
|
Utf8Error(str::Utf8Error),
|
|
|
|
NulError(::std::ffi::NulError),
|
|
|
|
InvalidParameterName(String),
|
|
|
|
InvalidPath(PathBuf),
|
|
|
|
ExecuteReturnedResults,
|
|
|
|
QueryReturnedNoRows,
|
|
|
|
GetFromStaleRow,
|
|
|
|
InvalidColumnIndex(c_int),
|
|
|
|
InvalidColumnType,
|
|
|
|
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
InvalidFunctionParameterType,
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
#[allow(dead_code)]
|
2015-12-16 03:34:42 +08:00
|
|
|
UserFunctionError(Box<error::Error + Send + Sync>),
|
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 {
|
|
|
|
match self {
|
|
|
|
&Error::SqliteFailure(ref err, None) => err.fmt(f),
|
|
|
|
&Error::SqliteFailure(_, Some(ref s)) => write!(f, "{}", s),
|
|
|
|
&Error::FromSqlConversionFailure(ref err) => err.fmt(f),
|
|
|
|
&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 => write!(f, "Execute returned results - did you mean to call query?"),
|
|
|
|
&Error::QueryReturnedNoRows => write!(f, "Query returned no rows"),
|
|
|
|
&Error::GetFromStaleRow => write!(f, "Attempted to get a value from a stale row"),
|
|
|
|
&Error::InvalidColumnIndex(i) => write!(f, "Invalid column index: {}", i),
|
|
|
|
&Error::InvalidColumnType => write!(f, "Invalid column type"),
|
|
|
|
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
&Error::InvalidFunctionParameterType => write!(f, "Invalid function parameter type"),
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
&Error::UserFunctionError(ref err) => err.fmt(f),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl error::Error for Error {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
match self {
|
|
|
|
&Error::SqliteFailure(ref err, None) => err.description(),
|
|
|
|
&Error::SqliteFailure(_, Some(ref s)) => s,
|
|
|
|
&Error::FromSqlConversionFailure(ref err) => err.description(),
|
|
|
|
&Error::Utf8Error(ref err) => err.description(),
|
|
|
|
&Error::InvalidParameterName(_) => "invalid parameter name",
|
|
|
|
&Error::NulError(ref err) => err.description(),
|
|
|
|
&Error::InvalidPath(_) => "invalid path",
|
|
|
|
&Error::ExecuteReturnedResults => "execute returned results - did you mean to call query?",
|
|
|
|
&Error::QueryReturnedNoRows => "query returned no rows",
|
|
|
|
&Error::GetFromStaleRow => "attempted to get a value from a stale row",
|
|
|
|
&Error::InvalidColumnIndex(_) => "invalid column index",
|
|
|
|
&Error::InvalidColumnType => "invalid column type",
|
|
|
|
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
&Error::InvalidFunctionParameterType => "invalid function parameter type",
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
&Error::UserFunctionError(ref err) => err.description(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn cause(&self) -> Option<&error::Error> {
|
|
|
|
match self {
|
|
|
|
&Error::SqliteFailure(ref err, _) => Some(err),
|
|
|
|
&Error::FromSqlConversionFailure(ref err) => Some(&**err),
|
|
|
|
&Error::Utf8Error(ref err) => Some(err),
|
|
|
|
&Error::NulError(ref err) => Some(err),
|
|
|
|
&Error::InvalidParameterName(_) => None,
|
|
|
|
&Error::InvalidPath(_) => None,
|
|
|
|
&Error::ExecuteReturnedResults => None,
|
|
|
|
&Error::QueryReturnedNoRows => None,
|
|
|
|
&Error::GetFromStaleRow => None,
|
|
|
|
&Error::InvalidColumnIndex(_) => None,
|
|
|
|
&Error::InvalidColumnType => None,
|
|
|
|
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
&Error::InvalidFunctionParameterType => None,
|
|
|
|
#[cfg(feature = "functions")]
|
|
|
|
&Error::UserFunctionError(ref err) => Some(&**err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// These are public but not re-exported by lib.rs, so only visible within crate.
|
|
|
|
|
|
|
|
pub fn error_from_sqlite_code(code: c_int, message: Option<String>) -> Error {
|
|
|
|
Error::SqliteFailure(ffi::Error::new(code), message)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn error_from_handle(db: *mut ffi::Struct_sqlite3, code: c_int) -> Error {
|
|
|
|
let message = if db.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(unsafe { errmsg_to_string(ffi::sqlite3_errmsg(db)) })
|
|
|
|
};
|
|
|
|
error_from_sqlite_code(code, message)
|
|
|
|
}
|