Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check and Increment the Version Number of an IndexedDB.

I have an IndexedDB that is storing a large amount of dynamic data. (The static data is already cached by a Service Worker)

My problem is as this data is dynamic, I need the IndexedDB to be cleared and it to be restored each time the application is opened. For this, I need the version number to be incremented so that the onupgradeneeded event is fired. I can't think of any logical way to do this, and even using the following call in the onupgradeneeded event I get an undefined answer.

e.target.result.oldversion

My IndexedDB code is as follows, with the parameteres being: Key - The name of the JSON object to store in the database. Value - The JSON object itself.

function dbInit(key, value) {
// Open (or create) the database

var open = indexedDB.open("MyDatabase", 1);

console.log(value);

// Create the schema
open.onupgradeneeded = function(e) {
    console.log("Old Version: " + e.target.result.oldversion); //Undefined
    console.log("New Version: " + e.target.result.newversion); //Undefined
    var db = open.result;
    var store = db.createObjectStore("Inspections", {keyPath: "id", autoIncrement: true});
    var index = store.createIndex(key, key);
};

open.onsuccess = function() {

    // Start a new transaction
    var db = open.result;
    var tx = db.transaction("Inspections", "readwrite");
    var store = tx.objectStore("Inspections");
    var index = store.index(key);

    store.add(value);

    // Close the db when the transaction is done
    tx.oncomplete = function() {
        db.close();
    };
  }
}

As this method is called several times for several 'Key' objects, I will need to work out a way to increment this Version number once per opening of the page, and then move the 'add' call to outside of the onupgradeneeded method - but for the moment the priority is making sure it runs through once - incrementing the version number, firing the onupgradeneeded, deleting the current data, storing the new data.

Thanks in advance!

like image 456
Richard Connon Avatar asked Oct 03 '17 09:10

Richard Connon


1 Answers

The oldVersion and newVersion properties (note the capitalization) are on the IDBVersionChangeEvent, not on the IDBDatabase. In other words, this:

console.log("Old Version: " + e.target.result.oldversion); //Undefined
console.log("New Version: " + e.target.result.newversion); //Undefined

should be:

console.log("Old Version: " + e.oldVersion);
console.log("New Version: " + e.newVersion);

Now that said... you're using the schema versioning in a somewhat atypical way. If you really want to start with a fresh database each time the page is opened, just delete before opening:

indexedDB.deleteDatabase("MyDatabase");
var open = indexedDB.open("MyDatabase", 1);
// An open/delete requests are always processed in the order they
// are made, so the open will wait for the delete to run.

Note that the queued operations (delete and open) would then be blocked if another tab was holding an open connection and didn't respond to a versionchange event sent out in response to the delete request. Maybe that's a good thing in your case - it would prevent two tabs from partying on the database simultaneously.

A more typical usage pattern would be to only change the version when the web app is upgraded and the database schema is different. If you did need to wipe the data across sessions you'd do that on open, rather than on upgrade, and use things like clear() on the object store. But now we're getting into the design of your app, which it sounds like you've got a good handle on.

like image 115
Joshua Bell Avatar answered Sep 30 '22 05:09

Joshua Bell