Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
5 "use strict";
7 let DEBUG = 0;
8 let debug;
9 if (DEBUG) {
10 debug = function (s) { dump("-*- IndexedDBHelper: " + s + "\n"); }
11 } else {
12 debug = function (s) {}
13 }
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.import("resource://gre/modules/Services.jsm");
23 Cu.importGlobalProperties(["indexedDB"]);
25 this.IndexedDBHelper = function IndexedDBHelper() {}
27 IndexedDBHelper.prototype = {
29 // Cache the database
30 _db: null,
32 // Close the database
33 close: function close() {
34 if (this._db) {
35 this._db.close();
36 this._db = null;
37 }
38 },
40 /**
41 * Open a new database.
42 * User has to provide upgradeSchema.
43 *
44 * @param successCb
45 * Success callback to call once database is open.
46 * @param failureCb
47 * Error callback to call when an error is encountered.
48 */
49 open: function open(aSuccessCb, aFailureCb) {
50 let self = this;
51 if (DEBUG) debug("Try to open database:" + self.dbName + " " + self.dbVersion);
52 let req = indexedDB.open(this.dbName, this.dbVersion);
53 req.onsuccess = function (event) {
54 if (DEBUG) debug("Opened database:" + self.dbName + " " + self.dbVersion);
55 self._db = event.target.result;
56 self._db.onversionchange = function(event) {
57 if (DEBUG) debug("WARNING: DB modified from a different window.");
58 }
59 aSuccessCb && aSuccessCb();
60 };
62 req.onupgradeneeded = function (aEvent) {
63 if (DEBUG) {
64 debug("Database needs upgrade:" + self.dbName + aEvent.oldVersion + aEvent.newVersion);
65 debug("Correct new database version:" + (aEvent.newVersion == this.dbVersion));
66 }
68 let _db = aEvent.target.result;
69 self.upgradeSchema(req.transaction, _db, aEvent.oldVersion, aEvent.newVersion);
70 };
71 req.onerror = function (aEvent) {
72 if (DEBUG) debug("Failed to open database: " + self.dbName);
73 aFailureCb && aFailureCb(aEvent.target.error.name);
74 };
75 req.onblocked = function (aEvent) {
76 if (DEBUG) debug("Opening database request is blocked.");
77 };
78 },
80 /**
81 * Use the cached DB or open a new one.
82 *
83 * @param successCb
84 * Success callback to call.
85 * @param failureCb
86 * Error callback to call when an error is encountered.
87 */
88 ensureDB: function ensureDB(aSuccessCb, aFailureCb) {
89 if (this._db) {
90 if (DEBUG) debug("ensureDB: already have a database, returning early.");
91 aSuccessCb && aSuccessCb();
92 return;
93 }
94 this.open(aSuccessCb, aFailureCb);
95 },
97 /**
98 * Start a new transaction.
99 *
100 * @param txn_type
101 * Type of transaction (e.g. "readwrite")
102 * @param store_name
103 * The object store you want to be passed to the callback
104 * @param callback
105 * Function to call when the transaction is available. It will
106 * be invoked with the transaction and the `store' object store.
107 * @param successCb
108 * Success callback to call on a successful transaction commit.
109 * The result is stored in txn.result.
110 * @param failureCb
111 * Error callback to call when an error is encountered.
112 */
113 newTxn: function newTxn(txn_type, store_name, callback, successCb, failureCb) {
114 this.ensureDB(function () {
115 if (DEBUG) debug("Starting new transaction" + txn_type);
116 let txn = this._db.transaction(Array.isArray(store_name) ? store_name : this.dbStoreNames, txn_type);
117 if (DEBUG) debug("Retrieving object store", this.dbName);
118 let stores;
119 if (Array.isArray(store_name)) {
120 stores = [];
121 for (let i = 0; i < store_name.length; ++i) {
122 stores.push(txn.objectStore(store_name[i]));
123 }
124 } else {
125 stores = txn.objectStore(store_name);
126 }
128 txn.oncomplete = function (event) {
129 if (DEBUG) debug("Transaction complete. Returning to callback.");
130 if (successCb) {
131 successCb(txn.result);
132 }
133 };
135 txn.onabort = function (event) {
136 if (DEBUG) debug("Caught error on transaction");
137 /*
138 * event.target.error may be null
139 * if txn was aborted by calling txn.abort()
140 */
141 if (failureCb) {
142 if (event.target.error) {
143 failureCb(event.target.error.name);
144 } else {
145 failureCb("UnknownError");
146 }
147 }
148 };
149 callback(txn, stores);
150 }.bind(this), failureCb);
151 },
153 /**
154 * Initialize the DB. Does not call open.
155 *
156 * @param aDBName
157 * DB name for the open call.
158 * @param aDBVersion
159 * Current DB version. User has to implement upgradeSchema.
160 * @param aDBStoreName
161 * ObjectStore that is used.
162 */
163 initDBHelper: function initDBHelper(aDBName, aDBVersion, aDBStoreNames) {
164 this.dbName = aDBName;
165 this.dbVersion = aDBVersion;
166 this.dbStoreNames = aDBStoreNames;
167 }
168 }