added get_by_id and started base for other crud functions

This commit is contained in:
Nicolai Van der Storm 2025-02-20 13:26:13 +01:00
parent 0a2ece6f6e
commit 598125abae
4 changed files with 66 additions and 14 deletions

View File

@ -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"

View File

@ -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<impl IntoResponse, String> {
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<C>(controller: Arc<C>, base_path: &str) -> Router
where
C: Deref<Target = Self> + 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<Arc<C>>, Path(id): Path<i32>| async move {
controller
.get_by_id(id)
.await
.map_err(|err| (StatusCode::NOT_FOUND, Json(err)))
}),
)
.with_state(controller)
}
}

View File

@ -1,11 +1,11 @@
use anyhow::Result;
use anyhow::{Error, Result};
use async_trait::async_trait;
use diesel::Identifiable;
#[async_trait]
pub trait IBaseService<T>: Send + Sync
where
T: Identifiable<Id = i32> + Send + Sync + 'static
{
async fn get_all(&self) -> Result<Vec<T>>;
pub trait IBaseService<T> {
async fn get_all(&self) -> Result<Vec<T>, Error>;
async fn get_by_id(&self, id: i32) -> Result<Option<T>, Error>;
async fn update(&self, entity: T) -> Result<T, Error>;
//async fn create(&self, entity: T) -> Result<i32, Error>;
async fn delete(&self, id: i32) -> Result<bool, Error>;
}

View File

@ -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<T, U>
@ -43,19 +42,48 @@ where
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 = pool.get().expect("Failed to get DB connection");
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!()
}
}