1use std::cell::RefCell;
24use std::rc::Rc;
25
26use fallible_streaming_iterator::FallibleStreamingIterator;
27use rdbc;
28use rusqlite::Rows;
29
30fn to_rdbc_err(e: &rusqlite::Error) -> rdbc::Error {
32 rdbc::Error::General(format!("{:?}", e))
33}
34
35pub struct SqliteDriver {}
36
37impl SqliteDriver {
38 pub fn new() -> Self {
39 SqliteDriver {}
40 }
41}
42
43impl rdbc::Driver for SqliteDriver {
44 fn connect(&self, _url: &str) -> rdbc::Result<Rc<RefCell<dyn rdbc::Connection + 'static>>> {
45 rusqlite::Connection::open_in_memory()
46 .map_err(|e| to_rdbc_err(&e))
47 .map(|c| {
48 Ok(Rc::new(RefCell::new(SConnection::new(c))) as Rc<RefCell<dyn rdbc::Connection>>)
49 })?
50 }
51}
52
53struct SConnection {
54 conn: rusqlite::Connection,
55}
56
57impl SConnection {
58 pub fn new(conn: rusqlite::Connection) -> Self {
59 Self { conn }
60 }
61}
62
63impl rdbc::Connection for SConnection {
64 fn create(&mut self, sql: &str) -> rdbc::Result<Rc<RefCell<dyn rdbc::Statement + '_>>> {
65 self.prepare(sql)
66 }
67
68 fn prepare(&mut self, sql: &str) -> rdbc::Result<Rc<RefCell<dyn rdbc::Statement + '_>>> {
69 let stmt = self.conn.prepare(sql).map_err(|e| to_rdbc_err(&e))?;
70 Ok(Rc::new(RefCell::new(SStatement { stmt })) as Rc<RefCell<dyn rdbc::Statement>>)
71 }
72}
73
74struct SStatement<'a> {
75 stmt: rusqlite::Statement<'a>,
76}
77
78impl<'a> rdbc::Statement for SStatement<'a> {
79 fn execute_query(
80 &mut self,
81 params: &[rdbc::Value],
82 ) -> rdbc::Result<Rc<RefCell<dyn rdbc::ResultSet + '_>>> {
83 let params = to_sqlite_value(params);
84 let params: Vec<&dyn rusqlite::types::ToSql> = params.iter().map(|v| v.as_ref()).collect();
85 let rows = self.stmt.query(¶ms).map_err(|e| to_rdbc_err(&e))?;
86 return Ok(Rc::new(RefCell::new(SResultSet { rows })) as Rc<RefCell<dyn rdbc::ResultSet>>);
87 }
88
89 fn execute_update(&mut self, params: &[rdbc::Value]) -> rdbc::Result<u64> {
90 let params = to_sqlite_value(params);
91 let params: Vec<&dyn rusqlite::types::ToSql> = params.iter().map(|v| v.as_ref()).collect();
92 return self
93 .stmt
94 .execute(¶ms)
95 .map_err(|e| to_rdbc_err(&e))
96 .map(|n| n as u64);
97 }
98}
99
100struct SResultSet<'stmt> {
101 rows: Rows<'stmt>,
102}
103
104impl<'stmt> rdbc::ResultSet for SResultSet<'stmt> {
105 fn meta_data(&self) -> rdbc::Result<Rc<dyn rdbc::ResultSetMetaData>> {
106 let meta: Vec<rdbc::Column> = self
107 .rows
108 .columns()
109 .unwrap()
110 .iter()
111 .map(|c| rdbc::Column::new(c.name(), to_rdbc_type(c.decl_type())))
112 .collect();
113 Ok(Rc::new(meta))
114 }
115
116 fn next(&mut self) -> bool {
117 self.rows.next().unwrap().is_some()
118 }
119
120 fn get_i8(&self, i: u64) -> rdbc::Result<Option<i8>> {
121 self.rows
122 .get()
123 .unwrap()
124 .get(i as usize)
125 .map_err(|e| to_rdbc_err(&e))
126 }
127
128 fn get_i16(&self, i: u64) -> rdbc::Result<Option<i16>> {
129 self.rows
130 .get()
131 .unwrap()
132 .get(i as usize)
133 .map_err(|e| to_rdbc_err(&e))
134 }
135
136 fn get_i32(&self, i: u64) -> rdbc::Result<Option<i32>> {
137 self.rows
138 .get()
139 .unwrap()
140 .get(i as usize)
141 .map_err(|e| to_rdbc_err(&e))
142 }
143
144 fn get_i64(&self, i: u64) -> rdbc::Result<Option<i64>> {
145 self.rows
146 .get()
147 .unwrap()
148 .get(i as usize)
149 .map_err(|e| to_rdbc_err(&e))
150 }
151
152 fn get_f32(&self, _i: u64) -> rdbc::Result<Option<f32>> {
153 Err(rdbc::Error::General("f32 not supported".to_owned()))
154 }
155
156 fn get_f64(&self, i: u64) -> rdbc::Result<Option<f64>> {
157 self.rows
158 .get()
159 .unwrap()
160 .get(i as usize)
161 .map_err(|e| to_rdbc_err(&e))
162 }
163
164 fn get_string(&self, i: u64) -> rdbc::Result<Option<String>> {
165 self.rows
166 .get()
167 .unwrap()
168 .get(i as usize)
169 .map_err(|e| to_rdbc_err(&e))
170 }
171
172 fn get_bytes(&self, i: u64) -> rdbc::Result<Option<Vec<u8>>> {
173 self.rows
174 .get()
175 .unwrap()
176 .get(i as usize)
177 .map_err(|e| to_rdbc_err(&e))
178 }
179}
180
181fn to_rdbc_type(t: Option<&str>) -> rdbc::DataType {
182 match t {
184 Some("INT") => rdbc::DataType::Integer,
185 _ => rdbc::DataType::Utf8,
186 }
187}
188
189fn to_sqlite_value(values: &[rdbc::Value]) -> Vec<Box<dyn rusqlite::types::ToSql>> {
190 values
191 .iter()
192 .map(|v| match v {
193 rdbc::Value::String(s) => Box::new(s.clone()) as Box<dyn rusqlite::types::ToSql>,
194 rdbc::Value::Int32(n) => Box::new(*n) as Box<dyn rusqlite::types::ToSql>,
195 rdbc::Value::UInt32(n) => Box::new(*n) as Box<dyn rusqlite::types::ToSql>,
196 })
197 .collect()
198}
199#[cfg(test)]
200mod tests {
201 use super::*;
202 use rdbc::{Connection, DataType};
203 use std::sync::Arc;
204
205 #[test]
206 fn execute_query() -> rdbc::Result<()> {
207 let driver: Arc<dyn rdbc::Driver> = Arc::new(SqliteDriver::new());
208 let url = "";
209 let mut conn = driver.connect(url)?;
210 execute(&mut conn, "DROP TABLE IF EXISTS test", &vec![])?;
211 execute(&mut conn, "CREATE TABLE test (a INT NOT NULL)", &vec![])?;
212 execute(
213 &mut conn,
214 "INSERT INTO test (a) VALUES (?)",
215 &vec![rdbc::Value::Int32(123)],
216 )?;
217
218 let mut conn = conn.as_ref().borrow_mut();
219 let stmt = conn.prepare("SELECT a FROM test")?;
220 let mut stmt = stmt.borrow_mut();
221 let rs = stmt.execute_query(&vec![])?;
222
223 let mut rs = rs.as_ref().borrow_mut();
224
225 let meta = rs.meta_data()?;
226 assert_eq!(1, meta.num_columns());
227 assert_eq!("a".to_owned(), meta.column_name(0));
228 assert_eq!(DataType::Integer, meta.column_type(0));
229
230 assert!(rs.next());
231 assert_eq!(Some(123), rs.get_i32(0)?);
232 assert!(!rs.next());
233
234 Ok(())
235 }
236
237 fn execute(
238 conn: &mut Rc<RefCell<dyn Connection>>,
239 sql: &str,
240 values: &Vec<rdbc::Value>,
241 ) -> rdbc::Result<u64> {
242 println!("Executing '{}' with {} params", sql, values.len());
243 let mut conn = conn.as_ref().borrow_mut();
244 let stmt = conn.prepare(sql)?;
245 let mut stmt = stmt.borrow_mut();
246 stmt.execute_update(values)
247 }
248}