109 lines
2.6 KiB
Rust
Raw Normal View History

2023-10-01 14:35:04 +02:00
use crate::model::user::User;
2023-11-18 12:21:37 +01:00
use chrono::Datelike;
2023-07-24 20:56:46 +02:00
use serde::Serialize;
2023-07-24 21:17:51 +02:00
use sqlx::{FromRow, Row, SqlitePool};
2023-07-24 20:56:46 +02:00
#[derive(FromRow, Serialize, Clone)]
pub struct Stat {
name: String,
rowed_km: i32,
}
impl Stat {
2023-11-18 12:21:37 +01:00
pub async fn boats(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
let year = match year {
Some(year) => year,
None => chrono::Utc::now().year(),
};
2023-10-31 16:07:15 +01:00
//TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
2023-11-18 12:21:37 +01:00
sqlx::query(&format!(
2023-10-31 16:07:15 +01:00
"
SELECT (SELECT name FROM boat WHERE id=logbook.boat_id) as name, CAST(SUM(distance_in_km) AS INTEGER) AS rowed_km
2023-11-18 12:21:37 +01:00
FROM logbook
WHERE arrival LIKE '{}-%'
2023-10-31 16:07:15 +01:00
GROUP BY boat_id
ORDER BY rowed_km DESC;
2023-11-18 12:21:37 +01:00
",year)
2023-10-31 16:07:15 +01:00
)
.fetch_all(db)
.await
.unwrap()
.into_iter()
.map(|row| Stat {
name: row.get("name"),
rowed_km: row.get("rowed_km"),
})
.collect()
}
2023-11-18 12:21:37 +01:00
pub async fn people(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
let year = match year {
Some(year) => year,
None => chrono::Utc::now().year(),
};
2023-07-24 21:17:51 +02:00
//TODO: switch to query! macro again (once upgraded to sqlite 3.42 on server)
2023-11-18 12:21:37 +01:00
sqlx::query(&format!(
2023-08-05 15:58:17 +02:00
"
2023-10-30 15:31:12 +01:00
SELECT u.name, CAST(SUM(l.distance_in_km) AS INTEGER) AS rowed_km
2023-08-05 15:58:17 +02:00
FROM user u
2023-10-30 15:31:12 +01:00
INNER JOIN rower r ON u.id = r.rower_id
INNER JOIN logbook l ON r.logbook_id = l.id
2023-11-18 12:21:37 +01:00
WHERE u.is_guest = 0 AND l.distance_in_km IS NOT NULL AND l.arrival LIKE '{}-%'
2023-08-05 15:58:17 +02:00
GROUP BY u.name
ORDER BY rowed_km DESC;
",
2023-11-18 12:21:37 +01:00
year
))
2023-07-24 20:56:46 +02:00
.fetch_all(db)
.await
.unwrap()
.into_iter()
.map(|row| Stat {
name: row.get("name"),
rowed_km: row.get("rowed_km"),
2023-07-24 20:56:46 +02:00
})
.collect()
}
}
2023-10-01 14:35:04 +02:00
#[derive(Debug, Serialize)]
pub struct PersonalStat {
date: String,
km: i32,
}
pub async fn get_personal(db: &SqlitePool, user: &User) -> Vec<PersonalStat> {
2023-10-01 18:14:05 +02:00
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()
2023-10-01 14:35:04 +02:00
}