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();
}
}
}
return new RSVP.Promise(function (resolve, reject) {
var i, count = 0;
function resolver(value) {
if (!value) {
resolve(false);
}
count += 1;
if (count === promises.length) {
resolve(true);
}
} }
if (context.query_list.length === i) {
function rejecter(err) { // No new element to loop on
reject(err); return true;
cancel();
} }
queue
.push(function () {
var sub_result = context.query_list[i].match(item);
i += 1;
return sub_result;
})
.push(executeNextIfNotFalse);
}
for (i = 0; i < promises.length; i += 1) { executeNextIfNotFalse(true);
promises[i].then(resolver, rejecter); return queue;
}
}, 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();
}
}
}
return new RSVP.Promise(function (resolve, reject) {
var i, count = 0;
function resolver(value) {
if (value) {
resolve(true);
}
count += 1;
if (count === promises.length) {
resolve(false);
}
} }
if (context.query_list.length === i) {
function rejecter(err) { // No new element to loop on
reject(err); return false;
cancel();
} }
queue
.push(function () {
var sub_result = context.query_list[i].match(item);
i += 1;
return sub_result;
})
.push(executeNextIfNotTrue);
}
for (i = 0; i < promises.length; i += 1) { executeNextIfNotTrue(false);
promises[i].then(resolver, rejecter); return queue;
}
}, 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()
return this.query_list[0].match(item); .push(function () {
}, function (answer) { return this.query_list[0].match(item);
return !answer; })
}]); .push(function (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,27 +81,32 @@ Query.prototype.exec = function (item_list, option) { ...@@ -81,27 +81,32 @@ 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()
return RSVP.all(promises); .push(function () {
}, function (answers) { return RSVP.all(promises);
var j; })
for (j = answers.length - 1; j >= 0; j -= 1) { .push(function (answers) {
if (!answers[j]) { var j;
item_list.splice(j, 1); for (j = answers.length - 1; j >= 0; j -= 1) {
if (!answers[j]) {
item_list.splice(j, 1);
}
} }
} 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 () { })
return select(option.select_list || [], item_list); .push(function () {
}, function () { return select(option.select_list || [], item_list);
return item_list; })
}]); .push(function () {
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,
queue = new RSVP.Queue(),
i;
function enqueue(j) {
queue
.push(function () {
object.parsed = query.query_list[j];
return recParse(object, option);
})
.push(function () {
query.query_list[j] = object.parsed;
});
}
if (query.type === "complex") { if (query.type === "complex") {
return sequence([function () {
return sequence(query.query_list.map(function (v, i) {
/*jslint unparam: true */ for (i = 0; i < query.query_list.length; i += 1) {
return function () { enqueue(i);
return sequence([function () { }
object.parsed = query.query_list[i];
return recParse(object, option); return queue
}, function () { .push(function () {
query.query_list[i] = object.parsed; object.parsed = query;
}]); return that.onParseComplexQuery(object, option);
}; });
}));
}, function () {
object.parsed = query;
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 that.onParseStart(object, option); };
}, function () { return new RSVP.Queue()
return recParse(object, option); .push(function () {
}, function () { return that.onParseStart(object, option);
return that.onParseEnd(object, option); })
}, function () { .push(function () {
return object.parsed; return recParse(object, option);
}]); })
.push(function () {
return that.onParseEnd(object, option);
})
.push(function () {
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