Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
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
Eugene Shen
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
Hide 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
...
@@ -28,6 +28,14 @@ var complex_queries;
...
@@ -28,6 +28,14 @@ var complex_queries;
"
value
"
:
value
"
value
"
:
value
});
});
}
}
/**
* 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
*/
function
parseStringToObject
(
string
)
{
function
parseStringToObject
(
string
)
{
/*
/*
...
@@ -714,105 +722,11 @@ if ((error_count = __NODEJS_parse(string, error_offsets, error_lookaheads)) > 0)
...
@@ -714,105 +722,11 @@ if ((error_count = __NODEJS_parse(string, error_offsets, error_lookaheads)) > 0)
return
result
;
return
result
;
}
// parseStringToObject
}
// parseStringToObject
_export
(
'
parseStringToObject
'
,
parseStringToObject
);
/*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.
*
*
...
@@ -844,51 +758,195 @@ function sortFunction(key, way) {
...
@@ -844,51 +758,195 @@ function sortFunction(key, way) {
return
a
[
key
]
>
b
[
key
]
?
1
:
a
[
key
]
<
b
[
key
]
?
-
1
:
0
;
return
a
[
key
]
>
b
[
key
]
?
1
:
a
[
key
]
<
b
[
key
]
?
-
1
:
0
;
};
};
}
}
/**
* Clones all native object in deep. Managed types: Object, Array, String,
* Number, Boolean, null.
*
* @param {A} object The object to clone
* @return {A} The cloned object
*/
function
deepClone
(
object
)
{
var
i
,
cloned
;
if
(
Object
.
prototype
.
toString
.
call
(
object
)
===
"
[object Array]
"
)
{
cloned
=
[];
for
(
i
=
0
;
i
<
object
.
length
;
i
+=
1
)
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
return
cloned
;
}
if
(
typeof
object
===
"
object
"
)
{
cloned
=
{};
for
(
i
in
object
)
{
if
(
object
.
hasOwnProperty
(
i
))
{
cloned
[
i
]
=
deepClone
(
object
[
i
]);
}
}
return
cloned
;
}
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.
*
* @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
*/
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.
*
* @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
*/
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.
*
* @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
*/
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.
*
* @method convertStringToRegExp
* @static
* @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
);
/*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.
*
*
* @method create
* @method create
* @static
* @static
* @param {Object,String} object The search text or the serialized version
* @param {Object,String} object The search text or the serialized version
* of a Query
* of a Query
* @return {Query} A Query object
* @return {Query} A Query object
*/
*/
QueryFactory
.
create
=
function
(
object
)
{
"
create
"
:
function
(
object
)
{
if
(
object
===
""
)
{
if
(
object
===
""
)
{
return
new
Query
();
return
new
Query
();
}
}
if
(
typeof
object
===
"
string
"
)
{
if
(
typeof
object
===
"
string
"
)
{
object
=
parseStringToObject
(
object
);
object
=
Query
.
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
;
}
}
}
},
function
()
{});
return
null
;
};
_export
(
"
QueryFactory
"
,
QueryFactory
);
_export
(
"
QueryFactory
"
,
QueryFactory
);
/*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 */
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.
...
@@ -897,99 +955,7 @@ _export("QueryFactory", QueryFactory);
...
@@ -897,99 +955,7 @@ _export("QueryFactory", QueryFactory);
* @class Query
* @class Query
* @constructor
* @constructor
*/
*/
var
Query
=
newClass
(
function
()
{
function
Query
()
{
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
{
i
+=
1
;
}
}
if
(
option
.
sort_on
)
{
Query
.
sortOn
(
option
.
sort_on
,
item_list
);
}
if
(
option
.
limit
)
{
item_list
.
splice
(
0
,
option
.
limit
[
0
]);
if
(
option
.
limit
[
1
])
{
item_list
.
splice
(
option
.
limit
[
1
]);
}
}
Query
.
filterListSelect
(
option
.
select_list
||
[],
item_list
);
};
/**
* 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
;
};
/**
* The recursive parser.
*
* @method recParse
* @private
* @param {Object} object The object shared in the parse process
* @param {Object} options Some options usable in the parseMethods
* @return {Any} The parser result
*/
function
recParse
(
object
,
option
)
{
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
;
};
/**
/**
* Called before parsing the query. Must be overridden!
* Called before parsing the query. Must be overridden!
...
@@ -998,7 +964,7 @@ var Query = newClass(function () {
...
@@ -998,7 +964,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseStart
=
emptyFunction
;
th
is
.
onParseStart
=
emptyFunction
;
/**
/**
* Called when parsing a simple query. Must be overridden!
* Called when parsing a simple query. Must be overridden!
...
@@ -1007,7 +973,7 @@ var Query = newClass(function () {
...
@@ -1007,7 +973,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseSimpleQuery
=
emptyFunction
;
th
is
.
onParseSimpleQuery
=
emptyFunction
;
/**
/**
* Called when parsing a complex query. Must be overridden!
* Called when parsing a complex query. Must be overridden!
...
@@ -1016,7 +982,7 @@ var Query = newClass(function () {
...
@@ -1016,7 +982,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseComplexQuery
=
emptyFunction
;
th
is
.
onParseComplexQuery
=
emptyFunction
;
/**
/**
* Called after parsing the query. Must be overridden!
* Called after parsing the query. Must be overridden!
...
@@ -1025,105 +991,121 @@ var Query = newClass(function () {
...
@@ -1025,105 +991,121 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseEnd
=
emptyFunction
;
th
is
.
onParseEnd
=
emptyFunction
;
/**
}
* Convert this query to a parsable string.
Query
.
prototype
.
constructor
=
Query
;
*
* @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
* Filter the item list with matching item only
* QueryFactory class.
*
*
* @method exec
* @method serialized
* @param {Array} item_list The list of object
* @return {Object} The jsonable object
* @param {Object} [option] Some operation option
*/
* @param {String} [option.wildcard_character="%"] The wildcard character
that
.
serialized
=
function
()
{
* @param {Array} [option.select_list] A object keys to retrieve
return
undefined
;
* @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.
*/
Query
.
prototype
.
exec
=
function
(
item_list
,
option
)
{
var
i
=
0
;
while
(
i
<
item_list
.
length
)
{
if
(
!
this
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
item_list
.
splice
(
i
,
1
);
}
else
{
i
+=
1
;
}
}
if
(
option
.
sort_on
)
{
sortOn
(
option
.
sort_on
,
item_list
);
}
if
(
option
.
limit
)
{
limit
(
option
.
limit
,
item_list
);
}
select
(
option
.
select_list
||
[],
item_list
);
};
},
{
"
static_methods
"
:
{
/**
* Test if an item matches this query
*
* @method match
* @param {Object} item The object to test
* @return {Boolean} true if match, false otherwise
*/
Query
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
true
;
};
/**
* 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
;
}
}
}
},
/**
* 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
;
/**
/**
*
Sort a list of items, according to keys and directions
.
*
The recursive parser
.
*
*
* @method sortOn
* @param {Object} object The object shared in the parse process
* @static
* @param {Object} options Some options usable in the parseMethods
* @param {Array} sort_on_option List of couples [key, direction]
* @return {Any} The parser result
* @param {Array} list The item list to sort
*/
*/
"
sortOn
"
:
function
(
sort_on_option
,
list
)
{
function
recParse
(
object
,
option
)
{
var
sort_index
;
var
i
,
query
=
object
.
parsed
;
for
(
sort_index
=
sort_on_option
.
length
-
1
;
sort_index
>=
0
;
if
(
query
.
type
===
"
complex
"
)
{
sort_index
-=
1
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
i
+=
1
)
{
list
.
sort
(
sortFunction
(
object
.
parsed
=
query
.
query_list
[
i
];
sort_on_option
[
sort_index
][
0
],
recParse
(
object
,
option
);
sort_on_option
[
sort_index
][
1
]
query
.
query_list
[
i
]
=
object
.
parsed
;
));
}
object
.
parsed
=
query
;
that
.
onParseComplexQuery
(
object
,
option
);
}
else
if
(
query
.
type
===
"
simple
"
)
{
that
.
onParseSimpleQuery
(
object
,
option
);
}
}
},
}
object
=
{
"
parsed
"
:
JSON
.
parse
(
JSON
.
stringify
(
that
.
serialized
()))};
that
.
onParseStart
(
object
,
option
);
recParse
(
object
,
option
);
that
.
onParseEnd
(
object
,
option
);
return
object
.
parsed
;
};
/**
/**
* Parse a text request to a json query object tree
* Convert this query to a parsable string.
*
*
* @method parseStringToObject
* @method toString
* @static
* @return {String} The string version of this query
* @param {String} string The string to parse
*/
* @return {Object} The json query tree
Query
.
prototype
.
toString
=
function
()
{
*/
return
""
;
"
parseStringToObject
"
:
parseStringToObject
,
};
/**
/**
* Convert a search text to a regexp.
* Convert this query to an jsonable object in order to be remake thanks to
*
* QueryFactory class.
* @method convertStringToRegExp
*
* @static
* @method serialized
* @param {String} string The string to convert
* @return {Object} The jsonable object
* @param {String} [wildcard_character=undefined] The wildcard chararter
*/
* @return {RegExp} The search text regexp
Query
.
prototype
.
serialized
=
function
()
{
*/
return
undefined
;
"
convertStringToRegExp
"
:
function
(
string
,
wildcard_character
)
{
};
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
).
replace
(
stringEscapeRegexpCharacters
(
wildcard_character
),
'
.*
'
)
+
"
$
"
);
}
}});
_export
(
"
Query
"
,
Query
);
_export
(
"
Query
"
,
Query
);
/*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
...
@@ -1135,7 +1117,9 @@ _export("Query", Query);
...
@@ -1135,7 +1117,9 @@ _export("Query", Query);
* @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
*
*
...
@@ -1162,124 +1146,127 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -1162,124 +1146,127 @@ var SimpleQuery = newClass(Query, function (spec) {
*/
*/
this
.
value
=
spec
.
value
;
this
.
value
=
spec
.
value
;
/**
}
* #crossLink "Query/match:method"
inherits
(
SimpleQuery
,
Query
);
*/
SimpleQuery
.
prototype
.
constructor
=
SimpleQuery
;
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
};
/**
/**
* #crossLink "Query/toString:method"
* #crossLink "Query/match:method"
*/
*/
this
.
toString
=
function
()
{
SimpleQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
this
.
value
+
'
"
'
;
};
};
/**
/**
* #crossLink "Query/serialized:method"
* #crossLink "Query/toString:method"
*/
*/
this
.
serialized
=
function
()
{
SimpleQuery
.
prototype
.
toString
=
function
()
{
return
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
"
type
"
:
"
simple
"
,
this
.
value
+
'
"
'
;
"
operator
"
:
this
.
operator
,
};
"
key
"
:
this
.
key
,
"
value
"
:
this
.
value
};
};
/**
/**
* Comparison operator, test if this query value matches the item value
* #crossLink "Query/serialized:method"
*
*/
* @method =
SimpleQuery
.
prototype
.
serialized
=
function
()
{
* @param {String} object_value The value to compare
return
{
* @param {String} comparison_value The comparison value
"
type
"
:
"
simple
"
,
* @param {String} wildcard_character The wildcard_character
"
operator
"
:
this
.
operator
,
* @return {Boolean} true if match, false otherwise
"
key
"
:
this
.
key
,
*/
"
value
"
:
this
.
value
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
* Comparison operator, test if this query value matches
the item value
*
*
* @method !
=
* @method
=
* @param {String} object_value The value to compare
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} comparison_value The comparison value
* @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
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 does not match the item value
*
*
* @method <
* @method !=
* @param {Number, String} object_value The value to compare
* @param {String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @param {String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
* @param {String} wildcard_character The wildcard_character
*/
* @return {Boolean} true if not match, false otherwise
this
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
*/
return
object_value
<
comparison_value
;
SimpleQuery
.
prototype
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
};
wildcard_character
)
{
return
!
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
};
/**
/**
* Comparison operator, test if this query value is equal or lower than the
* Comparison operator, test if this query value is lower than the item value
* item value
*
*
* @method <
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} object_value The value to compare
* @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 equal or lower, false otherwise
*/
*/
SimpleQuery
.
prototype
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
this
[
"
<=
"
]
=
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 equal or lower than the
*
value
* item
value
*
*
* @method >
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if great
er, false otherwise
* @return {Boolean} true if equal or low
er, 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 greater than the item
* item value
* value
*
*
* @method >=
* @method >
* @param {Number, String} object_value The value to compare
* @param {Number, String} object_value The value to compare
* @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 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
* 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
*/
SimpleQuery
.
prototype
[
"
>=
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
>=
comparison_value
;
};
query_class_dict
.
simple
=
SimpleQuery
;
query_class_dict
.
simple
=
SimpleQuery
;
_export
(
"
SimpleQuery
"
,
SimpleQuery
);
_export
(
"
SimpleQuery
"
,
SimpleQuery
);
/*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 */
/**
/**
...
@@ -1293,7 +1280,8 @@ _export("SimpleQuery", SimpleQuery);
...
@@ -1293,7 +1280,8 @@ _export("SimpleQuery", SimpleQuery);
* @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
...
@@ -1316,93 +1304,96 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -1316,93 +1304,96 @@ 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
);
/**
}
* #crossLink "Query/match:method"
inherits
(
ComplexQuery
,
Query
);
*/
ComplexQuery
.
prototype
.
constructor
=
ComplexQuery
;
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
,
wildcard_character
);
};
/**
/**
* #crossLink "Query/toString:method"
* #crossLink "Query/match:method"
*/
*/
this
.
toString
=
function
()
{
ComplexQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
return
this
[
this
.
operator
](
item
,
wildcard_character
);
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"
* #crossLink "Query/toString:method"
*/
*/
this
.
serialized
=
function
()
{
ComplexQuery
.
prototype
.
toString
=
function
()
{
var
s
=
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
"
type
"
:
"
complex
"
,
this
.
query_list
.
forEach
(
function
(
query
)
{
"
operator
"
:
this
.
operator
,
str_list
.
push
(
query
.
toString
());
"
query_list
"
:
[]
str_list
.
push
(
this_operator
);
};
});
this
.
query_list
.
forEach
(
function
(
query
)
{
str_list
.
pop
();
// remove last operator
s
.
query_list
.
push
(
query
.
serialized
());
str_list
.
push
(
"
)
"
);
});
return
str_list
.
join
(
"
"
);
return
s
;
};
/**
* #crossLink "Query/serialized:method"
*/
ComplexQuery
.
prototype
.
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
* Comparison operator, test if all sub queries match the
* item value
* item value
*
*
* @method AND
* @method AND
* @param {Object} item The item to match
* @param {Object} item The item to match
* @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
))
{
return
false
;
return
false
;
}
}
}
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
*
*
* @method OR
* @method OR
* @param {Object} item The item to match
* @param {Object} item The item to match
* @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
))
{
return
true
;
return
true
;
}
}
}
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
*
*
* @method NOT
* @method NOT
* @param {Object} item The item to match
* @param {Object} item The item to match
* @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/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,93 +37,96 @@ var ComplexQuery = newClass(Query, function (spec) {
...
@@ -36,93 +37,96 @@ 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
);
/**
}
* #crossLink "Query/match:method"
inherits
(
ComplexQuery
,
Query
);
*/
ComplexQuery
.
prototype
.
constructor
=
ComplexQuery
;
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
,
wildcard_character
);
};
/**
/**
* #crossLink "Query/toString:method"
* #crossLink "Query/match:method"
*/
*/
this
.
toString
=
function
()
{
ComplexQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
return
this
[
this
.
operator
](
item
,
wildcard_character
);
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"
* #crossLink "Query/toString:method"
*/
*/
this
.
serialized
=
function
()
{
ComplexQuery
.
prototype
.
toString
=
function
()
{
var
s
=
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
"
type
"
:
"
complex
"
,
this
.
query_list
.
forEach
(
function
(
query
)
{
"
operator
"
:
this
.
operator
,
str_list
.
push
(
query
.
toString
());
"
query_list
"
:
[]
str_list
.
push
(
this_operator
);
};
});
this
.
query_list
.
forEach
(
function
(
query
)
{
str_list
.
pop
();
// remove last operator
s
.
query_list
.
push
(
query
.
serialized
());
str_list
.
push
(
"
)
"
);
});
return
str_list
.
join
(
"
"
);
return
s
;
};
/**
* #crossLink "Query/serialized:method"
*/
ComplexQuery
.
prototype
.
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
* Comparison operator, test if all sub queries match the
* item value
* item value
*
*
* @method AND
* @method AND
* @param {Object} item The item to match
* @param {Object} item The item to match
* @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
))
{
return
false
;
return
false
;
}
}
}
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
*
*
* @method OR
* @method OR
* @param {Object} item The item to match
* @param {Object} item The item to match
* @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
))
{
return
true
;
return
true
;
}
}
}
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
*
*
* @method NOT
* @method NOT
* @param {Object} item The item to match
* @param {Object} item The item to match
* @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,96 +10,7 @@
...
@@ -9,96 +10,7 @@
* @class Query
* @class Query
* @constructor
* @constructor
*/
*/
var
Query
=
newClass
(
function
()
{
function
Query
()
{
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
{
i
+=
1
;
}
}
if
(
option
.
sort_on
)
{
Query
.
sortOn
(
option
.
sort_on
,
item_list
);
}
if
(
option
.
limit
)
{
Query
.
limit
(
option
.
limit
,
item_list
);
}
Query
.
select
(
option
.
select_list
||
[],
item_list
);
};
/**
* 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
;
};
/**
* The recursive parser.
*
* @method recParse
* @private
* @param {Object} object The object shared in the parse process
* @param {Object} options Some options usable in the parseMethods
* @return {Any} The parser result
*/
function
recParse
(
object
,
option
)
{
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
;
};
/**
/**
* Called before parsing the query. Must be overridden!
* Called before parsing the query. Must be overridden!
...
@@ -107,7 +19,7 @@ var Query = newClass(function () {
...
@@ -107,7 +19,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseStart
=
emptyFunction
;
th
is
.
onParseStart
=
emptyFunction
;
/**
/**
* Called when parsing a simple query. Must be overridden!
* Called when parsing a simple query. Must be overridden!
...
@@ -116,7 +28,7 @@ var Query = newClass(function () {
...
@@ -116,7 +28,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseSimpleQuery
=
emptyFunction
;
th
is
.
onParseSimpleQuery
=
emptyFunction
;
/**
/**
* Called when parsing a complex query. Must be overridden!
* Called when parsing a complex query. Must be overridden!
...
@@ -125,7 +37,7 @@ var Query = newClass(function () {
...
@@ -125,7 +37,7 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseComplexQuery
=
emptyFunction
;
th
is
.
onParseComplexQuery
=
emptyFunction
;
/**
/**
* Called after parsing the query. Must be overridden!
* Called after parsing the query. Must be overridden!
...
@@ -134,135 +46,115 @@ var Query = newClass(function () {
...
@@ -134,135 +46,115 @@ var Query = newClass(function () {
* @param {Object} object The object shared in the parse process
* @param {Object} object The object shared in the parse process
* @param {Object} option Some option gave in parse()
* @param {Object} option Some option gave in parse()
*/
*/
th
at
.
onParseEnd
=
emptyFunction
;
th
is
.
onParseEnd
=
emptyFunction
;
/**
}
* Convert this query to a parsable string.
Query
.
prototype
.
constructor
=
Query
;
*
* @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
* Filter the item list with matching item only
* QueryFactory class.
*
*
* @method exec
* @method serialized
* @param {Array} item_list The list of object
* @return {Object} The jsonable object
* @param {Object} [option] Some operation option
*/
* @param {String} [option.wildcard_character="%"] The wildcard character
that
.
serialized
=
function
()
{
* @param {Array} [option.select_list] A object keys to retrieve
return
undefined
;
* @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
},
{
"
static_methods
"
:
{
* second is the length.
*/
/**
Query
.
prototype
.
exec
=
function
(
item_list
,
option
)
{
* Filter a list of items, modifying them to select only wanted keys. If
var
i
=
0
;
* `clone` is true, then the method will act on a cloned list.
while
(
i
<
item_list
.
length
)
{
*
if
(
!
this
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
* @method select
item_list
.
splice
(
i
,
1
);
* @static
}
else
{
* @param {Array} select_option Key list to keep
i
+=
1
;
* @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
;
}
},
if
(
option
.
sort_on
)
{
sortOn
(
option
.
sort_on
,
item_list
);
}
if
(
option
.
limit
)
{
limit
(
option
.
limit
,
item_list
);
}
select
(
option
.
select_list
||
[],
item_list
);
};
/**
* Test if an item matches this query
*
* @method match
* @param {Object} item The object to test
* @return {Boolean} true if match, false otherwise
*/
Query
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
true
;
};
/**
* 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
;
},
/**
* 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
;
/**
/**
* Limit a list of items, according to index and length. If `clone` is true,
* The recursive parser.
* then the method will act on a cloned list.
*
*
* @method limit
* @param {Object} object The object shared in the parse process
* @static
* @param {Object} options Some options usable in the parseMethods
* @param {Array} limit_option A couple [from, length]
* @return {Any} The parser result
* @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
)
{
function
recParse
(
object
,
option
)
{
if
(
clone
)
{
var
i
,
query
=
object
.
parsed
;
list
=
deepClone
(
list
);
if
(
query
.
type
===
"
complex
"
)
{
}
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
i
+=
1
)
{
list
.
splice
(
0
,
limit_option
[
0
]);
object
.
parsed
=
query
.
query_list
[
i
];
if
(
limit_option
[
1
])
{
recParse
(
object
,
option
);
list
.
splice
(
limit_option
[
1
]);
query
.
query_list
[
i
]
=
object
.
parsed
;
}
object
.
parsed
=
query
;
that
.
onParseComplexQuery
(
object
,
option
);
}
else
if
(
query
.
type
===
"
simple
"
)
{
that
.
onParseSimpleQuery
(
object
,
option
);
}
}
return
list
;
}
},
object
=
{
"
parsed
"
:
JSON
.
parse
(
JSON
.
stringify
(
that
.
serialized
()))};
that
.
onParseStart
(
object
,
option
);
recParse
(
object
,
option
);
that
.
onParseEnd
(
object
,
option
);
return
object
.
parsed
;
};
/**
/**
* Parse a text request to a json query object tree
* Convert this query to a parsable string.
*
*
* @method parseStringToObject
* @method toString
* @static
* @return {String} The string version of this query
* @param {String} string The string to parse
*/
* @return {Object} The json query tree
Query
.
prototype
.
toString
=
function
()
{
*/
return
""
;
"
parseStringToObject
"
:
parseStringToObject
,
};
/**
/**
* Convert a search text to a regexp.
* Convert this query to an jsonable object in order to be remake thanks to
*
* QueryFactory class.
* @method convertStringToRegExp
*
* @static
* @method serialized
* @param {String} string The string to convert
* @return {Object} The jsonable object
* @param {String} [wildcard_character=undefined] The wildcard chararter
*/
* @return {RegExp} The search text regexp
Query
.
prototype
.
serialized
=
function
()
{
*/
return
undefined
;
"
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.
*
*
* @method create
* @method create
* @static
* @static
* @param {Object,String} object The search text or the serialized version
* @param {Object,String} object The search text or the serialized version
* 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
;
}
}
}
},
function
()
{});
return
null
;
};
_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,118 +41,121 @@ var SimpleQuery = newClass(Query, function (spec) {
...
@@ -39,118 +41,121 @@ var SimpleQuery = newClass(Query, function (spec) {
*/
*/
this
.
value
=
spec
.
value
;
this
.
value
=
spec
.
value
;
/**
}
* #crossLink "Query/match:method"
inherits
(
SimpleQuery
,
Query
);
*/
SimpleQuery
.
prototype
.
constructor
=
SimpleQuery
;
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
};
/**
/**
* #crossLink "Query/toString:method"
* #crossLink "Query/match:method"
*/
*/
this
.
toString
=
function
()
{
SimpleQuery
.
prototype
.
match
=
function
(
item
,
wildcard_character
)
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
this
.
value
+
'
"
'
;
};
};
/**
/**
* #crossLink "Query/serialized:method"
* #crossLink "Query/toString:method"
*/
*/
this
.
serialized
=
function
()
{
SimpleQuery
.
prototype
.
toString
=
function
()
{
return
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
"
type
"
:
"
simple
"
,
this
.
value
+
'
"
'
;
"
operator
"
:
this
.
operator
,
};
"
key
"
:
this
.
key
,
"
value
"
:
this
.
value
};
};
/**
/**
* Comparison operator, test if this query value matches the item value
* #crossLink "Query/serialized:method"
*
*/
* @method =
SimpleQuery
.
prototype
.
serialized
=
function
()
{
* @param {String} object_value The value to compare
return
{
* @param {String} comparison_value The comparison value
"
type
"
:
"
simple
"
,
* @param {String} wildcard_character The wildcard_character
"
operator
"
:
this
.
operator
,
* @return {Boolean} true if match, false otherwise
"
key
"
:
this
.
key
,
*/
"
value
"
:
this
.
value
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
* Comparison operator, test if this query value matches
the item value
*
*
* @method !
=
* @method
=
* @param {String} object_value The value to compare
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} comparison_value The comparison value
* @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
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 does not match the item value
*
*
* @method <
* @method !=
* @param {Number, String} object_value The value to compare
* @param {String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @param {String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
* @param {String} wildcard_character The wildcard_character
*/
* @return {Boolean} true if not match, false otherwise
this
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
*/
return
object_value
<
comparison_value
;
SimpleQuery
.
prototype
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
};
wildcard_character
)
{
return
!
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
};
/**
/**
* Comparison operator, test if this query value is equal or lower than the
* Comparison operator, test if this query value is lower than the item value
* item value
*
*
* @method <
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} object_value The value to compare
* @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 equal or lower, false otherwise
*/
*/
SimpleQuery
.
prototype
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
this
[
"
<=
"
]
=
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 equal or lower than the
*
value
* item
value
*
*
* @method >
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if great
er, false otherwise
* @return {Boolean} true if equal or low
er, 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 greater than the item
* item value
* value
*
*
* @method >=
* @method >
* @param {Number, String} object_value The value to compare
* @param {Number, String} object_value The value to compare
* @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 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
* 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
*/
SimpleQuery
.
prototype
[
"
>=
"
]
=
function
(
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