diff --git a/src/database/mod.rs b/src/database/mod.rs index e7e3099..092d725 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -1,11 +1,33 @@ use mysql::prelude::*; use mysql::*; use mysql_common::frunk::hlist_pat; -use std::env; use std::error::Error; use std::result::Result; +use std::{env, result}; pub mod map; +pub mod race; +pub mod teamrace; + +pub fn create_pool() -> Pool { + let url = match env::var("DB_URI") { + Ok(uri) => uri, + Err(err) => { + println!("You must provide an env var: 'DB_URI'!"); + panic!("{}", err); + } + }; + + let pool = match Pool::new(url.as_str()) { + Ok(pool) => pool, + Err(err) => { + println!("Couldn't connect to the database!"); + panic!("{}", err); + } + }; + + pool +} pub struct DatabasePoolStore(pub Pool); @@ -147,22 +169,88 @@ pub fn get_map_by_name(pool: &Pool, name: &str) -> Result, Box< }) } -pub fn create_pool() -> Pool { - let url = match env::var("DB_URI") { - Ok(uri) => uri, - Err(err) => { - println!("You must provide an env var: 'DB_URI'!"); - panic!("{}", err); - } - }; - - let pool = match Pool::new(url.as_str()) { - Ok(pool) => pool, - Err(err) => { - println!("Couldn't connect to the database!"); - panic!("{}", err); - } - }; - - pool +fn races_result(row: race::RaceRow) -> race::Race { + let hlist_pat![ + map, name, timestamp, time, server, cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8, cp9, cp10, + cp11, cp12, cp13, cp14, cp15, cp16, cp17, cp18, cp19, cp20, cp21, cp22, cp23, cp24, cp25, + gameid, ddnet7 + ] = row; + race::Race { + map, + name, + timestamp, + time, + server, + cp1, + cp2, + cp3, + cp4, + cp5, + cp6, + cp7, + cp8, + cp9, + cp10, + cp11, + cp12, + cp13, + cp14, + cp15, + cp16, + cp17, + cp18, + cp19, + cp20, + cp21, + cp22, + cp23, + cp24, + cp25, + gameid, + ddnet7, + } +} + +pub fn get_races_by_player(pool: &Pool, player: &str) -> Result, Box> { + let mut conn = pool.get_conn()?; + let stmt = conn.prep("SELECT * FROM record_race WHERE Name = ?")?; + + let races = conn.exec_map(&stmt, (player,), races_result)?; + + Ok(races) +} + +pub fn get_races_by_id(pool: &Pool, id: &str) -> Result, Box> { + let mut conn = pool.get_conn()?; + let stmt = conn.prep("SELECT * FROM record_race WHERE GameID = ?")?; + + let races = conn.exec_map(&stmt, (id,), races_result)?; + + Ok(races) +} + +pub fn get_races_by_map(pool: &Pool, map: &str) -> Result, Box> { + let mut conn = pool.get_conn()?; + let stmt = conn.prep("SELECT * FROM record_race WHERE Map = ?")?; + + let races = conn.exec_map(&stmt, (map,), races_result)?; + + Ok(races) +} + +pub fn get_player_total_playtime( + pool: &Pool, + player: &str, +) -> Result<(Option, Option), Box> { + let mut conn = pool.get_conn()?; + let stmt = conn.prep( + "SELECT COALESCE(SUM(Time),0), COALESCE(COUNT(Time),0) FROM record_race WHERE Name = ?", + )?; + + let result = conn.exec_first(&stmt, (player,))?; + + match result { + Some((total_playtime, total_games)) => Ok((total_playtime, total_games)), + None => Ok((None::, None::)), + } } diff --git a/src/database/race.rs b/src/database/race.rs index b8a343c..6ab0d61 100644 --- a/src/database/race.rs +++ b/src/database/race.rs @@ -1,41 +1,74 @@ use mysql_common::{chrono::NaiveDateTime, frunk::HList}; -use rocket::serde::{Serialize, Deserialize}; +use rocket::serde::{Deserialize, Serialize}; -type RaceRow = HList!(String, MapName, f64, NaiveDateTime, Servers, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, String, bool); +pub type RaceRow = HList!( + String, + String, + NaiveDateTime, + f64, + String, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + f64, + Option, + bool +); -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] #[serde(crate = "rocket::serde")] -struct Race { - name: String, - map: MapName, - time: f64, - timestamp: NaiveDateTime, - server: Servers, - cp1: f64, - cp2: f64, - cp3: f64, - cp4: f64, - cp5: f64, - cp6: f64, - cp7: f64, - cp8: f64, - cp9: f64, - cp10: f64, - cp11: f64, - cp12: f64, - cp13: f64, - cp14: f64, - cp15: f64, - cp16: f64, - cp17: f64, - cp18: f64, - cp19: f64, - cp20: f64, - cp21: f64, - cp22: f64, - cp23: f64, - cp24: f64, - cp25: f64, - gameid: String, - ddnet7: bool -} \ No newline at end of file +pub struct Race { + pub map: String, + pub name: String, + pub timestamp: NaiveDateTime, + pub time: f64, + pub server: String, + pub cp1: f64, + pub cp2: f64, + pub cp3: f64, + pub cp4: f64, + pub cp5: f64, + pub cp6: f64, + pub cp7: f64, + pub cp8: f64, + pub cp9: f64, + pub cp10: f64, + pub cp11: f64, + pub cp12: f64, + pub cp13: f64, + pub cp14: f64, + pub cp15: f64, + pub cp16: f64, + pub cp17: f64, + pub cp18: f64, + pub cp19: f64, + pub cp20: f64, + pub cp21: f64, + pub cp22: f64, + pub cp23: f64, + pub cp24: f64, + pub cp25: f64, + pub gameid: Option, + pub ddnet7: bool, +} diff --git a/src/database/teamrace.rs b/src/database/teamrace.rs index e4ec480..7c3352f 100644 --- a/src/database/teamrace.rs +++ b/src/database/teamrace.rs @@ -1,16 +1,16 @@ use mysql_common::{chrono::NaiveDateTime, frunk::HList}; -use rocket::serde::{Serialize, Deserialize}; +use rocket::serde::{Deserialize, Serialize}; -type TeamRaceRow = HList!(i8); +pub type TeamRaceRow = HList!(String, String, f64, NaiveDateTime, String, String, bool); -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] #[serde(crate = "rocket::serde")] -struct TeamRace { - name: String, - map: MapName, - time: f64, - timestamp: NaiveDateTime, - id: String, - gameid: String, - ddnet7: bool -} \ No newline at end of file +pub struct TeamRace { + pub name: String, + pub map: String, + pub time: f64, + pub timestamp: NaiveDateTime, + pub id: String, + pub gameid: String, + pub ddnet7: bool, +} diff --git a/src/main.rs b/src/main.rs index 12ae422..a33ae22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,8 +9,7 @@ extern crate dotenv; use dotenv::dotenv; mod database; -use database::map::Map; -use database::DatabasePoolStore; +use database::{map::Map, race::Race, DatabasePoolStore}; #[get("/maps")] fn get_all_maps(db_pool: &State) -> Option>> { @@ -34,13 +33,71 @@ fn get_map_by_name(db_pool: &State, map: &str) -> Option")] +fn get_races_by_player( + db_pool: &State, + player: &str, +) -> Option>> { + match database::get_races_by_player(&db_pool.0, player) { + Ok(races) => Some(Json(races)), + Err(err) => { + println!("{err}"); + None + } + } +} + +#[get("/races/by-id/")] +fn get_races_by_id(db_pool: &State, id: &str) -> Option>> { + match database::get_races_by_id(&db_pool.0, id) { + Ok(races) => Some(Json(races)), + Err(err) => { + println!("{err}"); + None + } + } +} + +#[get("/races/by-map/")] +fn get_races_by_map(db_pool: &State, map: &str) -> Option>> { + match database::get_races_by_map(&db_pool.0, map) { + Ok(races) => Some(Json(races)), + Err(err) => { + println!("{err}"); + None + } + } +} + +#[get("/player//playtime")] +fn get_player_playtime( + db_pool: &State, + player: &str, +) -> Option, Option)>> { + match database::get_player_total_playtime(&db_pool.0, player) { + Ok(playtime) => Some(Json(playtime)), + Err(err) => { + println!("{err}"); + None + } + } +} + #[launch] fn rocket() -> _ { dotenv().ok(); let db_pool = create_pool(); - rocket::build() - .manage(DatabasePoolStore(db_pool)) - .mount("/", routes![get_all_maps, get_map_by_name]) + rocket::build().manage(DatabasePoolStore(db_pool)).mount( + "/", + routes![ + get_all_maps, + get_map_by_name, + get_races_by_player, + get_races_by_id, + get_races_by_map, + get_player_playtime + ], + ) }