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, pub width: Option, pub height: Option, pub tiles: Option>, } impl Map { pub async fn get_all_maps(db: &DatabaseHandler) -> Result, 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 { 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, 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, 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()); } }