Added set_portal to the API
+ Bumped DB version to 3 + Renamed "tunnel" to "portal" on the location models + Added a new migration + Cargo + Clippymain
parent
3b8c7fc60f
commit
199516f3cc
|
@ -426,6 +426,7 @@ dependencies = [
|
|||
"geoffrey_models",
|
||||
"log",
|
||||
"rand 0.8.4",
|
||||
"regex",
|
||||
"serde 1.0.130",
|
||||
"serde_json",
|
||||
"simple_logger",
|
||||
|
|
|
@ -18,3 +18,4 @@ structopt = "0.3.21"
|
|||
log = "0.4.14"
|
||||
simple_logger = "1.13.0"
|
||||
rand = "0.8.4"
|
||||
regex = "1.5.4"
|
|
@ -3,6 +3,7 @@ use crate::commands::add_location::AddLocation;
|
|||
use crate::commands::find::FindCommand;
|
||||
use crate::commands::register::Register;
|
||||
use crate::commands::selling::Selling;
|
||||
use crate::commands::set_portal::SetPortal;
|
||||
use crate::context::Context;
|
||||
use crate::helper::{get_player_from_req, get_token_from_req};
|
||||
use crate::Result;
|
||||
|
@ -25,6 +26,7 @@ pub mod add_token;
|
|||
pub mod find;
|
||||
pub mod register;
|
||||
pub mod selling;
|
||||
pub mod set_portal;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
|
@ -122,6 +124,7 @@ pub fn command_filter(
|
|||
.or(create_command_filter::<AddLocation>(ctx.clone()))
|
||||
.or(create_command_filter::<Register>(ctx.clone()))
|
||||
.or(create_command_filter::<Selling>(ctx.clone()))
|
||||
.or(create_command_filter::<AddItem>(ctx)),
|
||||
.or(create_command_filter::<AddItem>(ctx.clone()))
|
||||
.or(create_command_filter::<SetPortal>(ctx)),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ impl Command for Selling {
|
|||
listing: item.clone(),
|
||||
shop_name: shop.name.clone(),
|
||||
shop_loc: shop.position,
|
||||
portal: shop.tunnel.clone(),
|
||||
portal: shop.portal.clone(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
use crate::commands::{Command, RequestType};
|
||||
use crate::context::Context;
|
||||
use crate::Result;
|
||||
use geoffrey_db::helper::load_location;
|
||||
use geoffrey_models::models::locations::{Location, LocationDb};
|
||||
use geoffrey_models::models::parameters::set_portal_params::SetPortalParams;
|
||||
use geoffrey_models::models::player::Player;
|
||||
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||
use geoffrey_models::models::CommandLevel;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct SetPortal {}
|
||||
|
||||
impl Command for SetPortal {
|
||||
type Req = SetPortalParams;
|
||||
type Resp = Location;
|
||||
|
||||
fn command_name() -> String {
|
||||
"set_portal".to_string()
|
||||
}
|
||||
|
||||
fn request_type() -> RequestType {
|
||||
RequestType::POST
|
||||
}
|
||||
|
||||
fn command_level() -> CommandLevel {
|
||||
CommandLevel::REGISTERED
|
||||
}
|
||||
|
||||
fn run_command(ctx: Arc<Context>, req: Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
||||
let user = user.unwrap();
|
||||
let filter = regex::Regex::new(format!(r"(?i)^{}$", req.loc_name).as_str()).unwrap();
|
||||
|
||||
let mut location: LocationDb = ctx
|
||||
.db
|
||||
.filter(|_, loc: &LocationDb| {
|
||||
loc.owners().contains(&user.id.unwrap()) && filter.is_match(loc.name.as_str())
|
||||
})?
|
||||
.next()
|
||||
.ok_or(GeoffreyAPIError::EntryNotFound)?;
|
||||
|
||||
location.portal = Some(req.portal);
|
||||
|
||||
let location = ctx.db.insert(location)?;
|
||||
|
||||
load_location(&ctx.db, &location).map_err(|err| err.into())
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
use crate::error::{GeoffreyDBError, Result};
|
||||
use crate::migration::do_migration;
|
||||
use geoffrey_models::models::db_metadata::DBMetadata;
|
||||
use geoffrey_models::GeoffreyDatabaseModel;
|
||||
use std::convert::TryInto;
|
||||
use std::path::Path;
|
||||
use geoffrey_models::models::db_metadata::DBMetadata;
|
||||
use crate::migration::do_migration;
|
||||
|
||||
const DB_VERSION: u64 = 2;
|
||||
const DB_VERSION: u64 = 3;
|
||||
const DB_METADATA_ID: u64 = 1;
|
||||
|
||||
pub struct Database {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::migration::Migration;
|
||||
use crate::database::Database;
|
||||
use crate::migration::Migration;
|
||||
use geoffrey_models::models::locations::LocationDb;
|
||||
use geoffrey_models::GeoffreyDatabaseModel;
|
||||
use json::JsonValue;
|
||||
|
@ -46,7 +46,6 @@ impl Migration for PosAndNetherMigration {
|
|||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
||||
|
||||
fn version() -> u64 {
|
||||
|
@ -57,12 +56,12 @@ impl Migration for PosAndNetherMigration {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::database::Database;
|
||||
use std::path::Path;
|
||||
use crate::migration::migration_2::PosAndNetherMigration;
|
||||
use crate::migration::Migration;
|
||||
use geoffrey_models::models::locations::LocationDb;
|
||||
use geoffrey_models::GeoffreyDatabaseModel;
|
||||
use sled::IVec;
|
||||
use crate::migration::migration_2::PosAndNetherMigration;
|
||||
use crate::migration::Migration;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn test_migration_2() {
|
||||
|
@ -70,7 +69,8 @@ mod tests {
|
|||
|
||||
let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap();
|
||||
|
||||
let old_loc_format = json::parse(r#"{
|
||||
let old_loc_format = json::parse(
|
||||
r#"{
|
||||
"id": 55,
|
||||
"name": "Test",
|
||||
"position": {
|
||||
|
@ -79,9 +79,13 @@ mod tests {
|
|||
"dimension": "Overworld"
|
||||
},
|
||||
"loc_data": "Base"
|
||||
}"#).unwrap();
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
loc_tree.insert(IVec::from(vec![55]), old_loc_format.to_string().as_bytes()).unwrap();
|
||||
loc_tree
|
||||
.insert(IVec::from(vec![55]), old_loc_format.to_string().as_bytes())
|
||||
.unwrap();
|
||||
|
||||
PosAndNetherMigration::up(&db).unwrap();
|
||||
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
use crate::database::Database;
|
||||
use crate::migration::Migration;
|
||||
use geoffrey_models::models::locations::LocationDb;
|
||||
use geoffrey_models::GeoffreyDatabaseModel;
|
||||
|
||||
pub(crate) struct TunnelToPortalMigration {}
|
||||
|
||||
impl Migration for TunnelToPortalMigration {
|
||||
fn up(db: &Database) -> crate::error::Result<()> {
|
||||
let loc_tree = db.db.open_tree(LocationDb::tree())?;
|
||||
|
||||
for entry in loc_tree.iter() {
|
||||
let (id, loc_ivec) = entry?;
|
||||
let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap();
|
||||
|
||||
let tunnel = loc["tunnel"].clone();
|
||||
|
||||
loc["portal"] = tunnel;
|
||||
|
||||
loc_tree.insert(id, loc.to_string().as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn down(db: &Database) -> crate::error::Result<()> {
|
||||
let loc_tree = db.db.open_tree(LocationDb::tree())?;
|
||||
|
||||
for entry in loc_tree.iter() {
|
||||
let (id, loc_ivec) = entry?;
|
||||
let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap();
|
||||
|
||||
let portal = loc["portal"].clone();
|
||||
|
||||
loc["tunnel"] = portal;
|
||||
|
||||
loc_tree.insert(id, loc.to_string().as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn version() -> u64 {
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::database::Database;
|
||||
use crate::migration::migration_3::TunnelToPortalMigration;
|
||||
use crate::migration::Migration;
|
||||
use geoffrey_models::models::locations::LocationDb;
|
||||
use geoffrey_models::GeoffreyDatabaseModel;
|
||||
use sled::IVec;
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn test_migration_2() {
|
||||
let db = Database::new(Path::new("../migration_3_db/")).unwrap();
|
||||
|
||||
let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap();
|
||||
|
||||
let old_loc = json::parse(
|
||||
r#"{
|
||||
"id": 55,
|
||||
"name": "Test",
|
||||
"position": {
|
||||
"x": 55,
|
||||
"y": 55,
|
||||
"z": 55,
|
||||
"dimension": "Overworld"
|
||||
},
|
||||
"tunnel": {
|
||||
"x": 8,
|
||||
"z": 8
|
||||
},
|
||||
"loc_data": "Base"
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
loc_tree
|
||||
.insert(IVec::from(vec![55]), old_loc.to_string().as_bytes())
|
||||
.unwrap();
|
||||
|
||||
TunnelToPortalMigration::up(&db).unwrap();
|
||||
|
||||
let new_loc = loc_tree.get(IVec::from(vec![55])).unwrap().unwrap();
|
||||
let new_loc = json::parse(std::str::from_utf8(&new_loc).unwrap()).unwrap();
|
||||
|
||||
assert_eq!(new_loc["portal"]["x"], 8);
|
||||
assert_eq!(new_loc["portal"]["z"], 8);
|
||||
|
||||
drop(db);
|
||||
|
||||
std::fs::remove_dir_all("../migration_3_db").unwrap();
|
||||
}
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
use crate::database::Database;
|
||||
use crate::error::Result;
|
||||
use crate::migration::migration_2::PosAndNetherMigration;
|
||||
use crate::migration::migration_3::TunnelToPortalMigration;
|
||||
use geoffrey_models::models::db_metadata::DBMetadata;
|
||||
|
||||
mod migration_2;
|
||||
mod migration_3;
|
||||
|
||||
trait Migration {
|
||||
fn up(db: &Database) -> Result<()>;
|
||||
|
@ -12,10 +14,11 @@ trait Migration {
|
|||
}
|
||||
|
||||
fn upgrade(db: &Database, current_version: u64, target_version: u64) -> Result<()> {
|
||||
for ver in current_version+1..=target_version {
|
||||
for ver in current_version + 1..=target_version {
|
||||
match ver {
|
||||
2 => PosAndNetherMigration::up(db)?,
|
||||
_ => ()
|
||||
3 => TunnelToPortalMigration::up(db)?,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,8 +28,9 @@ fn upgrade(db: &Database, current_version: u64, target_version: u64) -> Result<(
|
|||
fn downgrade(db: &Database, current_version: u64, target_version: u64) -> Result<()> {
|
||||
for ver in (target_version..current_version).rev() {
|
||||
match ver {
|
||||
2 => PosAndNetherMigration::up(db)?,
|
||||
_ => ()
|
||||
2 => PosAndNetherMigration::down(db)?,
|
||||
3 => TunnelToPortalMigration::down(db)?,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,10 +40,10 @@ fn downgrade(db: &Database, current_version: u64, target_version: u64) -> Result
|
|||
pub fn do_migration(db: &Database, target_version: u64) -> Result<()> {
|
||||
let current_version = db.version().unwrap_or(0);
|
||||
|
||||
#[allow(clippy::comparison_chain)]
|
||||
if target_version > current_version {
|
||||
upgrade(db, current_version, target_version)?;
|
||||
}
|
||||
else if target_version < current_version {
|
||||
} else if target_version < current_version {
|
||||
downgrade(db, current_version, target_version)?;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ use std::fmt::Debug;
|
|||
|
||||
pub mod models;
|
||||
|
||||
|
||||
pub trait GeoffreyDatabaseModel: Serialize + DeserializeOwned + Debug {
|
||||
fn id(&self) -> Option<u64>;
|
||||
fn set_id(&mut self, id: u64);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use crate::GeoffreyDatabaseModel;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct DBMetadata {
|
||||
|
@ -17,5 +17,3 @@ impl GeoffreyDatabaseModel for DBMetadata {
|
|||
"DBMetadata".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::models::locations::market::{Market, MarketDb};
|
|||
use crate::models::locations::shop::Shop;
|
||||
use crate::models::locations::town::{Town, TownDb};
|
||||
use crate::models::player::Player;
|
||||
use crate::models::{Position, Portal};
|
||||
use crate::models::{Portal, Position};
|
||||
use crate::GeoffreyDatabaseModel;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
|
@ -111,7 +111,7 @@ pub struct LocationDb {
|
|||
pub name: String,
|
||||
pub position: Position,
|
||||
owners: HashSet<u64>,
|
||||
pub tunnel: Option<Portal>,
|
||||
pub portal: Option<Portal>,
|
||||
pub loc_data: LocationDataDb,
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ impl LocationDb {
|
|||
name: name.to_string(),
|
||||
position,
|
||||
owners,
|
||||
tunnel,
|
||||
portal: tunnel,
|
||||
loc_data: loc_type,
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ pub struct Location {
|
|||
pub name: String,
|
||||
pub position: Position,
|
||||
pub owners: Vec<Player>,
|
||||
pub tunnel: Option<Portal>,
|
||||
pub portal: Option<Portal>,
|
||||
pub loc_data: LocationData,
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ impl Location {
|
|||
name: location.name,
|
||||
position: location.position,
|
||||
owners,
|
||||
tunnel: location.tunnel,
|
||||
portal: location.portal,
|
||||
loc_data,
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ mod tests {
|
|||
);
|
||||
let l2 = LocationDb::new(
|
||||
"teSt",
|
||||
Position::new(0, 0, 0,Dimension::Overworld),
|
||||
Position::new(0, 0, 0, Dimension::Overworld),
|
||||
0u64,
|
||||
None,
|
||||
LocationDataDb::Base,
|
||||
|
|
|
@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||
use std::fmt::{Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub mod db_metadata;
|
||||
pub mod item;
|
||||
pub mod locations;
|
||||
pub mod meta;
|
||||
|
@ -9,7 +10,6 @@ pub mod parameters;
|
|||
pub mod player;
|
||||
pub mod response;
|
||||
pub mod token;
|
||||
pub mod db_metadata;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
|
||||
pub enum Dimension {
|
||||
|
@ -86,42 +86,38 @@ impl Position {
|
|||
|
||||
impl Display for Position {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "(x={}, y={}, z={}) {} ", self.x, self.y, self.z, self.dimension)
|
||||
write!(
|
||||
f,
|
||||
"(x={}, y={}, z={}) {} ",
|
||||
self.x, self.y, self.z, self.dimension
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Portal {
|
||||
x: i32,
|
||||
z: i32
|
||||
z: i32,
|
||||
}
|
||||
|
||||
impl Portal {
|
||||
pub fn new(x: i32, z: i32) -> Self {
|
||||
Self {
|
||||
x,
|
||||
z
|
||||
}
|
||||
Self { x, z }
|
||||
}
|
||||
|
||||
pub fn direction(&self) -> Direction {
|
||||
if self.x.abs() > self.z.abs() {
|
||||
if self.x < 0 {
|
||||
Direction::West
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Direction::East
|
||||
}
|
||||
}
|
||||
else {
|
||||
if self.z < 0 {
|
||||
} else if self.z < 0 {
|
||||
Direction::North
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Direction::South
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Ord, PartialOrd, Eq, Hash)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::models::locations::LocationType;
|
||||
use crate::models::parameters::CommandRequest;
|
||||
use crate::models::player::UserID;
|
||||
use crate::models::{Position, Portal};
|
||||
use crate::models::{Portal, Position};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
|
|
|
@ -4,6 +4,7 @@ pub mod add_token_params;
|
|||
pub mod find_params;
|
||||
pub mod register_params;
|
||||
pub mod selling_params;
|
||||
pub mod set_portal_params;
|
||||
|
||||
use crate::models::player::{Player, UserID};
|
||||
use crate::models::token::{Permissions, Token};
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
use crate::models::parameters::CommandRequest;
|
||||
use crate::models::player::UserID;
|
||||
use crate::models::Portal;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct SetPortalParams {
|
||||
pub token: String,
|
||||
pub user_id: UserID,
|
||||
pub loc_name: String,
|
||||
pub portal: Portal,
|
||||
}
|
||||
|
||||
impl SetPortalParams {
|
||||
pub fn new(loc_name: String, portal: Portal) -> Self {
|
||||
Self {
|
||||
token: Default::default(),
|
||||
user_id: Default::default(),
|
||||
loc_name,
|
||||
portal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandRequest for SetPortalParams {
|
||||
fn token(&self) -> String {
|
||||
self.token.clone()
|
||||
}
|
||||
|
||||
fn user_id(&self) -> Option<UserID> {
|
||||
Some(self.user_id.clone())
|
||||
}
|
||||
|
||||
fn set_user_id(&mut self, user_id: UserID) {
|
||||
self.user_id = user_id;
|
||||
}
|
||||
|
||||
fn set_token(&mut self, token: String) {
|
||||
self.token = token;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::models::item::ItemListing;
|
||||
use crate::models::{Position, Portal};
|
||||
use crate::models::{Portal, Position};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
|
|
Loading…
Reference in New Issue