Commit b9464f1a authored by Aurélien Vermylen's avatar Aurélien Vermylen

Merge branch 'master' into clearroad

Conflicts:
	dist/jio-latest.js
	dist/jio-latest.min.js
parents c01fe22d 522f08a4
This diff is collapsed.
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",
"version": "v3.23.1",
"version": "v3.25.0",
"license": "LGPLv3",
"author": "Nexedi SA",
"contributors": [
......
This diff is collapsed.
/*jslint nomen: true*/
/*global RSVP*/
(function (jIO, RSVP) {
/*global RSVP, jiodate*/
(function (jIO, RSVP, jiodate) {
"use strict";
function dateType(str) {
return jiodate.JIODate(new Date(str).toISOString());
}
function initKeySchema(storage, spec) {
var property;
for (property in spec.schema) {
if (spec.schema.hasOwnProperty(property)) {
if (spec.schema[property].type === "string" &&
spec.schema[property].format === "date-time") {
storage._key_schema.key_set[property] = {
read_from: property,
cast_to: "dateType"
};
if (storage._key_schema.cast_lookup.dateType === undefined) {
storage._key_schema.cast_lookup.dateType = dateType;
}
} else {
throw new jIO.util.jIOError(
"Wrong schema for property: " + property,
400
);
}
}
}
}
/**
* The jIO QueryStorage extension
*
......@@ -11,7 +38,8 @@
*/
function QueryStorage(spec) {
this._sub_storage = jIO.createJIO(spec.sub_storage);
this._key_schema = spec.key_schema;
this._key_schema = {key_set: {}, cast_lookup: {}};
initKeySchema(this, spec);
}
QueryStorage.prototype.get = function () {
......@@ -211,4 +239,4 @@
jIO.addStorage('query', QueryStorage);
}(jIO, RSVP));
}(jIO, RSVP, jiodate));
......@@ -44,8 +44,8 @@
* @param {String} [way="ascending"] 'ascending' or 'descending'
* @return {Function} The sort function
*/
function sortFunction(key, way) {
var result;
function sortFunction(key, way, key_schema) {
var result, cast_to;
if (way === 'descending') {
result = 1;
} else if (way === 'ascending') {
......@@ -54,6 +54,29 @@
throw new TypeError("Query.sortFunction(): " +
"Argument 2 must be 'ascending' or 'descending'");
}
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;
}
return function (a, b) {
var f_a = cast_to(a[key]), f_b = cast_to(b[key]);
if (typeof f_b.cmp === 'function') {
return result * f_b.cmp(f_a);
}
if (f_a > f_b) {
return -result;
}
if (f_a < f_b) {
return result;
}
return 0;
};
}
return function (a, b) {
// this comparison is 5 times faster than json comparison
var i, l;
......@@ -78,6 +101,7 @@
};
}
/**
* Sort a list of items, according to keys and directions.
*
......@@ -85,7 +109,7 @@
* @param {Array} list The item list to sort
* @return {Array} The filtered list
*/
function sortOn(sort_on_option, list) {
function sortOn(sort_on_option, list, key_schema) {
var sort_index;
if (!Array.isArray(sort_on_option)) {
throw new TypeError("jioquery.sortOn(): " +
......@@ -95,7 +119,8 @@
sort_index -= 1) {
list.sort(sortFunction(
sort_on_option[sort_index][0],
sort_on_option[sort_index][1]
sort_on_option[sort_index][1],
key_schema
));
}
return list;
......@@ -158,6 +183,35 @@
return list;
}
function checkKeySchema(key_schema) {
var prop;
if (key_schema !== undefined) {
if (typeof key_schema !== 'object') {
throw new TypeError("Query().create(): " +
"key_schema is not of type 'object'");
}
// key_set is mandatory
if (key_schema.key_set === undefined) {
throw new TypeError("Query().create(): " +
"key_schema has no 'key_set' property");
}
for (prop in key_schema) {
if (key_schema.hasOwnProperty(prop)) {
switch (prop) {
case 'key_set':
case 'cast_lookup':
case 'match_lookup':
break;
default:
throw new TypeError("Query().create(): " +
"key_schema has unknown property '" + prop + "'");
}
}
}
}
}
/**
* The query to use to filter a list of objects.
* This is an abstract class.
......@@ -165,7 +219,10 @@
* @class Query
* @constructor
*/
function Query() {
function Query(key_schema) {
checkKeySchema(key_schema);
this._key_schema = key_schema || {};
/**
* Called before parsing the query. Must be overridden!
......@@ -238,7 +295,7 @@
}
if (option.sort_on) {
sortOn(option.sort_on, item_list);
sortOn(option.sort_on, item_list, this._key_schema);
}
if (option.limit) {
......@@ -577,7 +634,7 @@
*/
QueryFactory.create = function (object, key_schema) {
if (object === "") {
return new Query();
return new Query(key_schema);
}
if (typeof object === "string") {
object = parseStringToObject(object);
......@@ -609,35 +666,6 @@
throw new TypeError("This object is not a query");
}
function checkKeySchema(key_schema) {
var prop;
if (key_schema !== undefined) {
if (typeof key_schema !== 'object') {
throw new TypeError("SimpleQuery().create(): " +
"key_schema is not of type 'object'");
}
// key_set is mandatory
if (key_schema.key_set === undefined) {
throw new TypeError("SimpleQuery().create(): " +
"key_schema has no 'key_set' property");
}
for (prop in key_schema) {
if (key_schema.hasOwnProperty(prop)) {
switch (prop) {
case 'key_set':
case 'cast_lookup':
case 'match_lookup':
break;
default:
throw new TypeError("SimpleQuery().create(): " +
"key_schema has unknown property '" + prop + "'");
}
}
}
}
}
/**
* The SimpleQuery inherits from Query, and compares one metadata value
*
......@@ -649,11 +677,7 @@
* @param {String} spec.value The value of the metadata to compare
*/
function SimpleQuery(spec, key_schema) {
Query.call(this);
checkKeySchema(key_schema);
this._key_schema = key_schema || {};
Query.call(this, key_schema);
/**
* Operator to use to compare object values
......
This diff is collapsed.
/*jslint nomen: true*/
/*global Blob*/
/*global Blob, jiodate*/
(function (jIO, QUnit, Blob) {
"use strict";
var test = QUnit.test,
......@@ -24,9 +24,10 @@
// queryStorage.constructor
/////////////////////////////////////////////////////////////////
module("queryStorage.constructor");
test("create substorage", function () {
test("accept parameters", function () {
var jio = jIO.createJIO({
type: "query",
schema: {'date': {type: 'string', format: 'date-time'}},
sub_storage: {
type: "querystorage200"
}
......@@ -34,9 +35,37 @@
ok(jio.__storage._sub_storage instanceof jio.constructor);
equal(jio.__storage._sub_storage.__type, "querystorage200");
deepEqual(jio.__storage._key_schema.key_set, {
"date": {
"cast_to": "dateType",
"read_from": "date"
}
}, 'check key_schema');
ok(typeof jio.__storage._key_schema.cast_lookup.dateType === 'function');
});
test("failed on wrond schema", function () {
throws(
function () {
jIO.createJIO({
type: "query",
schema: {'date': {type: 'couscous'}},
sub_storage: {
type: "querystorage200"
}
});
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 400);
equal(error.message,
"Wrong schema for property: date");
return true;
}
);
});
/////////////////////////////////////////////////////////////////
// queryStorage.get
/////////////////////////////////////////////////////////////////
......@@ -823,6 +852,99 @@
});
});
test("manual query used and use schema", function () {
stop();
expect(4);
function StorageSchemaCapacity() {
return this;
}
StorageSchemaCapacity.prototype.get = function (id) {
var doc = {
title: id,
id: "ID " + id,
"another": "property"
};
if (id === "foo") {
equal(id, "foo", "Get foo");
doc.modification_date = "Fri, 08 Sep 2017 07:46:27 +0000";
} else {
equal(id, "bar", "Get bar");
doc.modification_date = "Thu, 07 Sep 2017 18:59:23 +0000";
}
return doc;
};
StorageSchemaCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list")) {
return true;
}
return false;
};
StorageSchemaCapacity.prototype.buildQuery = function (options) {
deepEqual(options, {}, "No query parameter");
var result2 = [{
id: "foo",
value: {}
}, {
id: "bar",
value: {}
}];
return result2;
};
jIO.addStorage(
'querystoragenoschemacapacity',
StorageSchemaCapacity
);
var jio = jIO.createJIO({
type: "query",
schema: {
"modification_date": {
"type": "string",
"format": "date-time"
}
},
sub_storage: {
type: "querystoragenoschemacapacity"
}
});
jio.allDocs({
sort_on: [["modification_date", "descending"]],
limit: [0, 5],
select_list: ['modification_date']
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [
{
id: "foo",
doc: {},
value: {
modification_date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
}, {
id: "bar",
doc: {},
value: {
modification_date: "Thu, 07 Sep 2017 18:59:23 +0000"
}
}
],
total_rows: 2
}
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
/////////////////////////////////////////////////////////////////
// queryStorage.repair
/////////////////////////////////////////////////////////////////
......
......@@ -54,7 +54,7 @@
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"SimpleQuery().create(): key_schema is not of type 'object'",
"Query().create(): key_schema is not of type 'object'",
'wrong exception message');
}
......@@ -64,7 +64,7 @@
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"SimpleQuery().create(): key_schema has no 'key_set' property",
"Query().create(): key_schema has no 'key_set' property",
'wrong exception message');
}
......@@ -76,7 +76,7 @@
} catch (e) {
equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message,
"SimpleQuery().create(): key_schema has unknown property 'foobar'",
"Query().create(): key_schema has unknown property 'foobar'",
'wrong exception message');
}
......
......@@ -505,6 +505,78 @@
});
});
test('Query & sort_on option', function () {
var doc_list = [
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
},
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
}
];
stop();
expect(2);
jIO.QueryFactory.create("").exec(
doc_list,
{sort_on: [['date', 'descending']]}
).
then(function (list) {
var key_schema =
{
key_set: {
date: {
read_from: 'date',
cast_to: 'dateType'
}
},
cast_lookup: {
dateType: function (str) {
return window.jiodate.JIODate(new Date(str).toISOString());
}
}
};
deepEqual(list, [
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
},
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
], 'Document list is sorted');
return jIO.QueryFactory.create("", key_schema).exec(
doc_list,
{sort_on: [['date', 'ascending']]}
);
})
.then(function (list) {
deepEqual(list, [
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
},
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
], 'Document list is sorted with key_schema');
}).always(start);
});
// Asterisk wildcard is not supported yet.
/* test('Full text query with asterisk', function () {
var doc_list = [
......
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