Merge remote-tracking branch 'jgallagher/master' into fallible-iterator

This commit is contained in:
gwenn
2019-03-10 11:12:14 +01:00
19 changed files with 727 additions and 264 deletions

View File

@@ -15,6 +15,23 @@ impl<'stmt> Rows<'stmt> {
stmt.reset();
}
}
/// Attempt to get the next row from the query. Returns `Ok(Some(Row))` if
/// there is another row, `Err(...)` if there was an error
/// getting the next row, and `Ok(None)` if all rows have been retrieved.
///
/// ## Note
///
/// This interface is not compatible with Rust's `Iterator` trait, because
/// the lifetime of the returned row is tied to the lifetime of `self`.
/// This is a fallible "streaming iterator". For a more natural interface,
/// consider using `query_map` or `query_and_then` instead, which
/// return types that implement `Iterator`.
#[allow(clippy::should_implement_trait)] // cannot implement Iterator
pub fn next(&mut self) -> Result<Option<&Row<'stmt>>> {
self.advance()?;
Ok((*self).get())
}
}
impl<'stmt> Rows<'stmt> {
@@ -47,7 +64,7 @@ pub struct MappedRows<'stmt, F> {
impl<'stmt, T, F> MappedRows<'stmt, F>
where
F: FnMut(&Row<'_>) -> T,
F: FnMut(&Row<'_>) -> Result<T>,
{
pub(crate) fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
MappedRows { rows, map: f }
@@ -56,7 +73,7 @@ where
impl<T, F> Iterator for MappedRows<'_, F>
where
F: FnMut(&Row<'_>) -> T,
F: FnMut(&Row<'_>) -> Result<T>,
{
type Item = Result<T>;
@@ -65,7 +82,7 @@ where
self.rows
.next()
.transpose()
.map(|row_result| row_result.map(|row| (map)(&row)))
.map(|row_result| row_result.and_then(|row| (map)(&row)))
}
}
@@ -145,16 +162,16 @@ impl<'stmt> Row<'stmt> {
///
/// ## Failure
///
/// Panics if calling `row.get_checked(idx)` would return an error,
/// Panics if calling `row.get(idx)` would return an error,
/// including:
///
/// * If the underlying SQLite column type is not a valid type as a
/// source for `T`
/// * If the underlying SQLite column type is not a valid type as a source
/// for `T`
/// * If the underlying SQLite integral value is outside the range
/// representable by `T`
/// * If `idx` is outside the range of columns in the returned query
pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> T {
self.get_checked(idx).unwrap()
pub fn get_unwrap<I: RowIndex, T: FromSql>(&self, idx: I) -> T {
self.get(idx).unwrap()
}
/// Get the value of a particular column of the result row.
@@ -173,7 +190,7 @@ impl<'stmt> Row<'stmt> {
/// If the result type is i128 (which requires the `i128_blob` feature to be
/// enabled), and the underlying SQLite column is a blob whose size is not
/// 16 bytes, `Error::InvalidColumnType` will also be returned.
pub fn get_checked<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> {
pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> {
let idx = idx.idx(self.stmt)?;
let value = self.stmt.value_ref(idx);
FromSql::column_result(value).map_err(|err| match err {
@@ -193,7 +210,7 @@ impl<'stmt> Row<'stmt> {
/// This `ValueRef` is valid only as long as this Row, which is enforced by
/// it's lifetime. This means that while this method is completely safe,
/// it can be somewhat difficult to use, and most callers will be better
/// served by `get` or `get_checked`.
/// served by `get` or `get`.
///
/// ## Failure
///
@@ -217,7 +234,7 @@ impl<'stmt> Row<'stmt> {
/// This `ValueRef` is valid only as long as this Row, which is enforced by
/// it's lifetime. This means that while this method is completely safe,
/// it can be difficult to use, and most callers will be better served by
/// `get` or `get_checked`.
/// `get` or `get`.
///
/// ## Failure
///