diff --git a/diesel.toml b/diesel.toml index 0c2623b..a0d61bf 100644 --- a/diesel.toml +++ b/diesel.toml @@ -6,4 +6,4 @@ file = "src/schema.rs" custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] [migrations_directory] -dir = "/home/nicolaivds/GIT/OpenLayerHub/migrations" +dir = "migrations" diff --git a/src/base/controller.rs b/src/base/controller.rs index 9e47999..1d56956 100644 --- a/src/base/controller.rs +++ b/src/base/controller.rs @@ -1,6 +1,6 @@ use crate::base::{entity::BaseEntity, i_service::IBaseService}; use anyhow::Result; -use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::get, Json, Router}; +use axum::{extract::{Path, State}, http::StatusCode, response::IntoResponse, routing::get, Json, Router}; use diesel::Identifiable; use serde::Serialize; use std::{marker::PhantomData, ops::Deref, sync::Arc}; @@ -35,6 +35,19 @@ where Ok((StatusCode::OK, Json(entities))) } + pub async fn get_by_id(&self, id: i32) -> Result { + let entity = self + .service + .get_by_id(id) + .await + .map_err(|err| err.to_string())?; + + match entity { + Some(entity) => Ok((StatusCode::OK, Json(entity))), + None => Err(format!("Entity with id {} not found.", id)) + } + } + pub fn default_routes(controller: Arc, base_path: &str) -> Router where C: Deref + Send + Sync + 'static, @@ -49,6 +62,17 @@ where .map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, Json(err))) }), ) + + .route( + // Add route for getting by ID (e.g., /:id) + &format!("{}/{{id}}", base_path), + get(|State(controller): State>, Path(id): Path| async move { + controller + .get_by_id(id) + .await + .map_err(|err| (StatusCode::NOT_FOUND, Json(err))) + }), + ) .with_state(controller) } } diff --git a/src/base/i_service.rs b/src/base/i_service.rs index 951fa16..af72c64 100644 --- a/src/base/i_service.rs +++ b/src/base/i_service.rs @@ -1,11 +1,11 @@ -use anyhow::Result; +use anyhow::{Error, Result}; use async_trait::async_trait; -use diesel::Identifiable; #[async_trait] -pub trait IBaseService: Send + Sync -where - T: Identifiable + Send + Sync + 'static -{ - async fn get_all(&self) -> Result>; +pub trait IBaseService { + async fn get_all(&self) -> Result, Error>; + async fn get_by_id(&self, id: i32) -> Result, Error>; + async fn update(&self, entity: T) -> Result; + //async fn create(&self, entity: T) -> Result; + async fn delete(&self, id: i32) -> Result; } diff --git a/src/base/service.rs b/src/base/service.rs index b5b5c22..64db363 100644 --- a/src/base/service.rs +++ b/src/base/service.rs @@ -1,12 +1,11 @@ use std::marker::PhantomData; - use anyhow::Error; use async_trait::async_trait; use diesel::prelude::*; use diesel::associations::HasTable; -use diesel::query_dsl::methods::LoadQuery; +use diesel::query_dsl::methods::{FindDsl, LoadQuery}; -use crate::config::db::DbPool; +use crate::config::db::{get_connection, DbPool}; use super::i_service::IBaseService; pub struct BaseService @@ -43,19 +42,48 @@ where 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 = pool.get().expect("Failed to get DB connection"); + let mut conn = get_connection(&pool).expect("Failed to get DB connection"); U::table().load::(&mut conn) }) .await??; Ok(result) } -} \ No newline at end of file + + 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!() + } +}