зеркало из https://github.com/mozilla/gecko-dev.git
337 строки
11 KiB
JavaScript
337 строки
11 KiB
JavaScript
/* global
|
|
sendAsyncMessage,
|
|
addMessageListener,
|
|
indexedDB
|
|
*/
|
|
"use strict";
|
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|
|
|
let imports = {};
|
|
|
|
Cu.import("resource://gre/modules/ContactDB.jsm", imports);
|
|
Cu.import("resource://gre/modules/ContactService.jsm", imports);
|
|
Cu.import("resource://gre/modules/Promise.jsm", imports);
|
|
Cu.importGlobalProperties(["indexedDB"]);
|
|
|
|
const {
|
|
STORE_NAME,
|
|
SAVED_GETALL_STORE_NAME,
|
|
REVISION_STORE,
|
|
DB_NAME,
|
|
ContactService,
|
|
} = imports;
|
|
// |const| will not work because
|
|
// it will make the Promise object immutable before assigning.
|
|
// Using Object.defineProperty() instead.
|
|
Object.defineProperty(this, "Promise", {
|
|
value: imports.Promise, writable: false, configurable: false
|
|
});
|
|
|
|
let DEBUG = false;
|
|
function debug(str) {
|
|
if (DEBUG){
|
|
dump("-*- TestMigrationChromeScript: " + str + "\n");
|
|
}
|
|
}
|
|
|
|
const DATA = {
|
|
12: {
|
|
SCHEMA: function createSchema12(db, transaction) {
|
|
let objectStore = db.createObjectStore(STORE_NAME, {keyPath: "id"});
|
|
objectStore.createIndex("familyName", "properties.familyName", { multiEntry: true });
|
|
objectStore.createIndex("givenName", "properties.givenName", { multiEntry: true });
|
|
objectStore.createIndex("familyNameLowerCase", "search.familyName", { multiEntry: true });
|
|
objectStore.createIndex("givenNameLowerCase", "search.givenName", { multiEntry: true });
|
|
objectStore.createIndex("telLowerCase", "search.tel", { multiEntry: true });
|
|
objectStore.createIndex("emailLowerCase", "search.email", { multiEntry: true });
|
|
objectStore.createIndex("tel", "search.exactTel", { multiEntry: true });
|
|
objectStore.createIndex("category", "properties.category", { multiEntry: true });
|
|
objectStore.createIndex("email", "search.email", { multiEntry: true });
|
|
objectStore.createIndex("telMatch", "search.parsedTel", {multiEntry: true});
|
|
db.createObjectStore(SAVED_GETALL_STORE_NAME);
|
|
db.createObjectStore(REVISION_STORE).put(0, "revision");
|
|
},
|
|
BAD: [
|
|
{
|
|
// this contact is bad because its "name" property is not an array and
|
|
// is the empty string (upgrade 16 to 17)
|
|
"properties": {
|
|
"name": "",
|
|
"email": [],
|
|
"url": [{
|
|
"type": ["source"],
|
|
"value": "urn:service:gmail:uid:http://www.google.com/m8/feeds/contacts/XXX/base/4567894654"
|
|
}],
|
|
"category": ["gmail"],
|
|
"adr": [],
|
|
"tel": [{
|
|
"type": ["mobile"],
|
|
"value": "+7 123 456-78-90"
|
|
}],
|
|
"sex": "undefined",
|
|
"genderIdentity": "undefined"
|
|
},
|
|
"search": {
|
|
"givenName": [],
|
|
"familyName": [],
|
|
"email": [],
|
|
"category": ["gmail"],
|
|
"tel": ["+71234567890","71234567890","1234567890","234567890","34567890",
|
|
"4567890","567890","67890","7890","890","90","0","81234567890"],
|
|
"exactTel": ["+71234567890"],
|
|
"parsedTel": ["+71234567890","1234567890","81234567890","34567890"]
|
|
},
|
|
"updated": new Date("2013-07-27T16:47:40.974Z"),
|
|
"published": new Date("2013-07-27T16:47:40.974Z"),
|
|
"id": "bad-1"
|
|
},
|
|
{
|
|
// This contact is bad because its "name" property is not an array
|
|
// (upgrade 14 to 15)
|
|
"properties": {
|
|
"name": "name-bad-2",
|
|
"email": [],
|
|
"url": [{
|
|
"type": ["source"],
|
|
"value": "urn:service:gmail:uid:http://www.google.com/m8/feeds/contacts/XXX/base/4567894654"
|
|
}],
|
|
"category": ["gmail"],
|
|
"adr": [],
|
|
"tel": [{
|
|
"type": ["mobile"],
|
|
"value": "+7 123 456-78-90"
|
|
}],
|
|
"sex": "undefined",
|
|
"genderIdentity": "undefined"
|
|
},
|
|
"search": {
|
|
"givenName": [],
|
|
"familyName": [],
|
|
"email": [],
|
|
"category": ["gmail"],
|
|
"tel": ["+71234567890","71234567890","1234567890","234567890","34567890",
|
|
"4567890","567890","67890","7890","890","90","0","81234567890"],
|
|
"exactTel": ["+71234567890"],
|
|
"parsedTel": ["+71234567890","1234567890","81234567890","34567890"]
|
|
},
|
|
"updated": new Date("2013-07-27T16:47:40.974Z"),
|
|
"published": new Date("2013-07-27T16:47:40.974Z"),
|
|
"id": "bad-2"
|
|
},
|
|
{
|
|
// This contact is bad because its bday property is a String (upgrade 15
|
|
// to 16), and its anniversary property is an empty string (upgrade 16
|
|
// to 17)
|
|
"properties": {
|
|
"name": ["name-bad-3"],
|
|
"email": [],
|
|
"url": [{
|
|
"type": ["source"],
|
|
"value": "urn:service:gmail:uid:http://www.google.com/m8/feeds/contacts/XXX/base/4567894654"
|
|
}],
|
|
"category": ["gmail"],
|
|
"adr": [],
|
|
"tel": [{
|
|
"type": ["mobile"],
|
|
"value": "+7 123 456-78-90"
|
|
}],
|
|
"sex": "undefined",
|
|
"genderIdentity": "undefined",
|
|
"bday": "2013-07-27T16:47:40.974Z",
|
|
"anniversary": ""
|
|
},
|
|
"search": {
|
|
"givenName": [],
|
|
"familyName": [],
|
|
"email": [],
|
|
"category": ["gmail"],
|
|
"tel": ["+71234567890","71234567890","1234567890","234567890","34567890",
|
|
"4567890","567890","67890","7890","890","90","0","81234567890"],
|
|
"exactTel": ["+71234567890"],
|
|
"parsedTel": ["+71234567890","1234567890","81234567890","34567890"]
|
|
},
|
|
"updated": new Date("2013-07-27T16:47:40.974Z"),
|
|
"published": new Date("2013-07-27T16:47:40.974Z"),
|
|
"id": "bad-3"
|
|
},
|
|
{
|
|
// This contact is bad because its tel property has a tel.type null
|
|
// value (upgrade 16 to 17), and email.type not array value (upgrade 14
|
|
// to 15)
|
|
"properties": {
|
|
"name": ["name-bad-4"],
|
|
"email": [{
|
|
"value": "toto@toto.com",
|
|
"type": "home"
|
|
}],
|
|
"url": [{
|
|
"type": ["source"],
|
|
"value": "urn:service:gmail:uid:http://www.google.com/m8/feeds/contacts/XXX/base/4567894654"
|
|
}],
|
|
"category": ["gmail"],
|
|
"adr": [],
|
|
"tel": [{
|
|
"type": null,
|
|
"value": "+7 123 456-78-90"
|
|
}],
|
|
"sex": "undefined",
|
|
"genderIdentity": "undefined"
|
|
},
|
|
"search": {
|
|
"givenName": [],
|
|
"familyName": [],
|
|
"email": [],
|
|
"category": ["gmail"],
|
|
"tel": ["+71234567890","71234567890","1234567890","234567890","34567890",
|
|
"4567890","567890","67890","7890","890","90","0","81234567890"],
|
|
"exactTel": ["+71234567890"],
|
|
"parsedTel": ["+71234567890","1234567890","81234567890","34567890"]
|
|
},
|
|
"updated": new Date("2013-07-27T16:47:40.974Z"),
|
|
"published": new Date("2013-07-27T16:47:40.974Z"),
|
|
"id": "bad-4"
|
|
}
|
|
],
|
|
GOOD: [
|
|
{
|
|
"properties": {
|
|
"name": ["name-good-1"],
|
|
"email": [],
|
|
"url": [{
|
|
"type": ["source"],
|
|
"value": "urn:service:gmail:uid:http://www.google.com/m8/feeds/contacts/XXX/base/4567894654"
|
|
}],
|
|
"category": ["gmail"],
|
|
"adr": [],
|
|
"tel": [{
|
|
"type": ["mobile"],
|
|
"value": "+7 123 456-78-90"
|
|
}],
|
|
"sex": "undefined",
|
|
"genderIdentity": "undefined"
|
|
},
|
|
"search": {
|
|
"givenName": [],
|
|
"familyName": [],
|
|
"email": [],
|
|
"category": ["gmail"],
|
|
"tel": ["+71234567890","71234567890","1234567890","234567890","34567890",
|
|
"4567890","567890","67890","7890","890","90","0","81234567890"],
|
|
"exactTel": ["+71234567890"],
|
|
"parsedTel": ["+71234567890","1234567890","81234567890","34567890"]
|
|
},
|
|
"updated": new Date("2013-07-27T16:47:40.974Z"),
|
|
"published": new Date("2013-07-27T16:47:40.974Z"),
|
|
"id": "good-1"
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
function DataManager(version) {
|
|
if (!(version in DATA)) {
|
|
throw new Error("Version " + version + " can't be found in our test datas.");
|
|
}
|
|
|
|
this.version = version;
|
|
this.data = DATA[version];
|
|
}
|
|
|
|
DataManager.prototype = {
|
|
open: function() {
|
|
debug("opening for version " + this.version);
|
|
var deferred = Promise.defer();
|
|
|
|
let req = indexedDB.open(DB_NAME, this.version);
|
|
req.onupgradeneeded = function() {
|
|
let db = req.result;
|
|
let transaction = req.transaction;
|
|
this.createSchema(db, transaction);
|
|
this.addContacts(db, transaction);
|
|
}.bind(this);
|
|
|
|
req.onsuccess = function() {
|
|
debug("succeeded opening the db, let's close it now");
|
|
req.result.close();
|
|
deferred.resolve(this.contactsCount());
|
|
}.bind(this);
|
|
|
|
req.onerror = function() {
|
|
deferred.reject(this.error);
|
|
};
|
|
|
|
return deferred.promise;
|
|
},
|
|
|
|
createSchema: function(db, transaction) {
|
|
debug("createSchema for version " + this.version);
|
|
this.data.SCHEMA(db, transaction);
|
|
},
|
|
|
|
addContacts: function(db, transaction) {
|
|
debug("adding contacts for version " + this.version);
|
|
var os = transaction.objectStore(STORE_NAME);
|
|
|
|
this.data.GOOD.forEach(function(contact) {
|
|
os.put(contact);
|
|
});
|
|
this.data.BAD.forEach(function(contact) {
|
|
os.put(contact);
|
|
});
|
|
},
|
|
|
|
contactsCount: function() {
|
|
return this.data.BAD.length + this.data.GOOD.length;
|
|
}
|
|
};
|
|
|
|
DataManager.delete = function() {
|
|
debug("Deleting the database");
|
|
var deferred = Promise.defer();
|
|
|
|
/* forcibly close the db before deleting it */
|
|
ContactService._db.close();
|
|
|
|
var req = indexedDB.deleteDatabase(DB_NAME);
|
|
req.onsuccess = function() {
|
|
debug("Successfully deleted!");
|
|
deferred.resolve();
|
|
};
|
|
|
|
req.onerror = function() {
|
|
debug("Not deleted, error is " + this.error.name);
|
|
deferred.reject(this.error);
|
|
};
|
|
|
|
req.onblocked = function() {
|
|
debug("Waiting for the current users");
|
|
};
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
addMessageListener("createDB", function(version) {
|
|
// Promises help handling gracefully exceptions
|
|
Promise.resolve().then(function() {
|
|
return new DataManager(version);
|
|
}).then(function(manager) {
|
|
return manager.open();
|
|
}).then(function onSuccess(count) {
|
|
sendAsyncMessage("createDB.success", count);
|
|
}, function onError(err) {
|
|
sendAsyncMessage("createDB.error", "Failed to create the DB: " +
|
|
"(" + err.name + ") " + err.message);
|
|
});
|
|
});
|
|
|
|
addMessageListener("deleteDB", function() {
|
|
Promise.resolve().then(
|
|
DataManager.delete
|
|
).then(function onSuccess() {
|
|
sendAsyncMessage("deleteDB.success");
|
|
}, function onError(err) {
|
|
sendAsyncMessage("deleteDB.error", "Failed to delete the DB:" + err.name);
|
|
});
|
|
});
|