• 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> {
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: convert::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     /// Renamed to [`get_ref`](Row::get_ref).
343     #[deprecated = "Use [`get_ref`](Row::get_ref) instead."]
344     #[inline]
get_raw_checked<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>>345     pub fn get_raw_checked<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>> {
346         self.get_ref(idx)
347     }
348 
349     /// Renamed to [`get_ref_unwrap`](Row::get_ref_unwrap).
350     #[deprecated = "Use [`get_ref_unwrap`](Row::get_ref_unwrap) instead."]
351     #[inline]
get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'_>352     pub fn get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'_> {
353         self.get_ref_unwrap(idx)
354     }
355 }
356 
357 impl<'stmt> AsRef<Statement<'stmt>> for Row<'stmt> {
as_ref(&self) -> &Statement<'stmt>358     fn as_ref(&self) -> &Statement<'stmt> {
359         self.stmt
360     }
361 }
362 
363 mod sealed {
364     /// This trait exists just to ensure that the only impls of `trait Params`
365     /// that are allowed are ones in this crate.
366     pub trait Sealed {}
367     impl Sealed for usize {}
368     impl Sealed for &str {}
369 }
370 
371 /// A trait implemented by types that can index into columns of a row.
372 ///
373 /// It is only implemented for `usize` and `&str`.
374 pub trait RowIndex: sealed::Sealed {
375     /// Returns the index of the appropriate column, or `None` if no such
376     /// column exists.
idx(&self, stmt: &Statement<'_>) -> Result<usize>377     fn idx(&self, stmt: &Statement<'_>) -> Result<usize>;
378 }
379 
380 impl RowIndex for usize {
381     #[inline]
idx(&self, stmt: &Statement<'_>) -> Result<usize>382     fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
383         if *self >= stmt.column_count() {
384             Err(Error::InvalidColumnIndex(*self))
385         } else {
386             Ok(*self)
387         }
388     }
389 }
390 
391 impl RowIndex for &'_ str {
392     #[inline]
idx(&self, stmt: &Statement<'_>) -> Result<usize>393     fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
394         stmt.column_index(*self)
395     }
396 }
397 
398 macro_rules! tuple_try_from_row {
399     ($($field:ident),*) => {
400         impl<'a, $($field,)*> convert::TryFrom<&'a Row<'a>> for ($($field,)*) where $($field: FromSql,)* {
401             type Error = crate::Error;
402 
403             // we end with index += 1, which rustc warns about
404             // unused_variables and unused_mut are allowed for ()
405             #[allow(unused_assignments, unused_variables, unused_mut)]
406             fn try_from(row: &'a Row<'a>) -> Result<Self> {
407                 let mut index = 0;
408                 $(
409                     #[allow(non_snake_case)]
410                     let $field = row.get::<_, $field>(index)?;
411                     index += 1;
412                 )*
413                 Ok(($($field,)*))
414             }
415         }
416     }
417 }
418 
419 macro_rules! tuples_try_from_row {
420     () => {
421         // not very useful, but maybe some other macro users will find this helpful
422         tuple_try_from_row!();
423     };
424     ($first:ident $(, $remaining:ident)*) => {
425         tuple_try_from_row!($first $(, $remaining)*);
426         tuples_try_from_row!($($remaining),*);
427     };
428 }
429 
430 tuples_try_from_row!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
431 
432 #[cfg(test)]
433 mod tests {
434     #![allow(clippy::redundant_closure)] // false positives due to lifetime issues; clippy issue #5594
435     use crate::{Connection, Result};
436 
437     #[test]
test_try_from_row_for_tuple_1() -> Result<()>438     fn test_try_from_row_for_tuple_1() -> Result<()> {
439         use crate::ToSql;
440         use std::convert::TryFrom;
441 
442         let conn = Connection::open_in_memory()?;
443         conn.execute(
444             "CREATE TABLE test (a INTEGER)",
445             crate::params_from_iter(std::iter::empty::<&dyn ToSql>()),
446         )?;
447         conn.execute("INSERT INTO test VALUES (42)", [])?;
448         let val = conn.query_row("SELECT a FROM test", [], |row| <(u32,)>::try_from(row))?;
449         assert_eq!(val, (42,));
450         let fail = conn.query_row("SELECT a FROM test", [], |row| <(u32, u32)>::try_from(row));
451         assert!(fail.is_err());
452         Ok(())
453     }
454 
455     #[test]
test_try_from_row_for_tuple_2() -> Result<()>456     fn test_try_from_row_for_tuple_2() -> Result<()> {
457         use std::convert::TryFrom;
458 
459         let conn = Connection::open_in_memory()?;
460         conn.execute("CREATE TABLE test (a INTEGER, b INTEGER)", [])?;
461         conn.execute("INSERT INTO test VALUES (42, 47)", [])?;
462         let val = conn.query_row("SELECT a, b FROM test", [], |row| {
463             <(u32, u32)>::try_from(row)
464         })?;
465         assert_eq!(val, (42, 47));
466         let fail = conn.query_row("SELECT a, b FROM test", [], |row| {
467             <(u32, u32, u32)>::try_from(row)
468         });
469         assert!(fail.is_err());
470         Ok(())
471     }
472 
473     #[test]
test_try_from_row_for_tuple_16() -> Result<()>474     fn test_try_from_row_for_tuple_16() -> Result<()> {
475         use std::convert::TryFrom;
476 
477         let create_table = "CREATE TABLE test (
478             a INTEGER,
479             b INTEGER,
480             c INTEGER,
481             d INTEGER,
482             e INTEGER,
483             f INTEGER,
484             g INTEGER,
485             h INTEGER,
486             i INTEGER,
487             j INTEGER,
488             k INTEGER,
489             l INTEGER,
490             m INTEGER,
491             n INTEGER,
492             o INTEGER,
493             p INTEGER
494         )";
495 
496         let insert_values = "INSERT INTO test VALUES (
497             0,
498             1,
499             2,
500             3,
501             4,
502             5,
503             6,
504             7,
505             8,
506             9,
507             10,
508             11,
509             12,
510             13,
511             14,
512             15
513         )";
514 
515         type BigTuple = (
516             u32,
517             u32,
518             u32,
519             u32,
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         );
533 
534         let conn = Connection::open_in_memory()?;
535         conn.execute(create_table, [])?;
536         conn.execute(insert_values, [])?;
537         let val = conn.query_row("SELECT * FROM test", [], |row| BigTuple::try_from(row))?;
538         // Debug is not implemented for tuples of 16
539         assert_eq!(val.0, 0);
540         assert_eq!(val.1, 1);
541         assert_eq!(val.2, 2);
542         assert_eq!(val.3, 3);
543         assert_eq!(val.4, 4);
544         assert_eq!(val.5, 5);
545         assert_eq!(val.6, 6);
546         assert_eq!(val.7, 7);
547         assert_eq!(val.8, 8);
548         assert_eq!(val.9, 9);
549         assert_eq!(val.10, 10);
550         assert_eq!(val.11, 11);
551         assert_eq!(val.12, 12);
552         assert_eq!(val.13, 13);
553         assert_eq!(val.14, 14);
554         assert_eq!(val.15, 15);
555 
556         // We don't test one bigger because it's unimplemented
557         Ok(())
558     }
559 }
560