deslite/
rows.rs

1use super::ffi;
2use super::{Error, Lesult, SqliteTypes, Stmt, Value};
3use std;
4
5#[derive(Debug)]
6pub struct Row<'con> {
7    stmt: &'con Stmt<'con>,
8}
9
10impl<'con> Row<'con> {
11    pub fn new(stmt: &'con Stmt<'con>) -> Self {
12        Row { stmt }
13    }
14
15    pub fn get<E, T>(&self, key: T) -> Lesult<E>
16    where
17        T: ColIndex,
18        E: std::convert::From<Value>,
19    {
20        let index = key.idx(self.stmt)?;
21        let val = self.get_value(index)?;
22        Ok(E::from(val))
23    }
24
25    pub fn get_value(&self, index: usize) -> Lesult<Value> {
26        match self.stmt.colum_type(index).unwrap() {
27            SqliteTypes::Int => Ok(self.stmt.get_int64(index)),
28            SqliteTypes::FLoat => Ok(self.stmt.get_double(index)),
29            SqliteTypes::Text => Ok(self.stmt.get_text(index)),
30            SqliteTypes::Blob => Ok(self.stmt.get_blob(index)),
31            SqliteTypes::Null => Ok(Value::Null),
32        }
33    }
34}
35
36#[derive(Debug)]
37pub struct Rows<'con> {
38    stmt: Stmt<'con>,
39}
40
41impl<'con> Rows<'con> {
42    pub fn get_stmt(&'con self) -> &'con Stmt<'con> {
43        &self.stmt
44    }
45
46    pub fn new(stmt: Stmt<'con>) -> Self {
47        Rows { stmt }
48    }
49
50    pub fn iter(&'con self) -> RowIterator<'con> {
51        RowIterator::new(self)
52    }
53
54    pub fn execute(&self) -> Lesult<()> {
55        let res = self.stmt.step()?;
56        if res == ffi::SQLITE_DONE || res == ffi::SQLITE_ROW {
57            Ok(())
58        } else {
59            Err(Error::Unknown(
60                "Failed to execute prepared stmt".to_string(),
61            ))
62        }
63    }
64}
65
66#[derive(Debug)]
67pub struct RowIterator<'con> {
68    stmt: &'con Stmt<'con>,
69}
70
71impl<'con> RowIterator<'con> {
72    pub fn new(rows: &'con Rows) -> Self {
73        RowIterator { stmt: &rows.stmt }
74    }
75}
76
77impl<'con> Iterator for RowIterator<'con> {
78    // we will be counting with usize
79    type Item = Row<'con>;
80
81    // next() is the only required method
82    fn next(&mut self) -> Option<Row<'con>> {
83        let step = match self.stmt.step() {
84            Ok(x) => x,
85            Err(_x) => return None,
86        };
87        if step == ffi::SQLITE_ROW {
88            let a = self.stmt; //self.get_stmt();
89            return Some(Row::new(a));
90        } else {
91            return None;
92        }
93    }
94}
95
96pub trait ColIndex {
97    fn idx(&self, stmt: &Stmt) -> Lesult<usize>;
98}
99
100impl ColIndex for usize {
101    fn idx(&self, stmt: &Stmt) -> Lesult<usize> {
102        if *self > stmt.colum_count() {
103            return Err(Error::IndexOutOfBounds(format!("{}", self)));
104        } else {
105            return Ok(*self);
106        }
107    }
108}
109
110impl<'a> ColIndex for &'a str {
111    fn idx(&self, stmt: &Stmt) -> Lesult<usize> {
112        stmt.colum_index(*self)
113    }
114}