use crate::database::Database; use crate::migration::Migration; use geoffrey_models::models::locations::LocationDb; use geoffrey_models::GeoffreyDatabaseModel; pub(crate) struct OutOfStockVoting {} impl Migration for OutOfStockVoting { 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(); 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()); } } loc_tree.insert(id, loc.to_string().as_bytes()).unwrap(); } 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(); 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() } } loc_tree.insert(id, loc.to_string().as_bytes()).unwrap(); } Ok(()) } fn version() -> u64 { 2 } } #[cfg(test)] mod tests { use crate::database::Database; use crate::migration::migration_4::OutOfStockVoting; 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_4() { let db = Database::new(Path::new("../migration_4_db/"), false).unwrap(); let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap(); let old_shop = json::parse( r#"{ "id": 55, "name": "Test", "owners": [0], "position": { "x": 55, "y": 55, "z": 55, "dimension": "Overworld" }, "portal": { "x": 8, "z": 8 }, "loc_data": { "Shop": { "item_listings": [ { "item": {"name": "sed"}, "price": 5, "count_per_price": 10, "restocked_time": "2021-12-26T17:47:10+00:00" } ] } } }"#, ) .unwrap(); let old_base = json::parse( r#"{ "id": 55, "name": "Test", "owners": [0], "position": { "x": 55, "y": 55, "z": 55, "dimension": "Overworld" }, "portal": { "x": 8, "z": 8 }, "loc_data": "Base" }"#, ) .unwrap(); loc_tree .insert(IVec::from(vec![55]), old_shop.to_string().as_bytes()) .unwrap(); loc_tree .insert(IVec::from(vec![64]), old_base.to_string().as_bytes()) .unwrap(); OutOfStockVoting::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(); println!("{}", new_loc); assert!(new_loc["loc_data"]["Shop"]["item_listings"][0]["out_of_stock_votes"].is_array()); drop(db); std::fs::remove_dir_all("../migration_4_db").unwrap(); } }