Implemented some random stuff...

main
BurnyLlama 2022-11-06 19:53:11 +01:00
parent 1934f294f9
commit dbd52f31c6
4 changed files with 251 additions and 73 deletions

View File

@ -1,11 +1,33 @@
use mysql::prelude::*; use mysql::prelude::*;
use mysql::*; use mysql::*;
use mysql_common::frunk::hlist_pat; use mysql_common::frunk::hlist_pat;
use std::env;
use std::error::Error; use std::error::Error;
use std::result::Result; use std::result::Result;
use std::{env, result};
pub mod map; 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); pub struct DatabasePoolStore(pub Pool);
@ -147,22 +169,88 @@ pub fn get_map_by_name(pool: &Pool, name: &str) -> Result<Option<map::Map>, Box<
}) })
} }
pub fn create_pool() -> Pool { fn races_result(row: race::RaceRow) -> race::Race {
let url = match env::var("DB_URI") { let hlist_pat![
Ok(uri) => uri, map, name, timestamp, time, server, cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8, cp9, cp10,
Err(err) => { cp11, cp12, cp13, cp14, cp15, cp16, cp17, cp18, cp19, cp20, cp21, cp22, cp23, cp24, cp25,
println!("You must provide an env var: 'DB_URI'!"); gameid, ddnet7
panic!("{}", err); ] = row;
} race::Race {
}; map,
name,
let pool = match Pool::new(url.as_str()) { timestamp,
Ok(pool) => pool, time,
Err(err) => { server,
println!("Couldn't connect to the database!"); cp1,
panic!("{}", err); cp2,
} cp3,
}; cp4,
cp5,
pool 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<Vec<race::Race>, Box<dyn Error>> {
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<Vec<race::Race>, Box<dyn Error>> {
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<Vec<race::Race>, Box<dyn Error>> {
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<f64>, Option<i32>), Box<dyn Error>> {
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::<f64>, None::<i32>)),
}
} }

View File

@ -1,41 +1,74 @@
use mysql_common::{chrono::NaiveDateTime, frunk::HList}; 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<String>,
bool
);
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(crate = "rocket::serde")] #[serde(crate = "rocket::serde")]
struct Race { pub struct Race {
name: String, pub map: String,
map: MapName, pub name: String,
time: f64, pub timestamp: NaiveDateTime,
timestamp: NaiveDateTime, pub time: f64,
server: Servers, pub server: String,
cp1: f64, pub cp1: f64,
cp2: f64, pub cp2: f64,
cp3: f64, pub cp3: f64,
cp4: f64, pub cp4: f64,
cp5: f64, pub cp5: f64,
cp6: f64, pub cp6: f64,
cp7: f64, pub cp7: f64,
cp8: f64, pub cp8: f64,
cp9: f64, pub cp9: f64,
cp10: f64, pub cp10: f64,
cp11: f64, pub cp11: f64,
cp12: f64, pub cp12: f64,
cp13: f64, pub cp13: f64,
cp14: f64, pub cp14: f64,
cp15: f64, pub cp15: f64,
cp16: f64, pub cp16: f64,
cp17: f64, pub cp17: f64,
cp18: f64, pub cp18: f64,
cp19: f64, pub cp19: f64,
cp20: f64, pub cp20: f64,
cp21: f64, pub cp21: f64,
cp22: f64, pub cp22: f64,
cp23: f64, pub cp23: f64,
cp24: f64, pub cp24: f64,
cp25: f64, pub cp25: f64,
gameid: String, pub gameid: Option<String>,
ddnet7: bool pub ddnet7: bool,
} }

View File

@ -1,16 +1,16 @@
use mysql_common::{chrono::NaiveDateTime, frunk::HList}; 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")] #[serde(crate = "rocket::serde")]
struct TeamRace { pub struct TeamRace {
name: String, pub name: String,
map: MapName, pub map: String,
time: f64, pub time: f64,
timestamp: NaiveDateTime, pub timestamp: NaiveDateTime,
id: String, pub id: String,
gameid: String, pub gameid: String,
ddnet7: bool pub ddnet7: bool,
} }

View File

@ -9,8 +9,7 @@ extern crate dotenv;
use dotenv::dotenv; use dotenv::dotenv;
mod database; mod database;
use database::map::Map; use database::{map::Map, race::Race, DatabasePoolStore};
use database::DatabasePoolStore;
#[get("/maps")] #[get("/maps")]
fn get_all_maps(db_pool: &State<DatabasePoolStore>) -> Option<Json<Vec<Map>>> { fn get_all_maps(db_pool: &State<DatabasePoolStore>) -> Option<Json<Vec<Map>>> {
@ -34,13 +33,71 @@ fn get_map_by_name(db_pool: &State<DatabasePoolStore>, map: &str) -> Option<Json
} }
} }
#[get("/races/by-player/<player>")]
fn get_races_by_player(
db_pool: &State<DatabasePoolStore>,
player: &str,
) -> Option<Json<Vec<Race>>> {
match database::get_races_by_player(&db_pool.0, player) {
Ok(races) => Some(Json(races)),
Err(err) => {
println!("{err}");
None
}
}
}
#[get("/races/by-id/<id>")]
fn get_races_by_id(db_pool: &State<DatabasePoolStore>, id: &str) -> Option<Json<Vec<Race>>> {
match database::get_races_by_id(&db_pool.0, id) {
Ok(races) => Some(Json(races)),
Err(err) => {
println!("{err}");
None
}
}
}
#[get("/races/by-map/<map>")]
fn get_races_by_map(db_pool: &State<DatabasePoolStore>, map: &str) -> Option<Json<Vec<Race>>> {
match database::get_races_by_map(&db_pool.0, map) {
Ok(races) => Some(Json(races)),
Err(err) => {
println!("{err}");
None
}
}
}
#[get("/player/<player>/playtime")]
fn get_player_playtime(
db_pool: &State<DatabasePoolStore>,
player: &str,
) -> Option<Json<(Option<f64>, Option<i32>)>> {
match database::get_player_total_playtime(&db_pool.0, player) {
Ok(playtime) => Some(Json(playtime)),
Err(err) => {
println!("{err}");
None
}
}
}
#[launch] #[launch]
fn rocket() -> _ { fn rocket() -> _ {
dotenv().ok(); dotenv().ok();
let db_pool = create_pool(); let db_pool = create_pool();
rocket::build() rocket::build().manage(DatabasePoolStore(db_pool)).mount(
.manage(DatabasePoolStore(db_pool)) "/",
.mount("/", routes![get_all_maps, get_map_by_name]) routes![
get_all_maps,
get_map_by_name,
get_races_by_player,
get_races_by_id,
get_races_by_map,
get_player_playtime
],
)
} }