Bug 734198 - Contacts API: Add Sorting. r=bent

This commit is contained in:
Gregor Wagner 2012-04-02 16:39:57 -07:00
Родитель d38cd2635d
Коммит 73c890014f
5 изменённых файлов: 188 добавлений и 18 удалений

Просмотреть файл

@ -19,7 +19,7 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
XPCOMUtils.defineLazyGetter(Services, "rs", function() {
XPCOMUtils.defineLazyGetter(Services, "DOMRequest", function() {
return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
});
@ -79,16 +79,7 @@ const CONTACTFINDOPTIONS_CONTRACTID = "@mozilla.org/contactFindOptions;1";
const CONTACTFINDOPTIONS_CID = Components.ID("{e31daea0-0cb6-11e1-be50-0800200c9a66}");
const nsIDOMContactFindOptions = Components.interfaces.nsIDOMContactFindOptions;
function ContactFindOptions(aFilterValue, aFilterBy, aFilterOp, aFilterLimit) {
this.filterValue = aFilterValue || '';
this.filterBy = new Array();
for (let field in aFilterBy)
this.filterBy.push(field);
this.filterOp = aFilterOp || '';
this.filterLimit = aFilterLimit || 0;
};
function ContactFindOptions() { };
ContactFindOptions.prototype = {
@ -282,7 +273,7 @@ ContactManager.prototype = {
if (req) {
let result = this._convertContactsArray(contacts);
debug("result: " + JSON.stringify(result));
Services.rs.fireSuccess(req, result);
Services.DOMRequest.fireSuccess(req, result);
} else {
debug("no request stored!" + msg.requestID);
}
@ -292,7 +283,7 @@ ContactManager.prototype = {
case "Contact:Remove:Return:OK":
req = this.getRequest(msg.requestID);
if (req)
Services.rs.fireSuccess(req, null);
Services.DOMRequest.fireSuccess(req, null);
break;
case "Contacts:Find:Return:KO":
case "Contact:Save:Return:KO":
@ -300,7 +291,7 @@ ContactManager.prototype = {
case "Contacts:Clear:Return:KO":
req = this.getRequest(msg.requestID);
if (req)
Services.rs.fireError(req, msg.errorMsg);
Services.DOMRequest.fireError(req, msg.errorMsg);
break;
default:
debug("Wrong message: " + aMessage.name);

Просмотреть файл

@ -377,6 +377,9 @@ ContactDB.prototype = {
}
}
// Sorting functions takes care of limit if set.
let limit = options.sortBy === 'undefined' ? options.filterLimit : null;
let filter_keys = fields.slice();
for (let key = filter_keys.shift(); key; key = filter_keys.shift()) {
let request;
@ -387,13 +390,13 @@ ContactDB.prototype = {
debug("Getting index: " + key);
// case sensitive
let index = store.index(key);
request = index.getAll(options.filterValue, options.filterLimit);
request = index.getAll(options.filterValue, limit);
} else {
// not case sensitive
let tmp = options.filterValue.toLowerCase();
let range = this._global.IDBKeyRange.bound(tmp, tmp + "\uFFFF");
let index = store.index(key + "LowerCase");
request = index.getAll(range, options.filterLimit);
request = index.getAll(range, limit);
}
if (!txn.result)
txn.result = {};
@ -410,8 +413,9 @@ ContactDB.prototype = {
debug("ContactDB:_findAll: " + JSON.stringify(options));
if (!txn.result)
txn.result = {};
store.getAll(null, options.filterLimit).onsuccess = function (event) {
// Sorting functions takes care of limit if set.
let limit = options.sortBy === 'undefined' ? options.filterLimit : null;
store.getAll(null, limit).onsuccess = function (event) {
debug("Request successful. Record count:", event.target.result.length);
for (let i in event.target.result)
txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]);

Просмотреть файл

@ -64,6 +64,16 @@ let DOMContactManager = {
},
receiveMessage: function(aMessage) {
function sortfunction(a, b){
let x, y;
if (a.properties[msg.findOptions.sortBy])
x = a.properties[msg.findOptions.sortBy][0].toLowerCase();
if (b.properties[msg.findOptions.sortBy])
y = b.properties[msg.findOptions.sortBy][0].toLowerCase();
if (msg.findOptions == 'ascending')
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
return ((x < y) ? 1 : ((x > y) ? -1 : 0));
}
debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
let msg = aMessage.json;
switch (aMessage.name) {
@ -73,6 +83,13 @@ let DOMContactManager = {
function(contacts) {
for (let i in contacts)
result.push(contacts[i]);
if (msg.findOptions.sortOrder !== 'undefined' && msg.findOptions.sortBy !== 'undefined') {
debug('sortBy: ' + msg.findOptions.sortBy + ', sortOrder: ' + msg.findOptions.sortOrder );
result.sort(sortfunction);
if (msg.findOptions.filterLimit)
result = result.slice(0, msg.findOptions.filterLimit);
}
debug("result:" + JSON.stringify(result));
ppmm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
}.bind(this),

Просмотреть файл

@ -28,6 +28,35 @@ Components.classes["@mozilla.org/permissionmanager;1"]
"webcontacts-manage",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
// For Sorting
var c1 = {
name: "a",
familyName: ["a"],
givenName: ["a"],
};
var c2 = {
name: "b",
familyName: ["b"],
givenName: ["b"],
};
var c3 = {
name: "c",
familyName: ["c","x"],
givenName: ["c","x"],
};
var c4 = {
name: "d",
familyName: ["d","e"],
givenName: ["d","e"],
};
var c5 = {
name: "empty"
};
var adr1 = {
streetAddress: "street 1",
locality: "locality 1",
@ -640,6 +669,18 @@ var steps = [
}
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts with limit 10 and sorted");
var options = { filterLimit: 10,
sortBy: 'FamilyName',
sortOrder: 'descending' };
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 10, "10 Entries.");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts2");
var options = {filterBy: ["name"],
@ -743,6 +784,121 @@ var steps = [
}
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact();
createResult1.init(c3);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
checkContacts(c3, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact();
createResult1.init(c2);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
checkContacts(c2, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact();
createResult1.init(c4);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
checkContacts(c4, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact();
createResult1.init(c1);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
checkContacts(c1, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting");
var options = {sortBy: "familyName",
sortOrder: "ascending"};
req = navigator.mozContacts.find(options);
req.onsuccess = function () {
is(req.result.length, 4, "4 results");
checkContacts(req.result[0], c1);
checkContacts(req.result[1], c2);
checkContacts(req.result[2], c3);
checkContacts(req.result[3], c4);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting");
var options = {sortBy: "familyName",
sortOrder: "descending"};
req = navigator.mozContacts.find(options);
req.onsuccess = function () {
is(req.result.length, 4, "4 results");
checkContacts(req.result[0], c4);
checkContacts(req.result[1], c3);
checkContacts(req.result[2], c2);
checkContacts(req.result[3], c1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting");
createResult1 = new mozContact();
createResult1.init(c5);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
checkContacts(c5, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Test sorting with empty string");
var options = {sortBy: "familyName",
sortOrder: "ascending"};
req = navigator.mozContacts.find(options);
req.onsuccess = function () {
is(req.result.length, 5, "5 results");
checkContacts(req.result[0], c5);
checkContacts(req.result[1], c1);
checkContacts(req.result[2], c2);
checkContacts(req.result[3], c3);
checkContacts(req.result[4], c4);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Deleting database");
req = mozContacts.clear()
req.onsuccess = function () {
ok(true, "Deleted the database");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "all done!\n");
clearTemps();

Просмотреть файл

@ -23,6 +23,8 @@ interface nsIDOMContactFindOptions : nsISupports
attribute DOMString filterValue; // e.g. "Tom"
attribute DOMString filterOp; // e.g. "contains"
attribute jsval filterBy; // DOMString[], e.g. ["givenName", "nickname"]
attribute DOMString sortBy; // e.g. "givenName"
attribute DOMString sortOrder; // e.g. "descending"
attribute unsigned long filterLimit;
};