87 lines
1.9 KiB
Rust
87 lines
1.9 KiB
Rust
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<Stat> {
|
|
//TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
|
|
sqlx::query(
|
|
"
|
|
SELECT u.name, CAST(SUM(sub.distance_in_km) AS INTEGER) 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
|
|
WHERE u.is_guest = false
|
|
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<PersonalStat> {
|
|
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()
|
|
}
|