mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-26 11:31:37 +08:00
Add Rows::map method
This commit is contained in:
parent
59a44cfae5
commit
71a2004894
@ -58,6 +58,7 @@ serde_json = { version = "1.0", optional = true }
|
|||||||
csv = { version = "1.0", optional = true }
|
csv = { version = "1.0", optional = true }
|
||||||
lazy_static = { version = "1.0", optional = true }
|
lazy_static = { version = "1.0", optional = true }
|
||||||
byteorder = { version = "1.2", features = ["i128"], optional = true }
|
byteorder = { version = "1.2", features = ["i128"], optional = true }
|
||||||
|
fallible-iterator = "0.1"
|
||||||
fallible-streaming-iterator = "0.1"
|
fallible-streaming-iterator = "0.1"
|
||||||
memchr = "2.2.0"
|
memchr = "2.2.0"
|
||||||
|
|
||||||
|
15
src/cache.rs
15
src/cache.rs
@ -151,6 +151,7 @@ impl StatementCache {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use fallible_iterator::FallibleIterator;
|
||||||
use super::StatementCache;
|
use super::StatementCache;
|
||||||
use crate::{Connection, NO_PARAMS};
|
use crate::{Connection, NO_PARAMS};
|
||||||
|
|
||||||
@ -277,12 +278,9 @@ mod test {
|
|||||||
{
|
{
|
||||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
1i32,
|
Ok(Some(1i32)),
|
||||||
stmt.query_map::<i32, _, _>(NO_PARAMS, |r| r.get(0))
|
stmt.query(NO_PARAMS).unwrap().map(|r| r.get(0))
|
||||||
.unwrap()
|
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
|
||||||
.unwrap()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,12 +295,9 @@ mod test {
|
|||||||
{
|
{
|
||||||
let mut stmt = db.prepare_cached(sql).unwrap();
|
let mut stmt = db.prepare_cached(sql).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
(1i32, 2i32),
|
Ok(Some((1i32, 2i32))),
|
||||||
stmt.query_map(NO_PARAMS, |r| Ok((r.get(0)?, r.get(1)?)))
|
stmt.query(NO_PARAMS).unwrap().map(|r| Ok((r.get(0)?, r.get(1)?)))
|
||||||
.unwrap()
|
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
|
||||||
.unwrap()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,6 @@ use std::str;
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
pub use fallible_streaming_iterator::FallibleStreamingIterator;
|
|
||||||
|
|
||||||
use crate::cache::StatementCache;
|
use crate::cache::StatementCache;
|
||||||
use crate::inner_connection::{InnerConnection, BYPASS_SQLITE_INIT};
|
use crate::inner_connection::{InnerConnection, BYPASS_SQLITE_INIT};
|
||||||
use crate::raw_statement::RawStatement;
|
use crate::raw_statement::RawStatement;
|
||||||
@ -846,6 +844,7 @@ unsafe fn db_filename(_: *mut ffi::sqlite3) -> Option<PathBuf> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use fallible_iterator::FallibleIterator;
|
||||||
use self::tempdir::TempDir;
|
use self::tempdir::TempDir;
|
||||||
pub use super::*;
|
pub use super::*;
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
@ -1132,8 +1131,7 @@ mod test {
|
|||||||
|
|
||||||
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
|
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
|
||||||
let results: Result<Vec<String>> = query
|
let results: Result<Vec<String>> = query
|
||||||
.query_map(NO_PARAMS, |row| row.get(1))
|
.query(NO_PARAMS).unwrap().map(|row| row.get(1))
|
||||||
.unwrap()
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
assert_eq!(results.unwrap().concat(), "hello, world!");
|
assert_eq!(results.unwrap().concat(), "hello, world!");
|
||||||
@ -1322,7 +1320,7 @@ mod test {
|
|||||||
.prepare("SELECT interrupt() FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)")
|
.prepare("SELECT interrupt() FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let result: Result<Vec<i32>> = stmt.query_map(NO_PARAMS, |r| r.get(0)).unwrap().collect();
|
let result: Result<Vec<i32>> = stmt.query(NO_PARAMS).unwrap().map(|r| r.get(0)).collect();
|
||||||
|
|
||||||
match result.unwrap_err() {
|
match result.unwrap_err() {
|
||||||
Error::SqliteFailure(err, _) => {
|
Error::SqliteFailure(err, _) => {
|
||||||
|
31
src/row.rs
31
src/row.rs
@ -1,6 +1,8 @@
|
|||||||
|
use fallible_iterator::FallibleIterator;
|
||||||
|
use fallible_streaming_iterator::FallibleStreamingIterator;
|
||||||
use std::{convert, result};
|
use std::{convert, result};
|
||||||
|
|
||||||
use super::{Error, FallibleStreamingIterator, Result, Statement};
|
use super::{Error, Result, Statement};
|
||||||
use crate::types::{FromSql, FromSqlError, ValueRef};
|
use crate::types::{FromSql, FromSqlError, ValueRef};
|
||||||
|
|
||||||
/// An handle for the resulting rows of a query.
|
/// An handle for the resulting rows of a query.
|
||||||
@ -32,6 +34,13 @@ impl<'stmt> Rows<'stmt> {
|
|||||||
self.advance()?;
|
self.advance()?;
|
||||||
Ok((*self).get())
|
Ok((*self).get())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn map<F, B>(self, f: F) -> Map<'stmt, F>
|
||||||
|
where
|
||||||
|
F: FnMut(&Row<'_>) -> Result<B>,
|
||||||
|
{
|
||||||
|
Map { rows: self, f: f }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'stmt> Rows<'stmt> {
|
impl<'stmt> Rows<'stmt> {
|
||||||
@ -56,6 +65,26 @@ impl Drop for Rows<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Map<'stmt, F> {
|
||||||
|
rows: Rows<'stmt>,
|
||||||
|
f: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, B> FallibleIterator for Map<'_, F>
|
||||||
|
where
|
||||||
|
F: FnMut(&Row<'_>) -> Result<B>,
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
type Item = B;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Result<Option<B>> {
|
||||||
|
match self.rows.next()? {
|
||||||
|
Some(v) => Ok(Some((self.f)(v)?)),
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator over the mapped resulting rows of a query.
|
/// An iterator over the mapped resulting rows of a query.
|
||||||
pub struct MappedRows<'stmt, F> {
|
pub struct MappedRows<'stmt, F> {
|
||||||
rows: Rows<'stmt>,
|
rows: Rows<'stmt>,
|
||||||
|
@ -10,13 +10,13 @@ use std::panic::{catch_unwind, RefUnwindSafe};
|
|||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice::{from_raw_parts, from_raw_parts_mut};
|
use std::slice::{from_raw_parts, from_raw_parts_mut};
|
||||||
|
|
||||||
|
use fallible_streaming_iterator::FallibleStreamingIterator;
|
||||||
|
|
||||||
use crate::error::error_from_sqlite_code;
|
use crate::error::error_from_sqlite_code;
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
use crate::hooks::Action;
|
use crate::hooks::Action;
|
||||||
use crate::types::ValueRef;
|
use crate::types::ValueRef;
|
||||||
use crate::{
|
use crate::{errmsg_to_string, str_to_cstring, Connection, DatabaseName, Result};
|
||||||
errmsg_to_string, str_to_cstring, Connection, DatabaseName, FallibleStreamingIterator, Result,
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://sqlite.org/session.html
|
// https://sqlite.org/session.html
|
||||||
|
|
||||||
@ -720,10 +720,11 @@ unsafe extern "C" fn x_output(p_out: *mut c_void, data: *const c_void, len: c_in
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use fallible_streaming_iterator::FallibleStreamingIterator;
|
||||||
|
|
||||||
use super::{Changeset, ChangesetIter, ConflictAction, ConflictType, Session};
|
use super::{Changeset, ChangesetIter, ConflictAction, ConflictType, Session};
|
||||||
use crate::hooks::Action;
|
use crate::hooks::Action;
|
||||||
use crate::{Connection, FallibleStreamingIterator};
|
use crate::Connection;
|
||||||
|
|
||||||
fn one_changeset() -> Changeset {
|
fn one_changeset() -> Changeset {
|
||||||
let db = Connection::open_in_memory().unwrap();
|
let db = Connection::open_in_memory().unwrap();
|
||||||
|
@ -168,7 +168,7 @@ impl Statement<'_> {
|
|||||||
/// ## Example
|
/// ## Example
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, FallibleStreamingIterator, Result, NO_PARAMS};
|
/// # use rusqlite::{Connection, Result, NO_PARAMS};
|
||||||
/// fn get_names(conn: &Connection) -> Result<Vec<String>> {
|
/// fn get_names(conn: &Connection) -> Result<Vec<String>> {
|
||||||
/// let mut stmt = conn.prepare("SELECT name FROM people")?;
|
/// let mut stmt = conn.prepare("SELECT name FROM people")?;
|
||||||
/// let mut rows = stmt.query(NO_PARAMS)?;
|
/// let mut rows = stmt.query(NO_PARAMS)?;
|
||||||
@ -204,7 +204,7 @@ impl Statement<'_> {
|
|||||||
/// ## Example
|
/// ## Example
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, FallibleStreamingIterator, Result};
|
/// # use rusqlite::{Connection, Result};
|
||||||
/// fn query(conn: &Connection) -> Result<()> {
|
/// fn query(conn: &Connection) -> Result<()> {
|
||||||
/// let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?;
|
/// let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?;
|
||||||
/// let mut rows = stmt.query_named(&[(":name", &"one")])?;
|
/// let mut rows = stmt.query_named(&[(":name", &"one")])?;
|
||||||
@ -219,7 +219,7 @@ impl Statement<'_> {
|
|||||||
/// and so the above example could also be written as:
|
/// and so the above example could also be written as:
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, FallibleStreamingIterator, Result, named_params};
|
/// # use rusqlite::{Connection, Result, named_params};
|
||||||
/// fn query(conn: &Connection) -> Result<()> {
|
/// fn query(conn: &Connection) -> Result<()> {
|
||||||
/// let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?;
|
/// let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?;
|
||||||
/// let mut rows = stmt.query_named(named_params!{ ":name": "one" })?;
|
/// let mut rows = stmt.query_named(named_params!{ ":name": "one" })?;
|
||||||
|
@ -345,6 +345,7 @@ impl From<csv::Error> for Error {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use fallible_iterator::FallibleIterator;
|
||||||
use crate::vtab::csvtab;
|
use crate::vtab::csvtab;
|
||||||
use crate::{Connection, Result, NO_PARAMS};
|
use crate::{Connection, Result, NO_PARAMS};
|
||||||
|
|
||||||
@ -363,8 +364,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ids: Result<Vec<i32>> = s
|
let ids: Result<Vec<i32>> = s
|
||||||
.query_map(NO_PARAMS, |row| row.get::<_, i32>(0))
|
.query(NO_PARAMS).unwrap().map(|row| row.get::<_, i32>(0))
|
||||||
.unwrap()
|
|
||||||
.collect();
|
.collect();
|
||||||
let sum = ids.unwrap().iter().sum::<i32>();
|
let sum = ids.unwrap().iter().sum::<i32>();
|
||||||
assert_eq!(sum, 15);
|
assert_eq!(sum, 15);
|
||||||
|
Loading…
Reference in New Issue
Block a user