Geoffrey-rs/geoffrey_db/src/query/location_query.rs

149 lines
4.5 KiB
Rust

use crate::error::Result;
use crate::query::QueryBuilder;
use geoffrey_models::models::locations::{LocationDb, LocationType};
impl QueryBuilder<LocationDb> {
pub fn with_owner(self, owner_id: u64) -> Self {
self.add_query_clause(Box::new(move |_: u64, loc: &LocationDb| {
loc.owners().contains(&owner_id)
}))
}
pub fn with_name_regex_case_insensitive(self, exp: &str) -> Result<Self> {
self.with_name_regex(&format!(r"(?i){}", exp))
}
pub fn with_name_regex(self, exp: &str) -> Result<Self> {
let filter = regex::Regex::new(exp)?;
Ok(
self.add_query_clause(Box::new(move |_: u64, loc: &LocationDb| {
filter.is_match(&loc.name)
})),
)
}
pub fn with_name(self, name: &str) -> Self {
let name = name.to_lowercase();
self.add_query_clause(Box::new(move |_: u64, loc: &LocationDb| {
loc.name.to_lowercase() == name
}))
}
pub fn with_type(self, loc_type: LocationType) -> Self {
self.add_query_clause(Box::new(move |_: u64, loc: &LocationDb| {
let next_loc_type: LocationType = LocationType::from(&loc.loc_data);
loc_type == next_loc_type
}))
}
}
#[cfg(test)]
mod test {
use crate::query::location_query::QueryBuilder;
use crate::test::{cleanup, DB, LOCK};
use geoffrey_models::models::locations::shop::Shop;
use geoffrey_models::models::locations::{LocationDataDb, LocationDb, LocationType};
use geoffrey_models::models::player::{Player, UserID};
use geoffrey_models::models::Position;
fn setup_db() -> (Player, LocationDb, LocationDb) {
let player = DB
.insert(Player::new("Test", UserID::DiscordUUID { discord_uuid: 5 }))
.unwrap();
let base = DB
.insert(LocationDb::new(
"Test Base",
Position::default(),
player.id.unwrap(),
None,
LocationDataDb::Base,
))
.unwrap();
let shop = DB
.insert(LocationDb::new(
"Test Shop",
Position::default(),
player.id.unwrap(),
None,
LocationDataDb::Shop(Shop::default()),
))
.unwrap();
(player, base, shop)
}
#[test]
fn test_with_owner_query() {
let _lock = LOCK.lock().unwrap();
cleanup();
let (player, base, _) = setup_db();
let query: QueryBuilder<LocationDb> = QueryBuilder::new();
let query = query.with_owner(55);
assert!(DB.run_query(query).is_err());
let query: QueryBuilder<LocationDb> = QueryBuilder::new();
let query = query.with_owner(player.id.unwrap());
let locations: Vec<LocationDb> = DB.run_query(query).unwrap();
assert_eq!(locations.len(), 2);
assert_eq!(locations[0].name, base.name);
}
#[test]
fn test_with_type_query() {
let _lock = LOCK.lock().unwrap();
cleanup();
let (_, base, shop) = setup_db();
let query: QueryBuilder<LocationDb> = QueryBuilder::new();
let query = query.with_type(LocationType::Base);
let locations: Vec<LocationDb> = DB.run_query(query).unwrap();
assert_eq!(locations.len(), 1);
assert_eq!(locations[0].name, base.name);
let query: QueryBuilder<LocationDb> = QueryBuilder::new();
let query = query.with_type(LocationType::Shop);
let locations: Vec<LocationDb> = DB.run_query(query).unwrap();
assert_eq!(locations.len(), 1);
assert_eq!(locations[0].name, shop.name);
}
#[test]
fn test_with_name_query() {
let _lock = LOCK.lock().unwrap();
cleanup();
let (_, base, _) = setup_db();
let query: QueryBuilder<LocationDb> = QueryBuilder::new();
let query = query.with_name("Test Base");
let locations: Vec<LocationDb> = DB.run_query(query).unwrap();
assert_eq!(locations.len(), 1);
assert_eq!(locations[0].name, base.name);
}
#[test]
fn test_with_name_regex_query() {
let _lock = LOCK.lock().unwrap();
cleanup();
let (_, base, _) = setup_db();
let query: QueryBuilder<LocationDb> = QueryBuilder::new();
let query = query.with_name_regex("Test").unwrap();
let locations: Vec<LocationDb> = DB.run_query(query).unwrap();
assert_eq!(locations.len(), 2);
assert_eq!(locations[0].name, base.name);
}
}