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 */
/*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
......@@ -107,41 +107,30 @@ ComplexQuery.prototype.toJSON = ComplexQuery.prototype.serialized;
* @return {Boolean} true if all match, false otherwise
*/
ComplexQuery.prototype.AND = function (item) {
var j, promises = [];
for (j = 0; j < this.query_list.length; j += 1) {
promises.push(this.query_list[j].match(item));
}
function cancel() {
var i;
for (i = 0; i < promises.length; i += 1) {
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);
}
var queue = new RSVP.Queue(),
context = this,
i = 0;
function executeNextIfNotFalse(result) {
if (result === false) {
// No need to evaluate the other elements, as one is false
return result;
}
function rejecter(err) {
reject(err);
cancel();
if (context.query_list.length === i) {
// No new element to loop on
return true;
}
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) {
promises[i].then(resolver, rejecter);
}
}, cancel);
executeNextIfNotFalse(true);
return queue;
};
/**
......@@ -153,41 +142,30 @@ ComplexQuery.prototype.AND = function (item) {
* @return {Boolean} true if one match, false otherwise
*/
ComplexQuery.prototype.OR = function (item) {
var j, promises = [];
for (j = 0; j < this.query_list.length; j += 1) {
promises.push(this.query_list[j].match(item));
}
function cancel() {
var i;
for (i = 0; i < promises.length; i += 1) {
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);
}
var queue = new RSVP.Queue(),
context = this,
i = 0;
function executeNextIfNotTrue(result) {
if (result === true) {
// No need to evaluate the other elements, as one is true
return result;
}
function rejecter(err) {
reject(err);
cancel();
if (context.query_list.length === i) {
// No new element to loop on
return false;
}
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) {
promises[i].then(resolver, rejecter);
}
}, cancel);
executeNextIfNotTrue(false);
return queue;
};
/**
......@@ -199,11 +177,13 @@ ComplexQuery.prototype.OR = function (item) {
* @return {Boolean} true if one match, false otherwise
*/
ComplexQuery.prototype.NOT = function (item) {
return sequence([function () {
return this.query_list[0].match(item);
}, function (answer) {
return !answer;
}]);
return new RSVP.Queue()
.push(function () {
return this.query_list[0].match(item);
})
.push(function (answer) {
return !answer;
});
};
query_class_dict.complex = ComplexQuery;
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit:
true, select: true, window, stringEscapeRegexpCharacters: true,
deepClone, RSVP, sequence */
deepClone, RSVP*/
/**
* The query to use to filter a list of objects.
......@@ -81,27 +81,32 @@ Query.prototype.exec = function (item_list, option) {
promises.push(this.match(item_list[i]));
}
}
return sequence([function () {
return RSVP.all(promises);
}, function (answers) {
var j;
for (j = answers.length - 1; j >= 0; j -= 1) {
if (!answers[j]) {
item_list.splice(j, 1);
return new RSVP.Queue()
.push(function () {
return RSVP.all(promises);
})
.push(function (answers) {
var j;
for (j = answers.length - 1; j >= 0; j -= 1) {
if (!answers[j]) {
item_list.splice(j, 1);
}
}
}
if (option.sort_on) {
return sortOn(option.sort_on, item_list);
}
}, function () {
if (option.limit) {
return limit(option.limit, item_list);
}
}, function () {
return select(option.select_list || [], item_list);
}, function () {
return item_list;
}]);
if (option.sort_on) {
return sortOn(option.sort_on, item_list);
}
})
.push(function () {
if (option.limit) {
return limit(option.limit, item_list);
}
})
.push(function () {
return select(option.select_list || [], item_list);
})
.push(function () {
return item_list;
});
};
/**
......@@ -129,7 +134,8 @@ Query.prototype.match = function () {
* @return {Any} The parse result
*/
Query.prototype.parse = function (option) {
var that = this, object;
var that = this,
object;
/**
* The recursive parser.
*
......@@ -138,39 +144,56 @@ Query.prototype.parse = function (option) {
* @return {Any} The parser result
*/
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") {
return sequence([function () {
return sequence(query.query_list.map(function (v, i) {
/*jslint unparam: true */
return function () {
return sequence([function () {
object.parsed = query.query_list[i];
return recParse(object, option);
}, function () {
query.query_list[i] = object.parsed;
}]);
};
}));
}, function () {
object.parsed = query;
return that.onParseComplexQuery(object, option);
}]);
for (i = 0; i < query.query_list.length; i += 1) {
enqueue(i);
}
return queue
.push(function () {
object.parsed = query;
return that.onParseComplexQuery(object, option);
});
}
if (query.type === "simple") {
return that.onParseSimpleQuery(object, option);
}
}
object = {"parsed": JSON.parse(JSON.stringify(that.serialized()))};
return sequence([function () {
return that.onParseStart(object, option);
}, function () {
return recParse(object, option);
}, function () {
return that.onParseEnd(object, option);
}, function () {
return object.parsed;
}]);
object = {
parsed: JSON.parse(JSON.stringify(that.serialized()))
};
return new RSVP.Queue()
.push(function () {
return that.onParseStart(object, option);
})
.push(function () {
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) {
}
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