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