use std::ops::DerefMut; use chrono::NaiveDate; use rocket::serde::{Deserialize, Serialize}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; #[derive(FromRow, Debug, Serialize, Deserialize, Eq, Hash, PartialEq, Clone)] pub struct Waterlevel { pub id: i64, pub day: NaiveDate, pub time: String, pub max: i64, pub min: i64, pub mittel: i64, pub tumax: i64, pub tumin: i64, pub tumittel: i64, } #[derive(Debug, Serialize)] pub struct WaterlevelDay { pub day: NaiveDate, pub avg: i64, pub fluctuation: i64, } pub struct Create { pub day: NaiveDate, pub time: String, pub max: i64, pub min: i64, pub mittel: i64, pub tumax: i64, pub tumin: i64, pub tumittel: i64, } impl Waterlevel { pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option { sqlx::query_as!(Self, "SELECT * FROM waterlevel WHERE id like ?", id) .fetch_one(db) .await .ok() } pub async fn find_by_id_tx(db: &mut Transaction<'_, Sqlite>, id: i32) -> Option { sqlx::query_as!(Self, "SELECT * FROM waterlevel WHERE id like ?", id) .fetch_one(db.deref_mut()) .await .ok() } pub async fn create(db: &mut Transaction<'_, Sqlite>, create: &Create) -> Result<(), String> { sqlx::query!( "INSERT INTO waterlevel(day, time, max, min, mittel, tumax, tumin, tumittel) VALUES (?,?,?,?,?,?,?,?)", create.day, create.time, create.max, create.min, create.mittel, create.tumax, create.tumin, create.tumittel ) .execute(db.deref_mut()) .await .map_err(|e| e.to_string())?; Ok(()) } pub async fn max_waterlevel_for_day(db: &SqlitePool, day: NaiveDate) -> Option { let waterlevel = sqlx::query_as!( Waterlevel, "SELECT id, day, time, max, min, mittel, tumax, tumin, tumittel FROM waterlevel WHERE day = ? ORDER BY mittel DESC LIMIT 1", day ) .fetch_optional(db) .await.unwrap(); if let Some(waterlevel) = waterlevel { let max_diff = (waterlevel.mittel - waterlevel.max).abs(); let min_diff = (waterlevel.mittel - waterlevel.min).abs(); let fluctuation = max_diff.max(min_diff); return Some(WaterlevelDay { day: waterlevel.day, avg: waterlevel.mittel, fluctuation, }); } None } pub async fn delete_all(db: &mut Transaction<'_, Sqlite>) { sqlx::query!("DELETE FROM waterlevel;") .execute(db.deref_mut()) .await .unwrap(); } }