-
-
Notifications
You must be signed in to change notification settings - Fork 12
Description
Overview
Currently, OpenDbRequestBuilder::with_on_upgrade_needed
passes two arguments to the provided callback: a VersionChangeEvent
and a Database
. Unfortunately, neither of these provides access to the active version change transaction, which means that it is impossible to accomplish certain kinds of tasks.
Note that in previous releases of this crate, the active version change transaction was accessible! (see here).
Example: Adding Index to Existing Object Store During Upgrade
For example, one cannot add an index to an existing object store. This is because in order to get access to the existing object store, the only option is to start a new transaction on the database, which interferes with the active one.
Code
use indexed_db_futures::{
Build,
database::Database,
error::{Error, OpenDbError},
transaction::TransactionMode,
};
const OBJECT_STORE: &str = "object_store";
pub async fn upgrade(name: &str) -> Result<(), OpenDbError> {
let current = Database::open(name).await?.version() as u32;
if current < 2 {
Database::open(name)
.with_version(2u32)
.with_on_upgrade_needed(|_, db: Database| -> Result<(), Error> {
db.create_object_store(OBJECT_STORE).build()?;
Ok(())
})
.await?
.close();
}
if current < 3 {
Database::open(name)
.with_version(3u32)
.with_on_upgrade_needed(|_, db: Database| -> Result<(), Error> {
db.transaction(OBJECT_STORE) // Fails to start this transaction!
.with_mode(TransactionMode::Versionchange)
.build()?
.object_store(OBJECT_STORE)?
.create_index("index", "key_path".into())
.build()?;
Ok(())
})
.await?
.close();
}
Ok(())
}
Test
To illustrate that the code above fails to run, one can construct the following test.
#[cfg(all(test, target_family = "wasm"))]
mod tests {
use crate::upgrade;
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test::wasm_bindgen_test]
async fn test_upgrade() {
upgrade("database").await.expect("should upgrade database");
}
}
One can then run this test with following command.
wasm-pack test --firefox --headless
And, finally, the error output contains the following information.
Base(DomException(InvalidStateError(DomException { obj: Object { obj: JsValue(InvalidStateError: IDBDatabase.transaction: Can't start a transaction while running an upgrade transaction)}})))
I'm not sure if there is a convenient workaround to accomplish what I'm trying to do here. If not, would it be possible to expose the active version change transaction through the VersionChangeEvent
or the Database
? I'm happy to try and push a pull request is you think it wouldn't be too involved.