diff --git a/src/cache.rs b/src/cache.rs index 305ef84..a36e089 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,6 +1,8 @@ use mongodb::{bson::doc, ClientSession}; -struct InventoryCache {} +use crate::get_mongo; + +pub struct InventoryCache {} impl InventoryCache { pub async fn push(uuid: &str, ses: &mut ClientSession) { @@ -21,6 +23,23 @@ impl InventoryCache { .unwrap(); } + pub async fn get() -> Vec { + let db = get_mongo!(); + let inventorycache = db + .database("cdb") + .collection::("cache") + .find_one(doc! {"_id": "inventory"}, None) + .await + .unwrap() + .unwrap(); + inventorycache + .get_array("transactions") + .unwrap() + .iter() + .map(|x| x.as_str().unwrap().to_string()) + .collect() + } + pub async fn remove(uuid: &str, ses: &mut ClientSession) { let update = doc! { "$pull": { "transactions": uuid}}; diff --git a/src/db.rs b/src/db.rs index 7d4f6e8..44517c6 100644 --- a/src/db.rs +++ b/src/db.rs @@ -39,11 +39,10 @@ macro_rules! id_of { pub struct ItemDB { index: mdq::Index, - mongodb: mongodb::Client, } impl ItemDB { - pub async fn new(dir: &str, mongodb: &str) -> Self { + pub async fn new(dir: &str) -> Self { // scan for markdown item entries let index = mdq::Index::new(dir, true); let mongodb = get_mongo!(); @@ -53,13 +52,12 @@ impl ItemDB { item.init_db(&mongodb).await; } - Self { index, mongodb } + Self { index } } /// Retrieves an item by name pub fn get_item(&self, item: &str) -> Option { Some(Item::new( - self.mongodb.clone(), self.index .documents .iter() diff --git a/src/item.rs b/src/item.rs index 3873378..710411f 100644 --- a/src/item.rs +++ b/src/item.rs @@ -1,8 +1,7 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; -use crate::{collect_results, id_of}; -use futures::TryStreamExt; -use mongodb::{bson::doc, ClientSession, Collection}; +use crate::id_of; +use mongodb::{bson::doc, Collection}; use crate::variant::Variant; @@ -16,18 +15,14 @@ use crate::variant::Variant; // DEMAND STATS // SEASONAL REVIEWS -#[derive(serde::Deserialize, serde::Serialize)] -pub struct ItemVariantEntry { - pub item_name: String, - pub variant_name: String, -} - -#[derive(serde::Deserialize, serde::Serialize)] -pub struct ItemInventoryEntry { - pub item_name: String, - pub variant_name: String, - pub origin: String, - pub price: f64, +fn hashmap_to_bson_document( + hashmap: HashMap, +) -> mongodb::bson::Document { + let mut document = mongodb::bson::Document::new(); + for (key, value) in hashmap { + document.insert(key, value); + } + document } pub struct ItemEntry { @@ -86,7 +81,8 @@ impl ItemEntry { let doc = mongodb::bson::doc! { "_id": self.name.clone(), "name": self.name.clone(), - "category": self.category.clone() + "category": self.category.clone(), + "variants": hashmap_to_bson_document(self.variants.iter().map(|x| (x.0.clone(), x.1.as_bson())).collect()) }; if items @@ -111,43 +107,12 @@ impl ItemEntry { /// a larger inventory or database of physical goods. It includes fields for /// the name of the item and its category. pub struct Item { - db: mongodb::Client, pub item: ItemEntry, } impl Item { - pub fn new(db: mongodb::Client, item: ItemEntry) -> Self { - Self { db, item } - } - - pub async fn get_inventory_entries(&self) -> Vec { - let quantities: Collection = - self.db.database("cdb").collection("item_quantities"); - - let mut found = quantities - .find(doc! { "item_name": self.item.name.clone()}, None) - .await - .unwrap(); - - collect_results!(found) - } - - pub async fn get_origins(&self) -> Vec { - let quantities: Collection = - self.db.database("cdb").collection("item_quantities"); - - let mut found = quantities - .find(doc! { "item_name": self.item.name.clone()}, None) - .await - .unwrap(); - - let mut hashset = HashSet::new(); - - while let Some(res) = found.try_next().await.unwrap() { - hashset.insert(res.origin); - } - - hashset.into_iter().collect() + pub fn new(item: ItemEntry) -> Self { + Self { item } } pub async fn get_variants(&self) -> Vec { diff --git a/src/main.rs b/src/main.rs index 0863f05..0481d66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ use actix_web::{get, HttpRequest, Responder}; -use maud::html; mod cache; mod db; @@ -34,7 +33,7 @@ pub(crate) async fn index(r: HttpRequest) -> impl Responder { async fn main() -> std::io::Result<()> { env_logger::init(); - let itemdb = db::ItemDB::new("./itemdb", "mongodb://user:pass@127.0.0.1:27017").await; + let itemdb = db::ItemDB::new("./itemdb").await; let itemdb = actix_web::web::Data::new(itemdb); web_base::map!(web_base::Site::new(), |app: actix_web::App<_>| { diff --git a/src/variant.rs b/src/variant.rs index 6ceb409..c59b1f6 100644 --- a/src/variant.rs +++ b/src/variant.rs @@ -1,6 +1,7 @@ use mongodb::bson::doc; use crate::{ + cache::InventoryCache, cdb_col, get_mongo, transaction::{BatchTransaction, Price, Transaction}, }; @@ -16,6 +17,7 @@ pub struct Variant { pub item: String, pub variant: String, pub amount: u64, + pub depends: Vec, } impl Variant { @@ -29,6 +31,18 @@ impl Variant { .get("amount") .map(|x| x.as_u64().unwrap()) .unwrap_or(1), + depends: json + .as_mapping() + .unwrap() + .get("depends") + .map(|x| { + x.as_sequence() + .unwrap() + .into_iter() + .map(|x| x.as_str().unwrap().to_string()) + .collect() + }) + .unwrap_or(Vec::new()), } } @@ -100,6 +114,9 @@ impl Variant { .insert_one_with_session(transaction.as_doc(), None, &mut ses) .await .unwrap(); + + // update cache + InventoryCache::push(&transaction.uuid, &mut ses).await; } // batch transaction @@ -118,10 +135,17 @@ impl Variant { batch.uuid }; - // todo : transaction overlap cache -> scale - ses.commit_transaction().await.unwrap(); ret_uuid } + + pub fn as_bson(&self) -> mongodb::bson::Document { + mongodb::bson::doc! { + "item": &self.item, + "variant": &self.variant, + "amount": self.amount as u32, + "depends": &self.depends + } + } }