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