Fix tests and improve InvalidColumnType error message.

This commit is contained in:
gwenn
2016-05-18 21:25:13 +02:00
parent 29373e7d0d
commit 42d95f042f
8 changed files with 63 additions and 38 deletions

View File

@@ -27,7 +27,7 @@ impl FromSql for NaiveDate {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
String::column_has_valid_sqlite_type(stmt, col)
}
}
@@ -55,7 +55,7 @@ impl FromSql for NaiveTime {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
String::column_has_valid_sqlite_type(stmt, col)
}
}
@@ -86,7 +86,7 @@ impl FromSql for NaiveDateTime {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
String::column_has_valid_sqlite_type(stmt, col)
}
}
@@ -118,7 +118,7 @@ impl FromSql for DateTime<UTC> {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
String::column_has_valid_sqlite_type(stmt, col)
}
}
@@ -130,7 +130,7 @@ impl FromSql for DateTime<Local> {
Ok(utc_dt.with_timezone(&Local))
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
DateTime::<UTC>::column_has_valid_sqlite_type(stmt, col)
}
}

View File

@@ -83,8 +83,17 @@ pub trait FromSql: Sized {
/// the type reported by SQLite matches a type suitable for Self. This method is used
/// by `Row::get_checked` to confirm that the column contains a valid type before
/// attempting to retrieve the value.
unsafe fn column_has_valid_sqlite_type(_: *mut sqlite3_stmt, _: c_int) -> bool {
true
unsafe fn column_has_valid_sqlite_type(_: *mut sqlite3_stmt, _: c_int) -> Result<()> {
Ok(())
}
}
unsafe fn column_has_expected_typed(stmt: *mut sqlite3_stmt, col: c_int, expected_type: c_int) -> Result<()> {
let actual_type = sqlite3_column_type(stmt, col);
if actual_type == expected_type {
Ok(())
} else {
Err(Error::InvalidColumnType(col, actual_type))
}
}
@@ -197,8 +206,8 @@ macro_rules! raw_from_impl(
Ok(ffi::$f(stmt, col))
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
sqlite3_column_type(stmt, col) == $c
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
column_has_expected_typed(stmt, col, $c)
}
}
)
@@ -216,8 +225,8 @@ impl FromSql for bool {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
sqlite3_column_type(stmt, col) == ffi::SQLITE_INTEGER
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
column_has_expected_typed(stmt, col, ffi::SQLITE_INTEGER)
}
}
@@ -233,8 +242,8 @@ impl FromSql for String {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
sqlite3_column_type(stmt, col) == ffi::SQLITE_TEXT
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
column_has_expected_typed(stmt, col, ffi::SQLITE_TEXT)
}
}
@@ -253,8 +262,8 @@ impl FromSql for Vec<u8> {
Ok(from_raw_parts(mem::transmute(c_blob), len).to_vec())
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
sqlite3_column_type(stmt, col) == ffi::SQLITE_BLOB
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
column_has_expected_typed(stmt, col, ffi::SQLITE_BLOB)
}
}
@@ -267,9 +276,12 @@ impl<T: FromSql> FromSql for Option<T> {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
sqlite3_column_type(stmt, col) == ffi::SQLITE_NULL ||
T::column_has_valid_sqlite_type(stmt, col)
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
if sqlite3_column_type(stmt, col) == ffi::SQLITE_NULL {
Ok(())
} else {
T::column_has_valid_sqlite_type(stmt, col)
}
}
}
@@ -297,7 +309,7 @@ impl FromSql for Value {
ffi::SQLITE_FLOAT => Ok(Value::Real(ffi::sqlite3_column_double(stmt, col))),
ffi::SQLITE_NULL => Ok(Value::Null),
ffi::SQLITE_BLOB => FromSql::column_result(stmt, col).map(Value::Blob),
_ => Err(Error::InvalidColumnType),
ct => Err(Error::InvalidColumnType(col, ct)),
}
}
}
@@ -371,7 +383,7 @@ mod test {
fn test_mismatched_types() {
fn is_invalid_column_type(err: Error) -> bool {
match err {
Error::InvalidColumnType => true,
Error::InvalidColumnType(_, _) => true,
_ => false,
}
}

View File

@@ -31,7 +31,7 @@ impl FromSql for Value {
let blob = try!(Vec::<u8>::column_result(stmt, col));
serde_json::from_slice(&blob)
}
_ => return Err(Error::InvalidColumnType),
ct => return Err(Error::InvalidColumnType(col, ct)),
};
value_result.map_err(|err| Error::FromSqlConversionFailure(Box::new(err)))
}

View File

@@ -24,7 +24,7 @@ impl FromSql for time::Timespec {
}
}
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> bool {
unsafe fn column_has_valid_sqlite_type(stmt: *mut sqlite3_stmt, col: c_int) -> Result<()> {
String::column_has_valid_sqlite_type(stmt, col)
}
}