Added forced migration option
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
+ Useful when u h*ck up like memain
parent
51d6ffb7be
commit
99cb470e6e
|
@ -103,6 +103,7 @@ mod test {
|
||||||
use crate::commands::Command;
|
use crate::commands::Command;
|
||||||
use crate::config::GeoffreyAPIConfig;
|
use crate::config::GeoffreyAPIConfig;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::Args;
|
||||||
use geoffrey_models::models::item::ItemListing;
|
use geoffrey_models::models::item::ItemListing;
|
||||||
use geoffrey_models::models::locations::shop::Shop;
|
use geoffrey_models::models::locations::shop::Shop;
|
||||||
use geoffrey_models::models::locations::{LocationDataDb, LocationDb};
|
use geoffrey_models::models::locations::{LocationDataDb, LocationDb};
|
||||||
|
@ -118,7 +119,7 @@ mod test {
|
||||||
max_str_len: 64,
|
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();
|
let mut shop_data = Shop::default();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::config::GeoffreyAPIConfig;
|
use crate::config::GeoffreyAPIConfig;
|
||||||
use crate::Result;
|
use crate::{Args, Result};
|
||||||
use geoffrey_db::database::Database;
|
use geoffrey_db::database::Database;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ pub struct Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new(cfg: GeoffreyAPIConfig) -> Result<Arc<Self>> {
|
pub fn new(cfg: GeoffreyAPIConfig, args: Args) -> Result<Arc<Self>> {
|
||||||
let ctx = 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,
|
cfg,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,9 @@ mod logging;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, GeoffreyAPIError>;
|
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")]
|
#[structopt(name = "GeoffreyAPI", about = "Geoffrey Central API")]
|
||||||
struct Args {
|
pub struct Args {
|
||||||
#[structopt(env = "GEOFFREY_CONFIG", parse(from_os_str))]
|
#[structopt(env = "GEOFFREY_CONFIG", parse(from_os_str))]
|
||||||
config: PathBuf,
|
config: PathBuf,
|
||||||
#[structopt(
|
#[structopt(
|
||||||
|
@ -39,18 +39,27 @@ struct Args {
|
||||||
)]
|
)]
|
||||||
log_level: LogLevel,
|
log_level: LogLevel,
|
||||||
|
|
||||||
|
#[structopt(short, long)]
|
||||||
|
force_migration: bool,
|
||||||
|
|
||||||
#[structopt(subcommand)]
|
#[structopt(subcommand)]
|
||||||
command: GeoffreyApiCommand,
|
command: GeoffreyApiCommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, StructOpt, Clone)]
|
#[derive(Debug, PartialEq, StructOpt, Clone)]
|
||||||
enum GeoffreyApiCommand {
|
pub enum GeoffreyApiCommand {
|
||||||
Run,
|
Run,
|
||||||
CreateAdminToken(CreateTokenCommand),
|
CreateAdminToken(CreateTokenCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for GeoffreyApiCommand {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Run
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, StructOpt, PartialEq, Clone)]
|
#[derive(Debug, StructOpt, PartialEq, Clone)]
|
||||||
struct CreateTokenCommand {
|
pub struct CreateTokenCommand {
|
||||||
#[structopt(parse(try_from_str = Permissions::try_from))]
|
#[structopt(parse(try_from_str = Permissions::try_from))]
|
||||||
pub permissions: Vec<Permissions>,
|
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 {
|
match args.command {
|
||||||
GeoffreyApiCommand::Run => run_server(ctx).await,
|
GeoffreyApiCommand::Run => run_server(ctx).await,
|
||||||
|
|
|
@ -24,9 +24,14 @@ pub struct Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 = 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)?;
|
do_migration(&db, DB_VERSION)?;
|
||||||
|
|
||||||
|
@ -168,7 +173,7 @@ impl Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_version(&mut self, version: u64) -> Result<()> {
|
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;
|
md.version = version;
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ mod test {
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
lazy_static! {
|
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();
|
pub static ref LOCK: Mutex<()> = Mutex::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_migration_2() {
|
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();
|
let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_migration_3() {
|
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();
|
let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ impl Migration for OutOfStockVoting {
|
||||||
let (id, loc_ivec) = entry?;
|
let (id, loc_ivec) = entry?;
|
||||||
let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap();
|
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() {
|
for item in loc["loc_data"]["Shop"]["item_listings"].members_mut() {
|
||||||
item["out_of_stock_votes"] = json::JsonValue::Array(Vec::new());
|
item["out_of_stock_votes"] = json::JsonValue::Array(Vec::new());
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ impl Migration for OutOfStockVoting {
|
||||||
let (id, loc_ivec) = entry?;
|
let (id, loc_ivec) = entry?;
|
||||||
let mut loc = json::parse(std::str::from_utf8(&loc_ivec).unwrap()).unwrap();
|
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() {
|
for item in &mut loc["loc_data"]["Shop"]["item_listings"].members_mut() {
|
||||||
item["out_of_stock_votes"].clear()
|
item["out_of_stock_votes"].clear()
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_migration_4() {
|
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();
|
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();
|
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);
|
drop(db);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ trait Migration {
|
||||||
fn version() -> u64;
|
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 {
|
for ver in current_version + 1..=target_version {
|
||||||
match ver {
|
match ver {
|
||||||
2 => PosAndNetherMigration::up(db)?,
|
2 => PosAndNetherMigration::up(db)?,
|
||||||
|
@ -28,7 +28,7 @@ fn upgrade(db: &Database, current_version: u64, target_version: u64) -> Result<(
|
||||||
Ok(())
|
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() {
|
for ver in (target_version..current_version).rev() {
|
||||||
match ver {
|
match ver {
|
||||||
2 => PosAndNetherMigration::down(db)?,
|
2 => PosAndNetherMigration::down(db)?,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
|
||||||
pub enum LogLevel {
|
pub enum LogLevel {
|
||||||
None,
|
None,
|
||||||
Warn,
|
Warn,
|
||||||
|
@ -9,6 +9,12 @@ pub enum LogLevel {
|
||||||
Debug,
|
Debug,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for LogLevel {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&str> for LogLevel {
|
impl From<&str> for LogLevel {
|
||||||
#[allow(clippy::wildcard_in_or_patterns)]
|
#[allow(clippy::wildcard_in_or_patterns)]
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
|
|
Loading…
Reference in New Issue