зеркало из https://github.com/mozilla/gecko-dev.git
Bug 821814 - Settings: upgrade settings DB after settings.json changed. r=bent a=blocking-basecamp
This commit is contained in:
Родитель
fa05279bc1
Коммит
5695e1cdf2
|
@ -2,6 +2,8 @@
|
|||
* 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";
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
|
@ -14,7 +16,7 @@ function debug(s) {
|
|||
}
|
||||
|
||||
this.SETTINGSDB_NAME = "settings";
|
||||
this.SETTINGSDB_VERSION = 1;
|
||||
this.SETTINGSDB_VERSION = 2;
|
||||
this.SETTINGSSTORE_NAME = "settings";
|
||||
|
||||
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
||||
|
@ -28,13 +30,17 @@ SettingsDB.prototype = {
|
|||
__proto__: IndexedDBHelper.prototype,
|
||||
|
||||
upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) {
|
||||
let objectStore = aDb.createObjectStore(SETTINGSSTORE_NAME,
|
||||
{ keyPath: "settingName" });
|
||||
objectStore.createIndex("settingValue", "settingValue", { unique: false });
|
||||
if (DEBUG) debug("Created object stores and indexes");
|
||||
|
||||
if (aOldVersion != 0) {
|
||||
return;
|
||||
let objectStore;
|
||||
if (aOldVersion == 0) {
|
||||
objectStore = aDb.createObjectStore(SETTINGSSTORE_NAME, { keyPath: "settingName" });
|
||||
if (DEBUG) debug("Created object stores");
|
||||
} else if (aOldVersion == 1) {
|
||||
if (DEBUG) debug("Get object store for upgrade and remove old index");
|
||||
objectStore = aTransaction.objectStore(SETTINGSSTORE_NAME);
|
||||
objectStore.deleteIndex("settingValue");
|
||||
} else {
|
||||
if (DEBUG) debug("Get object store for upgrade");
|
||||
objectStore = aTransaction.objectStore(SETTINGSSTORE_NAME);
|
||||
}
|
||||
|
||||
// Loading resource://app/defaults/settings.json doesn't work because
|
||||
|
@ -66,12 +72,39 @@ SettingsDB.prototype = {
|
|||
if (DEBUG) debug("Error parsing " + settingsFile.path + " : " + e);
|
||||
return;
|
||||
}
|
||||
stream.close();
|
||||
|
||||
for (let setting in settings) {
|
||||
if (DEBUG) debug("Adding setting " + setting);
|
||||
objectStore.put({ settingName: setting,
|
||||
settingValue: settings[setting] });
|
||||
}
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
if (cursor) {
|
||||
let value = cursor.value;
|
||||
if (value.settingName in settings) {
|
||||
if (DEBUG) debug("Upgrade " +settings[value.settingName]);
|
||||
value.defaultValue = settings[value.settingName];
|
||||
delete settings[value.settingName];
|
||||
if ("settingValue" in value) {
|
||||
value.userValue = value.settingValue;
|
||||
delete value.settingValue;
|
||||
}
|
||||
cursor.update(value);
|
||||
} else if ("userValue" in value || "settingValue" in value) {
|
||||
value.defaultValue = undefined;
|
||||
if (aOldVersion == 1 && value.settingValue) {
|
||||
value.userValue = value.settingValue;
|
||||
delete value.settingValue;
|
||||
}
|
||||
cursor.update(value);
|
||||
} else {
|
||||
cursor.delete();
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
for (let name in settings) {
|
||||
if (DEBUG) debug("Set new:" + name +", " + settings[name]);
|
||||
objectStore.add({ settingName: name, defaultValue: settings[name], userValue: undefined });
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
init: function init(aGlobal) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const DEBUG = false;
|
||||
const DEBUG = true;
|
||||
function debug(s) {
|
||||
if (DEBUG) dump("-*- SettingsManager: " + s + "\n");
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ const nsIDOMSettingsLock = Ci.nsIDOMSettingsLock;
|
|||
function SettingsLock(aSettingsManager)
|
||||
{
|
||||
this._open = true;
|
||||
this._isBusy = false;
|
||||
this._requests = new Queue();
|
||||
this._settingsManager = aSettingsManager;
|
||||
this._transaction = null;
|
||||
|
@ -48,11 +49,15 @@ SettingsLock.prototype = {
|
|||
let request = info.request;
|
||||
switch (info.intent) {
|
||||
case "clear":
|
||||
let req = store.clear();
|
||||
req.onsuccess = function() { this._open = true;
|
||||
Services.DOMRequest.fireSuccess(request, 0);
|
||||
this._open = false; }.bind(lock);
|
||||
req.onerror = function() { Services.DOMRequest.fireError(request, 0) };
|
||||
let clearReq = store.clear();
|
||||
clearReq.onsuccess = function() {
|
||||
this._open = true;
|
||||
Services.DOMRequest.fireSuccess(request, 0);
|
||||
this._open = false;
|
||||
}.bind(lock);
|
||||
clearReq.onerror = function() {
|
||||
Services.DOMRequest.fireError(request, 0)
|
||||
};
|
||||
break;
|
||||
case "set":
|
||||
let keys = Object.getOwnPropertyNames(info.settings);
|
||||
|
@ -60,49 +65,64 @@ SettingsLock.prototype = {
|
|||
let key = keys[i];
|
||||
let last = i === keys.length - 1;
|
||||
if (DEBUG) debug("key: " + key + ", val: " + JSON.stringify(info.settings[key]) + ", type: " + typeof(info.settings[key]));
|
||||
|
||||
lock._isBusy = true;
|
||||
let checkKeyRequest = store.get(key);
|
||||
|
||||
checkKeyRequest.onsuccess = function (event) {
|
||||
if (!event.target.result) {
|
||||
if (DEBUG) debug("MOZSETTINGS-SET-WARNING: " + key + " is not in the database. Please add it to build/settings.js\n");
|
||||
let defaultValue;
|
||||
let userValue = info.settings[key];
|
||||
if (event.target.result) {
|
||||
defaultValue = event.target.result.defaultValue;
|
||||
} else {
|
||||
defaultValue = null;
|
||||
if (DEBUG) debug("MOZSETTINGS-SET-WARNING: " + key + " is not in the database.\n");
|
||||
}
|
||||
|
||||
let setReq;
|
||||
if (typeof(info.settings[key]) != 'object') {
|
||||
let obj = {settingName: key, defaultValue: defaultValue, userValue: userValue};
|
||||
if (DEBUG) debug("store1: " + JSON.stringify(obj));
|
||||
setReq = store.put(obj);
|
||||
} else {
|
||||
//Workaround for cloning issues
|
||||
let defaultVal = JSON.parse(JSON.stringify(defaultValue));
|
||||
let userVal = JSON.parse(JSON.stringify(userValue));
|
||||
let obj = {settingName: key, defaultValue: defaultVal, userValue: userVal};
|
||||
if (DEBUG) debug("store2: " + JSON.stringify(obj));
|
||||
setReq = store.put(obj);
|
||||
}
|
||||
|
||||
setReq.onsuccess = function() {
|
||||
lock._isBusy = false;
|
||||
cpmm.sendAsyncMessage("Settings:Changed", { key: key, value: userValue });
|
||||
if (last && !request.error) {
|
||||
lock._open = true;
|
||||
Services.DOMRequest.fireSuccess(request, 0);
|
||||
lock._open = false;
|
||||
if (!lock._requests.isEmpty()) {
|
||||
lock.process();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setReq.onerror = function() {
|
||||
if (!request.error) {
|
||||
Services.DOMRequest.fireError(request, setReq.error.name)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if(typeof(info.settings[key]) != 'object') {
|
||||
req = store.put({settingName: key, settingValue: info.settings[key]});
|
||||
} else {
|
||||
//Workaround for cloning issues
|
||||
let obj = JSON.parse(JSON.stringify(info.settings[key]));
|
||||
req = store.put({settingName: key, settingValue: obj});
|
||||
}
|
||||
|
||||
req.onsuccess = function() {
|
||||
if (last && !request.error) {
|
||||
lock._open = true;
|
||||
Services.DOMRequest.fireSuccess(request, 0);
|
||||
lock._open = false;
|
||||
}
|
||||
cpmm.sendAsyncMessage("Settings:Changed", { key: key, value: info.settings[key] });
|
||||
};
|
||||
|
||||
req.onerror = function() {
|
||||
if (!request.error) {
|
||||
Services.DOMRequest.fireError(request, req.error.name)
|
||||
}
|
||||
};
|
||||
}
|
||||
break;
|
||||
case "get":
|
||||
req = (info.name === "*") ? store.mozGetAll()
|
||||
: store.mozGetAll(info.name);
|
||||
let getReq = (info.name === "*") ? store.mozGetAll()
|
||||
: store.mozGetAll(info.name);
|
||||
|
||||
req.onsuccess = function(event) {
|
||||
getReq.onsuccess = function(event) {
|
||||
if (DEBUG) debug("Request for '" + info.name + "' successful. " +
|
||||
"Record count: " + event.target.result.length);
|
||||
if (DEBUG) debug("result: " + JSON.stringify(event.target.result));
|
||||
|
||||
if (event.target.result.length == 0) {
|
||||
if (DEBUG) debug("MOZSETTINGS-GET-WARNING: " + info.name + " is not in the database. Please add it to build/settings.js\n");
|
||||
if (DEBUG) debug("MOZSETTINGS-GET-WARNING: " + info.name + " is not in the database.\n");
|
||||
}
|
||||
|
||||
let results = {
|
||||
|
@ -113,7 +133,8 @@ SettingsLock.prototype = {
|
|||
for (var i in event.target.result) {
|
||||
let result = event.target.result[i];
|
||||
var name = result.settingName;
|
||||
var value = result.settingValue;
|
||||
if (DEBUG) debug("VAL: " + result.userValue +", " + result.defaultValue + "\n");
|
||||
var value = result.userValue !== undefined ? result.userValue : result.defaultValue;
|
||||
results[name] = value;
|
||||
results.__exposedProps__[name] = "r";
|
||||
// If the value itself is an object, expose the properties.
|
||||
|
@ -129,14 +150,12 @@ SettingsLock.prototype = {
|
|||
this._open = false;
|
||||
}.bind(lock);
|
||||
|
||||
req.onerror = function() {
|
||||
getReq.onerror = function() {
|
||||
Services.DOMRequest.fireError(request, 0)
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!lock._requests.isEmpty())
|
||||
throw Components.results.NS_ERROR_ABORT;
|
||||
lock._open = true;
|
||||
},
|
||||
|
||||
|
@ -148,10 +167,15 @@ SettingsLock.prototype = {
|
|||
let transactionType = this._settingsManager.hasWritePrivileges ? "readwrite" : "readonly";
|
||||
lock._transaction = lock._settingsManager._settingsDB._db.transaction(SETTINGSSTORE_NAME, transactionType);
|
||||
}
|
||||
lock.process();
|
||||
if (!lock._isBusy) {
|
||||
lock.process();
|
||||
} else {
|
||||
this._settingsManager._locks.enqueue(lock);
|
||||
}
|
||||
}
|
||||
if (!this._requests.isEmpty())
|
||||
if (!this._requests.isEmpty() && !this._isBusy) {
|
||||
this.process();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -181,7 +205,8 @@ SettingsLock.prototype = {
|
|||
if (this._settingsManager.hasWritePrivileges) {
|
||||
let req = Services.DOMRequest.createRequest(this._settingsManager._window);
|
||||
if (DEBUG) debug("send: " + JSON.stringify(aSettings));
|
||||
this._requests.enqueue({request: req, intent: "set", settings: aSettings});
|
||||
let settings = JSON.parse(JSON.stringify(aSettings));
|
||||
this._requests.enqueue({request: req, intent: "set", settings: settings});
|
||||
this.createTransactionAndProcess();
|
||||
return req;
|
||||
} else {
|
||||
|
@ -266,7 +291,7 @@ SettingsManager.prototype = {
|
|||
this._locks.enqueue(lock);
|
||||
this._settingsDB.ensureDB(
|
||||
function() { lock.createTransactionAndProcess(); },
|
||||
function() { dump("ensureDB error cb!\n"); },
|
||||
function() { dump("Cannot open Settings DB. Trying to open an old version?\n"); },
|
||||
myGlobal );
|
||||
this.nextTick(function() { this._open = false; }, lock);
|
||||
return lock;
|
||||
|
|
|
@ -35,11 +35,13 @@ function onFailure() {
|
|||
ok(false, "in on Failure!");
|
||||
}
|
||||
|
||||
var wifi = {"net3g.apn": "internet.mnc012.mcc345.gprs"};
|
||||
var wifi2 = {"net3g.apn": "internet.mnc012.mcc345.test"};
|
||||
const wifi = {"net3g.apn": "internet.mnc012.mcc345.gprs"};
|
||||
const wifi2 = {"net3g.apn": "internet.mnc012.mcc345.test"};
|
||||
var wifi3 = {"net3g.apn2": "internet.mnc012.mcc345.test3"};
|
||||
var wifiEnabled = {"wifi.enabled": true};
|
||||
var wifiDisabled = {"wifi.enabled": false};
|
||||
var screenBright = {"screen.brightness": 0.7};
|
||||
var screenBright2 = {"screen.brightness": 0.1};
|
||||
var wifiNetworks0 = { "wifi.networks[0]": { ssid: "myfreenetwork", mac: "01:23:45:67:89:ab", passwd: "secret"}};
|
||||
var wifiNetworks1 = { "wifi.networks[1]": { ssid: "myfreenetwork2", mac: "01:23:45:67:89:ab", passwd: "secret2"}};
|
||||
|
||||
|
@ -47,7 +49,8 @@ var combination = {
|
|||
"wifi.enabled": false,
|
||||
"screen.brightness": 0.7,
|
||||
"wifi.networks[0]": { ssid: "myfreenetwork", mac: "01:23:45:67:89:ab", passwd: "secret" },
|
||||
"test.test": true
|
||||
"test.test": true,
|
||||
"net3g.apn2": "internet.mnc012.mcc345.gprs"
|
||||
}
|
||||
|
||||
function equals(o1, o2) {
|
||||
|
@ -101,14 +104,70 @@ var steps = [
|
|||
req = lock.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
};
|
||||
},
|
||||
function () {
|
||||
ok(true, "Setting wifi");
|
||||
var lock = mozSettings.createLock();
|
||||
req = lock.set(wifi);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
|
||||
var lock2 = mozSettings.createLock();
|
||||
req2 = lock2.get("net3g.apn");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 1, "length 1");
|
||||
check(wifi, req2.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Change wifi1");
|
||||
var lock = mozSettings.createLock();
|
||||
req = lock.set(wifi2);
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Set Done");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
req2 = lock.set(screenBright);
|
||||
ok(true, "Get changed net3g.apn");
|
||||
req2 = lock.get("net3g.apn");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 1, "length 1");
|
||||
check(wifi2, req2.result);
|
||||
ok(true, "Get net3g.apn Done");
|
||||
next();
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Set Combination");
|
||||
var lock = mozSettings.createLock();
|
||||
req3 = lock.set(combination);
|
||||
req3.onsuccess = function () {
|
||||
ok(true, "set done");
|
||||
req4 = lock.get("net3g.apn2");
|
||||
req4.onsuccess = function() {
|
||||
ok(true, "Done");
|
||||
check(combination["net3g.apn2"], req4.result["net3g.apn2"]);
|
||||
next();
|
||||
}
|
||||
}
|
||||
req3.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
var lock = mozSettings.createLock();
|
||||
req4 = lock.get("net3g.apn2");
|
||||
req4.onsuccess = function() {
|
||||
ok(true, "Done");
|
||||
check(combination["net3g.apn2"], req4.result["net3g.apn2"]);
|
||||
next();
|
||||
}
|
||||
req2.onerror = onFailure;
|
||||
req4.onerror = onFailure;
|
||||
},
|
||||
function() {
|
||||
ok(true, "Get unknown key");
|
||||
|
@ -293,7 +352,7 @@ var steps = [
|
|||
req2.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Change wifi");
|
||||
ok(true, "Change wifi1");
|
||||
var lock = mozSettings.createLock();
|
||||
req = lock.set(wifi2);
|
||||
req.onsuccess = function () {
|
||||
|
@ -354,34 +413,34 @@ var steps = [
|
|||
};
|
||||
{
|
||||
var lock2 = mozSettings.createLock();
|
||||
req = lock2.get("*");
|
||||
req.onsuccess = function () {
|
||||
is(Object.keys(req.result).length, 32, "length 12");
|
||||
ok(true, JSON.stringify(req.result));
|
||||
req2 = lock2.get("*");
|
||||
req2.onsuccess = function () {
|
||||
is(Object.keys(req2.result).length, 32, "length 12");
|
||||
ok(true, JSON.stringify(req2.result));
|
||||
ok(true, "Get all settings Done");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
req2.onerror = onFailure;
|
||||
}
|
||||
var lock2 = mozSettings.createLock();
|
||||
var obj = {};
|
||||
obj["wifi.enabled" + 30] = true;
|
||||
req2 = lock2.set( obj );
|
||||
req2.onsuccess = function () {
|
||||
req3 = lock2.set( obj );
|
||||
req3.onsuccess = function () {
|
||||
ok(true, "Set12 Done");
|
||||
};
|
||||
req2.onerror = onFailure;
|
||||
req3.onerror = onFailure;
|
||||
|
||||
var lock3 = mozSettings.createLock();
|
||||
// with one lock
|
||||
for (var i = 0; i < 30; i++) {
|
||||
req3 = lock3.get("wifi.enabled" + i);
|
||||
req4 = lock3.get("wifi.enabled" + i);
|
||||
var testObj = {};
|
||||
testObj["wifi.enabled" + i] = true;
|
||||
req3.onsuccess = function () {
|
||||
req4.onsuccess = function () {
|
||||
check(this.request.result, this.testObj);
|
||||
ok(true, "Get1 Done");
|
||||
}.bind({testObj: testObj, request: req3});
|
||||
req3.onerror = onFailure;
|
||||
}.bind({testObj: testObj, request: req4});
|
||||
req4.onerror = onFailure;
|
||||
}
|
||||
|
||||
ok(true, "start next2!");
|
||||
|
@ -483,7 +542,7 @@ var steps = [
|
|||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Change wifi");
|
||||
ok(true, "Change wifi2");
|
||||
var lock = mozSettings.createLock();
|
||||
req = lock.set(wifi2);
|
||||
req.onsuccess = function () {
|
||||
|
|
Загрузка…
Ссылка в новой задаче