ddstats/src/database/models/map.rs

288 lines
14 KiB
Rust

use chrono::NaiveDateTime;
use rocket::futures::StreamExt;
use serde::{Deserialize, Serialize};
use crate::database::DatabaseHandler;
#[derive(Debug, Clone, sqlx::FromRow, Serialize, Deserialize)]
pub struct Map {
pub map: String,
pub mapper: String,
pub category: String,
pub points: i16,
pub stars: i16,
pub release: Option<NaiveDateTime>,
pub width: Option<i16>,
pub height: Option<i16>,
pub tiles: Option<Vec<String>>,
}
impl Map {
pub async fn get_all_maps(db: &DatabaseHandler) -> Result<Vec<Map>, sqlx::Error> {
sqlx::query_as!(
Map,
"
SELECT record_maps.map, category, points, stars, mapper, release, width, height,
string_to_array(CONCAT_WS(',',
CASE WHEN DEATH = '1' THEN 'DEATH' END,
CASE WHEN THROUGH = '1' THEN 'THROUGH' END,
CASE WHEN JUMP = '1' THEN 'JUMP' END,
CASE WHEN DFREEZE = '1' THEN 'DFREEZE' END,
CASE WHEN EHOOK_START = '1' THEN 'EHOOK_START' END,
CASE WHEN HIT_END = '1' THEN 'HIT_END' END,
CASE WHEN SOLO_START = '1' THEN 'SOLO_START' END,
CASE WHEN TELE_GUN = '1' THEN 'TELE_GUN' END,
CASE WHEN TELE_GRENADE = '1' THEN 'TELE_GRENADE' END,
CASE WHEN TELE_LASER = '1' THEN 'TELE_LASER' END,
CASE WHEN NPC_START = '1' THEN 'NPC_START' END,
CASE WHEN SUPER_START = '1' THEN 'SUPER_START' END,
CASE WHEN JETPACK_START = '1' THEN 'JETPACK_START' END,
CASE WHEN WALLJUMP = '1' THEN 'WALLJUMP' END,
CASE WHEN NPH_START = '1' THEN 'NPH_START' END,
CASE WHEN WEAPON_SHOTGUN = '1' THEN 'WEAPON_SHOTGUN' END,
CASE WHEN WEAPON_GRENADE = '1' THEN 'WEAPON_GRENADE' END,
CASE WHEN POWERUP_NINJA = '1' THEN 'POWERUP_NINJA' END,
CASE WHEN WEAPON_RIFLE = '1' THEN 'WEAPON_RIFLE' END,
CASE WHEN LASER_STOP = '1' THEN 'LASER_STOP' END,
CASE WHEN CRAZY_SHOTGUN = '1' THEN 'CRAZY_SHOTGUN' END,
CASE WHEN DRAGGER = '1' THEN 'DRAGGER' END,
CASE WHEN DOOR = '1' THEN 'DOOR' END,
CASE WHEN SWITCH_TIMED = '1' THEN 'SWITCH_TIMED' END,
CASE WHEN SWITCH = '1' THEN 'SWITCH' END,
CASE WHEN STOP = '1' THEN 'STOP' END,
CASE WHEN THROUGH_ALL = '1' THEN 'THROUGH_ALL' END,
CASE WHEN TUNE = '1' THEN 'TUNE' END,
CASE WHEN OLDLASER = '1' THEN 'OLDLASER' END,
CASE WHEN TELEINEVIL = '1' THEN 'TELEINEVIL' END,
CASE WHEN TELEIN = '1' THEN 'TELEIN' END,
CASE WHEN TELECHECK = '1' THEN 'TELECHECK' END,
CASE WHEN TELEINWEAPON = '1' THEN 'TELEINWEAPON' END,
CASE WHEN TELEINHOOK = '1' THEN 'TELEINHOOK' END,
CASE WHEN CHECKPOINT_FIRST = '1' THEN 'CHECKPOINT_FIRST' END,
CASE WHEN BONUS = '1' THEN 'BONUS' END,
CASE WHEN BOOST = '1' THEN 'BOOST' END,
CASE WHEN PLASMAF = '1' THEN 'PLASMAF' END,
CASE WHEN PLASMAE = '1' THEN 'PLASMAE' END,
CASE WHEN PLASMAU = '1' THEN 'PLASMAU' END), ',') AS tiles
FROM record_maps JOIN record_mapinfo ON record_maps.map = record_mapinfo.map;
"
)
.fetch_all(&db.pool)
.await
}
pub async fn get_map_by_name(db: &DatabaseHandler, map: &str) -> Result<Map, sqlx::Error> {
sqlx::query_as!(
Map,
"
SELECT record_maps.map, category, points, stars, mapper, release, width, height,
string_to_array(CONCAT_WS(',',
CASE WHEN DEATH = '1' THEN 'DEATH' END,
CASE WHEN THROUGH = '1' THEN 'THROUGH' END,
CASE WHEN JUMP = '1' THEN 'JUMP' END,
CASE WHEN DFREEZE = '1' THEN 'DFREEZE' END,
CASE WHEN EHOOK_START = '1' THEN 'EHOOK_START' END,
CASE WHEN HIT_END = '1' THEN 'HIT_END' END,
CASE WHEN SOLO_START = '1' THEN 'SOLO_START' END,
CASE WHEN TELE_GUN = '1' THEN 'TELE_GUN' END,
CASE WHEN TELE_GRENADE = '1' THEN 'TELE_GRENADE' END,
CASE WHEN TELE_LASER = '1' THEN 'TELE_LASER' END,
CASE WHEN NPC_START = '1' THEN 'NPC_START' END,
CASE WHEN SUPER_START = '1' THEN 'SUPER_START' END,
CASE WHEN JETPACK_START = '1' THEN 'JETPACK_START' END,
CASE WHEN WALLJUMP = '1' THEN 'WALLJUMP' END,
CASE WHEN NPH_START = '1' THEN 'NPH_START' END,
CASE WHEN WEAPON_SHOTGUN = '1' THEN 'WEAPON_SHOTGUN' END,
CASE WHEN WEAPON_GRENADE = '1' THEN 'WEAPON_GRENADE' END,
CASE WHEN POWERUP_NINJA = '1' THEN 'POWERUP_NINJA' END,
CASE WHEN WEAPON_RIFLE = '1' THEN 'WEAPON_RIFLE' END,
CASE WHEN LASER_STOP = '1' THEN 'LASER_STOP' END,
CASE WHEN CRAZY_SHOTGUN = '1' THEN 'CRAZY_SHOTGUN' END,
CASE WHEN DRAGGER = '1' THEN 'DRAGGER' END,
CASE WHEN DOOR = '1' THEN 'DOOR' END,
CASE WHEN SWITCH_TIMED = '1' THEN 'SWITCH_TIMED' END,
CASE WHEN SWITCH = '1' THEN 'SWITCH' END,
CASE WHEN STOP = '1' THEN 'STOP' END,
CASE WHEN THROUGH_ALL = '1' THEN 'THROUGH_ALL' END,
CASE WHEN TUNE = '1' THEN 'TUNE' END,
CASE WHEN OLDLASER = '1' THEN 'OLDLASER' END,
CASE WHEN TELEINEVIL = '1' THEN 'TELEINEVIL' END,
CASE WHEN TELEIN = '1' THEN 'TELEIN' END,
CASE WHEN TELECHECK = '1' THEN 'TELECHECK' END,
CASE WHEN TELEINWEAPON = '1' THEN 'TELEINWEAPON' END,
CASE WHEN TELEINHOOK = '1' THEN 'TELEINHOOK' END,
CASE WHEN CHECKPOINT_FIRST = '1' THEN 'CHECKPOINT_FIRST' END,
CASE WHEN BONUS = '1' THEN 'BONUS' END,
CASE WHEN BOOST = '1' THEN 'BOOST' END,
CASE WHEN PLASMAF = '1' THEN 'PLASMAF' END,
CASE WHEN PLASMAE = '1' THEN 'PLASMAE' END,
CASE WHEN PLASMAU = '1' THEN 'PLASMAU' END), ',') AS tiles
FROM record_maps JOIN record_mapinfo ON record_maps.map = record_mapinfo.map
WHERE record_maps.map = $1;
",
map
)
.fetch_one(&db.pool)
.await
}
pub async fn get_maps_by_category(
db: &DatabaseHandler,
category: &str,
) -> Result<Vec<Map>, sqlx::Error> {
sqlx::query_as!(
Map,
"
SELECT record_maps.map, category, points, stars, mapper, release, width, height,
string_to_array(CONCAT_WS(',',
CASE WHEN DEATH = '1' THEN 'DEATH' END,
CASE WHEN THROUGH = '1' THEN 'THROUGH' END,
CASE WHEN JUMP = '1' THEN 'JUMP' END,
CASE WHEN DFREEZE = '1' THEN 'DFREEZE' END,
CASE WHEN EHOOK_START = '1' THEN 'EHOOK_START' END,
CASE WHEN HIT_END = '1' THEN 'HIT_END' END,
CASE WHEN SOLO_START = '1' THEN 'SOLO_START' END,
CASE WHEN TELE_GUN = '1' THEN 'TELE_GUN' END,
CASE WHEN TELE_GRENADE = '1' THEN 'TELE_GRENADE' END,
CASE WHEN TELE_LASER = '1' THEN 'TELE_LASER' END,
CASE WHEN NPC_START = '1' THEN 'NPC_START' END,
CASE WHEN SUPER_START = '1' THEN 'SUPER_START' END,
CASE WHEN JETPACK_START = '1' THEN 'JETPACK_START' END,
CASE WHEN WALLJUMP = '1' THEN 'WALLJUMP' END,
CASE WHEN NPH_START = '1' THEN 'NPH_START' END,
CASE WHEN WEAPON_SHOTGUN = '1' THEN 'WEAPON_SHOTGUN' END,
CASE WHEN WEAPON_GRENADE = '1' THEN 'WEAPON_GRENADE' END,
CASE WHEN POWERUP_NINJA = '1' THEN 'POWERUP_NINJA' END,
CASE WHEN WEAPON_RIFLE = '1' THEN 'WEAPON_RIFLE' END,
CASE WHEN LASER_STOP = '1' THEN 'LASER_STOP' END,
CASE WHEN CRAZY_SHOTGUN = '1' THEN 'CRAZY_SHOTGUN' END,
CASE WHEN DRAGGER = '1' THEN 'DRAGGER' END,
CASE WHEN DOOR = '1' THEN 'DOOR' END,
CASE WHEN SWITCH_TIMED = '1' THEN 'SWITCH_TIMED' END,
CASE WHEN SWITCH = '1' THEN 'SWITCH' END,
CASE WHEN STOP = '1' THEN 'STOP' END,
CASE WHEN THROUGH_ALL = '1' THEN 'THROUGH_ALL' END,
CASE WHEN TUNE = '1' THEN 'TUNE' END,
CASE WHEN OLDLASER = '1' THEN 'OLDLASER' END,
CASE WHEN TELEINEVIL = '1' THEN 'TELEINEVIL' END,
CASE WHEN TELEIN = '1' THEN 'TELEIN' END,
CASE WHEN TELECHECK = '1' THEN 'TELECHECK' END,
CASE WHEN TELEINWEAPON = '1' THEN 'TELEINWEAPON' END,
CASE WHEN TELEINHOOK = '1' THEN 'TELEINHOOK' END,
CASE WHEN CHECKPOINT_FIRST = '1' THEN 'CHECKPOINT_FIRST' END,
CASE WHEN BONUS = '1' THEN 'BONUS' END,
CASE WHEN BOOST = '1' THEN 'BOOST' END,
CASE WHEN PLASMAF = '1' THEN 'PLASMAF' END,
CASE WHEN PLASMAE = '1' THEN 'PLASMAE' END,
CASE WHEN PLASMAU = '1' THEN 'PLASMAU' END), ',') AS tiles
FROM record_maps JOIN record_mapinfo ON record_maps.map = record_mapinfo.map
WHERE category = $1;
",
category
)
.fetch_all(&db.pool)
.await
}
pub async fn get_maps_by_mapper(
db: &DatabaseHandler,
mapper: &str,
) -> Result<Vec<Map>, sqlx::Error> {
sqlx::query_as!(
Map,
"
SELECT record_maps.map, category, points, stars, mapper, release, width, height,
string_to_array(CONCAT_WS(',',
CASE WHEN DEATH = '1' THEN 'DEATH' END,
CASE WHEN THROUGH = '1' THEN 'THROUGH' END,
CASE WHEN JUMP = '1' THEN 'JUMP' END,
CASE WHEN DFREEZE = '1' THEN 'DFREEZE' END,
CASE WHEN EHOOK_START = '1' THEN 'EHOOK_START' END,
CASE WHEN HIT_END = '1' THEN 'HIT_END' END,
CASE WHEN SOLO_START = '1' THEN 'SOLO_START' END,
CASE WHEN TELE_GUN = '1' THEN 'TELE_GUN' END,
CASE WHEN TELE_GRENADE = '1' THEN 'TELE_GRENADE' END,
CASE WHEN TELE_LASER = '1' THEN 'TELE_LASER' END,
CASE WHEN NPC_START = '1' THEN 'NPC_START' END,
CASE WHEN SUPER_START = '1' THEN 'SUPER_START' END,
CASE WHEN JETPACK_START = '1' THEN 'JETPACK_START' END,
CASE WHEN WALLJUMP = '1' THEN 'WALLJUMP' END,
CASE WHEN NPH_START = '1' THEN 'NPH_START' END,
CASE WHEN WEAPON_SHOTGUN = '1' THEN 'WEAPON_SHOTGUN' END,
CASE WHEN WEAPON_GRENADE = '1' THEN 'WEAPON_GRENADE' END,
CASE WHEN POWERUP_NINJA = '1' THEN 'POWERUP_NINJA' END,
CASE WHEN WEAPON_RIFLE = '1' THEN 'WEAPON_RIFLE' END,
CASE WHEN LASER_STOP = '1' THEN 'LASER_STOP' END,
CASE WHEN CRAZY_SHOTGUN = '1' THEN 'CRAZY_SHOTGUN' END,
CASE WHEN DRAGGER = '1' THEN 'DRAGGER' END,
CASE WHEN DOOR = '1' THEN 'DOOR' END,
CASE WHEN SWITCH_TIMED = '1' THEN 'SWITCH_TIMED' END,
CASE WHEN SWITCH = '1' THEN 'SWITCH' END,
CASE WHEN STOP = '1' THEN 'STOP' END,
CASE WHEN THROUGH_ALL = '1' THEN 'THROUGH_ALL' END,
CASE WHEN TUNE = '1' THEN 'TUNE' END,
CASE WHEN OLDLASER = '1' THEN 'OLDLASER' END,
CASE WHEN TELEINEVIL = '1' THEN 'TELEINEVIL' END,
CASE WHEN TELEIN = '1' THEN 'TELEIN' END,
CASE WHEN TELECHECK = '1' THEN 'TELECHECK' END,
CASE WHEN TELEINWEAPON = '1' THEN 'TELEINWEAPON' END,
CASE WHEN TELEINHOOK = '1' THEN 'TELEINHOOK' END,
CASE WHEN CHECKPOINT_FIRST = '1' THEN 'CHECKPOINT_FIRST' END,
CASE WHEN BONUS = '1' THEN 'BONUS' END,
CASE WHEN BOOST = '1' THEN 'BOOST' END,
CASE WHEN PLASMAF = '1' THEN 'PLASMAF' END,
CASE WHEN PLASMAE = '1' THEN 'PLASMAE' END,
CASE WHEN PLASMAU = '1' THEN 'PLASMAU' END), ',') AS tiles
FROM record_maps JOIN record_mapinfo ON record_maps.map = record_mapinfo.map
WHERE mapper = $1;
",
mapper
)
.fetch_all(&db.pool)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_all_maps() {
async fn test() {
let db = match DatabaseHandler::create().await {
Ok(db) => db,
Err(err) => panic!("Error while connecting to database! {:?}", err),
};
let maps = match Map::get_all_maps(&db).await {
Ok(maps) => maps,
Err(err) => panic!("Error while getting all maps! {:?}", err),
};
for map in maps {
println!("{:?}", map);
}
}
tokio_test::block_on(test());
}
#[test]
fn test_get_map_by_name() {
async fn test() {
let db = match DatabaseHandler::create().await {
Ok(db) => db,
Err(err) => panic!("Error while connecting to database! {:?}", err),
};
let map = match Map::get_map_by_name(&db, "Kobra").await {
Ok(map) => map,
Err(err) => panic!("Error while getting all maps! {:?}", err),
};
println!("{:?}", map);
}
tokio_test::block_on(test());
}
}