From ed44e929f47d7cfba4c83feaf60e1b9aaa511e9b Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Fri, 12 Jul 2024 18:05:20 -0400 Subject: [PATCH] refactor: cleanup and make our upgrade logic more robust --- web/src/js_lib.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/web/src/js_lib.rs b/web/src/js_lib.rs index 8fec53c..a212c31 100644 --- a/web/src/js_lib.rs +++ b/web/src/js_lib.rs @@ -17,6 +17,7 @@ use web_sys::{window, Window}; use indexed_db::{self, Factory, Database, Transaction}; use anyhow::{Result, Context}; use std::future::Future; +use std::collections::HashSet; pub fn get_storage() -> web_sys::Storage { get_window() @@ -50,21 +51,31 @@ impl<'name> DBFactory<'name> { // NOTE(zaphar): This is the on upgradeneeded handler. It get's called on new databases or // database with an older version than the one we requested to build. let db = evt.database(); + let stores = db.object_store_names().into_iter().collect::>(); // NOTE(jwall): This needs to be somewhat clever in handling version upgrades. - if db.version() == 1 { - // We use out of line keys for this object store - db.build_object_store(STATE_STORE_NAME).create()?; - 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()?; + if db.version() > 0 { + self.version1_setup(&stores, db).await?; } Ok(()) }).await.context(format!("Opening or creating the database {}", self.name))?; Ok(db) } + async fn version1_setup<'db>(&self, stores: &HashSet, db: &'db Databse) -> std::result::Result<(), std::io::Error> { + // We use out of line keys for this object store + if !stores.contains(STATE_STORE_NAME) { + db.build_object_store(STATE_STORE_NAME).create()?; + } + if !stores.contains(RECIPE_STORE_NAME) { + 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(()) + } + pub async fn rw_transaction(&self, stores: &[&str], transaction: Fun) -> indexed_db::Result where Fun: 'static + FnOnce(Transaction) -> RetFut,