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 where T: Identifiable + Queryable + Send + Sync + 'static, U: Table + HasTable + LoadQuery<'static, PgConnection, T> + Send + Sync + 'static, { pool: DbPool, _marker: PhantomData<(T, U)>, } impl BaseService where T: Identifiable + Queryable + Send + Sync + 'static, U: Table + HasTable
+ LoadQuery<'static, PgConnection, T> + Send + Sync + 'static, { pub fn new(pool: DbPool) -> Self { Self { pool, _marker: PhantomData, } } } #[async_trait] impl IBaseService for BaseService where T: Identifiable + Queryable + Send + Sync + 'static, U: Table + HasTable
+ LoadQuery<'static, PgConnection, T> + FindDsl + Send + Sync + 'static, >::Output: LoadQuery<'static, PgConnection, T>, { async fn get_all(&self) -> Result, 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::(&mut conn) }) .await??; Ok(result) } async fn get_by_id(&self, id: i32) -> Result, 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::(&mut conn) .optional() }) .await??; Ok(result) } async fn update(&self, entity: T) -> Result { todo!() } // async fn create(&self, entity: T) -> Result { // todo!() // } async fn delete(&self, id: i32) -> Result { todo!() } }