From 51d165a50b16e0a06d29dcee25b7996748bc5bd3 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Fri, 12 Jul 2024 17:43:05 -0400 Subject: [PATCH] dev: indexeddb indexes on recipe category and serving_count --- kitchen/src/web/storage/file_store.rs | 14 ++++++------- kitchen/src/web/storage/mod.rs | 24 ++++++++++----------- recipes/src/lib.rs | 30 ++++++++++++++++++--------- web/src/components/add_recipe.rs | 10 ++++----- web/src/components/recipe.rs | 10 ++++----- web/src/js_lib.rs | 9 ++++++-- 6 files changed, 56 insertions(+), 41 deletions(-) diff --git a/kitchen/src/web/storage/file_store.rs b/kitchen/src/web/storage/file_store.rs index b7d23dc..f63758c 100644 --- a/kitchen/src/web/storage/file_store.rs +++ b/kitchen/src/web/storage/file_store.rs @@ -99,7 +99,7 @@ impl AsyncFileStore { let file_name = entry.file_name().to_string_lossy().to_string(); debug!("adding recipe file {}", file_name); let recipe_contents = read_to_string(entry.path()).await?; - entry_vec.push(RecipeEntry(file_name, recipe_contents, None, None)); + entry_vec.push(RecipeEntry::new(file_name, recipe_contents)); } else { warn!( file = %entry.path().to_string_lossy(), @@ -119,12 +119,12 @@ impl AsyncFileStore { if recipe_path.exists().await && recipe_path.is_file().await { debug!("Found recipe file {}", recipe_path.to_string_lossy()); let recipe_contents = read_to_string(recipe_path).await?; - return Ok(Some(RecipeEntry( - id.as_ref().to_owned(), - recipe_contents, - None, - None, - ))); + return Ok(Some(RecipeEntry { + id: id.as_ref().to_owned(), + text: recipe_contents, + category: None, + serving_count: None, + })); } else { return Ok(None); } diff --git a/kitchen/src/web/storage/mod.rs b/kitchen/src/web/storage/mod.rs index 17f21ba..2d04159 100644 --- a/kitchen/src/web/storage/mod.rs +++ b/kitchen/src/web/storage/mod.rs @@ -440,12 +440,12 @@ impl APIStore for SqliteStore { .await? .iter() .map(|row| { - RecipeEntry( - row.recipe_id.clone(), - row.recipe_text.clone().unwrap_or_else(|| String::new()), - row.category.clone(), - row.serving_count.clone(), - ) + RecipeEntry { + id: row.recipe_id.clone(), + text: row.recipe_text.clone().unwrap_or_else(|| String::new()), + category: row.category.clone(), + serving_count: row.serving_count.clone(), + } }) .nth(0); Ok(entry) @@ -460,12 +460,12 @@ impl APIStore for SqliteStore { .await? .iter() .map(|row| { - RecipeEntry( - row.recipe_id.clone(), - row.recipe_text.clone().unwrap_or_else(|| String::new()), - row.category.clone(), - row.serving_count.clone(), - ) + RecipeEntry { + id: row.recipe_id.clone(), + text: row.recipe_text.clone().unwrap_or_else(|| String::new()), + category: row.category.clone(), + serving_count: row.serving_count.clone(), + } }) .collect(); Ok(Some(rows)) diff --git a/recipes/src/lib.rs b/recipes/src/lib.rs index db9f61e..fd291ef 100644 --- a/recipes/src/lib.rs +++ b/recipes/src/lib.rs @@ -50,39 +50,49 @@ impl Mealplan { } #[derive(Serialize, Deserialize, Clone, Debug)] -pub struct RecipeEntry(pub String, pub String, pub Option, pub Option); +pub struct RecipeEntry { + pub id: String, + pub text: String, + pub category: Option, + pub serving_count: Option, +} impl RecipeEntry { pub fn new, TS: Into>(recipe_id: IS, text: TS) -> Self { - Self(recipe_id.into(), text.into(), None, None) + Self { + id: recipe_id.into(), + text: text.into(), + category: None, + serving_count: None, + } } pub fn set_recipe_id>(&mut self, id: S) { - self.0 = id.into(); + self.id = id.into(); } pub fn recipe_id(&self) -> &str { - self.0.as_str() + self.id.as_str() } pub fn set_recipe_text>(&mut self, text: S) { - self.1 = text.into(); + self.text = text.into(); } pub fn recipe_text(&self) -> &str { - self.1.as_str() + self.text.as_str() } pub fn set_category>(&mut self, cat: S) { - self.2 = Some(cat.into()); + self.category = Some(cat.into()); } pub fn category(&self) -> Option<&String> { - self.2.as_ref() + self.category.as_ref() } - + pub fn serving_count(&self) -> Option { - self.3.clone() + self.serving_count.clone() } } diff --git a/web/src/components/add_recipe.rs b/web/src/components/add_recipe.rs index b8ff672..25a4e17 100644 --- a/web/src/components/add_recipe.rs +++ b/web/src/components/add_recipe.rs @@ -42,19 +42,19 @@ pub fn AddRecipe<'ctx, G: Html>(cx: Scope<'ctx>, sh: StateHandler<'ctx>) -> View } else { Some(category) }; - RecipeEntry( - recipe_title + RecipeEntry { + id: recipe_title .get() .as_ref() .to_lowercase() .replace(" ", "_") .replace("\n", ""), - STARTER_RECIPE + text: STARTER_RECIPE .replace("TITLE_PLACEHOLDER", recipe_title.get().as_str()) .replace("\r", ""), category, - None, - ) + serving_count: None, + } }); view! {cx, diff --git a/web/src/components/recipe.rs b/web/src/components/recipe.rs index e87b3bd..9ccb4a8 100644 --- a/web/src/components/recipe.rs +++ b/web/src/components/recipe.rs @@ -115,12 +115,12 @@ pub fn Editor<'ctx, G: Html>(cx: Scope<'ctx>, props: RecipeComponentProps<'ctx>) } else { Some(category.as_ref().clone()) }; - let recipe_entry = RecipeEntry( - id.get_untracked().as_ref().clone(), - text.get_untracked().as_ref().clone(), + let recipe_entry = RecipeEntry { + id: id.get_untracked().as_ref().clone(), + text: text.get_untracked().as_ref().clone(), category, - None, - ); + serving_count: None, + }; sh.dispatch(cx, Message::SaveRecipe(recipe_entry, None)); dirty.set(false); } diff --git a/web/src/js_lib.rs b/web/src/js_lib.rs index 817d462..8fec53c 100644 --- a/web/src/js_lib.rs +++ b/web/src/js_lib.rs @@ -27,6 +27,8 @@ pub fn get_storage() -> web_sys::Storage { pub const STATE_STORE_NAME: &'static str = "state-store"; pub const RECIPE_STORE_NAME: &'static str = "recipe-store"; +pub const SERVING_COUNT_IDX: &'static str = "recipe-serving-count"; +pub const CATEGORY_IDX: &'static str = "recipe-category"; pub const DB_VERSION: u32 = 1; #[derive(Clone, Debug)] @@ -52,8 +54,11 @@ impl<'name> DBFactory<'name> { if db.version() == 1 { // We use out of line keys for this object store db.build_object_store(STATE_STORE_NAME).create()?; - db.build_object_store(RECIPE_STORE_NAME).create()?; - // TODO(jwall): Do we need indexes? + let recipe_store = db.build_object_store(RECIPE_STORE_NAME).create()?; + recipe_store.build_index(CATEGORY_IDX, "category") + .create()?; + recipe_store.build_index(SERVING_COUNT_IDX, "serving_count") + .create()?; } Ok(()) }).await.context(format!("Opening or creating the database {}", self.name))?;