1use sqlite::{Connection, State};
6
7pub trait FromSqliteRow {
8 fn from_row(row: &sqlite::Row) -> Self;
9}
10
11pub struct SqliteClient {
12 conn: Connection,
13}
14
15impl SqliteClient {
16 pub fn new(db_path: &str) -> Result<Self, sqlite::Error> {
17 let conn = Connection::open(db_path)?;
18 Ok(SqliteClient { conn })
19 }
20
21 pub fn execute(&self, sql: &str) -> Result<(), sqlite::Error> {
22 let mut stmt = self.conn.prepare(sql)?;
23 match stmt.next()? {
24 State::Done => Ok(()),
25 _ => Err(sqlite::Error {
26 code: None,
27 message: Some("ExecuteReturnedResults, please use query...".to_string()),
28 }),
29 }
30 }
31
32 pub fn query<T: FromSqliteRow>(&self, sql: &str) -> Vec<T> {
34 let stmt = self.conn.prepare(sql).unwrap();
35 let mut results = Vec::new();
36 for row in stmt.into_iter().map(|row| row.unwrap()) {
37 results.push(T::from_row(&row));
38 }
39 results
40 }
41
42}
43
44#[cfg(test)]
45mod tests {
46
47 use super::*;
48
49 #[derive(Debug)]
51 struct User {
52 id: i64, name: String,
54 }
55
56 impl FromSqliteRow for User {
58 fn from_row(row: &sqlite::Row) -> Self {
59 User {
60 id: row.read::<i64, _>("id"),
61 name: row.read::<&str, _>("name").to_string(),
62 }
63 }
64 }
65
66 #[test]
67 fn it_works() {
68 let util = SqliteClient::new("test.db").expect("Failed to create SqliteUtil");
69 let user_results = util.query::<User>("SELECT id, name FROM users");
70 println!("User results: {:?}", user_results);
71 }
72}