Merge pull request #216 from fabien/fix/sorty-by-id

Allow partial list of ids for sortByIds
This commit is contained in:
Raymond Feng 2014-08-15 13:05:24 -07:00
commit 572dac06cb
3 changed files with 72 additions and 24 deletions

View File

@ -341,31 +341,10 @@ DataAccessObject.findByIds = function(ids, cond, cb) {
filter.where[pk] = { inq: ids };
mergeQuery(filter, cond || {});
this.find(filter, function(err, results) {
cb(err, err ? results : this.sortByIds(ids, results));
cb(err, err ? results : utils.sortObjectsByIds(pk, ids, results));
}.bind(this));
};
DataAccessObject.sortByIds = function(ids, results) {
var pk = this.dataSource.idName(this.modelName) || 'id';
ids = ids.map(function(id) {
return (typeof id === 'object') ? id.toString() : id;
});
results.sort(function(x, y) {
var idA = (typeof x[pk] === 'object') ? x[pk].toString() : x[pk];
var idB = (typeof y[pk] === 'object') ? y[pk].toString() : y[pk];
var a = ids.indexOf(idA);
var b = ids.indexOf(idB);
if (a === -1 || b === -1) return 1; // last
if (a !== b) {
if (a > b) return 1;
if (a < b) return -1;
}
});
return results;
};
function convertNullToNotFoundError(ctx, cb) {
if (ctx.result !== null) return cb();

View File

@ -6,6 +6,7 @@ exports.parseSettings = parseSettings;
exports.mergeSettings = mergeSettings;
exports.isPlainObject = isPlainObject;
exports.defineCachedRelations = defineCachedRelations;
exports.sortObjectsByIds = sortObjectsByIds;
var traverse = require('traverse');
@ -203,4 +204,40 @@ function defineCachedRelations(obj) {
function isPlainObject(obj) {
return (typeof obj === 'object') && (obj !== null)
&& (obj.constructor === Object);
}
}
function sortObjectsByIds(idName, ids, objects, strict) {
ids = ids.map(function(id) {
return (typeof id === 'object') ? id.toString() : id;
});
var indexOf = function(x) {
var isObj = (typeof x[idName] === 'object'); // ObjectID
var id = isObj ? x[idName].toString() : x[idName];
return ids.indexOf(id);
};
var heading = [];
var tailing = [];
objects.forEach(function(x) {
if (typeof x === 'object') {
var idx = indexOf(x);
if (strict && idx === -1) return;
idx === -1 ? tailing.push(x) : heading.push(x);
}
});
heading.sort(function(x, y) {
var a = indexOf(x);
var b = indexOf(y);
if (a === -1 || b === -1) return 1; // last
if (a === b) return 0;
if (a > b) return 1;
if (a < b) return -1;
});
return heading.concat(tailing);
};

View File

@ -3,6 +3,7 @@ var utils = require('../lib/utils');
var fieldsToArray = utils.fieldsToArray;
var removeUndefined = utils.removeUndefined;
var mergeSettings = utils.mergeSettings;
var sortObjectsByIds = utils.sortObjectsByIds;
describe('util.fieldsToArray', function () {
it('Turn objects and strings into an array of fields to include when finding models', function () {
@ -185,4 +186,35 @@ describe('mergeSettings', function () {
should.deepEqual(dst.acls, expected.acls, 'Merged settings should match the expectation');
});
});
});
describe('sortObjectsByIds', function () {
var items = [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' },
{ id: 3, name: 'c' },
{ id: 4, name: 'd' },
{ id: 5, name: 'e' },
{ id: 6, name: 'f' }
];
it('should sort', function() {
var sorted = sortObjectsByIds('id', [6, 5, 4, 3, 2, 1], items);
var names = sorted.map(function(u) { return u.name; });
should.deepEqual(names, ['f', 'e', 'd', 'c', 'b', 'a']);
});
it('should sort - partial ids', function() {
var sorted = sortObjectsByIds('id', [5, 3, 2], items);
var names = sorted.map(function(u) { return u.name; });
should.deepEqual(names, ['e', 'c', 'b', 'a', 'd', 'f']);
});
it('should sort - strict', function() {
var sorted = sortObjectsByIds('id', [5, 3, 2], items, true);
var names = sorted.map(function(u) { return u.name; });
should.deepEqual(names, ['e', 'c', 'b']);
});
});