0
var db;
var version = 1;
var request = indexedDB.open("myDB", version);
request.onsuccess(function(e) {db = e.target.result;});
// db.close(); //??? happens async and has no callback
var request2 = indexedDB.open("myDB", ++version);
request.onsuccess = function() { console.log("success"); };
request.onerror = function() { console.log("error"); }; // called if db existed when page was loaded
request.onblocked = function(){console.log("blocked");}; // called on init creation
request.onupgradeneeded = function(){console.log("onupgradeneeded");};

I need to be able to open the db, read an object store, and then alter the db. It looks like you can only alter the db structure once per page load.

This works just fine in Chrome when using the deprecated setVersion method.

anonymous
  • 1,259
  • 2
  • 10
  • 15
  • request.onblocked = function() { db.close(); }; after you call close in this context the onupgradeneeded event gets fired. that should save someone from pulling their hair out. – anonymous May 04 '12 at 19:49

1 Answers1

7

The IndexedDB API isn't easy to use. A few things:

1) upgradeneeded won't fire until there are no other open connections to the db. Uncomment the db.close() line. But db won't be an IDBDatabase object until request has received a success event, so you have to wait for that.

2) The request2 object has no event handlers on it. You probably meant to put request2 instead of request on those last 4 lines in the code sample.

3) The first request.onsuccess assignment is wrong.

4) The error handler will be called if the the database on disk has a version higher than the one you are passing to open.

Try this:

indexedDB = indexedDB || mozIndexedDB;
var db;
var request = indexedDB.open("myDB");
request.onsuccess = function(e) {
    db = e.target.result;
    var version = db.version;
    db.close();
    var request2 = indexedDB.open("myDB", ++version);
    request2.onsuccess = function() { console.log("success"); };
    request2.onerror = function() { console.log("error"); };
    request2.onblocked = function() { console.log("blocked"); };
    request2.onupgradeneeded = function() { console.log("onupgradeneeded"); };
};

The console will show:

onupgradeneeded
success

If not:

  1. Check that no other tabs have connections opened to this db.
  2. Add handlers for the other three events to request, see which one fires.
dgrogan
  • 2,587
  • 1
  • 17
  • 21
  • 1
    hey man great answer. you are 100% right about it not being easy to use. i did finally get it working. for anyone that has to work with idb let me save you a lot of time. create a method for setting the version and rely heavily on that to do whatever it takes to get the job done. – anonymous Jun 13 '12 at 14:50
  • Neither setVersion nor closing the opening again work in Chrome 23 for me. It's driving me pretty bonkers. setVersion with an already open DB will cause an error. Closing then opening again with an incremented version will cause a 'BLOCKED' error. – hrdwdmrbl Dec 26 '12 at 22:34
  • OH YEAH! Closing then opening indexedDB works in Chrome 26 (Chrome Canary). – hrdwdmrbl Dec 26 '12 at 22:41