use crate::{Exception, Object, SqlCrud};
#[cfg(feature = "db-sqlite")]
use sqlite::Connection;
use std::collections::HashMap;
#[cfg(feature = "db-sqlite")]
pub trait FromSqliteRow {
fn from_row(row: &sqlite::Row) -> Self;
}
#[cfg(feature = "db-sqlite")]
pub struct SqliteClient {
pub conn: Connection,
}
#[cfg(feature = "db-sqlite")]
impl SqliteClient {
pub fn new(db_path: &str) -> Result<Self, Exception> {
let conn = Connection::open(db_path)?;
Ok(Self { conn })
}
pub fn execute(&self, sql: &str) -> Result<(), sqlite::Error> {
let res = self.conn.execute(sql)?;
Ok(res)
}
pub fn query<T: FromSqliteRow>(&self, sql: &str) -> Vec<T> {
let stmt = self.conn.prepare(sql).unwrap();
let mut results = Vec::new();
for row in stmt.into_iter().map(|row| row.unwrap()) {
results.push(T::from_row(&row));
}
results
}
pub fn query_one<T: FromSqliteRow>(&self, sql: &str) -> Option<T> {
let stmt = self.conn.prepare(sql).unwrap();
for row in stmt.into_iter().map(|row| row.unwrap()) {
return Some(T::from_row(&row));
}
None
}
}
#[cfg(feature = "db-sqlite")]
impl SqlCrud for SqliteClient {
fn insert(&self, sql: &str) -> Result<bool, Exception> {
match self.execute(sql) {
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
fn update(&self, sql: &str) -> Result<bool, Exception> {
match self.execute(sql) {
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
fn delete(&self, sql: &str) -> Result<bool, Exception> {
match self.execute(sql) {
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
fn select_one(&self, sql: &str) -> Result<HashMap<String, Object>, Exception> {
let stmt = self.conn.prepare(sql)?;
let row = stmt.into_iter().next();
if let Some(row) = row {
let row = row.unwrap();
let mut item: HashMap<String, Object> = HashMap::new();
for (key, value) in row.iter() {
item.insert(key.into(), value.into());
}
return Ok(item);
}
Err(Exception::DataNotFound)
}
fn select(&self, sql: &str) -> Result<Vec<HashMap<String, Object>>, Exception> {
let stmt = self.conn.prepare(sql)?;
let mut results = Vec::new();
for row in stmt.into_iter().map(|row| row.unwrap()) {
let mut item: HashMap<String, Object> = HashMap::new();
for (key, value) in row.iter() {
item.insert(key.into(), value.into());
}
results.push(item);
}
Ok(results)
}
}
#[cfg(feature = "db-sqlite")]
#[cfg(test)]
mod tests {
use crate::db_sqlite::SqliteClient;
use crate::{Exception, SqlCrud};
#[test]
fn it_works() -> Result<(), Exception> {
let client = SqliteClient::new("./docs/test.db")?;
let result = client.select("SELECT id, name FROM users")?;
println!("{:?}", result);
let x = result[0].get("name").unwrap().get_string().unwrap();
println!("{:?}", x);
let x = result[0].get("id").unwrap().get_string().unwrap();
println!("{:?}", x);
Ok(())
}
}