Add REST endpoint for slot
This commit is contained in:
parent
82e89baeeb
commit
8f378472ea
28 changed files with 1925 additions and 28 deletions
|
|
@ -5,6 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
async-trait = "0.1.80"
|
||||
uuid = "1.8.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
|
@ -14,3 +15,7 @@ features = ["runtime-tokio", "sqlite"]
|
|||
|
||||
[dependencies.dao]
|
||||
path = "../dao"
|
||||
|
||||
[dependencies.time]
|
||||
version = "0.3.36"
|
||||
features = ["parsing"]
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ use async_trait::async_trait;
|
|||
use dao::DaoError;
|
||||
use sqlx::{query, query_as, SqlitePool};
|
||||
|
||||
pub mod slot;
|
||||
|
||||
pub trait ResultDbErrorExt<T, E> {
|
||||
fn map_db_error(self) -> Result<T, DaoError>;
|
||||
}
|
||||
impl<T, E: std::error::Error + 'static> ResultDbErrorExt<T, E> for Result<T, E> {
|
||||
impl<T, E: std::error::Error + Send + Sync + 'static> ResultDbErrorExt<T, E> for Result<T, E> {
|
||||
fn map_db_error(self) -> Result<T, DaoError> {
|
||||
self.map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))
|
||||
}
|
||||
|
|
|
|||
128
dao_impl/src/slot.rs
Normal file
128
dao_impl/src/slot.rs
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use dao::{
|
||||
slot::{DayOfWeek, SlotEntity},
|
||||
DaoError,
|
||||
};
|
||||
use sqlx::{query, SqlitePool};
|
||||
use time::{format_description::well_known::Iso8601, Date, PrimitiveDateTime, Time};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::ResultDbErrorExt;
|
||||
|
||||
pub struct SlotDaoImpl {
|
||||
pool: Arc<SqlitePool>,
|
||||
}
|
||||
impl SlotDaoImpl {
|
||||
pub fn new(pool: Arc<SqlitePool>) -> Self {
|
||||
Self { pool }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl dao::slot::SlotDao for SlotDaoImpl {
|
||||
async fn get_slots(&self) -> Result<Arc<[SlotEntity]>, DaoError> {
|
||||
let result = query!(r"SELECT id, day_of_week, time_from, time_to, valid_from, valid_to, deleted, update_version FROM slot WHERE deleted IS NULL")
|
||||
.fetch_all(self.pool.as_ref())
|
||||
.await
|
||||
.map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))?;
|
||||
result
|
||||
.iter()
|
||||
.map(|row| {
|
||||
Ok(SlotEntity {
|
||||
id: Uuid::from_slice(row.id.as_ref())?,
|
||||
day_of_week: DayOfWeek::from_number(row.day_of_week as u8)
|
||||
.ok_or(DaoError::InvalidDayOfWeek(row.day_of_week as u8))?,
|
||||
from: Time::parse(&row.time_from, &Iso8601::TIME)?,
|
||||
to: Time::parse(&row.time_to, &Iso8601::TIME)?,
|
||||
valid_from: Date::parse(&row.valid_from, &Iso8601::DATE)?,
|
||||
valid_to: row
|
||||
.valid_to
|
||||
.as_ref()
|
||||
.map(|valid_to| Date::parse(valid_to, &Iso8601::DATE))
|
||||
.transpose()?,
|
||||
deleted: row
|
||||
.deleted
|
||||
.as_ref()
|
||||
.map(|deleted| PrimitiveDateTime::parse(deleted, &Iso8601::DATE))
|
||||
.transpose()?,
|
||||
version: Uuid::from_slice(&row.update_version)?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
async fn get_slot(&self, id: &Uuid) -> Result<Option<SlotEntity>, DaoError> {
|
||||
let id_vec = id.as_bytes().to_vec();
|
||||
let result = query!(r"SELECT id, day_of_week, time_from, time_to, valid_from, valid_to, deleted, update_version FROM slot WHERE id = ?", id_vec)
|
||||
.fetch_optional(self.pool.as_ref())
|
||||
.await
|
||||
.map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))?;
|
||||
result
|
||||
.map(|row| {
|
||||
Ok(SlotEntity {
|
||||
id: Uuid::from_slice(row.id.as_ref())?,
|
||||
day_of_week: DayOfWeek::from_number(row.day_of_week as u8)
|
||||
.ok_or(DaoError::InvalidDayOfWeek(row.day_of_week as u8))?,
|
||||
from: Time::parse(&row.time_from, &Iso8601::TIME)?,
|
||||
to: Time::parse(&row.time_to, &Iso8601::TIME)?,
|
||||
valid_from: Date::parse(&row.valid_from, &Iso8601::DATE)?,
|
||||
valid_to: row
|
||||
.valid_to
|
||||
.as_ref()
|
||||
.map(|valid_to| Date::parse(valid_to, &Iso8601::DATE))
|
||||
.transpose()?,
|
||||
deleted: row
|
||||
.deleted
|
||||
.as_ref()
|
||||
.map(|deleted| PrimitiveDateTime::parse(deleted, &Iso8601::DATE))
|
||||
.transpose()?,
|
||||
version: Uuid::from_slice(&row.update_version)?,
|
||||
})
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
async fn create_slot(&self, slot: &SlotEntity, process: &str) -> Result<(), DaoError> {
|
||||
let id_vec = slot.id.as_bytes().to_vec();
|
||||
let version_vec = slot.version.as_bytes().to_vec();
|
||||
let day_of_week = slot.day_of_week.to_number();
|
||||
let from = slot.from.to_string();
|
||||
let to = slot.to.to_string();
|
||||
let valid_from = slot.valid_from.to_string();
|
||||
let valid_to = slot.valid_to.map(|valid_to| valid_to.to_string());
|
||||
let deleted = slot.deleted.map(|deleted| deleted.to_string());
|
||||
query!("INSERT INTO slot (id, day_of_week, time_from, time_to, valid_from, valid_to, deleted, update_version, update_process) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
id_vec,
|
||||
day_of_week,
|
||||
from,
|
||||
to,
|
||||
valid_from,
|
||||
valid_to,
|
||||
deleted,
|
||||
version_vec,
|
||||
process,
|
||||
)
|
||||
.execute(self.pool.as_ref())
|
||||
.await
|
||||
.map_db_error()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_slot(&self, slot: &SlotEntity, process: &str) -> Result<(), DaoError> {
|
||||
let id_vec = slot.id.as_bytes().to_vec();
|
||||
let version_vec = slot.version.as_bytes().to_vec();
|
||||
let valid_to = slot.valid_to.map(|valid_to| valid_to.to_string());
|
||||
let deleted = slot.deleted.map(|deleted| deleted.to_string());
|
||||
query!("UPDATE slot SET valid_to = ?, deleted = ?, update_version = ?, update_process = ? WHERE id = ?",
|
||||
valid_to,
|
||||
deleted,
|
||||
version_vec,
|
||||
process,
|
||||
id_vec,
|
||||
)
|
||||
.execute(self.pool.as_ref())
|
||||
.await
|
||||
.map_db_error()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue