Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Stefane Fermigier
jio
Commits
a8eb67be
Commit
a8eb67be
authored
Jul 03, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
complex queries module redesigned to moved methods
parent
7cc44e36
Changes
8
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
931 additions
and
1020 deletions
+931
-1020
complex_queries.js
complex_queries.js
+485
-494
src/queries/complexquery.js
src/queries/complexquery.js
+85
-81
src/queries/parser-begin.js
src/queries/parser-begin.js
+6
-0
src/queries/parser-end.js
src/queries/parser-end.js
+2
-0
src/queries/query.js
src/queries/query.js
+106
-214
src/queries/queryfactory.js
src/queries/queryfactory.js
+26
-29
src/queries/simplequery.js
src/queries/simplequery.js
+111
-106
src/queries/tool.js
src/queries/tool.js
+110
-96
No files found.
complex_queries.js
View file @
a8eb67be
This diff is collapsed.
Click to expand it.
src/queries/complexquery.js
View file @
a8eb67be
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global
newClass: true, Query: true, query_class_dict
: true,
/*global
Query: true, query_class_dict: true, inherits
: true,
_export: true, QueryFactory: true */
_export: true, QueryFactory: true */
/**
/**
...
@@ -13,7 +13,8 @@
...
@@ -13,7 +13,8 @@
* @param {String} spec.key The metadata key
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
* @param {String} spec.value The value of the metadata to compare
*/
*/
var
ComplexQuery
=
newClass
(
Query
,
function
(
spec
)
{
function
ComplexQuery
(
spec
)
{
Query
.
call
(
this
);
/**
/**
* Logical operator to use to compare object values
* Logical operator to use to compare object values
...
@@ -36,17 +37,21 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -36,17 +37,21 @@ var ComplexQuery = newClass(Query, function (spec) {
this
.
query_list
=
spec
.
query_list
||
[];
this
.
query_list
=
spec
.
query_list
||
[];
this
.
query_list
=
this
.
query_list
.
map
(
QueryFactory
.
create
);
this
.
query_list
=
this
.
query_list
.
map
(
QueryFactory
.
create
);
/**
}
inherits
(
ComplexQuery
,
Query
);
ComplexQuery
.
prototype
.
constructor
=
ComplexQuery
;
/**
* #crossLink "Query/match:method"
* #crossLink "Query/match:method"
*/
*/
this
.
match
=
function
(
item
,
wildcard_character
)
{
ComplexQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
,
wildcard_character
);
return
this
[
this
.
operator
](
item
,
wildcard_character
);
};
};
/**
/**
* #crossLink "Query/toString:method"
* #crossLink "Query/toString:method"
*/
*/
this
.
toString
=
function
()
{
ComplexQuery
.
prototype
.
toString
=
function
()
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
this
.
query_list
.
forEach
(
function
(
query
)
{
this
.
query_list
.
forEach
(
function
(
query
)
{
str_list
.
push
(
query
.
toString
());
str_list
.
push
(
query
.
toString
());
...
@@ -55,12 +60,12 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -55,12 +60,12 @@ var ComplexQuery = newClass(Query, function (spec) {
str_list
.
pop
();
// remove last operator
str_list
.
pop
();
// remove last operator
str_list
.
push
(
"
)
"
);
str_list
.
push
(
"
)
"
);
return
str_list
.
join
(
"
"
);
return
str_list
.
join
(
"
"
);
};
};
/**
/**
* #crossLink "Query/serialized:method"
* #crossLink "Query/serialized:method"
*/
*/
this
.
serialized
=
function
()
{
ComplexQuery
.
prototype
.
serialized
=
function
()
{
var
s
=
{
var
s
=
{
"
type
"
:
"
complex
"
,
"
type
"
:
"
complex
"
,
"
operator
"
:
this
.
operator
,
"
operator
"
:
this
.
operator
,
...
@@ -70,9 +75,9 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -70,9 +75,9 @@ var ComplexQuery = newClass(Query, function (spec) {
s
.
query_list
.
push
(
query
.
serialized
());
s
.
query_list
.
push
(
query
.
serialized
());
});
});
return
s
;
return
s
;
};
};
/**
/**
* Comparison operator, test if all sub queries match the
* Comparison operator, test if all sub queries match the
* item value
* item value
*
*
...
@@ -81,7 +86,7 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -81,7 +86,7 @@ var ComplexQuery = newClass(Query, function (spec) {
* @param {String} wildcard_character The wildcard character
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if all match, false otherwise
* @return {Boolean} true if all match, false otherwise
*/
*/
this
.
AND
=
function
(
item
,
wildcard_character
)
{
ComplexQuery
.
prototype
.
AND
=
function
(
item
,
wildcard_character
)
{
var
i
;
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
!
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
if
(
!
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
...
@@ -89,9 +94,9 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -89,9 +94,9 @@ var ComplexQuery = newClass(Query, function (spec) {
}
}
}
}
return
true
;
return
true
;
};
};
/**
/**
* Comparison operator, test if one of the sub queries matches the
* Comparison operator, test if one of the sub queries matches the
* item value
* item value
*
*
...
@@ -100,7 +105,7 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -100,7 +105,7 @@ var ComplexQuery = newClass(Query, function (spec) {
* @param {String} wildcard_character The wildcard character
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
* @return {Boolean} true if one match, false otherwise
*/
*/
this
.
OR
=
function
(
item
,
wildcard_character
)
{
ComplexQuery
.
prototype
.
OR
=
function
(
item
,
wildcard_character
)
{
var
i
;
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
if
(
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
...
@@ -108,9 +113,9 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -108,9 +113,9 @@ var ComplexQuery = newClass(Query, function (spec) {
}
}
}
}
return
false
;
return
false
;
};
};
/**
/**
* Comparison operator, test if the sub query does not match the
* Comparison operator, test if the sub query does not match the
* item value
* item value
*
*
...
@@ -119,10 +124,9 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -119,10 +124,9 @@ var ComplexQuery = newClass(Query, function (spec) {
* @param {String} wildcard_character The wildcard character
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
* @return {Boolean} true if one match, false otherwise
*/
*/
this
.
NOT
=
function
(
item
,
wildcard_character
)
{
ComplexQuery
.
prototype
.
NOT
=
function
(
item
,
wildcard_character
)
{
return
!
this
.
query_list
[
0
].
match
(
item
,
wildcard_character
);
return
!
this
.
query_list
[
0
].
match
(
item
,
wildcard_character
);
};
};
});
query_class_dict
.
complex
=
ComplexQuery
;
query_class_dict
.
complex
=
ComplexQuery
;
...
...
src/queries/parser-begin.js
View file @
a8eb67be
/**
* Parse a text request to a json query object tree
*
* @param {String} string The string to parse
* @return {Object} The json query tree
*/
function
parseStringToObject
(
string
)
{
function
parseStringToObject
(
string
)
{
src/queries/parser-end.js
View file @
a8eb67be
return
result
;
return
result
;
}
// parseStringToObject
}
// parseStringToObject
_export
(
'
parseStringToObject
'
,
parseStringToObject
);
src/queries/query.js
View file @
a8eb67be
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, sortFunction: true, parseStringToObject: true,
/*global parseStringToObject: true, emptyFunction: true, sortOn: true, limit:
_export: true, stringEscapeRegexpCharacters: true, deepClone: true */
true, select: true, _export: true, stringEscapeRegexpCharacters: true,
deepClone: true */
/**
/**
* The query to use to filter a list of objects.
* The query to use to filter a list of objects.
...
@@ -9,11 +10,48 @@
...
@@ -9,11 +10,48 @@
* @class Query
* @class Query
* @constructor
* @constructor
*/
*/
var
Query
=
newClass
(
function
()
{
function
Query
()
{
var
that
=
this
,
emptyFunction
=
function
()
{};
/**
* Called before parsing the query. Must be overridden!
*
* @method onParseStart
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
this
.
onParseStart
=
emptyFunction
;
/**
* Called when parsing a simple query. Must be overridden!
*
* @method onParseSimpleQuery
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
this
.
onParseSimpleQuery
=
emptyFunction
;
/**
* Called when parsing a complex query. Must be overridden!
*
* @method onParseComplexQuery
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
this
.
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()
*/
this
.
onParseEnd
=
emptyFunction
;
}
Query
.
prototype
.
constructor
=
Query
;
/**
* Filter the item list with matching item only
* Filter the item list with matching item only
*
*
* @method exec
* @method exec
...
@@ -26,40 +64,53 @@ var Query = newClass(function () {
...
@@ -26,40 +64,53 @@ var Query = newClass(function () {
* @param {Array} [option.limit] Couple of integer, first is an index and
* @param {Array} [option.limit] Couple of integer, first is an index and
* second is the length.
* second is the length.
*/
*/
that
.
exec
=
function
(
item_list
,
option
)
{
Query
.
prototype
.
exec
=
function
(
item_list
,
option
)
{
var
i
=
0
;
var
i
=
0
;
while
(
i
<
item_list
.
length
)
{
while
(
i
<
item_list
.
length
)
{
if
(
!
that
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
if
(
!
this
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
item_list
.
splice
(
i
,
1
);
item_list
.
splice
(
i
,
1
);
}
else
{
}
else
{
i
+=
1
;
i
+=
1
;
}
}
}
}
if
(
option
.
sort_on
)
{
if
(
option
.
sort_on
)
{
Query
.
sortOn
(
option
.
sort_on
,
item_list
);
sortOn
(
option
.
sort_on
,
item_list
);
}
}
if
(
option
.
limit
)
{
if
(
option
.
limit
)
{
Query
.
limit
(
option
.
limit
,
item_list
);
limit
(
option
.
limit
,
item_list
);
}
}
Query
.
select
(
option
.
select_list
||
[],
item_list
);
select
(
option
.
select_list
||
[],
item_list
);
};
};
/**
/**
* Test if an item matches this query
* Test if an item matches this query
*
*
* @method match
* @method match
* @param {Object} item The object to test
* @param {Object} item The object to test
* @return {Boolean} true if match, false otherwise
* @return {Boolean} true if match, false otherwise
*/
*/
that
.
match
=
function
(
item
,
wildcard_character
)
{
Query
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
true
;
return
true
;
};
};
/**
* 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
*/
Query
.
prototype
.
parse
=
function
(
option
)
{
var
that
=
this
,
object
;
/**
/**
* The recursive parser.
* The recursive parser.
*
*
* @method recParse
* @private
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} options Some options usable in the parseMethods
* @param {Object} options Some options usable in the parseMethods
* @return {Any} The parser result
* @return {Any} The parser result
...
@@ -78,191 +129,32 @@ var Query = newClass(function () {
...
@@ -78,191 +129,32 @@ var Query = newClass(function () {
that
.
onParseSimpleQuery
(
object
,
option
);
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
()))};
object
=
{
"
parsed
"
:
JSON
.
parse
(
JSON
.
stringify
(
that
.
serialized
()))};
that
.
onParseStart
(
object
,
option
);
that
.
onParseStart
(
object
,
option
);
recParse
(
object
,
option
);
recParse
(
object
,
option
);
that
.
onParseEnd
(
object
,
option
);
that
.
onParseEnd
(
object
,
option
);
return
object
.
parsed
;
return
object
.
parsed
;
};
};
/**
/**
* Called before parsing the query. Must be overridden!
*
* @method onParseStart
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
that
.
onParseStart
=
emptyFunction
;
/**
* Called when parsing a simple query. Must be overridden!
*
* @method onParseSimpleQuery
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
*/
that
.
onParseSimpleQuery
=
emptyFunction
;
/**
* Called when parsing a complex query. Must be overridden!
*
* @method onParseComplexQuery
* @param {Object} object The object shared in the parse process
* @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.
* Convert this query to a parsable string.
*
*
* @method toString
* @method toString
* @return {String} The string version of this query
* @return {String} The string version of this query
*/
*/
that
.
toString
=
function
()
{
Query
.
prototype
.
toString
=
function
()
{
return
""
;
return
""
;
};
};
/**
/**
* Convert this query to an jsonable object in order to be remake thanks to
* Convert this query to an jsonable object in order to be remake thanks to
* QueryFactory class.
* QueryFactory class.
*
*
* @method serialized
* @method serialized
* @return {Object} The jsonable object
* @return {Object} The jsonable object
*/
*/
that
.
serialized
=
function
()
{
Query
.
prototype
.
serialized
=
function
()
{
return
undefined
;
return
undefined
;
};
};
},
{
"
static_methods
"
:
{
/**
* Filter a list of items, modifying them to select only wanted keys. If
* `clone` is true, then the method will act on a cloned list.
*
* @method select
* @static
* @param {Array} select_option Key list to keep
* @param {Array} list The item list to filter
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
"
select
"
:
function
(
select_option
,
list
,
clone
)
{
var
i
,
j
,
new_item
;
if
(
clone
)
{
list
=
deepClone
(
list
);
}
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
;
}
}
}
return
list
;
},
/**
* Sort a list of items, according to keys and directions. If `clone` is true,
* then the method will act on a cloned list.
*
* @method sortOn
* @static
* @param {Array} sort_on_option List of couples [key, direction]
* @param {Array} list The item list to sort
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
"
sortOn
"
:
function
(
sort_on_option
,
list
,
clone
)
{
var
sort_index
;
if
(
clone
)
{
list
=
deepClone
(
list
);
}
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
]
));
}
return
list
;
},
/**
* Limit a list of items, according to index and length. If `clone` is true,
* then the method will act on a cloned list.
*
* @method limit
* @static
* @param {Array} limit_option A couple [from, length]
* @param {Array} list The item list to limit
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
"
limit
"
:
function
(
limit_option
,
list
,
clone
)
{
if
(
clone
)
{
list
=
deepClone
(
list
);
}
list
.
splice
(
0
,
limit_option
[
0
]);
if
(
limit_option
[
1
])
{
list
.
splice
(
limit_option
[
1
]);
}
return
list
;
},
/**
* 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
);
_export
(
"
Query
"
,
Query
);
src/queries/queryfactory.js
View file @
a8eb67be
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true, ComplexQuery: true, SimpleQuery: true,
/*global _export: true, ComplexQuery: true, SimpleQuery: true,
Query: true,
newClass: true, Query
: true */
parseStringToObject
: true */
var
query_class_dict
=
{}
,
QueryFactory
;
var
query_class_dict
=
{};
/**
/**
* Provides static methods to create Query object
* Provides static methods to create Query object
*
*
* @class QueryFactory
* @class QueryFactory
*/
*/
QueryFactory
=
newClass
({
function
QueryFactory
()
{}
"
static_methods
"
:
{
/**
/**
* Creates Query object from a search text string or a serialized version
* Creates Query object from a search text string or a serialized version
* of a Query.
* of a Query.
*
*
...
@@ -23,20 +22,18 @@ QueryFactory = newClass({
...
@@ -23,20 +22,18 @@ QueryFactory = newClass({
* of a Query
* of a Query
* @return {Query} A Query object
* @return {Query} A Query object
*/
*/
"
create
"
:
function
(
object
)
{
QueryFactory
.
create
=
function
(
object
)
{
if
(
object
===
""
)
{
if
(
object
===
""
)
{
return
new
Query
();
return
new
Query
();
}
}
if
(
typeof
object
===
"
string
"
)
{
if
(
typeof
object
===
"
string
"
)
{
object
=
Query
.
parseStringToObject
(
object
);
object
=
parseStringToObject
(
object
);
}
}
if
(
typeof
(
object
||
{}).
type
===
"
string
"
&&
if
(
typeof
(
object
||
{}).
type
===
"
string
"
&&
query_class_dict
[
object
.
type
])
{
query_class_dict
[
object
.
type
])
{
return
new
query_class_dict
[
object
.
type
](
object
);
return
new
query_class_dict
[
object
.
type
](
object
);
}
}
return
null
;
return
null
;
}
};
}
},
function
()
{});
_export
(
"
QueryFactory
"
,
QueryFactory
);
_export
(
"
QueryFactory
"
,
QueryFactory
);
src/queries/simplequery.js
View file @
a8eb67be
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global
newClass: true, Query
: true,
/*global
Query: true, inherits: true, query_class_dict: true, _export
: true,
query_class_dict: true, _export
: true */
convertStringToRegExp
: true */
/**
/**
* The SimpleQuery inherits from Query, and compares one metadata value
* The SimpleQuery inherits from Query, and compares one metadata value
...
@@ -12,7 +12,9 @@
...
@@ -12,7 +12,9 @@
* @param {String} spec.key The metadata key
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
* @param {String} spec.value The value of the metadata to compare
*/
*/
var
SimpleQuery
=
newClass
(
Query
,
function
(
spec
)
{
function
SimpleQuery
(
spec
)
{
Query
.
call
(
this
);
/**
/**
* Operator to use to compare object values
* Operator to use to compare object values
*
*
...
@@ -39,34 +41,38 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -39,34 +41,38 @@ var SimpleQuery = newClass(Query, function (spec) {
*/
*/
this
.
value
=
spec
.
value
;
this
.
value
=
spec
.
value
;
/**
}
inherits
(
SimpleQuery
,
Query
);
SimpleQuery
.
prototype
.
constructor
=
SimpleQuery
;
/**
* #crossLink "Query/match:method"
* #crossLink "Query/match:method"
*/
*/
this
.
match
=
function
(
item
,
wildcard_character
)
{
SimpleQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
};
};
/**
/**
* #crossLink "Query/toString:method"
* #crossLink "Query/toString:method"
*/
*/
this
.
toString
=
function
()
{
SimpleQuery
.
prototype
.
toString
=
function
()
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
this
.
value
+
'
"
'
;
this
.
value
+
'
"
'
;
};
};
/**
/**
* #crossLink "Query/serialized:method"
* #crossLink "Query/serialized:method"
*/
*/
this
.
serialized
=
function
()
{
SimpleQuery
.
prototype
.
serialized
=
function
()
{
return
{
return
{
"
type
"
:
"
simple
"
,
"
type
"
:
"
simple
"
,
"
operator
"
:
this
.
operator
,
"
operator
"
:
this
.
operator
,
"
key
"
:
this
.
key
,
"
key
"
:
this
.
key
,
"
value
"
:
this
.
value
"
value
"
:
this
.
value
};
};
};
};
/**
/**
* Comparison operator, test if this query value matches the item value
* Comparison operator, test if this query value matches the item value
*
*
* @method =
* @method =
...
@@ -75,15 +81,15 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -75,15 +81,15 @@ var SimpleQuery = newClass(Query, function (spec) {
* @param {String} wildcard_character The wildcard_character
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if match, false otherwise
* @return {Boolean} true if match, false otherwise
*/
*/
this
[
"
=
"
]
=
function
(
object_value
,
comparison_value
,
SimpleQuery
.
prototype
[
"
=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
wildcard_character
)
{
return
Query
.
convertStringToRegExp
(
return
convertStringToRegExp
(
comparison_value
.
toString
(),
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
).
test
(
object_value
.
toString
());
};
};
/**
/**
* Comparison operator, test if this query value does not match the item value
* Comparison operator, test if this query value does not match the item value
*
*
* @method !=
* @method !=
...
@@ -92,15 +98,15 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -92,15 +98,15 @@ var SimpleQuery = newClass(Query, function (spec) {
* @param {String} wildcard_character The wildcard_character
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if not match, false otherwise
* @return {Boolean} true if not match, false otherwise
*/
*/
this
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
SimpleQuery
.
prototype
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
wildcard_character
)
{
return
!
Query
.
convertStringText
ToRegExp
(
return
!
convertString
ToRegExp
(
comparison_value
.
toString
(),
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
).
test
(
object_value
.
toString
());
};
};
/**
/**
* Comparison operator, test if this query value is lower than the item value
* Comparison operator, test if this query value is lower than the item value
*
*
* @method <
* @method <
...
@@ -108,11 +114,11 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -108,11 +114,11 @@ var SimpleQuery = newClass(Query, function (spec) {
* @param {Number, String} comparison_value The comparison value
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
* @return {Boolean} true if lower, false otherwise
*/
*/
this
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
SimpleQuery
.
prototype
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
<
comparison_value
;
return
object_value
<
comparison_value
;
};
};
/**
/**
* Comparison operator, test if this query value is equal or lower than the
* Comparison operator, test if this query value is equal or lower than the
* item value
* item value
*
*
...
@@ -121,11 +127,11 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -121,11 +127,11 @@ var SimpleQuery = newClass(Query, function (spec) {
* @param {Number, String} comparison_value The comparison value
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or lower, false otherwise
* @return {Boolean} true if equal or lower, false otherwise
*/
*/
this
[
"
<=
"
]
=
function
(
object_value
,
comparison_value
)
{
SimpleQuery
.
prototype
[
"
<=
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
<=
comparison_value
;
return
object_value
<=
comparison_value
;
};
};
/**
/**
* Comparison operator, test if this query value is greater than the item
* Comparison operator, test if this query value is greater than the item
* value
* value
*
*
...
@@ -134,11 +140,11 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -134,11 +140,11 @@ var SimpleQuery = newClass(Query, function (spec) {
* @param {Number, String} comparison_value The comparison value
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if greater, false otherwise
* @return {Boolean} true if greater, false otherwise
*/
*/
this
[
"
>
"
]
=
function
(
object_value
,
comparison_value
)
{
SimpleQuery
.
prototype
[
"
>
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
>
comparison_value
;
return
object_value
>
comparison_value
;
};
};
/**
/**
* Comparison operator, test if this query value is equal or greater than the
* Comparison operator, test if this query value is equal or greater than the
* item value
* item value
*
*
...
@@ -147,10 +153,9 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -147,10 +153,9 @@ var SimpleQuery = newClass(Query, function (spec) {
* @param {Number, String} comparison_value The comparison value
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or greater, false otherwise
* @return {Boolean} true if equal or greater, false otherwise
*/
*/
this
[
"
>=
"
]
=
function
(
object_value
,
comparison_value
)
{
SimpleQuery
.
prototype
[
"
>=
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
>=
comparison_value
;
return
object_value
>=
comparison_value
;
};
};
});
query_class_dict
.
simple
=
SimpleQuery
;
query_class_dict
.
simple
=
SimpleQuery
;
...
...
src/queries/tool.js
View file @
a8eb67be
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: 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
)
{
// 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_static_methods
===
false
?
true
:
false
,
"
enumerable
"
:
option
.
hide_static_methods
?
false
:
true
,
"
writable
"
:
option
.
secure_static_methods
===
false
?
true
:
false
,
"
value
"
:
that
[
key
]
});
}
}
}
}
}
new_class
=
function
(
spec
,
my
)
{
var
i
;
spec
=
spec
||
{};
my
=
my
||
{};
// 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
];
}
}
postClassCreation
(
new_class
);
return
new_class
;
}
/**
/**
* Escapes regexp special chars from a string.
* Escapes regexp special chars from a string.
*
*
...
@@ -156,3 +60,113 @@ function deepClone(object) {
...
@@ -156,3 +60,113 @@ function deepClone(object) {
}
}
return
object
;
return
object
;
}
}
/**
* Inherits the prototype methods from one constructor into another. The
* prototype of `constructor` will be set to a new object created from
* `superConstructor`.
*/
function
inherits
(
constructor
,
superConstructor
)
{
constructor
.
super_
=
superConstructor
;
constructor
.
prototype
=
Object
.
create
(
superConstructor
.
prototype
,
{});
}
/**
* Does nothing
*/
function
emptyFunction
()
{}
/**
* Filter a list of items, modifying them to select only wanted keys. If
* `clone` is true, then the method will act on a cloned list.
*
* @param {Array} select_option Key list to keep
* @param {Array} list The item list to filter
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
select
(
select_option
,
list
,
clone
)
{
var
i
,
j
,
new_item
;
if
(
clone
)
{
list
=
deepClone
(
list
);
}
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
;
}
}
}
return
list
;
}
_export
(
'
select
'
,
select
);
/**
* Sort a list of items, according to keys and directions. If `clone` is true,
* then the method will act on a cloned list.
*
* @param {Array} sort_on_option List of couples [key, direction]
* @param {Array} list The item list to sort
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
sortOn
(
sort_on_option
,
list
,
clone
)
{
var
sort_index
;
if
(
clone
)
{
list
=
deepClone
(
list
);
}
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
]
));
}
return
list
;
}
_export
(
'
sortOn
'
,
sortOn
);
/**
* Limit a list of items, according to index and length. If `clone` is true,
* then the method will act on a cloned list.
*
* @param {Array} limit_option A couple [from, length]
* @param {Array} list The item list to limit
* @param {Boolean} [clone=false] If true, modifies a clone of the list
* @return {Array} The filtered list
*/
function
limit
(
limit_option
,
list
,
clone
)
{
if
(
clone
)
{
list
=
deepClone
(
list
);
}
list
.
splice
(
0
,
limit_option
[
0
]);
if
(
limit_option
[
1
])
{
list
.
splice
(
limit_option
[
1
]);
}
return
list
;
}
_export
(
'
limit
'
,
limit
);
/**
* Convert a search text to a regexp.
*
* @param {String} string The string to convert
* @param {String} [wildcard_character=undefined] The wildcard chararter
* @return {RegExp} The search text regexp
*/
function
convertStringToRegExp
(
string
,
wildcard_character
)
{
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
).
replace
(
stringEscapeRegexpCharacters
(
wildcard_character
),
'
.*
'
)
+
"
$
"
);
}
_export
(
'
convertStringToRegExp
'
,
convertStringToRegExp
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment