Commit 935d3e28 authored by Tristan Cavelier's avatar Tristan Cavelier

complex_queries.js updated

parent 4a6e56c2
...@@ -4,19 +4,31 @@ ...@@ -4,19 +4,31 @@
* http://www.gnu.org/licenses/lgpl.html * http://www.gnu.org/licenses/lgpl.html
*/ */
(function (scope) { /**
* Provides some function to use complex queries with item list
*
* @module complex_queries
*/
var complex_queries;
(function () {
"use strict"; "use strict";
Object.defineProperty(scope, "ComplexQueries", { var to_export = {}, module_name = "complex_queries";
configurable: false, /**
enumerable: false, * Add a secured (write permission denied) property to an object.
writable: false, *
value: {} * @param {Object} object The object to fill
* @param {String} key The object key where to store the property
* @param {Any} value The value to store
*/
function _export(key, value) {
Object.defineProperty(to_export, key, {
"configurable": false,
"enumerable": true,
"writable": false,
"value": value
}); });
Object.defineProperty(scope.ComplexQueries, "parse", { }
configurable: false, function parseStringToObject(string) {
enumerable: false,
writable: false,
value: function (string) {
/* /*
Default template driver for JS/CC generated parsers running as Default template driver for JS/CC generated parsers running as
...@@ -563,7 +575,7 @@ switch( act ) ...@@ -563,7 +575,7 @@ switch( act )
break; break;
case 10: case 10:
{ {
simpleQuerySetId(vstack[ vstack.length - 1 ],vstack[ vstack.length - 2 ].split(':').slice(0,-1).join(':')); rval = vstack[ vstack.length - 1 ]; simpleQuerySetKey(vstack[ vstack.length - 1 ],vstack[ vstack.length - 2 ].split(':').slice(0,-1).join(':')); rval = vstack[ vstack.length - 1 ];
} }
break; break;
case 11: case 11:
...@@ -643,269 +655,776 @@ switch( act ) ...@@ -643,269 +655,776 @@ switch( act )
var arrayExtend = function () { var arrayExtend = function () {
var j,i,newlist=[],listoflists = arguments; var j, i, newlist = [], list_list = arguments;
for (j=0; j<listoflists.length; ++j) { for (j = 0; j < list_list.length; j += 1) {
for (i=0; i<listoflists[j].length; ++i) { for (i = 0; i < list_list[j].length; i += 1) {
newlist.push(listoflists[j][i]); newlist.push(list_list[j][i]);
} }
} }
return newlist; return newlist;
};
var mkSimpleQuery = function (id,value,operator) { }, mkSimpleQuery = function (key, value, operator) {
return {type:'simple',operator:'=',id:id,value:value}; return {"type": "simple", "operator": "=", "key": key, "value": value};
};
var mkNotQuery = function (query) { }, mkNotQuery = function (query) {
if (query.operator === 'NOT') { if (query.operator === "NOT") {
return query.query_list[0]; return query.query_list[0];
} }
return {type:'complex',operator:'NOT',query_list:[query]}; return {"type": "complex", "operator": "NOT", "query_list": [query]};
};
var mkComplexQuery = function (operator,query_list) { }, mkComplexQuery = function (operator, query_list) {
var i,query_list2 = []; var i, query_list2 = [];
for (i=0; i<query_list.length; ++i) { for (i = 0; i < query_list.length; i += 1) {
if (query_list[i].operator === operator) { if (query_list[i].operator === operator) {
query_list2 = arrayExtend(query_list2,query_list[i].query_list); query_list2 = arrayExtend(query_list2, query_list[i].query_list);
} else { } else {
query_list2.push(query_list[i]); query_list2.push(query_list[i]);
} }
} }
return {type:'complex',operator:operator,query_list:query_list2}; return {type:"complex",operator:operator,query_list:query_list2};
};
var simpleQuerySetId = function (query, id) { }, simpleQuerySetKey = function (query, key) {
var i; var i;
if (query.type === 'complex') { if (query.type === "complex") {
for (i = 0; i < query.query_list.length; ++i) { for (i = 0; i < query.query_list.length; ++i) {
simpleQuerySetId (query.query_list[i],id); simpleQuerySetKey (query.query_list[i],key);
} }
return true; return true;
} }
if (query.type === 'simple' && !query.id) { if (query.type === "simple" && !query.key) {
query.id = id; query.key = key;
return true; return true;
} }
return false; return false;
}; },
var error_offsets = []; error_offsets = [],
var error_lookaheads = []; error_lookaheads = [],
var error_count = 0; error_count = 0,
var result; result;
if ( ( error_count = __NODEJS_parse( string, error_offsets, error_lookaheads ) ) > 0 ) {
if ((error_count = __NODEJS_parse(string, error_offsets, error_lookaheads)) > 0) {
var i; var i;
for (i = 0; i < error_count; ++i) { for (i = 0; i < error_count; i += 1) {
throw new Error ( "Parse error near \"" + throw new Error("Parse error near \"" +
string.substr ( error_offsets[i] ) + string.substr(error_offsets[i]) +
"\", expecting \"" + "\", expecting \"" +
error_lookaheads[i].join() + "\"" ); error_lookaheads[i].join() + "\"");
} }
} }
return result; return result;
} // parseStringToObject
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true */
/**
* Create a class, manage inheritance, static methods,
* protected attributes and can hide methods or/and secure methods
*
* @param {Class} Class Classes to inherit from (0..n). The last class
* parameter will inherit from the previous one, and so on
* @param {Object} option Class option (0..n)
* @param {Boolean} [option.secure_methods=false] Make methods not configurable
* and not writable
* @param {Boolean} [option.hide_methods=false] Make methods not enumerable
* @param {Boolean} [option.secure_static_methods=true] Make static methods not
* configurable and not
* writable
* @param {Boolean} [option.hide_static_methods=false] Make static methods not
* enumerable
* @param {Object} [option.static_methods={}] Object of static methods
* @param {Function} constructor The new class constructor
* @return {Class} The new class
*/
function newClass() {
var j, k, constructors = [], option, new_class;
for (j = 0; j < arguments.length; j += 1) {
if (typeof arguments[j] === "function") {
constructors.push(arguments[j]);
} else if (typeof arguments[j] === "object") {
option = option || {};
for (k in arguments[j]) {
if (arguments[j].hasOwnProperty(k)) {
option[k] = arguments[j][k];
}
}
}
}
function postObjectCreation(that) {
// modify the object according to 'option'
var key;
if (option) {
for (key in that) {
if (that.hasOwnProperty(key)) {
if (typeof that[key] === "function") {
Object.defineProperty(that, key, {
"configurable": option.secure_methods ? false : true,
"enumerable": option.hide_methods ? false : true,
"writable": option.secure_methods ? false : true,
"value": that[key]
});
}
}
}
}
} }
}); function postClassCreation(that) {
Object.defineProperty(scope.ComplexQueries,"serialize",{ // modify the object according to 'option'
configurable:false,enumerable:false,writable:false,value:function(query){ var key;
var str_list = [], i; if (option) {
if (query.type === 'complex') { for (key in that) {
str_list.push ( '(' ); if (that.hasOwnProperty(key)) {
for (i=0; i<query.query_list.length; ++i) { if (typeof that[key] === "function") {
str_list.push( scope.ComplexQueries.serialize(query.query_list[i]) ); Object.defineProperty(that, key, {
str_list.push( query.operator ); "configurable": option.secure_static_methods ===
} false ? true : false,
str_list.length --; "enumerable": option.hide_static_methods ? false : true,
str_list.push ( ')' ); "writable": option.secure_static_methods === false ? true : false,
return str_list.join(' '); "value": that[key]
} else if (query.type === 'simple') { });
return query.id + (query.id?': ':'') + query.operator + ' "' + query.value + '"';
}
return query;
} }
});
Object.defineProperty(scope.ComplexQueries,"query",{
configurable:false,enumerable:false,writable:false,
value: function (query, object_list) {
var wildcard_character = typeof query.wildcard_character === 'string' ?
query.wildcard_character : '%',
operator_actions = {
'=': function (value1, value2) {
value1 = '' + value1;
return value1.match (convertToRegexp (
value2, wildcard_character
)) || false && true;
},
'!=': function (value1, value2) {
value1 = '' + value1;
return !(value1.match (convertToRegexp (
value2, wildcard_character
)));
},
'<': function (value1, value2) { return value1 < value2; },
'<=': function (value1, value2) { return value1 <= value2; },
'>': function (value1, value2) { return value1 > value2; },
'>=': function (value1, value2) { return value1 >= value2; },
'AND': function (item, query_list) {
var i;
for (i=0; i<query_list.length; ++i) {
if (! itemMatchesQuery (item, query_list[i])) {
return false;
} }
} }
return true; }
}, }
'OR': function (item, query_list) {
new_class = function (spec, my) {
var i; var i;
for (i=0; i<query_list.length; ++i) { spec = spec || {};
if (itemMatchesQuery (item, query_list[i])) { my = my || {};
return true; // don't use forEach !
for (i = 0; i < constructors.length; i += 1) {
constructors[i].apply(this, [spec, my]);
}
postObjectCreation(this);
return this;
};
option = option || {};
option.static_methods = option.static_methods || {};
for (j in option.static_methods) {
if (option.static_methods.hasOwnProperty(j)) {
new_class[j] = option.static_methods[j];
} }
} }
return false; postClassCreation(new_class);
}, return new_class;
'NOT': function (item, query_list) { }
return !itemMatchesQuery(item, query_list[0]);
/**
* Escapes regexp special chars from a string.
*
* @param {String} string The string to escape
* @return {String} The escaped string
*/
function stringEscapeRegexpCharacters(string) {
if (typeof string === "string") {
return string.replace(/([\\\.\$\[\]\(\)\{\}\^\?\*\+\-])/g, "\\$1");
} }
}, }
convertToRegexp = function (string) {
return subString('^' + string.replace( _export("stringEscapeRegexpCharacters", stringEscapeRegexpCharacters);
new RegExp(
'([\\{\\}\\(\\)\\^\\$\\&\\.\\*\\?\\\/\\+\\|\\[\\]\\-\\\\])'. /**
replace (wildcard_character? * A sort function to sort items by key
'\\'+wildcard_character:undefined,''), *
'g' * @param {String} key The key to sort on
), * @param {String} [way="ascending"] 'ascending' or 'descending'
'\\$1' * @return {Function} The sort function
) + '$',(wildcard_character||undefined), '.*'); */
}, function sortFunction(key, way) {
subString = function (string, substring, newsubstring) { if (way === 'descending') {
var res = '', i = 0; return function (a, b) {
if (substring === undefined) { return a[key] < b[key] ? 1 : a[key] > b[key] ? -1 : 0;
return string; };
} }
while (1) { return function (a, b) {
var tmp = string.indexOf(substring,i); return a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0;
if (tmp === -1) { };
break; }
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true, ComplexQuery: true, SimpleQuery: true,
newClass: true, Query: true */
var query_class_dict = {}, QueryFactory;
/**
* Provides static methods to create Query object
*
* @class QueryFactory
*/
QueryFactory = newClass({
"static_methods": {
/**
* Creates Query object from a search text string or a serialized version
* of a Query.
*
* @method create
* @static
* @param {Object,String} object The search text or the serialized version
* of a Query
* @return {Query} A Query object
*/
"create": function (object) {
if (object === "") {
return new Query();
} }
for (; i < tmp; ++i) { if (typeof object === "string") {
res += string[i]; object = Query.parseStringToObject(object);
} }
res += newsubstring; if (typeof (object || {}).type === "string" &&
i += substring.length; query_class_dict[object.type]) {
return new query_class_dict[object.type](object);
} }
for (; i<string.length; ++i) { return null;
res += string[i];
} }
return res;
},
itemMatchesQuery = function (item, query_object) {
var i;
if (query_object.type === 'complex') {
return operator_actions[query_object.operator](
item, query_object.query_list
);
} else {
if (query_object.id) {
if (typeof item[query_object.id] !== 'undefined') {
return operator_actions[query_object.operator](
item[query_object.id], query_object.value
);
} else {
return false;
} }
}, function () {});
_export("QueryFactory", QueryFactory);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, sortFunction: true, parseStringToObject: true,
_export: true, stringEscapeRegexpCharacters: true */
/**
* The query to use to filter a list of objects.
* This is an abstract class.
*
* @class Query
* @constructor
*/
var Query = newClass(function () {
var that = this, emptyFunction = function () {};
/**
* Filter the item list with matching item only
*
* @method exec
* @param {Array} item_list The list of object
* @param {Object} [option] Some operation option
* @param {String} [option.wildcard_character="%"] The wildcard character
* @param {Array} [option.select_list] A object keys to retrieve
* @param {Array} [option.sort_on] Couples of object keys and "ascending"
* or "descending"
* @param {Array} [option.limit] Couple of integer, first is an index and
* second is the length.
*/
that.exec = function (item_list, option) {
var i = 0;
while (i < item_list.length) {
if (!that.match(item_list[i], option.wildcard_character)) {
item_list.splice(i, 1);
} else { } else {
return true; i += 1;
} }
} }
}, if (option.sort_on) {
select = function (list, select_list) { Query.sortOn(option.sort_on, item_list);
var i;
if (select_list.length === 0) {
return;
} }
for (i=0; i<list.length; ++i) { if (option.limit) {
var list_value = {}, k; item_list.splice(0, option.limit[0]);
for (k=0; k<select_list.length; ++k) { if (option.limit[1]) {
list_value[select_list[k]] = item_list.splice(option.limit[1]);
list[i][select_list[k]];
} }
list[i] = list_value;
} }
}, Query.filterListSelect(option.select_list || [], item_list);
sortFunction = function (key, asc) {
if (asc === 'descending') {
return function (a,b) {
return a[key] < b[key] ? 1 : a[key] > b[key] ? -1 : 0;
}; };
}
return function (a,b) { /**
return a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0; * Test if an item matches this query
*
* @method match
* @param {Object} item The object to test
* @return {Boolean} true if match, false otherwise
*/
that.match = function (item, wildcard_character) {
return true;
}; };
},
mergeList = function (list, list_to_merge, index) { /**
var i,j; * The recursive parser.
for (i = index,j = 0; i < list_to_merge.length + index; ++i, ++j) { *
list[i] = list_to_merge[j]; * @method recParse
} * @private
}, * @param {Object} object The object shared in the parse process
sort = function (list, sort_list) { * @param {Object} options Some options usable in the parseMethods
var i, tmp, key, asc, sortAndMerge = function() { * @return {Any} The parser result
sort(tmp,sort_list.slice(1)); */
mergeList(list,tmp,i-tmp.length); function recParse(object, option) {
tmp = [list[i]]; var i, query = object.parsed;
if (query.type === "complex") {
for (i = 0; i < query.query_list.length; i += 1) {
object.parsed = query.query_list[i];
recParse(object, option);
query.query_list[i] = object.parsed;
}
object.parsed = query;
that.onParseComplexQuery(object, option);
} else if (query.type === "simple") {
that.onParseSimpleQuery(object, option);
}
}
/**
* Browse the Query in deep calling parser method in each step.
*
* `onParseStart` is called first, on end `onParseEnd` is called.
* It starts from the simple queries at the bottom of the tree calling the
* parser method `onParseSimpleQuery`, and go up calling the
* `onParseComplexQuery` method.
*
* @method parse
* @param {Object} option Any options you want (except 'parsed')
* @return {Any} The parse result
*/
that.parse = function (option) {
var object;
object = {"parsed": JSON.parse(JSON.stringify(that.serialized()))};
that.onParseStart(object, option);
recParse(object, option);
that.onParseEnd(object, option);
return object.parsed;
}; };
if (list.length < 2) {
return; /**
} * Called before parsing the query. Must be overridden!
if (sort_list.length === 0) { *
return; * @method onParseStart
} * @param {Object} object The object shared in the parse process
key = sort_list[0][0]; * @param {Object} option Some option gave in parse()
asc = sort_list[0][1]; */
list.sort (sortFunction (key,asc)); that.onParseStart = emptyFunction;
tmp = [list[0]];
for (i = 1; i < list.length; ++i) { /**
if (tmp[0][key] === list[i][key]) { * Called when parsing a simple query. Must be overridden!
tmp.push(list[i]); *
} else { * @method onParseSimpleQuery
sortAndMerge(); * @param {Object} object The object shared in the parse process
} * @param {Object} option Some option gave in parse()
} */
sortAndMerge(); that.onParseSimpleQuery = emptyFunction;
},
limit = function (list, limit_list) { /**
var i; * Called when parsing a complex query. Must be overridden!
if (typeof limit_list[0] !== 'undefined') { *
if (typeof limit_list[1] !== 'undefined') { * @method onParseComplexQuery
if (list.length > limit_list[1] + limit_list[0]) { * @param {Object} object The object shared in the parse process
list.length = limit_list[1] + limit_list[0]; * @param {Object} option Some option gave in parse()
*/
that.onParseComplexQuery = emptyFunction;
/**
* Called after parsing the query. Must be overridden!
*
* @method onParseEnd
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
that.onParseEnd = emptyFunction;
/**
* Convert this query to a parsable string.
*
* @method toString
* @return {String} The string version of this query
*/
that.toString = function () {
return "";
};
/**
* Convert this query to an jsonable object in order to be remake thanks to
* QueryFactory class.
*
* @method serialized
* @return {Object} The jsonable object
*/
that.serialized = function () {
return undefined;
};
}, {"static_methods": {
/**
* Filter a list of items, modifying them to select only wanted keys.
*
* @method filterListSelect
* @static
* @param {Array} select_option Key list to keep
* @param {Array} list The item list to filter
*/
"filterListSelect": function (select_option, list) {
var i, j, new_item;
for (i = 0; i < list.length; i += 1) {
new_item = {};
for (j = 0; j < select_option.length; j += 1) {
new_item[select_option[j]] = list[i][select_option[j]];
}
for (j in new_item) {
if (new_item.hasOwnProperty(j)) {
list[i] = new_item;
break;
} }
list.splice(0,limit_list[0]);
} else {
list.length = limit_list[0];
} }
} }
}, },
////////////////////////////////////////////////////////////
result_list = [], result_list_tmp = [], j; /**
object_list = object_list || []; * Sort a list of items, according to keys and directions.
if (query.query === undefined) { *
result_list = object_list; * @method sortOn
} else { * @static
for (j=0; j<object_list.length; ++j) { * @param {Array} sort_on_option List of couples [key, direction]
if ( itemMatchesQuery ( * @param {Array} list The item list to sort
object_list[j], scope.ComplexQueries.parse (query.query) */
)) { "sortOn": function (sort_on_option, list) {
result_list.push(object_list[j]); var sort_index;
for (sort_index = sort_on_option.length - 1; sort_index >= 0;
sort_index -= 1) {
list.sort(sortFunction(
sort_on_option[sort_index][0],
sort_on_option[sort_index][1]
));
} }
},
/**
* Parse a text request to a json query object tree
*
* @method parseStringToObject
* @static
* @param {String} string The string to parse
* @return {Object} The json query tree
*/
"parseStringToObject": parseStringToObject,
/**
* Convert a search text to a regexp.
*
* @method convertStringToRegExp
* @static
* @param {String} string The string to convert
* @param {String} [wildcard_character=undefined] The wildcard chararter
* @return {RegExp} The search text regexp
*/
"convertStringToRegExp": function (string, wildcard_character) {
return new RegExp("^" + stringEscapeRegexpCharacters(string).replace(
stringEscapeRegexpCharacters(wildcard_character),
'.*'
) + "$");
}
}});
_export("Query", Query);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, Query: true,
query_class_dict: true, _export: true */
/**
* The SimpleQuery inherits from Query, and compares one metadata value
*
* @class SimpleQuery
* @extends Query
* @param {Object} [spec={}] The specifications
* @param {String} [spec.operator="="] The compare method to use
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
var SimpleQuery = newClass(Query, function (spec) {
/**
* Operator to use to compare object values
*
* @attribute operator
* @type String
* @default "="
* @optional
*/
this.operator = spec.operator || "=";
/**
* Key of the object which refers to the value to compare
*
* @attribute key
* @type String
*/
this.key = spec.key;
/**
* Value is used to do the comparison with the object value
*
* @attribute value
* @type String
*/
this.value = spec.value;
/**
* #crossLink "Query/match:method"
*/
this.match = function (item, wildcard_character) {
return this[this.operator](item[this.key], this.value, wildcard_character);
};
/**
* #crossLink "Query/toString:method"
*/
this.toString = function () {
return (this.key ? this.key + ": " : "") + (this.operator || "=") + ' "' +
this.value + '"';
};
/**
* #crossLink "Query/serialized:method"
*/
this.serialized = function () {
return {
"type": "simple",
"operator": this.operator,
"key": this.key,
"value": this.value
};
};
/**
* Comparison operator, test if this query value matches the item value
*
* @method =
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if match, false otherwise
*/
this["="] = function (object_value, comparison_value,
wildcard_character) {
return Query.convertStringToRegExp(
comparison_value.toString(),
wildcard_character || "%"
).test(object_value.toString());
};
/**
* Comparison operator, test if this query value does not match the item value
*
* @method !=
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if not match, false otherwise
*/
this["!="] = function (object_value, comparison_value,
wildcard_character) {
return !Query.convertStringTextToRegExp(
comparison_value.toString(),
wildcard_character || "%"
).test(object_value.toString());
};
/**
* Comparison operator, test if this query value is lower than the item value
*
* @method <
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
*/
this["<"] = function (object_value, comparison_value) {
return object_value < comparison_value;
};
/**
* Comparison operator, test if this query value is equal or lower than the
* item value
*
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or lower, false otherwise
*/
this["<="] = function (object_value, comparison_value) {
return object_value <= comparison_value;
};
/**
* Comparison operator, test if this query value is greater than the item
* value
*
* @method >
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if greater, false otherwise
*/
this[">"] = function (object_value, comparison_value) {
return object_value > comparison_value;
};
/**
* Comparison operator, test if this query value is equal or greater than the
* item value
*
* @method >=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or greater, false otherwise
*/
this[">="] = function (object_value, comparison_value) {
return object_value >= comparison_value;
};
});
query_class_dict.simple = SimpleQuery;
_export("SimpleQuery", SimpleQuery);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, Query: true, query_class_dict: true,
_export: true, QueryFactory: true */
/**
* The ComplexQuery inherits from Query, and compares one or several metadata
* values.
*
* @class ComplexQuery
* @extends Query
* @param {Object} [spec={}] The specifications
* @param {String} [spec.operator="AND"] The compare method to use
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
var ComplexQuery = newClass(Query, function (spec) {
/**
* Logical operator to use to compare object values
*
* @attribute operator
* @type String
* @default "AND"
* @optional
*/
this.operator = spec.operator || "AND";
/**
* The sub Query list which are used to query an item.
*
* @attribute query_list
* @type Array
* @default []
* @optional
*/
this.query_list = spec.query_list || [];
this.query_list = this.query_list.map(QueryFactory.create);
/**
* #crossLink "Query/match:method"
*/
this.match = function (item, wildcard_character) {
return this[this.operator](item, wildcard_character);
};
/**
* #crossLink "Query/toString:method"
*/
this.toString = function () {
var str_list = ["("], this_operator = this.operator;
this.query_list.forEach(function (query) {
str_list.push(query.toString());
str_list.push(this_operator);
});
str_list.pop(); // remove last operator
str_list.push(")");
return str_list.join(" ");
};
/**
* #crossLink "Query/serialized:method"
*/
this.serialized = function () {
var s = {
"type": "complex",
"operator": this.operator,
"query_list": []
};
this.query_list.forEach(function (query) {
s.query_list.push(query.serialized());
});
return s;
};
/**
* Comparison operator, test if all sub queries match the
* item value
*
* @method AND
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if all match, false otherwise
*/
this.AND = function (item, wildcard_character) {
var i;
for (i = 0; i < this.query_list.length; i += 1) {
if (!this.query_list[i].match(item, wildcard_character)) {
return false;
} }
} }
if (query.filter) { return true;
select(result_list,query.filter.select_list || []); };
sort(result_list,query.filter.sort_on || []);
limit(result_list,query.filter.limit || []); /**
* Comparison operator, test if one of the sub queries matches the
* item value
*
* @method OR
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
this.OR = function (item, wildcard_character) {
var i;
for (i = 0; i < this.query_list.length; i += 1) {
if (this.query_list[i].match(item, wildcard_character)) {
return true;
} }
return result_list;
} }
return false;
};
/**
* Comparison operator, test if the sub query does not match the
* item value
*
* @method NOT
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
this.NOT = function (item, wildcard_character) {
return !this.query_list[0].match(item, wildcard_character);
};
}); });
}(jIO)); query_class_dict.complex = ComplexQuery;
_export("ComplexQuery", ComplexQuery);
if (typeof define === "function" && define.amd) {
define(to_export);
} else if (typeof window === "object") {
Object.defineProperty(window, module_name, {
configurable: false,
enumerable: true,
writable: false,
value: to_export
});
} else if (typeof exports === "object") {
var i;
for (i in to_export) {
if (to_export.hasOwnProperty(i)) {
exports[i] = to_export[i];
}
}
} else {
complex_queries = to_export;
}
}());
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