Commit baebb209 authored by Aurel's avatar Aurel

Merge remote-tracking branch 'origin/master' into nodejs

parents 37e84374 70754e8f
...@@ -6308,33 +6308,52 @@ return new Parser; ...@@ -6308,33 +6308,52 @@ return new Parser;
/** /**
* 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) {
if (way === 'descending') { var result,
result = 1; cast_to,
} else if (way === 'ascending') { key = sort_list[0][0],
result = -1; way = sort_list[0][1],
} else { i,
throw new TypeError("Query.sortFunction(): " + l,
"Argument 2 must be 'ascending' or 'descending'"); a_string_array,
} b_string_array,
if (key_schema !== undefined && f_a,
key_schema.key_set !== undefined && f_b,
key_schema.key_set[key] !== undefined && tmp;
key_schema.key_set[key].cast_to !== undefined) {
if (typeof key_schema.key_set[key].cast_to === "string") { if (way === 'descending') {
cast_to = key_schema.cast_lookup[key_schema.key_set[key].cast_to]; result = 1;
} else if (way === 'ascending') {
result = -1;
} else { } else {
cast_to = key_schema.key_set[key].cast_to; throw new TypeError("Query.sortFunction(): " +
"Argument 2 must be 'ascending' or 'descending'");
} }
return function (a, b) {
var f_a = cast_to(a[key]), f_b = cast_to(b[key]); if (key_schema !== undefined &&
key_schema.key_set !== undefined &&
key_schema.key_set[key] !== undefined &&
key_schema.key_set[key].cast_to !== undefined) {
if (typeof key_schema.key_set[key].cast_to === "string") {
cast_to = key_schema.cast_lookup[key_schema.key_set[key].cast_to];
} else {
cast_to = key_schema.key_set[key].cast_to;
}
f_a = cast_to(a[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;
...@@ -6342,30 +6361,35 @@ return new Parser; ...@@ -6342,30 +6361,35 @@ return new Parser;
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;
}; };
} }
...@@ -6378,19 +6402,14 @@ return new Parser; ...@@ -6378,19 +6402,14 @@ return new Parser;
* @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;
} }
...@@ -6756,7 +6775,7 @@ return new Parser; ...@@ -6756,7 +6775,7 @@ return new Parser;
* @param {String} spec.value The value of the metadata to compare * @param {String} spec.value The value of the metadata to compare
*/ */
function ComplexQuery(spec, key_schema) { function ComplexQuery(spec, key_schema) {
Query.call(this); Query.call(this, key_schema);
/** /**
* Logical operator to use to compare object values * Logical operator to use to compare object values
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
{ {
"name": "jio", "name": "jio",
"version": "v3.27.0", "version": "v3.28.0",
"license": "LGPLv3", "license": "LGPLv3",
"author": "Nexedi SA", "author": "Nexedi SA",
"contributors": [ "contributors": [
......
...@@ -507,7 +507,7 @@ ...@@ -507,7 +507,7 @@
* @param {String} spec.value The value of the metadata to compare * @param {String} spec.value The value of the metadata to compare
*/ */
function ComplexQuery(spec, key_schema) { function ComplexQuery(spec, key_schema) {
Query.call(this); Query.call(this, key_schema);
/** /**
* Logical operator to use to compare object values * Logical operator to use to compare object values
......
...@@ -232,6 +232,64 @@ ...@@ -232,6 +232,64 @@
RSVP.all(promise).then(noop).always(start); RSVP.all(promise).then(noop).always(start);
}); });
test('Test key schema + jio query with sort on', function () {
var docList = function () {
return [
{'identifier': '10', 'number': '10'},
{'identifier': '2', 'number': '2'},
{'identifier': '19', 'number': '19'},
{'identifier': '100', 'number': '100'}
];
}, test_key_schema = {
cast_lookup: {
intType: function (value) {
if (typeof value === 'string') {
return parseInt(value, 10);
}
return value;
}
},
key_set: {
number: {
read_from: 'number',
cast_to: 'intType'
}
}
}, promise = [];
stop();
promise.push(
jIO.QueryFactory.create({
type: 'complex',
operator: 'OR',
query_list: [{
type: 'simple',
key: 'number',
operator: '<',
value: '19'
}, {
type: 'simple',
key: 'number',
operator: '=',
value: '19'
}]
}, test_key_schema).
exec(
docList(),
{sort_on: [['number', 'ascending']]}
).
then(function (dl) {
deepEqual(dl, [
{'identifier': '2', 'number': '2'},
{'identifier': '10', 'number': '10'},
{'identifier': '19', 'number': '19'}
], 'Key schema should be propagated from complex to simple queries');
})
);
RSVP.all(promise).then(noop).always(start);
});
test('Key Schema with translation lookup', function () { test('Key Schema with translation lookup', function () {
var docList = function () { var docList = function () {
......
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