mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-22 16:29:20 +08:00
Reorganize: Extract Row/Rows and helper types into their own mod files.
This commit is contained in:
parent
745341716c
commit
ec78a2b5fa
18
src/cache.rs
18
src/cache.rs
@ -176,16 +176,14 @@ mod test {
|
||||
{
|
||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||
assert_eq!(0, cache.len());
|
||||
assert_eq!(0,
|
||||
stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32, i64>(0));
|
||||
assert_eq!(0, stmt.query_row(&[], |r| r.get::<i32, i64>(0)).unwrap());
|
||||
}
|
||||
assert_eq!(1, cache.len());
|
||||
|
||||
{
|
||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||
assert_eq!(0, cache.len());
|
||||
assert_eq!(0,
|
||||
stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32, i64>(0));
|
||||
assert_eq!(0, stmt.query_row(&[], |r| r.get::<i32, i64>(0)).unwrap());
|
||||
}
|
||||
assert_eq!(1, cache.len());
|
||||
|
||||
@ -203,8 +201,7 @@ mod test {
|
||||
{
|
||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||
assert_eq!(0, cache.len());
|
||||
assert_eq!(0,
|
||||
stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32, i64>(0));
|
||||
assert_eq!(0, stmt.query_row(&[], |r| r.get::<i32, i64>(0)).unwrap());
|
||||
}
|
||||
assert_eq!(1, cache.len());
|
||||
|
||||
@ -214,8 +211,7 @@ mod test {
|
||||
{
|
||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||
assert_eq!(0, cache.len());
|
||||
assert_eq!(0,
|
||||
stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32, i64>(0));
|
||||
assert_eq!(0, stmt.query_row(&[], |r| r.get::<i32, i64>(0)).unwrap());
|
||||
}
|
||||
assert_eq!(0, cache.len());
|
||||
|
||||
@ -223,8 +219,7 @@ mod test {
|
||||
{
|
||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||
assert_eq!(0, cache.len());
|
||||
assert_eq!(0,
|
||||
stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32, i64>(0));
|
||||
assert_eq!(0, stmt.query_row(&[], |r| r.get::<i32, i64>(0)).unwrap());
|
||||
}
|
||||
assert_eq!(1, cache.len());
|
||||
}
|
||||
@ -238,8 +233,7 @@ mod test {
|
||||
{
|
||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||
assert_eq!(0, cache.len());
|
||||
assert_eq!(0,
|
||||
stmt.query(&[]).unwrap().get_expected_row().unwrap().get::<i32, i64>(0));
|
||||
assert_eq!(0, stmt.query_row(&[], |r| r.get::<i32, i64>(0)).unwrap());
|
||||
stmt.discard();
|
||||
}
|
||||
assert_eq!(0, cache.len());
|
||||
|
177
src/lib.rs
177
src/lib.rs
@ -62,7 +62,6 @@ extern crate lazy_static;
|
||||
|
||||
use std::default::Default;
|
||||
use std::convert;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::fmt;
|
||||
@ -75,7 +74,7 @@ use std::sync::{Once, ONCE_INIT};
|
||||
use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
|
||||
use std::os::raw::{c_int, c_char};
|
||||
|
||||
use types::{ToSql, FromSql, FromSqlError, ValueRef};
|
||||
use types::{ToSql, ValueRef};
|
||||
use error::{error_from_sqlite_code, error_from_handle};
|
||||
use raw_statement::RawStatement;
|
||||
use cache::StatementCache;
|
||||
@ -83,6 +82,9 @@ use cache::StatementCache;
|
||||
pub use statement::Statement;
|
||||
use statement::StatementCrateImpl;
|
||||
|
||||
pub use row::{Row, Rows, MappedRows, AndThenRows};
|
||||
use row::RowsCrateImpl;
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub use transaction::{SqliteTransaction, SqliteTransactionBehavior};
|
||||
pub use transaction::{DropBehavior, Savepoint, Transaction, TransactionBehavior};
|
||||
@ -105,6 +107,7 @@ mod transaction;
|
||||
mod cache;
|
||||
mod error;
|
||||
mod raw_statement;
|
||||
mod row;
|
||||
mod statement;
|
||||
#[cfg(feature = "load_extension")]
|
||||
mod load_extension_guard;
|
||||
@ -865,185 +868,15 @@ impl Drop for InnerConnection {
|
||||
#[deprecated(since = "0.6.0", note = "Use Statement instead")]
|
||||
pub type SqliteStatement<'conn> = Statement<'conn>;
|
||||
|
||||
/// An iterator over the mapped resulting rows of a query.
|
||||
pub struct MappedRows<'stmt, F> {
|
||||
rows: Rows<'stmt>,
|
||||
map: F,
|
||||
}
|
||||
|
||||
impl<'stmt, T, F> Iterator for MappedRows<'stmt, F>
|
||||
where F: FnMut(&Row) -> T
|
||||
{
|
||||
type Item = Result<T>;
|
||||
|
||||
fn next(&mut self) -> Option<Result<T>> {
|
||||
let map = &mut self.map;
|
||||
self.rows.next().map(|row_result| row_result.map(|row| (map)(&row)))
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over the mapped resulting rows of a query, with an Error type
|
||||
/// unifying with Error.
|
||||
pub struct AndThenRows<'stmt, F> {
|
||||
rows: Rows<'stmt>,
|
||||
map: F,
|
||||
}
|
||||
|
||||
impl<'stmt, T, E, F> Iterator for AndThenRows<'stmt, F>
|
||||
where E: convert::From<Error>,
|
||||
F: FnMut(&Row) -> result::Result<T, E>
|
||||
{
|
||||
type Item = result::Result<T, E>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let map = &mut self.map;
|
||||
self.rows.next().map(|row_result| {
|
||||
row_result.map_err(E::from)
|
||||
.and_then(|row| (map)(&row))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Old name for `Rows`. `SqliteRows` is deprecated.
|
||||
#[deprecated(since = "0.6.0", note = "Use Rows instead")]
|
||||
pub type SqliteRows<'stmt> = Rows<'stmt>;
|
||||
|
||||
/// An handle for the resulting rows of a query.
|
||||
pub struct Rows<'stmt> {
|
||||
stmt: Option<&'stmt Statement<'stmt>>,
|
||||
}
|
||||
|
||||
#[allow(should_implement_trait)]
|
||||
impl<'stmt> Rows<'stmt> {
|
||||
fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> {
|
||||
Rows { stmt: Some(stmt) }
|
||||
}
|
||||
|
||||
fn get_expected_row<'a>(&'a mut self) -> Result<Row<'a, 'stmt>> {
|
||||
match self.next() {
|
||||
Some(row) => row,
|
||||
None => Err(Error::QueryReturnedNoRows),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
if let Some(stmt) = self.stmt.take() {
|
||||
stmt.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempt to get the next row from the query. Returns `Some(Ok(Row))` if there
|
||||
/// is another row, `Some(Err(...))` if there was an error getting the next
|
||||
/// row, and `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
|
||||
/// "streaming iterator". For a more natural interface, consider using `query_map`
|
||||
/// or `query_and_then` instead, which return types that implement `Iterator`.
|
||||
pub fn next<'a>(&'a mut self) -> Option<Result<Row<'a, 'stmt>>> {
|
||||
self.stmt.and_then(|stmt| match stmt.step() {
|
||||
Ok(true) => Some(Ok(Row {
|
||||
stmt: stmt,
|
||||
phantom: PhantomData,
|
||||
})),
|
||||
Ok(false) => {
|
||||
self.reset();
|
||||
None
|
||||
}
|
||||
Err(err) => {
|
||||
self.reset();
|
||||
Some(Err(err))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'stmt> Drop for Rows<'stmt> {
|
||||
fn drop(&mut self) {
|
||||
self.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/// Old name for `Row`. `SqliteRow` is deprecated.
|
||||
#[deprecated(since = "0.6.0", note = "Use Row instead")]
|
||||
pub type SqliteRow<'a, 'stmt> = Row<'a, 'stmt>;
|
||||
|
||||
/// A single result row of a query.
|
||||
pub struct Row<'a, 'stmt> {
|
||||
stmt: &'stmt Statement<'stmt>,
|
||||
phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a, 'stmt> Row<'a, 'stmt> {
|
||||
/// Get the value of a particular column of the result row.
|
||||
///
|
||||
/// ## Failure
|
||||
///
|
||||
/// Panics if calling `row.get_checked(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 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()
|
||||
}
|
||||
|
||||
/// Get the value of a particular column of the result row.
|
||||
///
|
||||
/// ## Failure
|
||||
///
|
||||
/// Returns an `Error::InvalidColumnType` if the underlying SQLite column
|
||||
/// type is not a valid type as a source for `T`.
|
||||
///
|
||||
/// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid column range
|
||||
/// for this row.
|
||||
///
|
||||
/// Returns an `Error::InvalidColumnName` if `idx` is not a valid column name
|
||||
/// for this row.
|
||||
pub fn get_checked<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> {
|
||||
let idx = try!(idx.idx(self.stmt));
|
||||
let value = self.stmt.value_ref(idx);
|
||||
FromSql::column_result(value).map_err(|err| match err {
|
||||
FromSqlError::InvalidType => Error::InvalidColumnType(idx, value.data_type()),
|
||||
FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
|
||||
FromSqlError::Other(err) => {
|
||||
Error::FromSqlConversionFailure(idx as usize, value.data_type(), err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the number of columns in the current row.
|
||||
pub fn column_count(&self) -> i32 {
|
||||
self.stmt.column_count()
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait implemented by types that can index into columns of a row.
|
||||
pub trait RowIndex {
|
||||
/// Returns the index of the appropriate column, or `None` if no such
|
||||
/// column exists.
|
||||
fn idx(&self, stmt: &Statement) -> Result<i32>;
|
||||
}
|
||||
|
||||
impl RowIndex for i32 {
|
||||
#[inline]
|
||||
fn idx(&self, stmt: &Statement) -> Result<i32> {
|
||||
if *self < 0 || *self >= stmt.column_count() {
|
||||
Err(Error::InvalidColumnIndex(*self))
|
||||
} else {
|
||||
Ok(*self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RowIndex for &'a str {
|
||||
#[inline]
|
||||
fn idx(&self, stmt: &Statement) -> Result<i32> {
|
||||
stmt.column_index(*self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
222
src/row.rs
Normal file
222
src/row.rs
Normal file
@ -0,0 +1,222 @@
|
||||
use std::{convert, result};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use super::{Statement, Error, Result};
|
||||
use types::{FromSql, FromSqlError};
|
||||
use statement::StatementCrateImpl;
|
||||
|
||||
/// An handle for the resulting rows of a query.
|
||||
pub struct Rows<'stmt> {
|
||||
stmt: Option<&'stmt Statement<'stmt>>,
|
||||
}
|
||||
|
||||
impl<'stmt> Rows<'stmt> {
|
||||
fn reset(&mut self) {
|
||||
if let Some(stmt) = self.stmt.take() {
|
||||
stmt.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempt to get the next row from the query. Returns `Some(Ok(Row))` if there
|
||||
/// is another row, `Some(Err(...))` if there was an error getting the next
|
||||
/// row, and `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
|
||||
/// "streaming iterator". For a more natural interface, consider using `query_map`
|
||||
/// or `query_and_then` instead, which return types that implement `Iterator`.
|
||||
pub fn next<'a>(&'a mut self) -> Option<Result<Row<'a, 'stmt>>> {
|
||||
self.stmt.and_then(|stmt| match stmt.step() {
|
||||
Ok(true) => {
|
||||
Some(Ok(Row {
|
||||
stmt: stmt,
|
||||
phantom: PhantomData,
|
||||
}))
|
||||
}
|
||||
Ok(false) => {
|
||||
self.reset();
|
||||
None
|
||||
}
|
||||
Err(err) => {
|
||||
self.reset();
|
||||
Some(Err(err))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This trait lets us have "pub(crate)" visibility on some methods. Remove this
|
||||
// once pub(crate) is stable.
|
||||
pub trait RowsCrateImpl<'stmt> {
|
||||
fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt>;
|
||||
fn get_expected_row<'a>(&'a mut self) -> Result<Row<'a, 'stmt>>;
|
||||
}
|
||||
|
||||
impl<'stmt> RowsCrateImpl<'stmt> for Rows<'stmt> {
|
||||
fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> {
|
||||
Rows { stmt: Some(stmt) }
|
||||
}
|
||||
|
||||
fn get_expected_row<'a>(&'a mut self) -> Result<Row<'a, 'stmt>> {
|
||||
match self.next() {
|
||||
Some(row) => row,
|
||||
None => Err(Error::QueryReturnedNoRows),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'stmt> Drop for Rows<'stmt> {
|
||||
fn drop(&mut self) {
|
||||
self.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over the mapped resulting rows of a query.
|
||||
pub struct MappedRows<'stmt, F> {
|
||||
rows: Rows<'stmt>,
|
||||
map: F,
|
||||
}
|
||||
|
||||
// TODO: This trait lets us have "pub(crate)" visibility on some methods. Remove this
|
||||
// once pub(crate) is stable.
|
||||
pub trait MappedRowsCrateImpl<'stmt, T, F> {
|
||||
fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F>;
|
||||
}
|
||||
|
||||
impl<'stmt, T, F> MappedRowsCrateImpl<'stmt, T, F> for MappedRows<'stmt, F>
|
||||
where F: FnMut(&Row) -> T
|
||||
{
|
||||
fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
|
||||
MappedRows {
|
||||
rows: rows,
|
||||
map: f,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'conn, T, F> Iterator for MappedRows<'conn, F>
|
||||
where F: FnMut(&Row) -> T
|
||||
{
|
||||
type Item = Result<T>;
|
||||
|
||||
fn next(&mut self) -> Option<Result<T>> {
|
||||
let map = &mut self.map;
|
||||
self.rows.next().map(|row_result| row_result.map(|row| (map)(&row)))
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over the mapped resulting rows of a query, with an Error type
|
||||
/// unifying with Error.
|
||||
pub struct AndThenRows<'stmt, F> {
|
||||
rows: Rows<'stmt>,
|
||||
map: F,
|
||||
}
|
||||
|
||||
// TODO: This trait lets us have "pub(crate)" visibility on some methods. Remove this
|
||||
// once pub(crate) is stable.
|
||||
pub trait AndThenRowsCrateImpl<'stmt, T, E, F> {
|
||||
fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F>;
|
||||
}
|
||||
|
||||
impl<'stmt, T, E, F> AndThenRowsCrateImpl<'stmt, T, E, F> for AndThenRows<'stmt, F>
|
||||
where F: FnMut(&Row) -> result::Result<T, E>
|
||||
{
|
||||
fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F> {
|
||||
AndThenRows {
|
||||
rows: rows,
|
||||
map: f,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'stmt, T, E, F> Iterator for AndThenRows<'stmt, F>
|
||||
where E: convert::From<Error>,
|
||||
F: FnMut(&Row) -> result::Result<T, E>
|
||||
{
|
||||
type Item = result::Result<T, E>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let map = &mut self.map;
|
||||
self.rows.next().map(|row_result| {
|
||||
row_result.map_err(E::from)
|
||||
.and_then(|row| (map)(&row))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A single result row of a query.
|
||||
pub struct Row<'a, 'stmt> {
|
||||
stmt: &'stmt Statement<'stmt>,
|
||||
phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a, 'stmt> Row<'a, 'stmt> {
|
||||
/// Get the value of a particular column of the result row.
|
||||
///
|
||||
/// ## Failure
|
||||
///
|
||||
/// Panics if calling `row.get_checked(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 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()
|
||||
}
|
||||
|
||||
/// Get the value of a particular column of the result row.
|
||||
///
|
||||
/// ## Failure
|
||||
///
|
||||
/// Returns an `Error::InvalidColumnType` if the underlying SQLite column
|
||||
/// type is not a valid type as a source for `T`.
|
||||
///
|
||||
/// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid column range
|
||||
/// for this row.
|
||||
///
|
||||
/// Returns an `Error::InvalidColumnName` if `idx` is not a valid column name
|
||||
/// for this row.
|
||||
pub fn get_checked<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> {
|
||||
let idx = try!(idx.idx(self.stmt));
|
||||
let value = self.stmt.value_ref(idx);
|
||||
FromSql::column_result(value).map_err(|err| match err {
|
||||
FromSqlError::InvalidType => Error::InvalidColumnType(idx, value.data_type()),
|
||||
FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
|
||||
FromSqlError::Other(err) => {
|
||||
Error::FromSqlConversionFailure(idx as usize, value.data_type(), err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the number of columns in the current row.
|
||||
pub fn column_count(&self) -> i32 {
|
||||
self.stmt.column_count()
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait implemented by types that can index into columns of a row.
|
||||
pub trait RowIndex {
|
||||
/// Returns the index of the appropriate column, or `None` if no such
|
||||
/// column exists.
|
||||
fn idx(&self, stmt: &Statement) -> Result<i32>;
|
||||
}
|
||||
|
||||
impl RowIndex for i32 {
|
||||
#[inline]
|
||||
fn idx(&self, stmt: &Statement) -> Result<i32> {
|
||||
if *self < 0 || *self >= stmt.column_count() {
|
||||
Err(Error::InvalidColumnIndex(*self))
|
||||
} else {
|
||||
Ok(*self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RowIndex for &'a str {
|
||||
#[inline]
|
||||
fn idx(&self, stmt: &Statement) -> Result<i32> {
|
||||
stmt.column_index(*self)
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ use super::ffi;
|
||||
use super::{Connection, RawStatement, Result, Error, ValueRef, Row, Rows, AndThenRows, MappedRows};
|
||||
use super::str_to_cstring;
|
||||
use types::{ToSql, ToSqlOutput};
|
||||
use row::{RowsCrateImpl, MappedRowsCrateImpl, AndThenRowsCrateImpl};
|
||||
|
||||
/// A prepared statement.
|
||||
pub struct Statement<'conn> {
|
||||
@ -211,12 +212,8 @@ impl<'conn> Statement<'conn> {
|
||||
pub fn query_map<'a, T, F>(&'a mut self, params: &[&ToSql], f: F) -> Result<MappedRows<'a, F>>
|
||||
where F: FnMut(&Row) -> T
|
||||
{
|
||||
let row_iter = try!(self.query(params));
|
||||
|
||||
Ok(MappedRows {
|
||||
rows: row_iter,
|
||||
map: f,
|
||||
})
|
||||
let rows = self.query(params)?;
|
||||
Ok(MappedRows::new(rows, f))
|
||||
}
|
||||
|
||||
/// Execute the prepared statement with named parameter(s), returning an iterator over the
|
||||
@ -251,11 +248,8 @@ impl<'conn> Statement<'conn> {
|
||||
-> Result<MappedRows<'a, F>>
|
||||
where F: FnMut(&Row) -> T
|
||||
{
|
||||
let rows = try!(self.query_named(params));
|
||||
Ok(MappedRows {
|
||||
rows: rows,
|
||||
map: f,
|
||||
})
|
||||
let rows = self.query_named(params)?;
|
||||
Ok(MappedRows::new(rows, f))
|
||||
}
|
||||
|
||||
/// Executes the prepared statement and maps a function over the resulting
|
||||
@ -272,12 +266,8 @@ impl<'conn> Statement<'conn> {
|
||||
where E: convert::From<Error>,
|
||||
F: FnMut(&Row) -> result::Result<T, E>
|
||||
{
|
||||
let row_iter = try!(self.query(params));
|
||||
|
||||
Ok(AndThenRows {
|
||||
rows: row_iter,
|
||||
map: f,
|
||||
})
|
||||
let rows = self.query(params)?;
|
||||
Ok(AndThenRows::new(rows, f))
|
||||
}
|
||||
|
||||
/// Execute the prepared statement with named parameter(s), returning an iterator over the
|
||||
@ -322,11 +312,8 @@ impl<'conn> Statement<'conn> {
|
||||
where E: convert::From<Error>,
|
||||
F: FnMut(&Row) -> result::Result<T, E>
|
||||
{
|
||||
let rows = try!(self.query_named(params));
|
||||
Ok(AndThenRows {
|
||||
rows: rows,
|
||||
map: f,
|
||||
})
|
||||
let rows = self.query_named(params)?;
|
||||
Ok(AndThenRows::new(rows, f))
|
||||
}
|
||||
|
||||
/// Return `true` if a query in the SQL statement it executes returns one or more rows
|
||||
|
Loading…
Reference in New Issue
Block a user