use crate::{model::client::Client, Backend}; pub(crate) struct Rank { pub(crate) rank: i64, pub(crate) client: Client, pub(crate) amount: i64, pub(crate) show_dots_above: bool, } impl Backend { pub(crate) async fn amount_participants(&self) -> i64 { match self { Backend::Sqlite(db) => { let row = sqlx::query!("SELECT COUNT(*) as count FROM client") .fetch_one(db) .await .unwrap(); row.count } } } pub(crate) async fn highscore(&self, client: &Client) -> Vec { match self { Backend::Sqlite(db) => { let rows = sqlx::query!( "WITH ranked_clients AS ( SELECT DENSE_RANK() OVER (ORDER BY COUNT(s.client_uuid) DESC) as rank, c.name, c.uuid, COUNT(s.client_uuid) as amount FROM client c LEFT JOIN sightings s ON c.uuid = s.client_uuid GROUP BY c.uuid, c.name ) SELECT rank, name, uuid, amount FROM ranked_clients WHERE rank <= ( SELECT rank FROM ranked_clients ORDER BY rank LIMIT 1 OFFSET 9 ) ORDER BY rank, name" ) .fetch_all(db) .await .unwrap_or_default(); let mut ret: Vec = rows .into_iter() .map(|row| Rank { rank: row.rank.unwrap(), client: Client { uuid: row.uuid.unwrap(), name: row.name, }, amount: row.amount.unwrap(), show_dots_above: false, }) .collect(); let user_is_in_top = ret.iter().any(|x| &x.client == client); if !user_is_in_top { let row = sqlx::query!( "WITH ranked_clients AS ( SELECT DENSE_RANK() OVER (ORDER BY COUNT(s.client_uuid) DESC) as rank, c.name, c.uuid, COUNT(s.client_uuid) as amount FROM client c LEFT JOIN sightings s ON c.uuid = s.client_uuid GROUP BY c.uuid, c.name ) SELECT rank, name, uuid, amount FROM ranked_clients WHERE uuid = ? ORDER BY rank, name", client.uuid ) .fetch_one(db) .await .unwrap(); ret.push(Rank { rank: row.rank, client: Client { uuid: row.uuid, name: row.name, }, amount: row.amount, show_dots_above: true, }) } ret } } } }