• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use fallible_iterator::FallibleIterator;
2 use fallible_streaming_iterator::FallibleStreamingIterator;
3 use std::convert;
4 
5 use super::{Error, Result, Statement};
6 use crate::types::{FromSql, FromSqlError, ValueRef};
7 
8 /// An handle for the resulting rows of a query.
9 #[must_use = "Rows is lazy and will do nothing unless consumed"]
10 pub struct Rows<'stmt> {
11     pub(crate) stmt: Option<&'stmt Statement<'stmt>>,
12     row: Option<Row<'stmt>>,
13 }
14 
15 impl<'stmt> Rows<'stmt> {
reset(&mut self)16     fn reset(&mut self) {
17         if let Some(stmt) = self.stmt.take() {
18             stmt.reset();
19         }
20     }
21 
22     /// Attempt to get the next row from the query. Returns `Ok(Some(Row))` if
23     /// there is another row, `Err(...)` if there was an error
24     /// getting the next row, and `Ok(None)` if all rows have been retrieved.
25     ///
26     /// ## Note
27     ///
28     /// This interface is not compatible with Rust's `Iterator` trait, because
29     /// the lifetime of the returned row is tied to the lifetime of `self`.
30     /// This is a fallible "streaming iterator". For a more natural interface,
31     /// consider using `query_map` or `query_and_then` instead, which
32     /// return types that implement `Iterator`.
33     #[allow(clippy::should_implement_trait)] // cannot implement Iterator
next(&mut self) -> Result<Option<&Row<'stmt>>>34     pub fn next(&mut self) -> Result<Option<&Row<'stmt>>> {
35         self.advance()?;
36         Ok((*self).get())
37     }
38 
39     /// Map over this `Rows`, converting it to a [`Map`], which
40     /// implements `FallibleIterator`.
41     /// ```rust,no_run
42     /// use fallible_iterator::FallibleIterator;
43     /// # use rusqlite::{Result, Statement, NO_PARAMS};
44     /// fn query(stmt: &mut Statement) -> Result<Vec<i64>> {
45     ///     let rows = stmt.query(NO_PARAMS)?;
46     ///     rows.map(|r| r.get(0)).collect()
47     /// }
48     /// ```
49     // FIXME Hide FallibleStreamingIterator::map
map<F, B>(self, f: F) -> Map<'stmt, F> where F: FnMut(&Row<'_>) -> Result<B>,50     pub fn map<F, B>(self, f: F) -> Map<'stmt, F>
51     where
52         F: FnMut(&Row<'_>) -> Result<B>,
53     {
54         Map { rows: self, f }
55     }
56 
57     /// Map over this `Rows`, converting it to a [`MappedRows`], which
58     /// implements `Iterator`.
mapped<F, B>(self, f: F) -> MappedRows<'stmt, F> where F: FnMut(&Row<'_>) -> Result<B>,59     pub fn mapped<F, B>(self, f: F) -> MappedRows<'stmt, F>
60     where
61         F: FnMut(&Row<'_>) -> Result<B>,
62     {
63         MappedRows { rows: self, map: f }
64     }
65 
66     /// Map over this `Rows` with a fallible function, converting it to a
67     /// [`AndThenRows`], which implements `Iterator` (instead of
68     /// `FallibleStreamingIterator`).
and_then<F, T, E>(self, f: F) -> AndThenRows<'stmt, F> where F: FnMut(&Row<'_>) -> Result<T, E>,69     pub fn and_then<F, T, E>(self, f: F) -> AndThenRows<'stmt, F>
70     where
71         F: FnMut(&Row<'_>) -> Result<T, E>,
72     {
73         AndThenRows { rows: self, map: f }
74     }
75 }
76 
77 impl<'stmt> Rows<'stmt> {
new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt>78     pub(crate) fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> {
79         Rows {
80             stmt: Some(stmt),
81             row: None,
82         }
83     }
84 
get_expected_row(&mut self) -> Result<&Row<'stmt>>85     pub(crate) fn get_expected_row(&mut self) -> Result<&Row<'stmt>> {
86         match self.next()? {
87             Some(row) => Ok(row),
88             None => Err(Error::QueryReturnedNoRows),
89         }
90     }
91 }
92 
93 impl Drop for Rows<'_> {
drop(&mut self)94     fn drop(&mut self) {
95         self.reset();
96     }
97 }
98 
99 /// `F` is used to tranform the _streaming_ iterator into a _fallible_ iterator.
100 #[must_use = "iterators are lazy and do nothing unless consumed"]
101 pub struct Map<'stmt, F> {
102     rows: Rows<'stmt>,
103     f: F,
104 }
105 
106 impl<F, B> FallibleIterator for Map<'_, F>
107 where
108     F: FnMut(&Row<'_>) -> Result<B>,
109 {
110     type Error = Error;
111     type Item = B;
112 
next(&mut self) -> Result<Option<B>>113     fn next(&mut self) -> Result<Option<B>> {
114         match self.rows.next()? {
115             Some(v) => Ok(Some((self.f)(v)?)),
116             None => Ok(None),
117         }
118     }
119 }
120 
121 /// An iterator over the mapped resulting rows of a query.
122 ///
123 /// `F` is used to tranform the _streaming_ iterator into a _standard_ iterator.
124 #[must_use = "iterators are lazy and do nothing unless consumed"]
125 pub struct MappedRows<'stmt, F> {
126     rows: Rows<'stmt>,
127     map: F,
128 }
129 
130 impl<'stmt, T, F> MappedRows<'stmt, F>
131 where
132     F: FnMut(&Row<'_>) -> Result<T>,
133 {
new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F>134     pub(crate) fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
135         MappedRows { rows, map: f }
136     }
137 }
138 
139 impl<T, F> Iterator for MappedRows<'_, F>
140 where
141     F: FnMut(&Row<'_>) -> Result<T>,
142 {
143     type Item = Result<T>;
144 
next(&mut self) -> Option<Result<T>>145     fn next(&mut self) -> Option<Result<T>> {
146         let map = &mut self.map;
147         self.rows
148             .next()
149             .transpose()
150             .map(|row_result| row_result.and_then(|row| (map)(&row)))
151     }
152 }
153 
154 /// An iterator over the mapped resulting rows of a query, with an Error type
155 /// unifying with Error.
156 #[must_use = "iterators are lazy and do nothing unless consumed"]
157 pub struct AndThenRows<'stmt, F> {
158     rows: Rows<'stmt>,
159     map: F,
160 }
161 
162 impl<'stmt, T, E, F> AndThenRows<'stmt, F>
163 where
164     F: FnMut(&Row<'_>) -> Result<T, E>,
165 {
new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F>166     pub(crate) fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F> {
167         AndThenRows { rows, map: f }
168     }
169 }
170 
171 impl<T, E, F> Iterator for AndThenRows<'_, F>
172 where
173     E: convert::From<Error>,
174     F: FnMut(&Row<'_>) -> Result<T, E>,
175 {
176     type Item = Result<T, E>;
177 
next(&mut self) -> Option<Self::Item>178     fn next(&mut self) -> Option<Self::Item> {
179         let map = &mut self.map;
180         self.rows
181             .next()
182             .transpose()
183             .map(|row_result| row_result.map_err(E::from).and_then(|row| (map)(&row)))
184     }
185 }
186 
187 /// `FallibleStreamingIterator` differs from the standard library's `Iterator`
188 /// in two ways:
189 /// * each call to `next` (sqlite3_step) can fail.
190 /// * returned `Row` is valid until `next` is called again or `Statement` is
191 ///   reset or finalized.
192 ///
193 /// While these iterators cannot be used with Rust `for` loops, `while let`
194 /// loops offer a similar level of ergonomics:
195 /// ```rust,no_run
196 /// # use rusqlite::{Result, Statement, NO_PARAMS};
197 /// fn query(stmt: &mut Statement) -> Result<()> {
198 ///     let mut rows = stmt.query(NO_PARAMS)?;
199 ///     while let Some(row) = rows.next()? {
200 ///         // scan columns value
201 ///     }
202 ///     Ok(())
203 /// }
204 /// ```
205 impl<'stmt> FallibleStreamingIterator for Rows<'stmt> {
206     type Error = Error;
207     type Item = Row<'stmt>;
208 
advance(&mut self) -> Result<()>209     fn advance(&mut self) -> Result<()> {
210         match self.stmt {
211             Some(ref stmt) => match stmt.step() {
212                 Ok(true) => {
213                     self.row = Some(Row { stmt });
214                     Ok(())
215                 }
216                 Ok(false) => {
217                     self.reset();
218                     self.row = None;
219                     Ok(())
220                 }
221                 Err(e) => {
222                     self.reset();
223                     self.row = None;
224                     Err(e)
225                 }
226             },
227             None => {
228                 self.row = None;
229                 Ok(())
230             }
231         }
232     }
233 
get(&self) -> Option<&Row<'stmt>>234     fn get(&self) -> Option<&Row<'stmt>> {
235         self.row.as_ref()
236     }
237 }
238 
239 /// A single result row of a query.
240 pub struct Row<'stmt> {
241     pub(crate) stmt: &'stmt Statement<'stmt>,
242 }
243 
244 impl<'stmt> Row<'stmt> {
245     /// Get the value of a particular column of the result row.
246     ///
247     /// ## Failure
248     ///
249     /// Panics if calling `row.get(idx)` would return an error,
250     /// including:
251     ///
252     /// * If the underlying SQLite column type is not a valid type as a source
253     ///   for `T`
254     /// * If the underlying SQLite integral value is outside the range
255     ///   representable by `T`
256     /// * If `idx` is outside the range of columns in the returned query
get_unwrap<I: RowIndex, T: FromSql>(&self, idx: I) -> T257     pub fn get_unwrap<I: RowIndex, T: FromSql>(&self, idx: I) -> T {
258         self.get(idx).unwrap()
259     }
260 
261     /// Get the value of a particular column of the result row.
262     ///
263     /// ## Failure
264     ///
265     /// Returns an `Error::InvalidColumnType` if the underlying SQLite column
266     /// type is not a valid type as a source for `T`.
267     ///
268     /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid
269     /// column range for this row.
270     ///
271     /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column
272     /// name for this row.
273     ///
274     /// If the result type is i128 (which requires the `i128_blob` feature to be
275     /// enabled), and the underlying SQLite column is a blob whose size is not
276     /// 16 bytes, `Error::InvalidColumnType` will also be returned.
get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T>277     pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> {
278         let idx = idx.idx(self.stmt)?;
279         let value = self.stmt.value_ref(idx);
280         FromSql::column_result(value).map_err(|err| match err {
281             FromSqlError::InvalidType => Error::InvalidColumnType(
282                 idx,
283                 self.stmt.column_name_unwrap(idx).into(),
284                 value.data_type(),
285             ),
286             FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
287             FromSqlError::Other(err) => {
288                 Error::FromSqlConversionFailure(idx as usize, value.data_type(), err)
289             }
290             #[cfg(feature = "i128_blob")]
291             FromSqlError::InvalidI128Size(_) => Error::InvalidColumnType(
292                 idx,
293                 self.stmt.column_name_unwrap(idx).into(),
294                 value.data_type(),
295             ),
296             #[cfg(feature = "uuid")]
297             FromSqlError::InvalidUuidSize(_) => Error::InvalidColumnType(
298                 idx,
299                 self.stmt.column_name_unwrap(idx).into(),
300                 value.data_type(),
301             ),
302         })
303     }
304 
305     /// Get the value of a particular column of the result row as a `ValueRef`,
306     /// allowing data to be read out of a row without copying.
307     ///
308     /// This `ValueRef` is valid only as long as this Row, which is enforced by
309     /// it's lifetime. This means that while this method is completely safe,
310     /// it can be somewhat difficult to use, and most callers will be better
311     /// served by `get` or `get`.
312     ///
313     /// ## Failure
314     ///
315     /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid
316     /// column range for this row.
317     ///
318     /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column
319     /// name for this row.
get_raw_checked<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>>320     pub fn get_raw_checked<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>> {
321         let idx = idx.idx(self.stmt)?;
322         // Narrowing from `ValueRef<'stmt>` (which `self.stmt.value_ref(idx)`
323         // returns) to `ValueRef<'a>` is needed because it's only valid until
324         // the next call to sqlite3_step.
325         let val_ref = self.stmt.value_ref(idx);
326         Ok(val_ref)
327     }
328 
329     /// Get the value of a particular column of the result row as a `ValueRef`,
330     /// allowing data to be read out of a row without copying.
331     ///
332     /// This `ValueRef` is valid only as long as this Row, which is enforced by
333     /// it's lifetime. This means that while this method is completely safe,
334     /// it can be difficult to use, and most callers will be better served by
335     /// `get` or `get`.
336     ///
337     /// ## Failure
338     ///
339     /// Panics if calling `row.get_raw_checked(idx)` would return an error,
340     /// including:
341     ///
342     /// * If `idx` is outside the range of columns in the returned query.
343     /// * If `idx` is not a valid column name for this row.
get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'_>344     pub fn get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'_> {
345         self.get_raw_checked(idx).unwrap()
346     }
347 }
348 
349 /// A trait implemented by types that can index into columns of a row.
350 pub trait RowIndex {
351     /// Returns the index of the appropriate column, or `None` if no such
352     /// column exists.
idx(&self, stmt: &Statement<'_>) -> Result<usize>353     fn idx(&self, stmt: &Statement<'_>) -> Result<usize>;
354 }
355 
356 impl RowIndex for usize {
357     #[inline]
idx(&self, stmt: &Statement<'_>) -> Result<usize>358     fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
359         if *self >= stmt.column_count() {
360             Err(Error::InvalidColumnIndex(*self))
361         } else {
362             Ok(*self)
363         }
364     }
365 }
366 
367 impl RowIndex for &'_ str {
368     #[inline]
idx(&self, stmt: &Statement<'_>) -> Result<usize>369     fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
370         stmt.column_index(*self)
371     }
372 }
373 
374 macro_rules! tuple_try_from_row {
375     ($($field:ident),*) => {
376         impl<'a, $($field,)*> convert::TryFrom<&'a Row<'a>> for ($($field,)*) where $($field: FromSql,)* {
377             type Error = crate::Error;
378 
379             // we end with index += 1, which rustc warns about
380             // unused_variables and unused_mut are allowed for ()
381             #[allow(unused_assignments, unused_variables, unused_mut)]
382             fn try_from(row: &'a Row<'a>) -> Result<Self> {
383                 let mut index = 0;
384                 $(
385                     #[allow(non_snake_case)]
386                     let $field = row.get::<_, $field>(index)?;
387                     index += 1;
388                 )*
389                 Ok(($($field,)*))
390             }
391         }
392     }
393 }
394 
395 macro_rules! tuples_try_from_row {
396     () => {
397         // not very useful, but maybe some other macro users will find this helpful
398         tuple_try_from_row!();
399     };
400     ($first:ident $(, $remaining:ident)*) => {
401         tuple_try_from_row!($first $(, $remaining)*);
402         tuples_try_from_row!($($remaining),*);
403     };
404 }
405 
406 tuples_try_from_row!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
407 
408 #[cfg(test)]
409 mod tests {
410     #![allow(clippy::redundant_closure)] // false positives due to lifetime issues; clippy issue #5594
411 
412     #[test]
test_try_from_row_for_tuple_1()413     fn test_try_from_row_for_tuple_1() {
414         use crate::{Connection, ToSql};
415         use std::convert::TryFrom;
416 
417         let conn = Connection::open_in_memory().expect("failed to create in-memoory database");
418         conn.execute(
419             "CREATE TABLE test (a INTEGER)",
420             std::iter::empty::<&dyn ToSql>(),
421         )
422         .expect("failed to create table");
423         conn.execute(
424             "INSERT INTO test VALUES (42)",
425             std::iter::empty::<&dyn ToSql>(),
426         )
427         .expect("failed to insert value");
428         let val = conn
429             .query_row(
430                 "SELECT a FROM test",
431                 std::iter::empty::<&dyn ToSql>(),
432                 |row| <(u32,)>::try_from(row),
433             )
434             .expect("failed to query row");
435         assert_eq!(val, (42,));
436         let fail = conn.query_row(
437             "SELECT a FROM test",
438             std::iter::empty::<&dyn ToSql>(),
439             |row| <(u32, u32)>::try_from(row),
440         );
441         assert!(fail.is_err());
442     }
443 
444     #[test]
test_try_from_row_for_tuple_2()445     fn test_try_from_row_for_tuple_2() {
446         use crate::{Connection, ToSql};
447         use std::convert::TryFrom;
448 
449         let conn = Connection::open_in_memory().expect("failed to create in-memoory database");
450         conn.execute(
451             "CREATE TABLE test (a INTEGER, b INTEGER)",
452             std::iter::empty::<&dyn ToSql>(),
453         )
454         .expect("failed to create table");
455         conn.execute(
456             "INSERT INTO test VALUES (42, 47)",
457             std::iter::empty::<&dyn ToSql>(),
458         )
459         .expect("failed to insert value");
460         let val = conn
461             .query_row(
462                 "SELECT a, b FROM test",
463                 std::iter::empty::<&dyn ToSql>(),
464                 |row| <(u32, u32)>::try_from(row),
465             )
466             .expect("failed to query row");
467         assert_eq!(val, (42, 47));
468         let fail = conn.query_row(
469             "SELECT a, b FROM test",
470             std::iter::empty::<&dyn ToSql>(),
471             |row| <(u32, u32, u32)>::try_from(row),
472         );
473         assert!(fail.is_err());
474     }
475 
476     #[test]
test_try_from_row_for_tuple_16()477     fn test_try_from_row_for_tuple_16() {
478         use crate::{Connection, ToSql};
479         use std::convert::TryFrom;
480 
481         let create_table = "CREATE TABLE test (
482             a INTEGER,
483             b INTEGER,
484             c INTEGER,
485             d INTEGER,
486             e INTEGER,
487             f INTEGER,
488             g INTEGER,
489             h INTEGER,
490             i INTEGER,
491             j INTEGER,
492             k INTEGER,
493             l INTEGER,
494             m INTEGER,
495             n INTEGER,
496             o INTEGER,
497             p INTEGER
498         )";
499 
500         let insert_values = "INSERT INTO test VALUES (
501             0,
502             1,
503             2,
504             3,
505             4,
506             5,
507             6,
508             7,
509             8,
510             9,
511             10,
512             11,
513             12,
514             13,
515             14,
516             15
517         )";
518 
519         type BigTuple = (
520             u32,
521             u32,
522             u32,
523             u32,
524             u32,
525             u32,
526             u32,
527             u32,
528             u32,
529             u32,
530             u32,
531             u32,
532             u32,
533             u32,
534             u32,
535             u32,
536         );
537 
538         let conn = Connection::open_in_memory().expect("failed to create in-memoory database");
539         conn.execute(create_table, std::iter::empty::<&dyn ToSql>())
540             .expect("failed to create table");
541         conn.execute(insert_values, std::iter::empty::<&dyn ToSql>())
542             .expect("failed to insert value");
543         let val = conn
544             .query_row(
545                 "SELECT * FROM test",
546                 std::iter::empty::<&dyn ToSql>(),
547                 |row| BigTuple::try_from(row),
548             )
549             .expect("failed to query row");
550         // Debug is not implemented for tuples of 16
551         assert_eq!(val.0, 0);
552         assert_eq!(val.1, 1);
553         assert_eq!(val.2, 2);
554         assert_eq!(val.3, 3);
555         assert_eq!(val.4, 4);
556         assert_eq!(val.5, 5);
557         assert_eq!(val.6, 6);
558         assert_eq!(val.7, 7);
559         assert_eq!(val.8, 8);
560         assert_eq!(val.9, 9);
561         assert_eq!(val.10, 10);
562         assert_eq!(val.11, 11);
563         assert_eq!(val.12, 12);
564         assert_eq!(val.13, 13);
565         assert_eq!(val.14, 14);
566         assert_eq!(val.15, 15);
567 
568         // We don't test one bigger because it's unimplemented
569     }
570 }
571