diff --git a/libs/fs.js b/libs/fs.js index 03655dc42..82fe230e3 100644 --- a/libs/fs.js +++ b/libs/fs.js @@ -32,12 +32,14 @@ var fs = (function() { window.setZeroTimeout(function() { cb(value) }); } else { var transaction = this.db.transaction(Store.DBSTORENAME, "readonly"); + if (DEBUG_FS) { console.log("get " + key + " initiated"); } var objectStore = transaction.objectStore(Store.DBSTORENAME); var req = objectStore.get(key); req.onerror = function() { console.error("Error getting " + key + ": " + req.error.name); }; transaction.oncomplete = (function() { + if (DEBUG_FS) { console.log("get " + key + " completed"); } var value = req.result; if (value === undefined) { value = null; @@ -52,33 +54,60 @@ var fs = (function() { this.map.set(key, value); var transaction = this.db.transaction(Store.DBSTORENAME, "readwrite"); + if (DEBUG_FS) { console.log("put " + key + " initiated"); } var objectStore = transaction.objectStore(Store.DBSTORENAME); var req = objectStore.put(value, key); req.onerror = function() { console.error("Error putting " + key + ": " + req.error.name); }; + transaction.oncomplete = function() { + if (DEBUG_FS) { console.log("put " + key + " completed"); } + }; }; Store.prototype.removeItem = function(key) { this.map.delete(key); var transaction = this.db.transaction(Store.DBSTORENAME, "readwrite"); + if (DEBUG_FS) { console.log("delete " + key + " initiated"); } var objectStore = transaction.objectStore(Store.DBSTORENAME); var req = objectStore.delete(key); req.onerror = function() { console.error("Error deleting " + key + ": " + req.error.name); }; + transaction.oncomplete = function() { + if (DEBUG_FS) { console.log("delete " + key + " completed"); } + }; }; Store.prototype.clear = function() { this.map.clear(); var transaction = this.db.transaction(Store.DBSTORENAME, "readwrite"); + if (DEBUG_FS) { console.log("clear initiated"); } var objectStore = transaction.objectStore(Store.DBSTORENAME); var req = objectStore.clear(); req.onerror = function() { console.error("Error clearing store: " + req.error.name); }; + transaction.oncomplete = function() { + if (DEBUG_FS) { console.log("clear completed"); } + }; + } + + Store.prototype.sync = function(cb) { + // Process a readwrite transaction to ensure previous writes have completed, + // so we leave the datastore in a consistent state. This is a bit hacky; + // we should instead monitor ongoing transactions and call our callback + // once they've all completed. + var transaction = this.db.transaction(Store.DBSTORENAME, "readwrite"); + if (DEBUG_FS) { console.log("get \"\" initiated"); } + var objectStore = transaction.objectStore(Store.DBSTORENAME); + objectStore.get(""); + transaction.oncomplete = function() { + if (DEBUG_FS) { console.log("get \"\" completed"); } + cb(); + }; } var store = new Store(); @@ -560,6 +589,10 @@ var fs = (function() { initRootDir(cb || function() {}); } + function storeSync(cb) { + store.sync(cb); + } + return { dirname: dirname, init: init, @@ -583,5 +616,6 @@ var fs = (function() { rename: rename, stat: stat, clear: clear, + storeSync: storeSync, }; })(); diff --git a/tests/automation.js b/tests/automation.js index 6cde78d1d..4a3de9340 100644 --- a/tests/automation.js +++ b/tests/automation.js @@ -102,7 +102,7 @@ casper.test.begin("unit tests", 7 + gfxTests.length, function(test) { casper .thenOpen("http://localhost:8000/tests/fstests.html") .waitForText("DONE", function() { - test.assertTextExists("DONE: 126 PASS, 0 FAIL", "run fs.js unit tests"); + test.assertTextExists("DONE: 127 PASS, 0 FAIL", "run fs.js unit tests"); }); casper diff --git a/tests/fstests.js b/tests/fstests.js index 8a2aacf94..86c78c8f1 100644 --- a/tests/fstests.js +++ b/tests/fstests.js @@ -808,6 +808,16 @@ tests.push(function() { }); }); +tests.push(function() { + fs.storeSync(function() { + // There's nothing we can check, since the sync status of the store + // is private to the fs module, but we have at least confirmed that the call + // resulted in the callback being called. + ok(true, "storeSync callback called"); + next(); + }); +}); + fs.init(function() { fs.clear(function() { next();