sqlite_bindings_lunatic/
cursor.rs

1use std::collections::HashMap;
2use std::convert::TryFrom;
3use std::ops::{Deref, Index};
4use std::rc::Rc;
5
6use error::{Error, Result};
7use statement::{Bindable, State, Statement};
8use value::Value;
9
10/// An iterator for a prepared statement.
11pub struct Cursor<'m> {
12    statement: &'m mut Statement,
13    values: Vec<Value>,
14}
15
16/// An iterator for a prepared statement with ownership.
17pub struct CursorWithOwnership {
18    statement: Statement,
19    values: Vec<Value>,
20}
21
22/// A row.
23#[derive(Debug)]
24pub struct Row {
25    column_mapping: Rc<HashMap<String, usize>>,
26    values: Vec<Value>,
27}
28
29/// A type suitable for indexing columns in a row.
30pub trait RowIndex: std::fmt::Debug {
31    /// Identify the ordinal position.
32    ///
33    /// The first column has index 0.
34    fn index(self, row: &Row) -> usize;
35}
36
37macro_rules! implement(
38    ($type:ident<$($lifetime:lifetime),+>) => {
39        impl<$($lifetime),+> $type<$($lifetime),+> {
40            /// Bind values to parameters.
41            ///
42            /// In case of integer indices, the first parameter has index 1. See
43            /// `Statement::bind` for further details.
44            pub fn bind<T: Bindable>(self, value: T) -> Result<Self> {
45                #[allow(unused_mut)]
46                let mut cursor = self.reset()?;
47                cursor.statement.bind(value)?;
48                Ok(cursor)
49            }
50
51            /// Bind values to parameters via an iterator.
52            ///
53            /// See `Statement::bind_iter` for further details.
54            #[allow(unused_mut)]
55            pub fn bind_iter<T, U>(self, value: T) -> Result<Self>
56            where
57                T: IntoIterator<Item = U>,
58                U: Bindable,
59            {
60                let mut cursor = self.reset()?;
61                cursor.statement.bind_iter(value)?;
62                Ok(cursor)
63            }
64
65            /// Reset the internal state.
66            #[allow(unused_mut)]
67            pub fn reset(mut self) -> Result<Self> {
68                self.statement.reset()?;
69                Ok(self)
70            }
71
72            /// Advance to the next row and read all columns.
73            pub fn try_next(&mut self) -> Result<Option<&[Value]>> {
74                if self.statement.next()? == State::Done {
75                    return Ok(None);
76                }
77                for (index, value) in self.values.iter_mut().enumerate() {
78                    *value = self.statement.read(index)?;
79                }
80                Ok(Some(&self.values))
81            }
82        }
83
84        impl<$($lifetime),+> Deref for $type<$($lifetime),+> {
85            type Target = Statement;
86
87            #[inline]
88            fn deref(&self) -> &Self::Target {
89                &self.statement
90            }
91        }
92
93        impl<$($lifetime),+> Iterator for $type<$($lifetime),+> {
94            type Item = Result<Row>;
95
96            fn next(&mut self) -> Option<Self::Item> {
97                let column_mapping = self.statement.column_mapping();
98                self.try_next()
99                    .map(|row| {
100                        row.map(|row| Row {
101                            column_mapping: column_mapping,
102                            values: row.to_vec(),
103                        })
104                    })
105                    .transpose()
106            }
107        }
108    };
109    ($type:ident) => {
110        impl$type {
111            /// Bind values to parameters.
112            ///
113            /// See `Statement::bind` for further details.
114            pub fn bind<T: Bindable>(self, value: T) -> Result<Self> {
115                #[allow(unused_mut)]
116                let mut cursor = self.reset()?;
117                cursor.statement.bind(value)?;
118                Ok(cursor)
119            }
120
121            /// Bind values to parameters via an iterator.
122            ///
123            /// See `Statement::bind_iter` for further details.
124            pub fn bind_iter<T, U>(self, value: T) -> Result<Self>
125            where
126                T: IntoIterator<Item = U>,
127                U: Bindable,
128            {
129                #[allow(unused_mut)]
130                let mut cursor = self.reset()?;
131                cursor.statement.bind_iter(value)?;
132                Ok(cursor)
133            }
134
135            /// Reset the internal state.
136            pub fn reset(mut self) -> Result<Self> {
137                self.statement.reset()?;
138                Ok(self)
139            }
140
141            /// Advance to the next row and read all columns.
142            pub fn try_next(&mut self) -> Result<Option<&[Value]>> {
143                if self.statement.next()? == State::Done {
144                    return Ok(None);
145                }
146                for (index, value) in self.values.iter_mut().enumerate() {
147                    *value = self.statement.read(index)?;
148                }
149                Ok(Some(&self.values))
150            }
151        }
152
153        impl Deref for $type {
154            type Target = Statement;
155
156            #[inline]
157            fn deref(&self) -> &Self::Target {
158                &self.statement
159            }
160        }
161
162        impl Iterator for $type {
163            type Item = Result<Row>;
164
165            fn next(&mut self) -> Option<Self::Item> {
166                let column_mapping = self.statement.column_mapping();
167                self.try_next()
168                    .map(|row| {
169                        row.map(|row| Row {
170                            column_mapping: column_mapping,
171                            values: row.to_vec(),
172                        })
173                    })
174                    .transpose()
175            }
176        }
177    }
178);
179
180implement!(Cursor<'m>);
181implement!(CursorWithOwnership);
182
183impl<'l> From<CursorWithOwnership> for Statement {
184    #[inline]
185    fn from(cursor: CursorWithOwnership) -> Self {
186        cursor.statement
187    }
188}
189
190impl Row {
191    /// Read the value in a column.
192    ///
193    /// In case of integer indices, the first column has index 0.
194    ///
195    /// # Panics
196    ///
197    /// Panics if the column could not be read.
198    #[inline]
199    pub fn read<'l, T, U>(&'l self, column: U) -> T
200    where
201        T: TryFrom<&'l Value, Error = Error>,
202        U: RowIndex,
203    {
204        self.try_read(column).unwrap()
205    }
206
207    /// Try to read the value in a column.
208    ///
209    /// In case of integer indices, the first column has index 0.
210    #[inline]
211    pub fn try_read<'l, T, U>(&'l self, column: U) -> Result<T>
212    where
213        T: TryFrom<&'l Value, Error = Error>,
214        U: RowIndex,
215    {
216        T::try_from(&self.values[column.index(self)])
217    }
218}
219
220impl From<Row> for Vec<Value> {
221    #[inline]
222    fn from(row: Row) -> Self {
223        row.values
224    }
225}
226
227impl<T> Index<T> for Row
228where
229    T: RowIndex,
230{
231    type Output = Value;
232
233    fn index(&self, index: T) -> &Value {
234        &self.values[index.index(self)]
235    }
236}
237
238impl RowIndex for &str {
239    #[inline]
240    fn index(self, row: &Row) -> usize {
241        debug_assert!(
242            row.column_mapping.contains_key(self),
243            "the index is out of range"
244        );
245        row.column_mapping[self]
246    }
247}
248
249impl RowIndex for usize {
250    #[inline]
251    fn index(self, row: &Row) -> usize {
252        debug_assert!(self < row.values.len(), "the index is out of range");
253        self
254    }
255}
256
257pub fn new<'l, 'm>(statement: &'m mut Statement) -> Cursor<'m> {
258    let values = vec![Value::Null; statement.column_count()];
259    Cursor {
260        statement: statement,
261        values: values,
262    }
263}
264
265pub fn new_with_ownership<'l>(statement: Statement) -> CursorWithOwnership {
266    let values = vec![Value::Null; statement.column_count()];
267    CursorWithOwnership {
268        statement: statement,
269        values: values,
270    }
271}