use rusqlite::{Connection, Result};
use serde_rusqlite::{from_rows, to_params_named};
use crate::RusqliteStruct;
pub trait RusqliteStructHelper {
fn insert_into_table_struct<T: RusqliteStruct + serde::Serialize>(&self, from: &T) -> Result<()>;
fn get_from_table_struct<T: RusqliteStruct + for<'a> serde::Deserialize<'a>>(&self) -> Result<Vec<T>>;
}
impl RusqliteStructHelper for Connection {
fn insert_into_table_struct<T: RusqliteStruct + serde::Serialize>(&self, from: &T) -> Result<()> {
let to_execute = format!(
"INSERT INTO {} ({}) VALUES ({})",
T::struct_name(),
format!("{}", T::field_names().join(",")),
format!("{}", T::field_names().iter().map(|s| format!(":{}", s)).collect::<Vec<String>>().join(","))
);
self.execute(&to_execute, to_params_named(from).unwrap().to_slice().as_slice())?;
Ok(())
}
fn get_from_table_struct<T: RusqliteStruct + for<'a> serde::Deserialize<'a>>(&self) -> Result<Vec<T>> {
let mut stmt = self.prepare(
format!("SELECT {} FROM {}", T::field_names().join(","), T::struct_name()).as_str()
)?;
let rows = stmt.query([])?;
from_rows::<T>(rows)
.map(|r| r.map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e))))
.collect::<rusqlite::Result<Vec<_>>>()
}
}