diff --git a/src/adapters/indexed-db.js b/src/adapters/indexed-db.js index a995311d..2e501142 100644 --- a/src/adapters/indexed-db.js +++ b/src/adapters/indexed-db.js @@ -1,9 +1,9 @@ /** * indexed db adapter - * === + * === * - originally authored by Vivian Li * - */ + */ Lawnchair.adapter('indexed-db', (function(){ @@ -31,9 +31,9 @@ Lawnchair.adapter('indexed-db', (function(){ return { - + valid: function() { return !!getIDB(); }, - + init:function(options, callback) { this.idb = getIDB(); this.waiting = []; @@ -41,7 +41,7 @@ Lawnchair.adapter('indexed-db', (function(){ var self = this; var cb = self.fn(self.name, callback); var win = function(){ return cb.call(self, self); }; - + var upgrade = function(from, to) { // don't try to migrate dbs, just recreate try { @@ -54,18 +54,13 @@ Lawnchair.adapter('indexed-db', (function(){ // ok, create object store. self.store = self.db.createObjectStore(STORE_NAME, { autoIncrement: true} ); - for (var i = 0; i < self.waiting.length; i++) { - self.waiting[i].call(self); - } - self.waiting = []; - win(); }; request.onupgradeneeded = function(event) { upgrade(event.oldVersion, event.newVersion); }; request.onsuccess = function(event) { - self.db = request.result; - + self.db = request.result; + if(self.db.version != (''+STORE_VERSION)) { // DEPRECATED API: modern implementations will fire the // upgradeneeded event instead. @@ -74,11 +69,20 @@ Lawnchair.adapter('indexed-db', (function(){ // onsuccess is the only place we can create Object Stores setVrequest.onsuccess = function(e) { upgrade(oldVersion, STORE_VERSION); + + var transaction = e.target.result; + transaction.oncomplete = function() { + for (var i = 0; i < self.waiting.length; i++) { + self.waiting[i].call(self); + } + self.waiting = []; + win(); + }; }; setVrequest.onerror = function(e) { console.log("Failed to create objectstore " + e); fail(e); - } + }; } else { self.store = {}; for (var i = 0; i < self.waiting.length; i++) { @@ -87,56 +91,65 @@ Lawnchair.adapter('indexed-db', (function(){ self.waiting = []; win(); } - } + }; request.onerror = fail; }, save:function(obj, callback) { + if(!this.store) { - this.waiting.push(function() { - this.save(obj, callback); - }); - return; - } - - var self = this; - var win = function (e) { if (callback) { obj.key = e.target.result; self.lambda(callback).call(self, obj) }}; - - var trans = this.db.transaction(STORE_NAME, getIDBTransaction().READ_WRITE); - var store = trans.objectStore(STORE_NAME); - var request = obj.key ? store.put(obj, obj.key) : store.put(obj); - - request.onsuccess = win; - request.onerror = fail; - - return this; + this.waiting.push(function() { + this.save(obj, callback); + }); + return; + } + + var self = this; + var win = function (e) { + if (callback) { + obj.key = e.target.result; + self.lambda(callback).call(self, obj); + } + }; + + var trans = this.db.transaction(STORE_NAME, 'readwrite'); + var store = trans.objectStore(STORE_NAME); + var request = obj.key ? store.put(obj, obj.key) : store.put(obj); + + request.onsuccess = win; + request.onerror = fail; + + return this; }, - + // FIXME this should be a batch insert / just getting the test to pass... batch: function (objs, cb) { - - var results = [] - , done = false - , self = this + + var results = [], + done = false, + self = this; var updateProgress = function(obj) { - results.push(obj) - done = results.length === objs.length - } + results.push(obj); + done = results.length === objs.length; + }; var checkProgress = setInterval(function() { if (done) { - if (cb) self.lambda(cb).call(self, results) - clearInterval(checkProgress) + if (cb) { + self.lambda(cb).call(self, results); + } + clearInterval(checkProgress); } - }, 200) + }, 200); + + for (var i = 0, l = objs.length; i < l; i++) { + this.save(objs[i], updateProgress); + } - for (var i = 0, l = objs.length; i < l; i++) - this.save(objs[i], updateProgress) - - return this + return this; }, - + get:function(key, callback) { if(!this.store) { @@ -145,12 +158,12 @@ Lawnchair.adapter('indexed-db', (function(){ }); return; } - - + + var self = this; var win = function (e) { if (callback) { self.lambda(callback).call(self, e.target.result) }}; - - + + if (!this.isArray(key)){ var req = this.db.transaction(STORE_NAME).objectStore(STORE_NAME).get(key); @@ -159,8 +172,8 @@ Lawnchair.adapter('indexed-db', (function(){ console.log("Failed to find " + key); fail(event); }; - - // FIXME: again the setInterval solution to async callbacks.. + + // FIXME: again the setInterval solution to async callbacks.. } else { // note: these are hosted. @@ -180,9 +193,9 @@ Lawnchair.adapter('indexed-db', (function(){ } }, 200) - for (var i = 0, l = keys.length; i < l; i++) + for (var i = 0, l = keys.length; i < l; i++) this.get(keys[i], updateProgress) - + } return this; @@ -247,9 +260,9 @@ Lawnchair.adapter('indexed-db', (function(){ keyOrObj = keyOrObj.key; } var self = this; - var win = function () { if (callback) self.lambda(callback).call(self) }; - - var request = this.db.transaction(STORE_NAME, getIDBTransaction().READ_WRITE).objectStore(STORE_NAME)['delete'](keyOrObj); + var win = function () { if (callback) self.lambda(callback).call(self); }; + + var request = this.db.transaction(STORE_NAME, 'readwrite').objectStore(STORE_NAME)['delete'](keyOrObj); request.onsuccess = win; request.onerror = fail; return this; @@ -262,21 +275,21 @@ Lawnchair.adapter('indexed-db', (function(){ }); return; } - - var self = this - , win = callback ? function() { self.lambda(callback).call(self) } : function(){}; - + + var self = this, + win = callback ? function() { self.lambda(callback).call(self); } : function(){}; + try { this.db - .transaction(STORE_NAME, getIDBTransaction().READ_WRITE) + .transaction(STORE_NAME, 'readwrite') .objectStore(STORE_NAME).clear().onsuccess = win; - + } catch(e) { fail(); } return this; } - + }; - + })());