Commit 794535b8 authored by Romain Courteaud's avatar Romain Courteaud

Drop sequence function in queries

parent 4b86c4a1
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */ /*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global Query: true, query_class_dict: true, inherits: true, /*global Query: true, query_class_dict: true, inherits: true,
window, QueryFactory, RSVP, sequence */ window, QueryFactory, RSVP */
/** /**
* The ComplexQuery inherits from Query, and compares one or several metadata * The ComplexQuery inherits from Query, and compares one or several metadata
...@@ -107,41 +107,30 @@ ComplexQuery.prototype.toJSON = ComplexQuery.prototype.serialized; ...@@ -107,41 +107,30 @@ ComplexQuery.prototype.toJSON = ComplexQuery.prototype.serialized;
* @return {Boolean} true if all match, false otherwise * @return {Boolean} true if all match, false otherwise
*/ */
ComplexQuery.prototype.AND = function (item) { ComplexQuery.prototype.AND = function (item) {
var j, promises = []; var queue = new RSVP.Queue(),
for (j = 0; j < this.query_list.length; j += 1) { context = this,
promises.push(this.query_list[j].match(item)); i = 0;
}
function executeNextIfNotFalse(result) {
function cancel() { if (result === false) {
var i; // No need to evaluate the other elements, as one is false
for (i = 0; i < promises.length; i += 1) { return result;
if (typeof promises.cancel === 'function') { }
promises.cancel(); if (context.query_list.length === i) {
} // No new element to loop on
} return true;
} }
queue
return new RSVP.Promise(function (resolve, reject) { .push(function () {
var i, count = 0; var sub_result = context.query_list[i].match(item);
function resolver(value) { i += 1;
if (!value) { return sub_result;
resolve(false); })
} .push(executeNextIfNotFalse);
count += 1; }
if (count === promises.length) {
resolve(true); executeNextIfNotFalse(true);
} return queue;
}
function rejecter(err) {
reject(err);
cancel();
}
for (i = 0; i < promises.length; i += 1) {
promises[i].then(resolver, rejecter);
}
}, cancel);
}; };
/** /**
...@@ -153,41 +142,30 @@ ComplexQuery.prototype.AND = function (item) { ...@@ -153,41 +142,30 @@ ComplexQuery.prototype.AND = function (item) {
* @return {Boolean} true if one match, false otherwise * @return {Boolean} true if one match, false otherwise
*/ */
ComplexQuery.prototype.OR = function (item) { ComplexQuery.prototype.OR = function (item) {
var j, promises = []; var queue = new RSVP.Queue(),
for (j = 0; j < this.query_list.length; j += 1) { context = this,
promises.push(this.query_list[j].match(item)); i = 0;
}
function executeNextIfNotTrue(result) {
function cancel() { if (result === true) {
var i; // No need to evaluate the other elements, as one is true
for (i = 0; i < promises.length; i += 1) { return result;
if (typeof promises.cancel === 'function') { }
promises.cancel(); if (context.query_list.length === i) {
} // No new element to loop on
} return false;
} }
queue
return new RSVP.Promise(function (resolve, reject) { .push(function () {
var i, count = 0; var sub_result = context.query_list[i].match(item);
function resolver(value) { i += 1;
if (value) { return sub_result;
resolve(true); })
} .push(executeNextIfNotTrue);
count += 1; }
if (count === promises.length) {
resolve(false); executeNextIfNotTrue(false);
} return queue;
}
function rejecter(err) {
reject(err);
cancel();
}
for (i = 0; i < promises.length; i += 1) {
promises[i].then(resolver, rejecter);
}
}, cancel);
}; };
/** /**
...@@ -199,11 +177,13 @@ ComplexQuery.prototype.OR = function (item) { ...@@ -199,11 +177,13 @@ ComplexQuery.prototype.OR = function (item) {
* @return {Boolean} true if one match, false otherwise * @return {Boolean} true if one match, false otherwise
*/ */
ComplexQuery.prototype.NOT = function (item) { ComplexQuery.prototype.NOT = function (item) {
return sequence([function () { return new RSVP.Queue()
.push(function () {
return this.query_list[0].match(item); return this.query_list[0].match(item);
}, function (answer) { })
.push(function (answer) {
return !answer; return !answer;
}]); });
}; };
query_class_dict.complex = ComplexQuery; query_class_dict.complex = ComplexQuery;
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */ /*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit: /*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit:
true, select: true, window, stringEscapeRegexpCharacters: true, true, select: true, window, stringEscapeRegexpCharacters: true,
deepClone, RSVP, sequence */ deepClone, RSVP*/
/** /**
* The query to use to filter a list of objects. * The query to use to filter a list of objects.
...@@ -81,9 +81,11 @@ Query.prototype.exec = function (item_list, option) { ...@@ -81,9 +81,11 @@ Query.prototype.exec = function (item_list, option) {
promises.push(this.match(item_list[i])); promises.push(this.match(item_list[i]));
} }
} }
return sequence([function () { return new RSVP.Queue()
.push(function () {
return RSVP.all(promises); return RSVP.all(promises);
}, function (answers) { })
.push(function (answers) {
var j; var j;
for (j = answers.length - 1; j >= 0; j -= 1) { for (j = answers.length - 1; j >= 0; j -= 1) {
if (!answers[j]) { if (!answers[j]) {
...@@ -93,15 +95,18 @@ Query.prototype.exec = function (item_list, option) { ...@@ -93,15 +95,18 @@ Query.prototype.exec = function (item_list, option) {
if (option.sort_on) { if (option.sort_on) {
return sortOn(option.sort_on, item_list); return sortOn(option.sort_on, item_list);
} }
}, function () { })
.push(function () {
if (option.limit) { if (option.limit) {
return limit(option.limit, item_list); return limit(option.limit, item_list);
} }
}, function () { })
.push(function () {
return select(option.select_list || [], item_list); return select(option.select_list || [], item_list);
}, function () { })
.push(function () {
return item_list; return item_list;
}]); });
}; };
/** /**
...@@ -129,7 +134,8 @@ Query.prototype.match = function () { ...@@ -129,7 +134,8 @@ Query.prototype.match = function () {
* @return {Any} The parse result * @return {Any} The parse result
*/ */
Query.prototype.parse = function (option) { Query.prototype.parse = function (option) {
var that = this, object; var that = this,
object;
/** /**
* The recursive parser. * The recursive parser.
* *
...@@ -138,39 +144,56 @@ Query.prototype.parse = function (option) { ...@@ -138,39 +144,56 @@ Query.prototype.parse = function (option) {
* @return {Any} The parser result * @return {Any} The parser result
*/ */
function recParse(object, option) { function recParse(object, option) {
var query = object.parsed; var query = object.parsed,
if (query.type === "complex") { queue = new RSVP.Queue(),
return sequence([function () { i;
return sequence(query.query_list.map(function (v, i) {
/*jslint unparam: true */ function enqueue(j) {
return function () { queue
return sequence([function () { .push(function () {
object.parsed = query.query_list[i]; object.parsed = query.query_list[j];
return recParse(object, option); return recParse(object, option);
}, function () { })
query.query_list[i] = object.parsed; .push(function () {
}]); query.query_list[j] = object.parsed;
}; });
})); }
}, function () {
if (query.type === "complex") {
for (i = 0; i < query.query_list.length; i += 1) {
enqueue(i);
}
return queue
.push(function () {
object.parsed = query; object.parsed = query;
return that.onParseComplexQuery(object, option); return that.onParseComplexQuery(object, option);
}]); });
} }
if (query.type === "simple") { if (query.type === "simple") {
return that.onParseSimpleQuery(object, option); return that.onParseSimpleQuery(object, option);
} }
} }
object = {"parsed": JSON.parse(JSON.stringify(that.serialized()))}; object = {
return sequence([function () { parsed: JSON.parse(JSON.stringify(that.serialized()))
};
return new RSVP.Queue()
.push(function () {
return that.onParseStart(object, option); return that.onParseStart(object, option);
}, function () { })
.push(function () {
return recParse(object, option); return recParse(object, option);
}, function () { })
.push(function () {
return that.onParseEnd(object, option); return that.onParseEnd(object, option);
}, function () { })
.push(function () {
return object.parsed; return object.parsed;
}]); });
}; };
/** /**
......
...@@ -257,43 +257,3 @@ function searchTextToRegExp(string, use_wildcard_characters) { ...@@ -257,43 +257,3 @@ function searchTextToRegExp(string, use_wildcard_characters) {
} }
Query.searchTextToRegExp = searchTextToRegExp; Query.searchTextToRegExp = searchTextToRegExp;
/**
* sequence(thens): Promise
*
* Executes a sequence of *then* callbacks. It acts like
* `smth().then(callback).then(callback)...`. The first callback is called with
* no parameter.
*
* Elements of `thens` array can be a function or an array contaning at most
* three *then* callbacks: *onFulfilled*, *onRejected*, *onNotified*.
*
* When `cancel()` is executed, each then promises are cancelled at the same
* time.
*
* @param {Array} thens An array of *then* callbacks
* @return {Promise} A new promise
*/
function sequence(thens) {
var promises = [];
return new RSVP.Promise(function (resolve, reject, notify) {
var i;
promises[0] = new RSVP.Promise(function (resolve) {
resolve();
});
for (i = 0; i < thens.length; i += 1) {
if (Array.isArray(thens[i])) {
promises[i + 1] = promises[i].
then(thens[i][0], thens[i][1], thens[i][2]);
} else {
promises[i + 1] = promises[i].then(thens[i]);
}
}
promises[i].then(resolve, reject, notify);
}, function () {
var i;
for (i = 0; i < promises.length; i += 1) {
promises[i].cancel();
}
});
}
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