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 { query_as!( Teacher, r#" SELECT * FROM `teachers`"#, ) .fetch_all(db) .await } pub async fn get_teacher_by_id(db: &Pool, teacher_id: IdType) -> Result { query_as!( Teacher, r#" SELECT * FROM `teachers` WHERE id = ?"#, teacher_id ) .fetch_one(db) .await } pub async fn get_subjects(db: &Pool) -> Result { query_as!( Subject, r#" SELECT * FROM `subjects`"#, ) .fetch_all(db) .await } pub async fn get_slots(db: &Pool) -> Result { 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 { 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, 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, } #[derive(Debug, Deserialize, Serialize, Clone)] pub struct FullAppointment { id: IdType, teacher_id: IdType, slot_id: IdType, nutzer_id: IdType, expires: Option, } #[derive(Debug, Deserialize, Serialize, Clone)] pub struct AssignedAppointment { appointment: FullAppointment, slot: AppointmentSlot, nutzer: Nutzer, } pub async fn get_all_teachers(db: &Pool) -> Result, 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 = 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 = 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) }