161 lines
4.0 KiB
Rust
161 lines
4.0 KiB
Rust
use std::collections::HashSet;
|
|
|
|
use chrono::NaiveDateTime;
|
|
use serde::{Deserialize, Serialize};
|
|
use sqlx::query_as;
|
|
|
|
use terminwahl_typen::{
|
|
AppointmentSlot, AppointmentSlots, IdType, Nutzer, SlotId, Subject, Subjects, Teacher, Teachers,
|
|
};
|
|
|
|
use super::Pool;
|
|
|
|
pub async fn get_teachers(db: &Pool) -> Result<Teachers, sqlx::Error> {
|
|
query_as!(
|
|
Teacher,
|
|
r#"
|
|
SELECT *
|
|
FROM `teachers`"#,
|
|
)
|
|
.fetch_all(db)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_teacher_by_id(db: &Pool, teacher_id: IdType) -> Result<Teacher, sqlx::Error> {
|
|
query_as!(
|
|
Teacher,
|
|
r#"
|
|
SELECT *
|
|
FROM `teachers` WHERE id = ?"#,
|
|
teacher_id
|
|
)
|
|
.fetch_one(db)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_subjects(db: &Pool) -> Result<Subjects, sqlx::Error> {
|
|
query_as!(
|
|
Subject,
|
|
r#"
|
|
SELECT *
|
|
FROM `subjects`"#,
|
|
)
|
|
.fetch_all(db)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_slots(db: &Pool) -> Result<AppointmentSlots, sqlx::Error> {
|
|
match query_as!(
|
|
AppointmentSlot,
|
|
r#"
|
|
SELECT *
|
|
FROM `appointment_slots`"#,
|
|
)
|
|
.fetch_all(db)
|
|
.await
|
|
{
|
|
Ok(elems) => Ok(elems.into_iter().map(|e| (e.id, e)).collect()),
|
|
Err(e) => Err(e),
|
|
}
|
|
}
|
|
pub async fn get_slot_by_id(db: &Pool, slot_id: IdType) -> Result<AppointmentSlot, sqlx::Error> {
|
|
match query_as!(
|
|
AppointmentSlot,
|
|
r#"
|
|
SELECT *
|
|
FROM `appointment_slots` WHERE id = ?"#,
|
|
slot_id
|
|
)
|
|
.fetch_one(db)
|
|
.await
|
|
{
|
|
Ok(slot) => Ok(slot),
|
|
Err(e) => Err(e),
|
|
}
|
|
}
|
|
pub async fn get_unavailable(db: &Pool) -> Result<HashSet<SlotId>, sqlx::Error> {
|
|
match query_as!(
|
|
SlotId,
|
|
r#"
|
|
SELECT teacher_id, slot_id
|
|
FROM `appointments` WHERE datetime(expires) > datetime('now') OR expires is NULL;"#,
|
|
)
|
|
.fetch_all(db)
|
|
.await
|
|
{
|
|
Ok(elems) => Ok(elems.into_iter().collect()),
|
|
Err(e) => Err(e),
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
|
pub struct TeacherWithAppointments {
|
|
teacher: Teacher,
|
|
appointments: Vec<AssignedAppointment>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
|
pub struct FullAppointment {
|
|
id: IdType,
|
|
teacher_id: IdType,
|
|
slot_id: IdType,
|
|
nutzer_id: IdType,
|
|
expires: Option<NaiveDateTime>,
|
|
}
|
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
|
pub struct AssignedAppointment {
|
|
appointment: FullAppointment,
|
|
slot: AppointmentSlot,
|
|
nutzer: Nutzer,
|
|
}
|
|
|
|
pub async fn get_all_teachers(db: &Pool) -> Result<Vec<TeacherWithAppointments>, sqlx::Error> {
|
|
let teachers = get_teachers(db).await?;
|
|
let mut response = Vec::new();
|
|
|
|
for teacher in teachers.into_iter() {
|
|
let teacher_id: i64 = teacher.id;
|
|
let mut appointments: Vec<FullAppointment> = query_as!(
|
|
FullAppointment,
|
|
r#"
|
|
SELECT id,teacher_id,slot_id,nutzer_id,expires
|
|
FROM `appointments` WHERE teacher_id = ?"#,
|
|
teacher_id
|
|
)
|
|
.fetch_all(db)
|
|
.await?;
|
|
appointments.sort_by(|a, b| a.slot_id.cmp(&b.slot_id));
|
|
let mut assigned_appointments: Vec<AssignedAppointment> = Vec::new();
|
|
for appointment in appointments.into_iter() {
|
|
let slot = query_as!(
|
|
AppointmentSlot,
|
|
r#"
|
|
SELECT *
|
|
FROM `appointment_slots` WHERE id = ? "#,
|
|
appointment.slot_id
|
|
)
|
|
.fetch_one(db)
|
|
.await?;
|
|
let nutzer = query_as!(
|
|
Nutzer,
|
|
r#"
|
|
SELECT name, schueler as schueler,email
|
|
FROM `nutzer` WHERE id = ? "#,
|
|
appointment.nutzer_id
|
|
)
|
|
.fetch_one(db)
|
|
.await?;
|
|
assigned_appointments.push(AssignedAppointment {
|
|
appointment,
|
|
slot,
|
|
nutzer,
|
|
})
|
|
}
|
|
response.push(TeacherWithAppointments {
|
|
teacher,
|
|
appointments: assigned_appointments,
|
|
})
|
|
}
|
|
Ok(response)
|
|
}
|