mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
b8eea4d16b
Fix xpcshell tests. Add support for webapps-clear-data. Trash old regs on idb version upgrade. Use principal for permission check. use principal in PushSubscription. --HG-- extra : source : d7554019b424327a3271e2c0debda995fff36cb5 extra : intermediate-source : be40dea6534771bdeedc9f7c6ccd8bbddb6e41c2
250 lines
6.4 KiB
JavaScript
250 lines
6.4 KiB
JavaScript
/* jshint moz: true, esnext: true */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
// Don't modify this, instead set dom.push.debug.
|
|
let gDebuggingEnabled = false;
|
|
|
|
function debug(s) {
|
|
if (gDebuggingEnabled) {
|
|
dump("-*- PushDB.jsm: " + s + "\n");
|
|
}
|
|
}
|
|
|
|
const Cu = Components.utils;
|
|
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
|
Cu.import("resource://gre/modules/Preferences.jsm");
|
|
Cu.importGlobalProperties(["indexedDB"]);
|
|
|
|
const prefs = new Preferences("dom.push.");
|
|
|
|
this.EXPORTED_SYMBOLS = ["PushDB"];
|
|
|
|
this.PushDB = function PushDB(dbName, dbVersion, dbStoreName, schemaFunction) {
|
|
debug("PushDB()");
|
|
this._dbStoreName = dbStoreName;
|
|
this._schemaFunction = schemaFunction;
|
|
|
|
// set the indexeddb database
|
|
this.initDBHelper(dbName, dbVersion,
|
|
[dbStoreName]);
|
|
gDebuggingEnabled = prefs.get("debug");
|
|
prefs.observe("debug", this);
|
|
};
|
|
|
|
this.PushDB.prototype = {
|
|
__proto__: IndexedDBHelper.prototype,
|
|
|
|
upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
|
|
if (this._schemaFunction) {
|
|
this._schemaFunction(aTransaction, aDb, aOldVersion, aNewVersion, this);
|
|
}
|
|
},
|
|
|
|
/*
|
|
* @param aRecord
|
|
* The record to be added.
|
|
*/
|
|
|
|
put: function(aRecord) {
|
|
debug("put()" + JSON.stringify(aRecord));
|
|
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readwrite",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
aStore.put(aRecord).onsuccess = function setTxnResult(aEvent) {
|
|
debug("Request successful. Updated record ID: " +
|
|
aEvent.target.result);
|
|
};
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
/*
|
|
* @param aKeyID
|
|
* The ID of record to be deleted.
|
|
*/
|
|
delete: function(aKeyID) {
|
|
debug("delete()");
|
|
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readwrite",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
debug("Going to delete " + aKeyID);
|
|
aStore.delete(aKeyID);
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
clearAll: function clear() {
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readwrite",
|
|
this._dbStoreName,
|
|
function (aTxn, aStore) {
|
|
debug("Going to clear all!");
|
|
aStore.clear();
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
getByPushEndpoint: function(aPushEndpoint) {
|
|
debug("getByPushEndpoint()");
|
|
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readonly",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
aTxn.result = undefined;
|
|
|
|
let index = aStore.index("pushEndpoint");
|
|
index.get(aPushEndpoint).onsuccess = function setTxnResult(aEvent) {
|
|
aTxn.result = aEvent.target.result;
|
|
debug("Fetch successful " + aEvent.target.result);
|
|
};
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
getByKeyID: function(aKeyID) {
|
|
debug("getByKeyID()");
|
|
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readonly",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
aTxn.result = undefined;
|
|
|
|
aStore.get(aKeyID).onsuccess = function setTxnResult(aEvent) {
|
|
aTxn.result = aEvent.target.result;
|
|
debug("Fetch successful " + aEvent.target.result);
|
|
};
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
// Perform a unique match against { scope, originAttributes }
|
|
getByIdentifiers: function(aPageRecord) {
|
|
debug("getByIdentifiers() { " + aPageRecord.scope + ", " +
|
|
JSON.stringify(aPageRecord.originAttributes) + " }");
|
|
if (!aPageRecord.scope || aPageRecord.originAttributes == undefined) {
|
|
return Promise.reject(
|
|
new TypeError("Scope and originAttributes are required! " +
|
|
JSON.stringify(aPageRecord)));
|
|
}
|
|
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readonly",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
aTxn.result = undefined;
|
|
|
|
let index = aStore.index("identifiers");
|
|
let request = index.get(IDBKeyRange.only([aPageRecord.scope, aPageRecord.originAttributes]));
|
|
request.onsuccess = function setTxnResult(aEvent) {
|
|
aTxn.result = aEvent.target.result;
|
|
}
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
_getAllByKey: function(aKeyName, aKeyValue) {
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readonly",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
aTxn.result = undefined;
|
|
|
|
let index = aStore.index(aKeyName);
|
|
// It seems ok to use getAll here, since unlike contacts or other
|
|
// high storage APIs, we don't expect more than a handful of
|
|
// registrations per domain, and usually only one.
|
|
let getAllReq = index.mozGetAll(aKeyValue);
|
|
getAllReq.onsuccess = function setTxnResult(aEvent) {
|
|
aTxn.result = aEvent.target.result;
|
|
}
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
// aOriginAttributes must be a string!
|
|
getAllByOriginAttributes: function(aOriginAttributes) {
|
|
if (typeof aOriginAttributes !== "string") {
|
|
return Promise.reject("Expected string!");
|
|
}
|
|
return this._getAllByKey("originAttributes", aOriginAttributes);
|
|
},
|
|
|
|
getAllKeyIDs: function() {
|
|
debug("getAllKeyIDs()");
|
|
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readonly",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
aTxn.result = undefined;
|
|
aStore.mozGetAll().onsuccess = function(event) {
|
|
aTxn.result = event.target.result;
|
|
};
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
drop: function() {
|
|
debug("drop()");
|
|
|
|
return new Promise((resolve, reject) =>
|
|
this.newTxn(
|
|
"readwrite",
|
|
this._dbStoreName,
|
|
function txnCb(aTxn, aStore) {
|
|
aStore.clear();
|
|
},
|
|
resolve,
|
|
reject
|
|
)
|
|
);
|
|
},
|
|
|
|
observe: function observe(aSubject, aTopic, aData) {
|
|
if ((aTopic == "nsPref:changed") && (aData == "dom.push.debug"))
|
|
gDebuggingEnabled = prefs.get("debug");
|
|
}
|
|
};
|