use crate::data_err;
use crate::errors::Result;
use crate::mapper::blocking::AkitaMapper;
use crate::mapper::IPage;
use crate::prelude::AkitaError;
use akita_core::{FromAkitaValue, GetFields, GetTableName, IntoAkitaValue, Params, Rows, Wrapper};
use std::sync::Arc;
pub struct EntityRepository<M, T> {
mapper: Arc<M>,
_phantom: std::marker::PhantomData<T>,
}
impl<M, T> EntityRepository<M, T> {
pub fn new(mapper: M) -> Self {
Self {
mapper: Arc::new(mapper),
_phantom: std::marker::PhantomData,
}
}
}
#[allow(unused)]
impl<M, T> EntityRepository<M, T>
where
M: AkitaMapper,
{
pub fn list(&self, wrapper: Wrapper) -> Result<Vec<T>>
where
T: GetTableName + GetFields + FromAkitaValue,
{
self.mapper.list(wrapper)
}
pub fn select_one(&self, wrapper: Wrapper) -> Result<Option<T>>
where
T: GetTableName + GetFields + FromAkitaValue,
{
self.mapper.select_one(wrapper)
}
pub fn select_by_id<I>(&self, id: I) -> Result<Option<T>>
where
T: GetTableName + GetFields + FromAkitaValue,
I: IntoAkitaValue,
{
self.mapper.select_by_id(id)
}
pub fn page(&self, page: u64, size: u64, wrapper: Wrapper) -> Result<IPage<T>>
where
T: GetTableName + GetFields + FromAkitaValue,
{
self.mapper.page(page, size, wrapper)
}
pub fn count(&self, wrapper: Wrapper) -> Result<u64>
where
T: GetTableName + GetFields,
{
self.mapper.count::<T>(wrapper)
}
pub fn remove(&self, wrapper: Wrapper) -> Result<u64>
where
T: GetTableName + GetFields,
{
self.mapper.remove::<T>(wrapper)
}
pub fn remove_by_ids<I>(&self, ids: Vec<I>) -> Result<u64>
where
I: IntoAkitaValue,
T: GetTableName + GetFields,
{
self.mapper.remove_by_ids::<T, I>(ids)
}
pub fn remove_by_id<I>(&self, id: I) -> Result<u64>
where
I: IntoAkitaValue,
T: GetTableName + GetFields,
{
self.mapper.remove_by_id::<T, I>(id)
}
pub fn update(&self, entity: &T, wrapper: Wrapper) -> Result<u64>
where
T: GetTableName + GetFields + IntoAkitaValue,
{
self.mapper.update(entity, wrapper)
}
pub fn update_by_id(&self, entity: &T) -> Result<u64>
where
T: GetTableName + GetFields + IntoAkitaValue,
{
self.mapper.update_by_id(entity)
}
#[allow(unused_variables)]
pub fn update_batch_by_id(&self, entities: &Vec<T>) -> Result<u64>
where
T: GetTableName + GetFields + IntoAkitaValue,
{
self.mapper.update_batch_by_id(entities)
}
#[allow(unused_variables)]
pub fn save_batch<E>(&self, entities: E) -> Result<()>
where
T: GetTableName + GetFields + IntoAkitaValue,
E: IntoIterator<Item = T>,
{
self.mapper.save_batch(entities)
}
pub fn save<I>(&self, entity: &T) -> Result<Option<I>>
where
T: GetTableName + GetFields + IntoAkitaValue,
I: FromAkitaValue,
{
self.mapper.save(entity)
}
pub fn save_or_update<I>(&self, entity: &T) -> Result<Option<I>>
where
T: GetTableName + GetFields + IntoAkitaValue,
I: FromAkitaValue,
{
self.mapper.save_or_update(entity)
}
pub fn query_iter<S: Into<String>>(&self, sql: S) -> Result<Rows> {
self.exec_iter(sql, ())
}
pub fn exec_iter<S: Into<String>, P: Into<Params>>(&self, sql: S, params: P) -> Result<Rows> {
self.mapper.exec_iter(sql, params)
}
#[allow(clippy::redundant_closure)]
pub fn exec_raw<R, S: Into<String>, P: Into<Params>>(&self, sql: S, params: P) -> Result<Vec<R>>
where
R: FromAkitaValue,
{
let rows = self.exec_iter(&sql.into(), params.into())?;
Ok(rows
.object_iter()
.map(|data| R::from_value(&data))
.collect::<Vec<R>>())
}
pub fn exec_first<R, S: Into<String>, P: Into<Params>>(&self, sql: S, params: P) -> Result<R>
where
R: FromAkitaValue,
{
let sql: String = sql.into();
let result: Result<Vec<R>> = self.exec_raw(&sql, params);
match result {
Ok(mut result) => match result.len() {
0 => Err(data_err!("Empty record returned".to_string())),
1 => Ok(result.remove(0)),
_ => Err(data_err!("More than one record returned".to_string())),
},
Err(e) => Err(e),
}
}
pub fn exec_drop<S: Into<String>, P: Into<Params>>(&self, sql: S, params: P) -> Result<()> {
let sql: String = sql.into();
let _result: Vec<()> = self.exec_raw(&sql, params)?;
Ok(())
}
pub fn exec_first_opt<R, S: Into<String>, P: Into<Params>>(
&self,
sql: S,
params: P,
) -> Result<Option<R>>
where
R: FromAkitaValue,
{
let sql: String = sql.into();
let result: Result<Vec<R>> = self.exec_raw(&sql, params);
match result {
Ok(mut result) => match result.len() {
0 => Ok(None),
1 => Ok(Some(result.remove(0))),
_ => Err(data_err!("More than one record returned".to_string())),
},
Err(e) => Err(e),
}
}
}