90 lines
2.3 KiB
Rust
90 lines
2.3 KiB
Rust
use std::marker::PhantomData;
|
|
use anyhow::Error;
|
|
use async_trait::async_trait;
|
|
use diesel::prelude::*;
|
|
use diesel::associations::HasTable;
|
|
use diesel::query_dsl::methods::{FindDsl, LoadQuery};
|
|
|
|
use crate::config::db::{get_connection, DbPool};
|
|
use super::i_service::IBaseService;
|
|
|
|
pub struct BaseService<T, U>
|
|
where
|
|
T: Identifiable<Id = i32> + Queryable<U::SqlType, diesel::pg::Pg> + Send + Sync + 'static,
|
|
U: Table + HasTable<Table = U> + LoadQuery<'static, PgConnection, T> + Send + Sync + 'static,
|
|
{
|
|
pool: DbPool,
|
|
_marker: PhantomData<(T, U)>,
|
|
}
|
|
|
|
impl<T, U> BaseService<T, U>
|
|
where
|
|
T: Identifiable<Id = i32> + Queryable<U::SqlType, diesel::pg::Pg> + Send + Sync + 'static,
|
|
U: Table
|
|
+ HasTable<Table = U>
|
|
+ LoadQuery<'static, PgConnection, T>
|
|
+ Send
|
|
+ Sync
|
|
+ 'static,
|
|
{
|
|
pub fn new(pool: DbPool) -> Self {
|
|
Self {
|
|
pool,
|
|
_marker: PhantomData,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl<T, U> IBaseService<T> for BaseService<T, U>
|
|
where
|
|
T: Identifiable<Id = i32> + Queryable<U::SqlType, diesel::pg::Pg> + Send + Sync + 'static,
|
|
U: Table
|
|
+ HasTable<Table = U>
|
|
+ LoadQuery<'static, PgConnection, T>
|
|
+ FindDsl<i32>
|
|
+ Send
|
|
+ Sync
|
|
+ 'static,
|
|
<U as FindDsl<i32>>::Output: LoadQuery<'static, PgConnection, T>,
|
|
{
|
|
async fn get_all(&self) -> Result<Vec<T>, Error> {
|
|
let pool = self.pool.clone();
|
|
|
|
let result = tokio::task::spawn_blocking(move || {
|
|
let mut conn = get_connection(&pool).expect("Failed to get DB connection");
|
|
U::table().load::<T>(&mut conn)
|
|
})
|
|
.await??;
|
|
|
|
Ok(result)
|
|
}
|
|
|
|
async fn get_by_id(&self, id: i32) -> Result<Option<T>, Error> {
|
|
let pool = self.pool.clone();
|
|
|
|
let result = tokio::task::spawn_blocking(move || {
|
|
let mut conn = get_connection(&pool).expect("Failed to get DB connection");
|
|
U::table()
|
|
.find(id)
|
|
.get_result::<T>(&mut conn)
|
|
.optional()
|
|
})
|
|
.await??;
|
|
|
|
Ok(result)
|
|
}
|
|
|
|
async fn update(&self, entity: T) -> Result<T, Error> {
|
|
todo!()
|
|
}
|
|
|
|
// async fn create(&self, entity: T) -> Result<T, Error> {
|
|
// todo!()
|
|
// }
|
|
|
|
async fn delete(&self, id: i32) -> Result<bool, Error> {
|
|
todo!()
|
|
}
|
|
}
|