0

I am using indexedDB of HTML5. I have problem in creating second object store and make transactions. First object store works fine but the second one is not working. I have tried two approaches; both are not working correctly.

In first approach second object store creates but it takes the properties(such as keypath, autoincrement) of the first object store. My Second Object Store does not make more than one transaction in this approach.

Here is First Approach

var request, secondRequest, db, version;
var database;


if (!window.indexedDB) {
    alert("Your Browser does not support IndexedDB");
}
else {
    var dbName = "MyStatus";
    request = window.indexedDB.open(dbName, 2);
    request.onerror = function(event) {
        alert("Error opening DB", event);
    };
    request.onupgradeneeded = function (event) {
        alert("Upgrading");
        db = event.target.result;
        var tblIncident = db.createObjectStore("Incident", { keyPath: "MyID", unique: true });

        var tblIncidentStatus = db.createObjectStore("tblVolunteerIncidentStatus",{ keyPath: "ID", unique: false, autoincrement: true });
    };

    request.onsuccess = function(event) {
        alert("Success opening DB");
        db = event.target.result;
        alert(db);
        $(document).trigger('insert');
    };
   }

   $(document).bind('insert', function () {
   var incidID = 0;
   var transaction = db.transaction(["Incident"], "readwrite");
    transaction.oncomplete = function (event) {
     alert("Case Inserted Successfully :)");
    incidID++;
    };

    transaction.onerror = function (event) {
        alert("Case Insertion Error :(");
    };
    var oStoreIncident = transaction.objectStore("Incident");

    oStoreIncident.add({ INCID: incidId, INCDETAILS: "" });
    });

  $(document).bind('insertStatus', function () {
   var incidID = 0;
   var transaction = db.transaction(["IncidentStatus"], "readwrite");
    transaction.oncomplete = function (event) {
        alert("Case Inserted Successfully :)");
   incidID++;
    };

    transaction.onerror = function (event) {
        alert("Case Insertion Error :(");
    };
    var oStoreIncident = transaction.objectStore("IncidentStatus");

    oStoreIncident.add({ INCID: incidId, INCDETAILS: "" });
     });

Then I followed this link How to Create Multiple Object Stores

and using this my second object store not creating therefore my transactions on this are also not working.

Here is Second Approach

 if (!window.indexedDB) {
    alert("Your Browser does not support IndexedDB");
}
else {
    var dbName = "MyStatus";
    request = window.indexedDB.open(dbName, 2);
    request.onerror = function(event) {
        alert("Error opening DB", event);
    };
    request.onupgradeneeded = function (event) {
        alert("Upgrading");
        db = event.target.result;
        var tblIncident = db.createObjectStore("Incident", { keyPath: "MyID", unique: true });

    };

    request.onsuccess = function(event) {
        alert("Success opening DB");
        db = event.target.result;
        alert(db);
        version = parseInt(db.version);
        db.close();

        request2 = window.indexedDB.open(dbName, 3);
        request2.onupgradeneeded = function (evnt) {
            alert("on upgrade needed");
            db = evnt.target.result;
            alert("DB: " + db);
            var tblIncidentStatus = db.createObjectStore("IncidentStatus");
            alert(tblIncidentStatus);

        };
        request2.onsuccess = function (evnt) {
            db = evnt.target.result;
            alert("Second Table Created Successfully");
        };
        request2.onerror = function (evnt) {
            db = evnt.target.result;
            alert("Second Table not creating " + db);
        };
     $(document).trigger('insert');
     $(document).trigger('insertStatus');
       };
    }

   $(document).bind('insert', function () {
   var incidID = 0;
   var transaction = db.transaction(["Incident"], "readwrite");
    transaction.oncomplete = function (event) {
     alert("Case Inserted Successfully :)");
    incidID++;
    };

    transaction.onerror = function (event) {
        alert("Case Insertion Error :(");
    };
    var oStoreIncident = transaction.objectStore("Incident");

    oStoreIncident.add({ INCID: incidId, INCDETAILS: "" });
    });

  $(document).bind('insertStatus', function () {
   var incidID = 0;
   var transaction = db.transaction(["IncidentStatus"], "readwrite");
    transaction.oncomplete = function (event) {
        alert("Case Inserted Successfully :)");
   incidID++;
    };

    transaction.onerror = function (event) {
        alert("Case Insertion Error :(");
    };
    var oStoreIncident = transaction.objectStore("IncidentStatus");

    oStoreIncident.add({ INCID: incidId, INCDETAILS: "" });
     });

I am new to indexedDB; if anyone has solution so please share.

Thanks in advance.

Community
  • 1
  • 1
Zia Ul Mustafa
  • 301
  • 3
  • 14
  • You seem to be throwing away the handle to things because the go out of scope of the function you don't retain a reference. How are you confirming it is created? Which browser and platform do you prefer to test with? Is the browser enabled to allow IndexDB, maybe find a test website on the topic and see if a DB is created. What JS errors and exceptions are in the web-console? – Darryl Miles Nov 18 '15 at 12:42
  • I am testing it on Google Chrome Only. Firefox, Opera and IE are not supported for IndexedDB. There are no any errors in web-console; I debugged it many times step by step. And please tell me that which reference is not retaining? And please mention (from above mentioned) which approach you discussed? – Zia Ul Mustafa Nov 18 '15 at 12:51
  • So if you breakpoint and step through the code line by line (setting breakpoints inside each callback function like `onupgradeneeded`. If you use Chrome F12 and then Resources tab and then IndexDB from list? You know about this right? There are a number of alerts() in the code you are claiming you never see any ? – Darryl Miles Nov 18 '15 at 12:57
  • Yes i did in the same manner as you told. I setup alerts for the sake of confirmations about the broken points where I made mistake. – Zia Ul Mustafa Nov 18 '15 at 13:01
  • So for each approach you tried, document the exact sequence and message of the alerts you see. You are claiming nothing is created inside the IndexedDB pane of Chrome Developer Tools (press F12 inside chrome). Is this true ? – Darryl Miles Nov 18 '15 at 13:03
  • Now I am getting this error on console. "Uncaught ConstraintError: Failed to execute 'createObjectStore' on 'IDBDatabase': An object store with the specified name already exists." on this line "var tblIncidentStatus = db.createObjectStore("IncidentStatus");" – Zia Ul Mustafa Nov 18 '15 at 13:09
  • So this will show up in that Chrome Developer Tools area, and you can edit data, insert records, delete object stores. So delete the object stores and restart. Work through your bugs. Maybe you should try to check if the object store exists, before trying to create it with `IDBDatabase.createObjectStore` ? By looking at `IDBDatabase.objectStoreNames` as per https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/objectStoreNames ? – Darryl Miles Nov 18 '15 at 13:20

2 Answers2

4

Use this pattern for opening database connections and upgrading the schema:

var open = indexedDB.open(dbName, 3);
open.onupgradeneeded = function(e) {
   var db = open.result;
   if (e.oldVersion < 1) {
       // initial database creation
       // (your code does nothing here)
   }
   if (e.oldVersion < 2) {
       // version 1 -> 2 upgrade
       db.createObjectStore("Incident", { keyPath: "MyID", unique: true });
       // ...
   }
   if (e.oldVersion < 3) {
       // version 2 -> 3 upgrade
       db.createObjectStore("IncidentStatus");
       // ...
   }
};
open.onsuccess = function(e) {
    var db = open.result;
    // db.version guaranteed to be 3 (or open would have failed)
};
Joshua Bell
  • 7,727
  • 27
  • 30
1

The reason because you can't open a transaction to the second object store in the second example, is because it isn't created yet. You are triggering the insert event to soon. You should call the insert trigger for the object store in the onsuccess callback of request2.

As joshua mentions you should bundle your upgrades in a single call checking the version. You can also create multiple object stores inside one onupgradeneeded event.

Kristof Degrave
  • 4,142
  • 22
  • 32