fancier boat stats
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m48s
CI/CD Pipeline / deploy-staging (push) Has been skipped
CI/CD Pipeline / deploy-main (push) Has been skipped

This commit is contained in:
2024-04-06 15:27:35 +02:00
parent d0c2b4d703
commit 955f657298
5 changed files with 112 additions and 72 deletions

View File

@ -1,8 +1,82 @@
use std::collections::HashMap;
use crate::model::user::User;
use chrono::Datelike;
use serde::Serialize;
use sqlx::{FromRow, Row, SqlitePool};
#[derive(Serialize, Clone)]
pub struct BoatStat {
pot_years: Vec<i32>,
boats: Vec<SingleBoatStat>,
}
#[derive(Serialize, Clone)]
pub struct SingleBoatStat {
name: String,
location: String,
years: HashMap<String, i32>,
}
impl BoatStat {
pub async fn get(db: &SqlitePool) -> BoatStat {
let mut years = Vec::new();
let mut boat_stats_map: HashMap<String, SingleBoatStat> = HashMap::new();
let rows = sqlx::query(
"
SELECT
boat.name,
location.name AS location,
CAST(strftime('%Y', arrival) AS INTEGER) AS year,
CAST(SUM(distance_in_km) AS INTEGER) AS rowed_km
FROM
logbook
INNER JOIN
boat ON boat.id = logbook.boat_id
INNER JOIN
location ON boat.location_id = location.id
WHERE
boat.name != 'Externes Boot'
GROUP BY
boat_id, year
ORDER BY
boat.name, year DESC;
",
)
.fetch_all(db)
.await
.unwrap();
for row in rows {
let name: String = row.get("name");
let location: String = row.get("location");
let year: i32 = row.get("year");
if !years.contains(&year) {
years.push(year);
}
let year: String = format!("{year}");
let rowed_km: i32 = row.get("rowed_km");
let boat_stat = boat_stats_map
.entry(name.clone())
.or_insert(SingleBoatStat {
name,
location,
years: HashMap::new(),
});
boat_stat.years.insert(year, rowed_km);
}
BoatStat {
pot_years: years,
boats: boat_stats_map.into_values().collect(),
}
}
}
#[derive(FromRow, Serialize, Clone)]
pub struct Stat {
name: String,
@ -10,32 +84,6 @@ pub struct Stat {
}
impl Stat {
pub async fn boats(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
let year = match year {
Some(year) => year,
None => chrono::Local::now().year(),
};
//TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
sqlx::query(&format!(
"
SELECT (SELECT name FROM boat WHERE id=logbook.boat_id) as name, CAST(SUM(distance_in_km) AS INTEGER) AS rowed_km
FROM logbook
WHERE arrival LIKE '{year}-%' AND name != 'Externes Boot'
GROUP BY boat_id
ORDER BY rowed_km DESC;
")
)
.fetch_all(db)
.await
.unwrap()
.into_iter()
.map(|row| Stat {
name: row.get("name"),
rowed_km: row.get("rowed_km"),
})
.collect()
}
pub async fn guest(db: &SqlitePool, year: Option<i32>) -> Stat {
let year = match year {
Some(year) => year,