use crate::model::user::User; use chrono::Datelike; use serde::Serialize; use sqlx::{FromRow, Row, SqlitePool}; #[derive(FromRow, Serialize, Clone)] pub struct Stat { name: String, rowed_km: i32, } impl Stat { pub async fn boats(db: &SqlitePool, year: Option) -> Vec { let year = match year { Some(year) => year, None => chrono::Utc::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}-%' 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 people(db: &SqlitePool, year: Option) -> Vec { let year = match year { Some(year) => year, None => chrono::Utc::now().year(), }; //TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server) sqlx::query(&format!( " SELECT u.name, CAST(SUM(l.distance_in_km) AS INTEGER) AS rowed_km FROM user u INNER JOIN rower r ON u.id = r.rower_id INNER JOIN logbook l ON r.logbook_id = l.id WHERE u.is_guest = 0 AND l.distance_in_km IS NOT NULL AND l.arrival LIKE '{year}-%' GROUP BY u.name 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() } } #[derive(Debug, Serialize)] pub struct PersonalStat { date: String, km: i32, } pub async fn get_personal(db: &SqlitePool, user: &User) -> Vec { sqlx::query(&format!( " SELECT departure_date as date, SUM(total_distance) OVER (ORDER BY departure_date) as km FROM ( SELECT date(l.departure) as departure_date, COALESCE(SUM(l.distance_in_km),0) as total_distance FROM logbook l LEFT JOIN rower r ON l.id = r.logbook_id WHERE l.shipmaster = {0} OR r.rower_id = {0} GROUP BY departure_date ) as subquery ORDER BY departure_date; ", user.id )) .fetch_all(db) .await .unwrap() .into_iter() .map(|row| PersonalStat { date: row.get("date"), km: row.get("km"), }) .collect() }