Added `out_of_stock_votes` to ItemListing
continuous-integration/woodpecker the build was successful
Details
continuous-integration/woodpecker the build was successful
Details
+ Records a list of player ids that reported an item as empty + Re-did item hash implementation so multiple items can have the same name + Bumped DB version to 4 + fmt + clippymain
parent
29a4cd3eb6
commit
ec8926d693
|
@ -6,7 +6,7 @@ use sled::IVec;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
const DB_VERSION: u64 = 3;
|
const DB_VERSION: u64 = 4;
|
||||||
const DB_METADATA_ID: u64 = 1;
|
const DB_METADATA_ID: u64 = 1;
|
||||||
|
|
||||||
fn option_bytes_to_model<T: GeoffreyDatabaseModel>(bytes: Option<IVec>, id: u64) -> Result<T> {
|
fn option_bytes_to_model<T: GeoffreyDatabaseModel>(bytes: Option<IVec>, id: u64) -> Result<T> {
|
||||||
|
|
|
@ -21,8 +21,6 @@ impl Migration for PosAndNetherMigration {
|
||||||
|
|
||||||
loc["tunnel"] = JsonValue::Null;
|
loc["tunnel"] = JsonValue::Null;
|
||||||
|
|
||||||
println!("{}", loc.dump());
|
|
||||||
|
|
||||||
loc_tree.insert(id, loc.to_string().as_bytes())?;
|
loc_tree.insert(id, loc.to_string().as_bytes())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ mod tests {
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_migration_2() {
|
fn test_migration_3() {
|
||||||
let db = Database::new(Path::new("../migration_3_db/")).unwrap();
|
let db = Database::new(Path::new("../migration_3_db/")).unwrap();
|
||||||
|
|
||||||
let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap();
|
let loc_tree = db.db.open_tree(LocationDb::tree()).unwrap();
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
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();
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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/")).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();
|
||||||
|
|
||||||
|
assert_eq!(new_loc["loc_data"]["Shop"]["out_of_stock_votes"].len(), 0);
|
||||||
|
|
||||||
|
drop(db);
|
||||||
|
|
||||||
|
std::fs::remove_dir_all("../migration_4_db").unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,10 +2,12 @@ use crate::database::Database;
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::migration::migration_2::PosAndNetherMigration;
|
use crate::migration::migration_2::PosAndNetherMigration;
|
||||||
use crate::migration::migration_3::TunnelToPortalMigration;
|
use crate::migration::migration_3::TunnelToPortalMigration;
|
||||||
|
use crate::migration::migration_4::OutOfStockVoting;
|
||||||
use geoffrey_models::models::db_metadata::DBMetadata;
|
use geoffrey_models::models::db_metadata::DBMetadata;
|
||||||
|
|
||||||
mod migration_2;
|
mod migration_2;
|
||||||
mod migration_3;
|
mod migration_3;
|
||||||
|
mod migration_4;
|
||||||
|
|
||||||
trait Migration {
|
trait Migration {
|
||||||
fn up(db: &Database) -> Result<()>;
|
fn up(db: &Database) -> Result<()>;
|
||||||
|
@ -18,6 +20,7 @@ fn upgrade(db: &Database, current_version: u64, target_version: u64) -> Result<(
|
||||||
match ver {
|
match ver {
|
||||||
2 => PosAndNetherMigration::up(db)?,
|
2 => PosAndNetherMigration::up(db)?,
|
||||||
3 => TunnelToPortalMigration::up(db)?,
|
3 => TunnelToPortalMigration::up(db)?,
|
||||||
|
4 => OutOfStockVoting::up(db)?,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +33,7 @@ fn downgrade(db: &Database, current_version: u64, target_version: u64) -> Result
|
||||||
match ver {
|
match ver {
|
||||||
2 => PosAndNetherMigration::down(db)?,
|
2 => PosAndNetherMigration::down(db)?,
|
||||||
3 => TunnelToPortalMigration::down(db)?,
|
3 => TunnelToPortalMigration::down(db)?,
|
||||||
|
4 => OutOfStockVoting::down(db)?,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq)]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
|
@ -15,12 +17,13 @@ impl Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct ItemListing {
|
pub struct ItemListing {
|
||||||
pub item: Item,
|
pub item: Item,
|
||||||
pub price: u32,
|
pub price: u32,
|
||||||
pub count_per_price: u32,
|
pub count_per_price: u32,
|
||||||
pub restocked_time: DateTime<Utc>,
|
pub restocked_time: DateTime<Utc>,
|
||||||
|
pub out_of_stock_votes: HashSet<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemListing {
|
impl ItemListing {
|
||||||
|
@ -32,6 +35,7 @@ impl ItemListing {
|
||||||
price,
|
price,
|
||||||
count_per_price,
|
count_per_price,
|
||||||
restocked_time: Utc::now(),
|
restocked_time: Utc::now(),
|
||||||
|
out_of_stock_votes: HashSet::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,4 +58,35 @@ impl ItemListing {
|
||||||
pub fn order_by_restock(a: &Self, b: &Self) -> Ordering {
|
pub fn order_by_restock(a: &Self, b: &Self) -> Ordering {
|
||||||
a.restocked_time.cmp(&b.restocked_time)
|
a.restocked_time.cmp(&b.restocked_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn report_out_of_stock(&mut self, id: u64) {
|
||||||
|
self.out_of_stock_votes.insert(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_out_of_stock(&self, report_limit: u32) -> bool {
|
||||||
|
self.out_of_stock_votes.len() > report_limit as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn restock(&mut self) {
|
||||||
|
self.restocked_time = Utc::now();
|
||||||
|
self.out_of_stock_votes.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Hash for ItemListing {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.item.name.hash(state);
|
||||||
|
self.price.hash(state);
|
||||||
|
self.count_per_price.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq<Self> for ItemListing {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
(self.item.name == other.item.name)
|
||||||
|
&& (self.price == other.price)
|
||||||
|
&& (self.count_per_price == other.count_per_price)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for ItemListing {}
|
||||||
|
|
Loading…
Reference in New Issue