Commit 7066ac03 authored by Romain Courteaud's avatar Romain Courteaud

Queries: fix multi key sorting

parent be73a5c4
...@@ -40,12 +40,23 @@ ...@@ -40,12 +40,23 @@
/** /**
* A sort function to sort items by key * A sort function to sort items by key
* *
* @param {String} key The key to sort on * @param {Array} sort_list List of couples [key, direction]
* @param {String} [way="ascending"] 'ascending' or 'descending'
* @return {Function} The sort function * @return {Function} The sort function
*/ */
function sortFunction(key, way, key_schema) { function generateSortFunction(key_schema, sort_list) {
var result, cast_to; return function sortByMultipleIndex(a, b) {
var result,
cast_to,
key = sort_list[0][0],
way = sort_list[0][1],
i,
l,
a_string_array,
b_string_array,
f_a,
f_b,
tmp;
if (way === 'descending') { if (way === 'descending') {
result = 1; result = 1;
} else if (way === 'ascending') { } else if (way === 'ascending') {
...@@ -54,6 +65,7 @@ ...@@ -54,6 +65,7 @@
throw new TypeError("Query.sortFunction(): " + throw new TypeError("Query.sortFunction(): " +
"Argument 2 must be 'ascending' or 'descending'"); "Argument 2 must be 'ascending' or 'descending'");
} }
if (key_schema !== undefined && if (key_schema !== undefined &&
key_schema.key_set !== undefined && key_schema.key_set !== undefined &&
key_schema.key_set[key] !== undefined && key_schema.key_set[key] !== undefined &&
...@@ -63,10 +75,17 @@ ...@@ -63,10 +75,17 @@
} else { } else {
cast_to = key_schema.key_set[key].cast_to; cast_to = key_schema.key_set[key].cast_to;
} }
return function (a, b) { f_a = cast_to(a[key]);
var f_a = cast_to(a[key]), f_b = cast_to(b[key]); f_b = cast_to(b[key]);
if (typeof f_b.cmp === 'function') { if (typeof f_b.cmp === 'function') {
return result * f_b.cmp(f_a); tmp = result * f_b.cmp(f_a);
if (tmp !== 0) {
return tmp;
}
if (sort_list.length > 1) {
return generateSortFunction(key_schema, sort_list.slice(1))(a, b);
}
return tmp;
} }
if (f_a > f_b) { if (f_a > f_b) {
return -result; return -result;
...@@ -74,30 +93,35 @@ ...@@ -74,30 +93,35 @@
if (f_a < f_b) { if (f_a < f_b) {
return result; return result;
} }
if (sort_list.length > 1) {
return generateSortFunction(key_schema, sort_list.slice(1))(a, b);
}
return 0; return 0;
};
} }
return function (a, b) {
// this comparison is 5 times faster than json comparison // this comparison is 5 times faster than json comparison
var i, l; a_string_array = metadataValueToStringArray(a[key]) || [];
a = metadataValueToStringArray(a[key]) || []; b_string_array = metadataValueToStringArray(b[key]) || [];
b = metadataValueToStringArray(b[key]) || []; l = Math.max(a_string_array.length, b_string_array.length);
l = a.length > b.length ? a.length : b.length;
for (i = 0; i < l; i += 1) { for (i = 0; i < l; i += 1) {
if (a[i] === undefined) { if (a_string_array[i] === undefined) {
return result; return result;
} }
if (b[i] === undefined) { if (b_string_array[i] === undefined) {
return -result; return -result;
} }
if (a[i] > b[i]) { if (a_string_array[i] > b_string_array[i]) {
return -result; return -result;
} }
if (a[i] < b[i]) { if (a_string_array[i] < b_string_array[i]) {
return result; return result;
} }
} }
if (sort_list.length > 1) {
return generateSortFunction(key_schema, sort_list.slice(1))(a, b);
}
return 0; return 0;
}; };
} }
...@@ -110,19 +134,14 @@ ...@@ -110,19 +134,14 @@
* @return {Array} The filtered list * @return {Array} The filtered list
*/ */
function sortOn(sort_on_option, list, key_schema) { function sortOn(sort_on_option, list, key_schema) {
var sort_index;
if (!Array.isArray(sort_on_option)) { if (!Array.isArray(sort_on_option)) {
throw new TypeError("jioquery.sortOn(): " + throw new TypeError("jioquery.sortOn(): " +
"Argument 1 is not of type 'array'"); "Argument 1 is not of type 'array'");
} }
for (sort_index = sort_on_option.length - 1; sort_index >= 0; list.sort(generateSortFunction(
sort_index -= 1) { key_schema,
list.sort(sortFunction( sort_on_option
sort_on_option[sort_index][0],
sort_on_option[sort_index][1],
key_schema
)); ));
}
return list; return list;
} }
......
...@@ -594,4 +594,30 @@ ...@@ -594,4 +594,30 @@
.always(start); .always(start);
}); });
});*/ });*/
test('Multiple sort_on options', function () {
var i,
len = 1000,
doc_list = [];
for (i = 0; i < len; i += 1) {
doc_list.push({s: 'b', i: i});
}
stop();
expect(1);
jIO.QueryFactory.create("").exec(
doc_list,
{
sort_on: [['s', 'ascending'], ['i', 'ascending']],
limit: [0, 2]
}
)
.then(function (list) {
deepEqual(list, [
{s: 'b', i: 0},
{s: 'b', i: 1}
], 'Document list is sorted');
}).always(start);
});
})); }));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment