Added forced migration option
ci/woodpecker/push/woodpecker Pipeline was successful Details

+ Useful when u h*ck up like me
main
Joey Hines 2022-01-06 19:26:14 -07:00
parent 51d6ffb7be
commit 99cb470e6e
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
10 changed files with 44 additions and 22 deletions

View File

@ -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();

View File

@ -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<Arc<Self>> {
pub fn new(cfg: GeoffreyAPIConfig, args: Args) -> Result<Arc<Self>> {
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,
};

View File

@ -25,9 +25,9 @@ mod logging;
pub type Result<T> = std::result::Result<T, GeoffreyAPIError>;
#[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<Permissions>,
}
@ -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,

View File

@ -24,9 +24,14 @@ pub struct Database {
}
impl Database {
pub fn new(db_path: &Path) -> Result<Self> {
pub fn new(db_path: &Path, force_migration: bool) -> Result<Self> {
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::<DBMetadata>(0)?;
let mut md = self.get::<DBMetadata>(DB_METADATA_ID)?;
md.version = version;

View File

@ -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();
}

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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)?,

View File

@ -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 {