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