mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-23 00:39:20 +08:00
Merge pull request #451 from gwenn/optional
Introduce `OptionalExtension`
This commit is contained in:
commit
2bf1a9f89f
52
src/lib.rs
52
src/lib.rs
@ -144,6 +144,26 @@ pub const NO_PARAMS: &[&dyn ToSql] = &[];
|
|||||||
/// A typedef of the result returned by many methods.
|
/// A typedef of the result returned by many methods.
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
/// See the [method documentation](#tymethod.optional).
|
||||||
|
pub trait OptionalExtension<T> {
|
||||||
|
/// Converts a `Result<T>` into a `Result<Option<T>>`.
|
||||||
|
///
|
||||||
|
/// By default, Rusqlite treats 0 rows being returned from a query that is expected to return 1
|
||||||
|
/// row as an error. This method will
|
||||||
|
/// handle that error, and give you back an `Option<T>` instead.
|
||||||
|
fn optional(self) -> Result<Option<T>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> OptionalExtension<T> for Result<T> {
|
||||||
|
fn optional(self) -> Result<Option<T>> {
|
||||||
|
match self {
|
||||||
|
Ok(value) => Ok(Some(value)),
|
||||||
|
Err(Error::QueryReturnedNoRows) => Ok(None),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn errmsg_to_string(errmsg: *const c_char) -> String {
|
unsafe fn errmsg_to_string(errmsg: *const c_char) -> String {
|
||||||
let c_slice = CStr::from_ptr(errmsg).to_bytes();
|
let c_slice = CStr::from_ptr(errmsg).to_bytes();
|
||||||
String::from_utf8_lossy(c_slice).into_owned()
|
String::from_utf8_lossy(c_slice).into_owned()
|
||||||
@ -372,6 +392,9 @@ impl Connection {
|
|||||||
/// If the query returns more than one row, all rows except the first are
|
/// If the query returns more than one row, all rows except the first are
|
||||||
/// ignored.
|
/// ignored.
|
||||||
///
|
///
|
||||||
|
/// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the query truly is optional,
|
||||||
|
/// you can call `.optional()` on the result of this to get a `Result<Option<T>>`.
|
||||||
|
///
|
||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
||||||
@ -392,6 +415,9 @@ impl Connection {
|
|||||||
/// If the query returns more than one row, all rows except the first are
|
/// If the query returns more than one row, all rows except the first are
|
||||||
/// ignored.
|
/// ignored.
|
||||||
///
|
///
|
||||||
|
/// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the query truly is optional,
|
||||||
|
/// you can call `.optional()` on the result of this to get a `Result<Option<T>>`.
|
||||||
|
///
|
||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
||||||
@ -1378,6 +1404,32 @@ mod test {
|
|||||||
assert!(bad_query_result.is_err());
|
assert!(bad_query_result.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_optional() {
|
||||||
|
let db = checked_memory_handle();
|
||||||
|
|
||||||
|
let result: Result<i64> =
|
||||||
|
db.query_row("SELECT 1 WHERE 0 <> 0", NO_PARAMS, |r| r.get(0));
|
||||||
|
let result = result.optional();
|
||||||
|
match result.unwrap() {
|
||||||
|
None => (),
|
||||||
|
_ => panic!("Unexpected result"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: Result<i64> =
|
||||||
|
db.query_row("SELECT 1 WHERE 0 == 0", NO_PARAMS, |r| r.get(0));
|
||||||
|
let result = result.optional();
|
||||||
|
match result.unwrap() {
|
||||||
|
Some(1) => (),
|
||||||
|
_ => panic!("Unexpected result"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let bad_query_result: Result<i64> =
|
||||||
|
db.query_row("NOT A PROPER QUERY", NO_PARAMS, |r| r.get(0));
|
||||||
|
let bad_query_result = bad_query_result.optional();
|
||||||
|
assert!(bad_query_result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_pragma_query_row() {
|
fn test_pragma_query_row() {
|
||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
|
@ -377,6 +377,9 @@ impl<'conn> Statement<'conn> {
|
|||||||
/// If the query returns more than one row, all rows except the first are
|
/// If the query returns more than one row, all rows except the first are
|
||||||
/// ignored.
|
/// ignored.
|
||||||
///
|
///
|
||||||
|
/// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the query truly is optional,
|
||||||
|
/// you can call `.optional()` on the result of this to get a `Result<Option<T>>`.
|
||||||
|
///
|
||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if the underlying SQLite call fails.
|
/// Will return `Err` if the underlying SQLite call fails.
|
||||||
|
Loading…
Reference in New Issue
Block a user