rusqlite/
row.rs

1use fallible_iterator::FallibleIterator;
2use fallible_streaming_iterator::FallibleStreamingIterator;
3use std::convert;
4
5use super::{Error, Result, Statement};
6use 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"]
10pub struct Rows<'stmt> {
11    pub(crate) stmt: Option<&'stmt Statement<'stmt>>,
12    row: Option<Row<'stmt>>,
13}
14
15impl<'stmt> Rows<'stmt> {
16    #[inline]
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]
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]
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]
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]
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]
84    pub fn as_ref(&self) -> Option<&Statement<'stmt>> {
85        self.stmt
86    }
87}
88
89impl<'stmt> Rows<'stmt> {
90    #[inline]
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]
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
107impl Drop for Rows<'_> {
108    #[inline]
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"]
117pub struct Map<'stmt, F> {
118    rows: Rows<'stmt>,
119    f: F,
120}
121
122impl<F, B> FallibleIterator for Map<'_, F>
123where
124    F: FnMut(&Row<'_>) -> Result<B>,
125{
126    type Error = Error;
127    type Item = B;
128
129    #[inline]
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"]
143pub struct MappedRows<'stmt, F> {
144    rows: Rows<'stmt>,
145    map: F,
146}
147
148impl<T, F> Iterator for MappedRows<'_, F>
149where
150    F: FnMut(&Row<'_>) -> Result<T>,
151{
152    type Item = Result<T>;
153
154    #[inline]
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"]
167pub struct AndThenRows<'stmt, F> {
168    rows: Rows<'stmt>,
169    map: F,
170}
171
172impl<T, E, F> Iterator for AndThenRows<'_, F>
173where
174    E: From<Error>,
175    F: FnMut(&Row<'_>) -> Result<T, E>,
176{
177    type Item = Result<T, E>;
178
179    #[inline]
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/// ```
207impl<'stmt> FallibleStreamingIterator for Rows<'stmt> {
208    type Error = Error;
209    type Item = Row<'stmt>;
210
211    #[inline]
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]
237    fn get(&self) -> Option<&Row<'stmt>> {
238        self.row.as_ref()
239    }
240}
241
242/// A single result row of a query.
243pub struct Row<'stmt> {
244    pub(crate) stmt: &'stmt Statement<'stmt>,
245}
246
247impl<'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
260    #[track_caller]
261    pub fn get_unwrap<I: RowIndex, T: FromSql>(&self, idx: I) -> T {
262        self.get(idx).unwrap()
263    }
264
265    /// Get the value of a particular column of the result row.
266    ///
267    /// ## Failure
268    ///
269    /// Returns an `Error::InvalidColumnType` if the underlying SQLite column
270    /// type is not a valid type as a source for `T`.
271    ///
272    /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid
273    /// column range for this row.
274    ///
275    /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column
276    /// name for this row.
277    ///
278    /// If the result type is i128 (which requires the `i128_blob` feature to be
279    /// enabled), and the underlying SQLite column is a blob whose size is not
280    /// 16 bytes, `Error::InvalidColumnType` will also be returned.
281    #[track_caller]
282    pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> {
283        let idx = idx.idx(self.stmt)?;
284        let value = self.stmt.value_ref(idx);
285        FromSql::column_result(value).map_err(|err| match err {
286            FromSqlError::InvalidType => Error::InvalidColumnType(
287                idx,
288                self.stmt.column_name_unwrap(idx).into(),
289                value.data_type(),
290            ),
291            FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
292            FromSqlError::Other(err) => {
293                Error::FromSqlConversionFailure(idx, value.data_type(), err)
294            }
295            FromSqlError::InvalidBlobSize { .. } => {
296                Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
297            }
298        })
299    }
300
301    /// Get the value of a particular column of the result row as a `ValueRef`,
302    /// allowing data to be read out of a row without copying.
303    ///
304    /// This `ValueRef` is valid only as long as this Row, which is enforced by
305    /// it's lifetime. This means that while this method is completely safe,
306    /// it can be somewhat difficult to use, and most callers will be better
307    /// served by [`get`](Row::get) or [`get_unwrap`](Row::get_unwrap).
308    ///
309    /// ## Failure
310    ///
311    /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid
312    /// column range for this row.
313    ///
314    /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column
315    /// name for this row.
316    pub fn get_ref<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>> {
317        let idx = idx.idx(self.stmt)?;
318        // Narrowing from `ValueRef<'stmt>` (which `self.stmt.value_ref(idx)`
319        // returns) to `ValueRef<'a>` is needed because it's only valid until
320        // the next call to sqlite3_step.
321        let val_ref = self.stmt.value_ref(idx);
322        Ok(val_ref)
323    }
324
325    /// Get the value of a particular column of the result row as a `ValueRef`,
326    /// allowing data to be read out of a row without copying.
327    ///
328    /// This `ValueRef` is valid only as long as this Row, which is enforced by
329    /// it's lifetime. This means that while this method is completely safe,
330    /// it can be difficult to use, and most callers will be better served by
331    /// [`get`](Row::get) or [`get_unwrap`](Row::get_unwrap).
332    ///
333    /// ## Failure
334    ///
335    /// Panics if calling [`row.get_ref(idx)`](Row::get_ref) would return an
336    /// error, including:
337    ///
338    /// * If `idx` is outside the range of columns in the returned query.
339    /// * If `idx` is not a valid column name for this row.
340    #[track_caller]
341    pub fn get_ref_unwrap<I: RowIndex>(&self, idx: I) -> ValueRef<'_> {
342        self.get_ref(idx).unwrap()
343    }
344}
345
346impl<'stmt> AsRef<Statement<'stmt>> for Row<'stmt> {
347    fn as_ref(&self) -> &Statement<'stmt> {
348        self.stmt
349    }
350}
351
352/// Debug `Row` like an ordered `Map<Result<&str>, Result<(Type, ValueRef)>>`
353/// with column name as key except that for `Type::Blob` only its size is
354/// printed (not its content).
355impl<'stmt> std::fmt::Debug for Row<'stmt> {
356    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
357        let mut dm = f.debug_map();
358        for c in 0..self.stmt.column_count() {
359            let name = self.stmt.column_name(c);
360            dm.key(&name);
361            let value = self.get_ref(c);
362            match value {
363                Ok(value) => {
364                    let dt = value.data_type();
365                    match value {
366                        ValueRef::Null => {
367                            dm.value(&(dt, ()));
368                        }
369                        ValueRef::Integer(i) => {
370                            dm.value(&(dt, i));
371                        }
372                        ValueRef::Real(f) => {
373                            dm.value(&(dt, f));
374                        }
375                        ValueRef::Text(s) => {
376                            dm.value(&(dt, String::from_utf8_lossy(s)));
377                        }
378                        ValueRef::Blob(b) => {
379                            dm.value(&(dt, b.len()));
380                        }
381                    }
382                }
383                Err(ref _err) => {
384                    dm.value(&value);
385                }
386            }
387        }
388        dm.finish()
389    }
390}
391
392mod sealed {
393    /// This trait exists just to ensure that the only impls of `trait Params`
394    /// that are allowed are ones in this crate.
395    pub trait Sealed {}
396    impl Sealed for usize {}
397    impl Sealed for &str {}
398}
399
400/// A trait implemented by types that can index into columns of a row.
401///
402/// It is only implemented for `usize` and `&str`.
403pub trait RowIndex: sealed::Sealed {
404    /// Returns the index of the appropriate column, or `None` if no such
405    /// column exists.
406    fn idx(&self, stmt: &Statement<'_>) -> Result<usize>;
407}
408
409impl RowIndex for usize {
410    #[inline]
411    fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
412        if *self >= stmt.column_count() {
413            Err(Error::InvalidColumnIndex(*self))
414        } else {
415            Ok(*self)
416        }
417    }
418}
419
420impl RowIndex for &'_ str {
421    #[inline]
422    fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
423        stmt.column_index(self)
424    }
425}
426
427macro_rules! tuple_try_from_row {
428    ($($field:ident),*) => {
429        impl<'a, $($field,)*> convert::TryFrom<&'a Row<'a>> for ($($field,)*) where $($field: FromSql,)* {
430            type Error = crate::Error;
431
432            // we end with index += 1, which rustc warns about
433            // unused_variables and unused_mut are allowed for ()
434            #[allow(unused_assignments, unused_variables, unused_mut)]
435            fn try_from(row: &'a Row<'a>) -> Result<Self> {
436                let mut index = 0;
437                $(
438                    #[allow(non_snake_case)]
439                    let $field = row.get::<_, $field>(index)?;
440                    index += 1;
441                )*
442                Ok(($($field,)*))
443            }
444        }
445    }
446}
447
448macro_rules! tuples_try_from_row {
449    () => {
450        // not very useful, but maybe some other macro users will find this helpful
451        tuple_try_from_row!();
452    };
453    ($first:ident $(, $remaining:ident)*) => {
454        tuple_try_from_row!($first $(, $remaining)*);
455        tuples_try_from_row!($($remaining),*);
456    };
457}
458
459tuples_try_from_row!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
460
461#[cfg(test)]
462mod tests {
463    #![allow(clippy::redundant_closure)] // false positives due to lifetime issues; clippy issue #5594
464    use crate::{Connection, Result};
465
466    #[test]
467    fn test_try_from_row_for_tuple_1() -> Result<()> {
468        use crate::ToSql;
469        use std::convert::TryFrom;
470
471        let conn = Connection::open_in_memory()?;
472        conn.execute(
473            "CREATE TABLE test (a INTEGER)",
474            crate::params_from_iter(std::iter::empty::<&dyn ToSql>()),
475        )?;
476        conn.execute("INSERT INTO test VALUES (42)", [])?;
477        let val = conn.query_row("SELECT a FROM test", [], |row| <(u32,)>::try_from(row))?;
478        assert_eq!(val, (42,));
479        let fail = conn.query_row("SELECT a FROM test", [], |row| <(u32, u32)>::try_from(row));
480        fail.unwrap_err();
481        Ok(())
482    }
483
484    #[test]
485    fn test_try_from_row_for_tuple_2() -> Result<()> {
486        use std::convert::TryFrom;
487
488        let conn = Connection::open_in_memory()?;
489        conn.execute("CREATE TABLE test (a INTEGER, b INTEGER)", [])?;
490        conn.execute("INSERT INTO test VALUES (42, 47)", [])?;
491        let val = conn.query_row("SELECT a, b FROM test", [], |row| {
492            <(u32, u32)>::try_from(row)
493        })?;
494        assert_eq!(val, (42, 47));
495        let fail = conn.query_row("SELECT a, b FROM test", [], |row| {
496            <(u32, u32, u32)>::try_from(row)
497        });
498        fail.unwrap_err();
499        Ok(())
500    }
501
502    #[test]
503    fn test_try_from_row_for_tuple_16() -> Result<()> {
504        use std::convert::TryFrom;
505
506        let create_table = "CREATE TABLE test (
507            a INTEGER,
508            b INTEGER,
509            c INTEGER,
510            d INTEGER,
511            e INTEGER,
512            f INTEGER,
513            g INTEGER,
514            h INTEGER,
515            i INTEGER,
516            j INTEGER,
517            k INTEGER,
518            l INTEGER,
519            m INTEGER,
520            n INTEGER,
521            o INTEGER,
522            p INTEGER
523        )";
524
525        let insert_values = "INSERT INTO test VALUES (
526            0,
527            1,
528            2,
529            3,
530            4,
531            5,
532            6,
533            7,
534            8,
535            9,
536            10,
537            11,
538            12,
539            13,
540            14,
541            15
542        )";
543
544        type BigTuple = (
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            u32,
559            u32,
560            u32,
561        );
562
563        let conn = Connection::open_in_memory()?;
564        conn.execute(create_table, [])?;
565        conn.execute(insert_values, [])?;
566        let val = conn.query_row("SELECT * FROM test", [], |row| BigTuple::try_from(row))?;
567        // Debug is not implemented for tuples of 16
568        assert_eq!(val.0, 0);
569        assert_eq!(val.1, 1);
570        assert_eq!(val.2, 2);
571        assert_eq!(val.3, 3);
572        assert_eq!(val.4, 4);
573        assert_eq!(val.5, 5);
574        assert_eq!(val.6, 6);
575        assert_eq!(val.7, 7);
576        assert_eq!(val.8, 8);
577        assert_eq!(val.9, 9);
578        assert_eq!(val.10, 10);
579        assert_eq!(val.11, 11);
580        assert_eq!(val.12, 12);
581        assert_eq!(val.13, 13);
582        assert_eq!(val.14, 14);
583        assert_eq!(val.15, 15);
584
585        // We don't test one bigger because it's unimplemented
586        Ok(())
587    }
588}