use crate::model::user::User; 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 get_rowed_km(db: &SqlitePool) -> Vec { //TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server) sqlx::query( " SELECT u.name, SUM(sub.distance_in_km) AS rowed_km FROM user u INNER JOIN ( SELECT r.rower_id AS user_id, l.distance_in_km FROM logbook l INNER JOIN rower r ON l.id = r.logbook_id WHERE l.distance_in_km IS NOT NULL UNION ALL SELECT l.shipmaster AS user_id, l.distance_in_km FROM logbook l WHERE l.distance_in_km IS NOT NULL ) sub ON u.id = sub.user_id 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() }