1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
10 debug = function (s) { dump("-*- IndexedDBHelper: " + s + "\n"); }
12 debug = function (s) {}
15 const Cu = Components.utils;
16 const Cc = Components.classes;
17 const Ci = Components.interfaces;
19 this.EXPORTED_SYMBOLS = ["IndexedDBHelper"];
21 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
22 Cu.importGlobalProperties(["indexedDB"]);
24 XPCOMUtils.defineLazyModuleGetter(this, 'Services',
25 'resource://gre/modules/Services.jsm');
27 this.IndexedDBHelper = function IndexedDBHelper() {}
29 IndexedDBHelper.prototype = {
35 close: function close() {
43 * Open a new database.
44 * User has to provide upgradeSchema.
47 * Success callback to call once database is open.
49 * Error callback to call when an error is encountered.
51 open: function open(aSuccessCb, aFailureCb) {
53 if (DEBUG) debug("Try to open database:" + self.dbName + " " + self.dbVersion);
54 let req = indexedDB.open(this.dbName, this.dbVersion);
55 req.onsuccess = function (event) {
56 if (DEBUG) debug("Opened database:" + self.dbName + " " + self.dbVersion);
57 self._db = event.target.result;
58 self._db.onversionchange = function(event) {
59 if (DEBUG) debug("WARNING: DB modified from a different window.");
61 aSuccessCb && aSuccessCb();
64 req.onupgradeneeded = function (aEvent) {
66 debug("Database needs upgrade:" + self.dbName + aEvent.oldVersion + aEvent.newVersion);
67 debug("Correct new database version:" + (aEvent.newVersion == this.dbVersion));
70 let _db = aEvent.target.result;
71 self.upgradeSchema(req.transaction, _db, aEvent.oldVersion, aEvent.newVersion);
73 req.onerror = function (aEvent) {
74 if (DEBUG) debug("Failed to open database: " + self.dbName);
75 aFailureCb && aFailureCb(aEvent.target.error.name);
77 req.onblocked = function (aEvent) {
78 if (DEBUG) debug("Opening database request is blocked.");
83 * Use the cached DB or open a new one.
86 * Success callback to call.
88 * Error callback to call when an error is encountered.
90 ensureDB: function ensureDB(aSuccessCb, aFailureCb) {
92 if (DEBUG) debug("ensureDB: already have a database, returning early.");
94 Services.tm.currentThread.dispatch(aSuccessCb,
95 Ci.nsIThread.DISPATCH_NORMAL);
99 this.open(aSuccessCb, aFailureCb);
103 * Start a new transaction.
106 * Type of transaction (e.g. "readwrite")
108 * The object store you want to be passed to the callback
110 * Function to call when the transaction is available. It will
111 * be invoked with the transaction and the `store' object store.
113 * Success callback to call on a successful transaction commit.
114 * The result is stored in txn.result.
116 * Error callback to call when an error is encountered.
118 newTxn: function newTxn(txn_type, store_name, callback, successCb, failureCb) {
119 this.ensureDB(function () {
120 if (DEBUG) debug("Starting new transaction" + txn_type);
121 let txn = this._db.transaction(Array.isArray(store_name) ? store_name : this.dbStoreNames, txn_type);
122 if (DEBUG) debug("Retrieving object store", this.dbName);
124 if (Array.isArray(store_name)) {
126 for (let i = 0; i < store_name.length; ++i) {
127 stores.push(txn.objectStore(store_name[i]));
130 stores = txn.objectStore(store_name);
133 txn.oncomplete = function (event) {
134 if (DEBUG) debug("Transaction complete. Returning to callback.");
136 successCb(txn.result);
140 txn.onabort = function (event) {
141 if (DEBUG) debug("Caught error on transaction");
143 * event.target.error may be null
144 * if txn was aborted by calling txn.abort()
147 if (event.target.error) {
148 failureCb(event.target.error.name);
150 failureCb("UnknownError");
154 callback(txn, stores);
155 }.bind(this), failureCb);
159 * Initialize the DB. Does not call open.
162 * DB name for the open call.
164 * Current DB version. User has to implement upgradeSchema.
165 * @param aDBStoreName
166 * ObjectStore that is used.
168 initDBHelper: function initDBHelper(aDBName, aDBVersion, aDBStoreNames) {
169 this.dbName = aDBName;
170 this.dbVersion = aDBVersion;
171 this.dbStoreNames = aDBStoreNames;