257 lines
7.5 KiB
Rust
257 lines
7.5 KiB
Rust
use mysql::prelude::*;
|
|
use mysql::*;
|
|
use mysql_common::frunk::hlist_pat;
|
|
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);
|
|
|
|
pub fn get_maps(pool: &Pool) -> Result<Vec<map::Map>, Box<dyn Error>> {
|
|
let mut conn = pool.get_conn()?;
|
|
|
|
let maps = conn.query_map(
|
|
"SELECT * FROM record_maps AS maps JOIN record_mapinfo AS mapinfo ON maps.Map = mapinfo.Map",
|
|
|row: map::MapRow| {
|
|
let hlist_pat![ name, server, points, stars, mapper, timestamp, _name_again, width, height, death, through, jump, dfreeze, hit_end, ehook_start, solo_start, tele_gun, tele_grenade, tele_laser, npc_start, super_start, jetpack_start, walljump, nph_start, weapon_shotgun, weapon_grenade, powerup_ninja, weapon_rifle, laser_stop, crazy_shotgun, dragger, door, switch_timed, switch, stop, through_all, tune, oldlaser, teleinevil, telein, telecheck, teleinweapon, teleinhook, checkpoint_first, bonus, boost, plasmaf, plasmae, plasmau ] = row;
|
|
map::Map {
|
|
name,
|
|
server, points,
|
|
stars, mapper,
|
|
timestamp,
|
|
width,
|
|
height,
|
|
tile_data: map::MapTileData { death, through, jump, dfreeze, hit_end, ehook_start, solo_start, tele_gun, tele_grenade, tele_laser, npc_start, super_start, jetpack_start, walljump, nph_start, weapon_shotgun, weapon_grenade, powerup_ninja, weapon_rifle, laser_stop, crazy_shotgun, dragger, door, switch_timed, switch, stop, through_all, tune, oldlaser, teleinevil, telein, telecheck, teleinweapon, teleinhook, checkpoint_first, bonus, boost, plasmaf, plasmae, plasmau }
|
|
}
|
|
}
|
|
)?;
|
|
|
|
Ok(maps)
|
|
}
|
|
|
|
pub fn get_map_by_name(pool: &Pool, name: &str) -> Result<Option<map::Map>, Box<dyn Error>> {
|
|
let mut conn = pool.get_conn()?;
|
|
let stmt = conn.prep("SELECT * FROM record_maps AS maps JOIN record_mapinfo AS mapinfo ON maps.Map = mapinfo.Map WHERE maps.Map = ?")?;
|
|
|
|
let map: Option<map::MapRow> = conn.exec_first(&stmt, (name,))?;
|
|
|
|
Ok(match map {
|
|
Some(row) => {
|
|
let hlist_pat![
|
|
name,
|
|
server,
|
|
points,
|
|
stars,
|
|
mapper,
|
|
timestamp,
|
|
_name_again,
|
|
width,
|
|
height,
|
|
death,
|
|
through,
|
|
jump,
|
|
dfreeze,
|
|
hit_end,
|
|
ehook_start,
|
|
solo_start,
|
|
tele_gun,
|
|
tele_grenade,
|
|
tele_laser,
|
|
npc_start,
|
|
super_start,
|
|
jetpack_start,
|
|
walljump,
|
|
nph_start,
|
|
weapon_shotgun,
|
|
weapon_grenade,
|
|
powerup_ninja,
|
|
weapon_rifle,
|
|
laser_stop,
|
|
crazy_shotgun,
|
|
dragger,
|
|
door,
|
|
switch_timed,
|
|
switch,
|
|
stop,
|
|
through_all,
|
|
tune,
|
|
oldlaser,
|
|
teleinevil,
|
|
telein,
|
|
telecheck,
|
|
teleinweapon,
|
|
teleinhook,
|
|
checkpoint_first,
|
|
bonus,
|
|
boost,
|
|
plasmaf,
|
|
plasmae,
|
|
plasmau
|
|
] = row;
|
|
Some(map::Map {
|
|
name,
|
|
server,
|
|
points,
|
|
stars,
|
|
mapper,
|
|
timestamp,
|
|
width,
|
|
height,
|
|
tile_data: map::MapTileData {
|
|
death,
|
|
through,
|
|
jump,
|
|
dfreeze,
|
|
hit_end,
|
|
ehook_start,
|
|
solo_start,
|
|
tele_gun,
|
|
tele_grenade,
|
|
tele_laser,
|
|
npc_start,
|
|
super_start,
|
|
jetpack_start,
|
|
walljump,
|
|
nph_start,
|
|
weapon_shotgun,
|
|
weapon_grenade,
|
|
powerup_ninja,
|
|
weapon_rifle,
|
|
laser_stop,
|
|
crazy_shotgun,
|
|
dragger,
|
|
door,
|
|
switch_timed,
|
|
switch,
|
|
stop,
|
|
through_all,
|
|
tune,
|
|
oldlaser,
|
|
teleinevil,
|
|
telein,
|
|
telecheck,
|
|
teleinweapon,
|
|
teleinhook,
|
|
checkpoint_first,
|
|
bonus,
|
|
boost,
|
|
plasmaf,
|
|
plasmae,
|
|
plasmau,
|
|
},
|
|
})
|
|
}
|
|
None => None,
|
|
})
|
|
}
|
|
|
|
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<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>)),
|
|
}
|
|
}
|