From 99cb470e6e6f12c41b9f2c71582b4e18bbc98eb9 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Thu, 6 Jan 2022 19:26:14 -0700 Subject: [PATCH] Added forced migration option + Useful when u h*ck up like me --- geoffrey_api/src/commands/selling.rs | 3 ++- geoffrey_api/src/context.rs | 6 +++--- geoffrey_api/src/main.rs | 19 ++++++++++++++----- geoffrey_db/src/database.rs | 11 ++++++++--- geoffrey_db/src/lib.rs | 2 +- geoffrey_db/src/migration/migration_2.rs | 2 +- geoffrey_db/src/migration/migration_3.rs | 2 +- geoffrey_db/src/migration/migration_4.rs | 9 +++++---- geoffrey_db/src/migration/mod.rs | 4 ++-- geoffrey_models/src/logging/mod.rs | 8 +++++++- 10 files changed, 44 insertions(+), 22 deletions(-) diff --git a/geoffrey_api/src/commands/selling.rs b/geoffrey_api/src/commands/selling.rs index 6ee9a1a..8e3d49c 100644 --- a/geoffrey_api/src/commands/selling.rs +++ b/geoffrey_api/src/commands/selling.rs @@ -103,6 +103,7 @@ mod test { use crate::commands::Command; use crate::config::GeoffreyAPIConfig; use crate::context::Context; + use crate::Args; use geoffrey_models::models::item::ItemListing; use geoffrey_models::models::locations::shop::Shop; use geoffrey_models::models::locations::{LocationDataDb, LocationDb}; @@ -118,7 +119,7 @@ mod test { max_str_len: 64, }; - let ctx = Context::new(config.clone()).unwrap(); + let ctx = Context::new(config.clone(), Args::default()).unwrap(); let mut shop_data = Shop::default(); diff --git a/geoffrey_api/src/context.rs b/geoffrey_api/src/context.rs index 9174762..0d5a487 100644 --- a/geoffrey_api/src/context.rs +++ b/geoffrey_api/src/context.rs @@ -1,5 +1,5 @@ use crate::config::GeoffreyAPIConfig; -use crate::Result; +use crate::{Args, Result}; use geoffrey_db::database::Database; use std::sync::Arc; @@ -9,9 +9,9 @@ pub struct Context { } impl Context { - pub fn new(cfg: GeoffreyAPIConfig) -> Result> { + pub fn new(cfg: GeoffreyAPIConfig, args: Args) -> Result> { let ctx = Self { - db: Database::new(cfg.db_path.as_path()).unwrap(), + db: Database::new(cfg.db_path.as_path(), args.force_migration).unwrap(), cfg, }; diff --git a/geoffrey_api/src/main.rs b/geoffrey_api/src/main.rs index c44efb1..4904cce 100644 --- a/geoffrey_api/src/main.rs +++ b/geoffrey_api/src/main.rs @@ -25,9 +25,9 @@ mod logging; pub type Result = std::result::Result; -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt, Clone, Default)] #[structopt(name = "GeoffreyAPI", about = "Geoffrey Central API")] -struct Args { +pub struct Args { #[structopt(env = "GEOFFREY_CONFIG", parse(from_os_str))] config: PathBuf, #[structopt( @@ -39,18 +39,27 @@ struct Args { )] log_level: LogLevel, + #[structopt(short, long)] + force_migration: bool, + #[structopt(subcommand)] command: GeoffreyApiCommand, } #[derive(Debug, PartialEq, StructOpt, Clone)] -enum GeoffreyApiCommand { +pub enum GeoffreyApiCommand { Run, CreateAdminToken(CreateTokenCommand), } +impl Default for GeoffreyApiCommand { + fn default() -> Self { + Self::Run + } +} + #[derive(Debug, StructOpt, PartialEq, Clone)] -struct CreateTokenCommand { +pub struct CreateTokenCommand { #[structopt(parse(try_from_str = Permissions::try_from))] pub permissions: Vec, } @@ -98,7 +107,7 @@ async fn main() { } }; - let ctx = Context::new(cfg).unwrap(); + let ctx = Context::new(cfg, args.clone()).unwrap(); match args.command { GeoffreyApiCommand::Run => run_server(ctx).await, diff --git a/geoffrey_db/src/database.rs b/geoffrey_db/src/database.rs index 4040d60..c193b8c 100644 --- a/geoffrey_db/src/database.rs +++ b/geoffrey_db/src/database.rs @@ -24,9 +24,14 @@ pub struct Database { } impl Database { - pub fn new(db_path: &Path) -> Result { + pub fn new(db_path: &Path, force_migration: bool) -> Result { let db = sled::open(db_path)?; - let db = Self { db }; + let mut db = Self { db }; + let ver = db.version().unwrap_or(0); + + if force_migration && ver > 0 { + db.set_version(ver - 1)?; + } do_migration(&db, DB_VERSION)?; @@ -168,7 +173,7 @@ impl Database { } pub(crate) fn set_version(&mut self, version: u64) -> Result<()> { - let mut md = self.get::(0)?; + let mut md = self.get::(DB_METADATA_ID)?; md.version = version; diff --git a/geoffrey_db/src/lib.rs b/geoffrey_db/src/lib.rs index 0f40950..32d269f 100644 --- a/geoffrey_db/src/lib.rs +++ b/geoffrey_db/src/lib.rs @@ -16,7 +16,7 @@ mod test { use std::sync::Mutex; lazy_static! { - pub static ref DB: Database = Database::new(Path::new("../test_database")).unwrap(); + pub static ref DB: Database = Database::new(Path::new("../test_database"), false).unwrap(); pub static ref LOCK: Mutex<()> = Mutex::default(); } diff --git a/geoffrey_db/src/migration/migration_2.rs b/geoffrey_db/src/migration/migration_2.rs index a7f252e..2759424 100644 --- a/geoffrey_db/src/migration/migration_2.rs +++ b/geoffrey_db/src/migration/migration_2.rs @@ -63,7 +63,7 @@ mod tests { #[test] fn test_migration_2() { - let db = Database::new(Path::new("../migration_2_db/")).unwrap(); + let db = Database::new(Path::new("../migration_2_db/"), false).unwrap(); let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap(); diff --git a/geoffrey_db/src/migration/migration_3.rs b/geoffrey_db/src/migration/migration_3.rs index 0da862e..41a569b 100644 --- a/geoffrey_db/src/migration/migration_3.rs +++ b/geoffrey_db/src/migration/migration_3.rs @@ -57,7 +57,7 @@ mod tests { #[test] fn test_migration_3() { - let db = Database::new(Path::new("../migration_3_db/")).unwrap(); + let db = Database::new(Path::new("../migration_3_db/"), false).unwrap(); let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap(); diff --git a/geoffrey_db/src/migration/migration_4.rs b/geoffrey_db/src/migration/migration_4.rs index ddaaf3a..5d8ba01 100644 --- a/geoffrey_db/src/migration/migration_4.rs +++ b/geoffrey_db/src/migration/migration_4.rs @@ -13,7 +13,7 @@ impl Migration for OutOfStockVoting { let (id, loc_ivec) = entry?; let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap(); - if !loc["loc_data"]["shop"].is_empty() { + if !loc["loc_data"]["Shop"].is_empty() { for item in loc["loc_data"]["Shop"]["item_listings"].members_mut() { item["out_of_stock_votes"] = json::JsonValue::Array(Vec::new()); } @@ -32,7 +32,7 @@ impl Migration for OutOfStockVoting { let (id, loc_ivec) = entry?; let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap(); - if !loc["loc_data"]["shop"].is_empty() { + if !loc["loc_data"]["Shop"].is_empty() { for item in &mut loc["loc_data"]["Shop"]["item_listings"].members_mut() { item["out_of_stock_votes"].clear() } @@ -61,7 +61,7 @@ mod tests { #[test] fn test_migration_4() { - let db = Database::new(Path::new("../migration_4_db/")).unwrap(); + let db = Database::new(Path::new("../migration_4_db/"), false).unwrap(); let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap(); @@ -130,7 +130,8 @@ mod tests { let new_loc = json::parse(std::str::from_utf8(&new_loc).unwrap()).unwrap(); - assert_eq!(new_loc["loc_data"]["Shop"]["out_of_stock_votes"].len(), 0); + println!("{}", new_loc); + assert!(new_loc["loc_data"]["Shop"]["item_listings"][0]["out_of_stock_votes"].is_array()); drop(db); diff --git a/geoffrey_db/src/migration/mod.rs b/geoffrey_db/src/migration/mod.rs index 4e78d58..030a8f7 100644 --- a/geoffrey_db/src/migration/mod.rs +++ b/geoffrey_db/src/migration/mod.rs @@ -15,7 +15,7 @@ trait Migration { fn version() -> u64; } -fn upgrade(db: &Database, current_version: u64, target_version: u64) -> Result<()> { +pub(crate) fn upgrade(db: &Database, current_version: u64, target_version: u64) -> Result<()> { for ver in current_version + 1..=target_version { match ver { 2 => PosAndNetherMigration::up(db)?, @@ -28,7 +28,7 @@ fn upgrade(db: &Database, current_version: u64, target_version: u64) -> Result<( Ok(()) } -fn downgrade(db: &Database, current_version: u64, target_version: u64) -> Result<()> { +pub(crate) fn downgrade(db: &Database, current_version: u64, target_version: u64) -> Result<()> { for ver in (target_version..current_version).rev() { match ver { 2 => PosAndNetherMigration::down(db)?, diff --git a/geoffrey_models/src/logging/mod.rs b/geoffrey_models/src/logging/mod.rs index 4373de0..c508d07 100644 --- a/geoffrey_models/src/logging/mod.rs +++ b/geoffrey_models/src/logging/mod.rs @@ -1,7 +1,7 @@ use log::LevelFilter; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Copy)] pub enum LogLevel { None, Warn, @@ -9,6 +9,12 @@ pub enum LogLevel { Debug, } +impl Default for LogLevel { + fn default() -> Self { + Self::Info + } +} + impl From<&str> for LogLevel { #[allow(clippy::wildcard_in_or_patterns)] fn from(s: &str) -> Self {