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 type Item = Row<'con>;
80
81 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; 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}