use rusqlite::{Connection, Row, ToSql};
use crate::entities::errors::DbResult;
pub trait IConnection {
type Locked: IConnection;
fn lock(&self) -> DbResult<Self::Locked>;
fn with<T, F: FnOnce(&Connection) -> DbResult<T>>(&self, fun: F) -> DbResult<T>;
}
pub trait INewDbRepo<Connection> {
fn create(connect: Connection) -> Self;
}
pub trait IDbRepo {
fn as_super(&self) -> &dyn IDbRepo {
unimplemented!()
}
fn init(&self) -> DbResult<()> {
self.as_super().init()
}
fn recreate_tables(&self) -> DbResult<()> {
self.drop()?;
self.init()
}
fn drop(&self) -> DbResult<()> {
self.as_super().drop()
}
fn set_indexes(&self) -> DbResult<()> {
self.as_super().set_indexes()
}
fn drop_indexes(&self) -> DbResult<()> {
self.as_super().drop_indexes()
}
fn get_size(&self) -> DbResult<usize> {
self.as_super().get_size()
}
}
pub trait IExecutor {
type Locked: IExecutor;
fn lock(&self) -> DbResult<Self::Locked>;
fn get_one<T, F: FnMut(&rusqlite::Row<'_>) -> rusqlite::Result<T>>(
&self,
query: &str,
params: &[&dyn ToSql],
serializer: F,
) -> DbResult<T>;
fn get_many<T, F: FnMut(&rusqlite::Row<'_>) -> rusqlite::Result<T>>(
&self,
query: &str,
params: &[&dyn ToSql],
serializer: F,
) -> DbResult<Vec<T>>;
fn execute(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<()>;
fn execute_return_id(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<i64>;
}
impl IConnection for Connection {
type Locked = Self;
fn lock(&self) -> DbResult<Self::Locked> {
panic!("Can not lock bare connection")
}
fn with<T, F: FnOnce(&Connection) -> DbResult<T>>(&self, fun: F) -> DbResult<T> {
fun(self)
}
}
impl<Cnn: IConnection> IConnection for &Cnn {
type Locked = Cnn::Locked;
fn lock(&self) -> DbResult<Self::Locked> {
(**self).lock()
}
fn with<T, F: FnOnce(&Connection) -> DbResult<T>>(&self, fun: F) -> DbResult<T> {
(**self).with(fun)
}
}
impl<Ex: IExecutor> IExecutor for &Ex {
type Locked = Ex::Locked;
fn lock(&self) -> DbResult<Self::Locked> {
(**self).lock()
}
fn get_one<T, F: FnMut(&Row<'_>) -> rusqlite::Result<T>>(
&self,
query: &str,
params: &[&dyn ToSql],
serializer: F,
) -> DbResult<T> {
(**self).get_one(query, params, serializer)
}
fn get_many<T, F: FnMut(&Row<'_>) -> rusqlite::Result<T>>(
&self,
query: &str,
params: &[&dyn ToSql],
serializer: F,
) -> DbResult<Vec<T>> {
(**self).get_many(query, params, serializer)
}
fn execute(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<()> {
(**self).execute(query, params)
}
fn execute_return_id(&self, query: &str, params: &[&dyn ToSql]) -> DbResult<i64> {
(**self).execute_return_id(query, params)
}
}