diff --git a/dom/contacts/fallback/ContactDB.jsm b/dom/contacts/fallback/ContactDB.jsm index ed73241562a2..c0db32c36fe4 100644 --- a/dom/contacts/fallback/ContactDB.jsm +++ b/dom/contacts/fallback/ContactDB.jsm @@ -20,7 +20,7 @@ Cu.import("resource://gre/modules/IndexedDBHelper.jsm"); Cu.import("resource://gre/modules/PhoneNumberUtils.jsm"); const DB_NAME = "contacts"; -const DB_VERSION = 17; +const DB_VERSION = 18; const STORE_NAME = "contacts"; const SAVED_GETALL_STORE_NAME = "getallcache"; const CHUNK_SIZE = 20; @@ -167,8 +167,10 @@ ContactDB.prototype = { let objectStore = aDb.createObjectStore(STORE_NAME, {keyPath: "id"}); objectStore.createIndex("familyName", "properties.familyName", { multiEntry: true }); objectStore.createIndex("givenName", "properties.givenName", { multiEntry: true }); + objectStore.createIndex("name", "properties.name", { multiEntry: true }); objectStore.createIndex("familyNameLowerCase", "search.familyName", { multiEntry: true }); objectStore.createIndex("givenNameLowerCase", "search.givenName", { multiEntry: true }); + objectStore.createIndex("nameLowerCase", "search.name", { multiEntry: true }); objectStore.createIndex("telLowerCase", "search.tel", { multiEntry: true }); objectStore.createIndex("emailLowerCase", "search.email", { multiEntry: true }); objectStore.createIndex("tel", "search.exactTel", { multiEntry: true }); @@ -403,11 +405,11 @@ ContactDB.prototype = { objectStore = aTransaction.objectStore(STORE_NAME); } let names = objectStore.indexNames; - let blackList = ["tel", "familyName", "givenName", "familyNameLowerCase", + let whiteList = ["tel", "familyName", "givenName", "familyNameLowerCase", "givenNameLowerCase", "telLowerCase", "category", "email", "emailLowerCase"]; for (var i = 0; i < names.length; i++) { - if (blackList.indexOf(names[i]) < 0) { + if (whiteList.indexOf(names[i]) < 0) { objectStore.deleteIndex(names[i]); } } @@ -699,6 +701,34 @@ ContactDB.prototype = { } } }, + function upgrade17to18() { + if (DEBUG) { + debug("Adding the name index"); + } + + if (!objectStore) { + objectStore = aTransaction.objectStore(STORE_NAME); + } + + objectStore.createIndex("name", "properties.name", { multiEntry: true }); + objectStore.createIndex("nameLowerCase", "search.name", { multiEntry: true }); + + objectStore.openCursor().onsuccess = function(event) { + let cursor = event.target.result; + if (cursor) { + let value = cursor.value; + value.search.name = []; + if (value.properties.name) { + value.properties.name.forEach(function addNameIndex(name) { + value.search.name.push(name.toLowerCase()); + }); + } + cursor.update(value); + } else { + next(); + } + }; + }, ]; let index = aOldVersion; @@ -718,10 +748,21 @@ ContactDB.prototype = { return; } }; - if (aNewVersion > steps.length) { - dump("Contacts DB upgrade error!"); + + function fail(why) { + why = why || ""; + if (this.error) { + why += " (root cause: " + this.error.name + ")"; + } + + debug("Contacts DB upgrade error: " + why); aTransaction.abort(); } + + if (aNewVersion > steps.length) { + fail("No migration steps for the new version!"); + } + next(); }, @@ -729,6 +770,7 @@ ContactDB.prototype = { let contact = {properties: {}}; contact.search = { + name: [], givenName: [], familyName: [], email: [], diff --git a/dom/contacts/tests/test_contacts_basics.html b/dom/contacts/tests/test_contacts_basics.html index f5a6b2c46bfc..bdbf0fab5327 100644 --- a/dom/contacts/tests/test_contacts_basics.html +++ b/dom/contacts/tests/test_contacts_basics.html @@ -102,6 +102,7 @@ var adr2 = { }; var properties1 = { + // please keep capital letters at the start of these names name: ["Test1 TestFamilyName", "Test2 Wagner"], familyName: ["TestFamilyName","Wagner"], givenName: ["Test1","Test2"], @@ -527,6 +528,62 @@ var steps = [ }; req.onerror = onFailure; }, + function() { + ok(true, "Retrieving by name equality 1"); + var options = {filterBy: ["name"], + filterOp: "equals", + filterValue: properties1.name[0]}; + req = mozContacts.find(options); + req.onsuccess = function () { + is(req.result.length, 1, "Found exactly 1 contact."); + findResult1 = req.result[0]; + checkContacts(createResult1, findResult1); + next(); + }; + req.onerror = onFailure; + }, + function() { + ok(true, "Retrieving by name equality 2"); + var options = {filterBy: ["name"], + filterOp: "equals", + filterValue: properties1.name[1]}; + req = mozContacts.find(options); + req.onsuccess = function () { + is(req.result.length, 1, "Found exactly 1 contact."); + findResult1 = req.result[0]; + checkContacts(createResult1, findResult1); + next(); + }; + req.onerror = onFailure; + }, + function() { + ok(true, "Retrieving by name substring 1"); + var options = {filterBy: ["name"], + filterOp: "startsWith", + filterValue: properties1.name[0].substring(0,3).toLowerCase()}; + req = mozContacts.find(options); + req.onsuccess = function () { + is(req.result.length, 1, "Found exactly 1 contact."); + findResult1 = req.result[0]; + checkContacts(createResult1, findResult1); + next(); + }; + req.onerror = onFailure; + }, + function() { + ok(true, "Retrieving by name substring 2"); + var options = {filterBy: ["name"], + filterOp: "startsWith", + filterValue: properties1.name[1].substring(0,3).toLowerCase()}; + req = mozContacts.find(options); + req.onsuccess = function () { + is(req.result.length, 1, "Found exactly 1 contact."); + findResult1 = req.result[0]; + checkContacts(createResult1, findResult1); + next(); + }; + req.onerror = onFailure; + }, function () { ok(true, "Remove contact1"); mozContacts.oncontactchange = function(event) { diff --git a/dom/contacts/tests/test_contacts_upgrade.html b/dom/contacts/tests/test_contacts_upgrade.html index a937fdd36bb4..b4438292aaa2 100644 --- a/dom/contacts/tests/test_contacts_upgrade.html +++ b/dom/contacts/tests/test_contacts_upgrade.html @@ -133,6 +133,7 @@ function checkDBContacts(dbContact1, dbContact2) { checkStrArray(contact1.familyNameLowerCase, contact2.familyNameLowerCase, "Same familyNameLowerCase index"); checkStrArray(contact1.givenName, contact2.givenName, "Same givenName index"); checkStrArray(contact1.givenNameLowerCase, contact2.givenNameLowerCase, "Same givenNameLowerCase index"); + checkStrArray(contact1.name, contact2.name, "Same name index"); checkStrArray(contact1.tel, contact2.tel, "Same tel index"); checkStrArray(contact1.telLowerCase, contact2.telLowerCase, "Same telLowerCase index"); checkStrArray(contact1.telMatch, contact2.telMatch, "Same telMatch index"); @@ -154,7 +155,7 @@ cdb.init(); let CONTACT_PROPS = { id: "ab74671e36be41b680f8f030e7e24ea2", properties: { - name: ["magnificentest foo bar the third"], + name: ["Magnificentest foo bar the third"], givenName: ["foo"], familyName: ["bar"], honorificPrefix: ["magnificentest"],