dev: indexeddb indexes on recipe category and serving_count

This commit is contained in:
Jeremy Wall 2024-07-12 17:43:05 -04:00
parent 84cc2a2713
commit 51d165a50b
6 changed files with 56 additions and 41 deletions

View File

@ -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);
}

View File

@ -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))

View File

@ -50,39 +50,49 @@ impl Mealplan {
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct RecipeEntry(pub String, pub String, pub Option<String>, pub Option<i64>);
pub struct RecipeEntry {
pub id: String,
pub text: String,
pub category: Option<String>,
pub serving_count: Option<i64>,
}
impl RecipeEntry {
pub fn new<IS: Into<String>, TS: Into<String>>(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<S: Into<String>>(&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<S: Into<String>>(&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<S: Into<String>>(&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<i64> {
self.3.clone()
self.serving_count.clone()
}
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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))?;