Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio-main
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
Hardik Juneja
jio-main
Commits
935d3e28
Commit
935d3e28
authored
Jun 17, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
complex_queries.js updated
parent
4a6e56c2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
779 additions
and
260 deletions
+779
-260
complex_queries.js
complex_queries.js
+779
-260
No files found.
complex_queries.js
View file @
935d3e28
...
...
@@ -4,19 +4,31 @@
* http://www.gnu.org/licenses/lgpl.html
*/
(
function
(
scope
)
{
/**
* Provides some function to use complex queries with item list
*
* @module complex_queries
*/
var
complex_queries
;
(
function
()
{
"
use strict
"
;
Object
.
defineProperty
(
scope
,
"
ComplexQueries
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
{}
});
Object
.
defineProperty
(
scope
.
ComplexQueries
,
"
parse
"
,
{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
string
)
{
var
to_export
=
{},
module_name
=
"
complex_queries
"
;
/**
* Add a secured (write permission denied) property to an object.
*
* @param {Object} object The object to fill
* @param {String} key The object key where to store the property
* @param {Any} value The value to store
*/
function
_export
(
key
,
value
)
{
Object
.
defineProperty
(
to_export
,
key
,
{
"
configurable
"
:
false
,
"
enumerable
"
:
true
,
"
writable
"
:
false
,
"
value
"
:
value
});
}
function
parseStringToObject
(
string
)
{
/*
Default template driver for JS/CC generated parsers running as
...
...
@@ -563,7 +575,7 @@ switch( act )
break
;
case
10
:
{
simpleQuerySet
Id
(
vstack
[
vstack
.
length
-
1
],
vstack
[
vstack
.
length
-
2
].
split
(
'
:
'
).
slice
(
0
,
-
1
).
join
(
'
:
'
));
rval
=
vstack
[
vstack
.
length
-
1
];
simpleQuerySet
Key
(
vstack
[
vstack
.
length
-
1
],
vstack
[
vstack
.
length
-
2
].
split
(
'
:
'
).
slice
(
0
,
-
1
).
join
(
'
:
'
));
rval
=
vstack
[
vstack
.
length
-
1
];
}
break
;
case
11
:
...
...
@@ -643,269 +655,776 @@ switch( act )
var
arrayExtend
=
function
()
{
var
j
,
i
,
newlist
=
[],
listoflists
=
arguments
;
for
(
j
=
0
;
j
<
listoflists
.
length
;
++
j
)
{
for
(
i
=
0
;
i
<
listoflists
[
j
].
length
;
++
i
)
{
newlist
.
push
(
listoflists
[
j
][
i
]);
}
var
j
,
i
,
newlist
=
[],
list_list
=
arguments
;
for
(
j
=
0
;
j
<
list_list
.
length
;
j
+=
1
)
{
for
(
i
=
0
;
i
<
list_list
[
j
].
length
;
i
+=
1
)
{
newlist
.
push
(
list_list
[
j
][
i
]);
}
}
return
newlist
;
},
mkSimpleQuery
=
function
(
key
,
value
,
operator
)
{
return
{
"
type
"
:
"
simple
"
,
"
operator
"
:
"
=
"
,
"
key
"
:
key
,
"
value
"
:
value
};
},
mkNotQuery
=
function
(
query
)
{
if
(
query
.
operator
===
"
NOT
"
)
{
return
query
.
query_list
[
0
];
}
return
{
"
type
"
:
"
complex
"
,
"
operator
"
:
"
NOT
"
,
"
query_list
"
:
[
query
]};
},
mkComplexQuery
=
function
(
operator
,
query_list
)
{
var
i
,
query_list2
=
[];
for
(
i
=
0
;
i
<
query_list
.
length
;
i
+=
1
)
{
if
(
query_list
[
i
].
operator
===
operator
)
{
query_list2
=
arrayExtend
(
query_list2
,
query_list
[
i
].
query_list
);
}
else
{
query_list2
.
push
(
query_list
[
i
]);
}
return
newlist
;
};
var
mkSimpleQuery
=
function
(
id
,
value
,
operator
)
{
return
{
type
:
'
simple
'
,
operator
:
'
=
'
,
id
:
id
,
value
:
value
};
}
;
var
mkNotQuery
=
function
(
query
)
{
if
(
query
.
operator
===
'
NOT
'
)
{
return
query
.
query_list
[
0
]
;
}
return
{
type
:
"
complex
"
,
operator
:
operator
,
query_list
:
query_list2
};
},
simpleQuerySetKey
=
function
(
query
,
key
)
{
var
i
;
if
(
query
.
type
===
"
complex
"
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
++
i
)
{
simpleQuerySetKey
(
query
.
query_list
[
i
],
key
)
;
}
return
{
type
:
'
complex
'
,
operator
:
'
NOT
'
,
query_list
:[
query
]};
};
var
mkComplexQuery
=
function
(
operator
,
query_list
)
{
var
i
,
query_list2
=
[];
for
(
i
=
0
;
i
<
query_list
.
length
;
++
i
)
{
if
(
query_list
[
i
].
operator
===
operator
)
{
query_list2
=
arrayExtend
(
query_list2
,
query_list
[
i
].
query_list
);
}
else
{
query_list2
.
push
(
query_list
[
i
]);
return
true
;
}
if
(
query
.
type
===
"
simple
"
&&
!
query
.
key
)
{
query
.
key
=
key
;
return
true
;
}
return
false
;
},
error_offsets
=
[],
error_lookaheads
=
[],
error_count
=
0
,
result
;
if
((
error_count
=
__NODEJS_parse
(
string
,
error_offsets
,
error_lookaheads
))
>
0
)
{
var
i
;
for
(
i
=
0
;
i
<
error_count
;
i
+=
1
)
{
throw
new
Error
(
"
Parse error near
\"
"
+
string
.
substr
(
error_offsets
[
i
])
+
"
\"
, expecting
\"
"
+
error_lookaheads
[
i
].
join
()
+
"
\"
"
);
}
}
return
result
;
}
// parseStringToObject
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true */
/**
* Create a class, manage inheritance, static methods,
* protected attributes and can hide methods or/and secure methods
*
* @param {Class} Class Classes to inherit from (0..n). The last class
* parameter will inherit from the previous one, and so on
* @param {Object} option Class option (0..n)
* @param {Boolean} [option.secure_methods=false] Make methods not configurable
* and not writable
* @param {Boolean} [option.hide_methods=false] Make methods not enumerable
* @param {Boolean} [option.secure_static_methods=true] Make static methods not
* configurable and not
* writable
* @param {Boolean} [option.hide_static_methods=false] Make static methods not
* enumerable
* @param {Object} [option.static_methods={}] Object of static methods
* @param {Function} constructor The new class constructor
* @return {Class} The new class
*/
function
newClass
()
{
var
j
,
k
,
constructors
=
[],
option
,
new_class
;
for
(
j
=
0
;
j
<
arguments
.
length
;
j
+=
1
)
{
if
(
typeof
arguments
[
j
]
===
"
function
"
)
{
constructors
.
push
(
arguments
[
j
]);
}
else
if
(
typeof
arguments
[
j
]
===
"
object
"
)
{
option
=
option
||
{};
for
(
k
in
arguments
[
j
])
{
if
(
arguments
[
j
].
hasOwnProperty
(
k
))
{
option
[
k
]
=
arguments
[
j
][
k
];
}
}
}
return
{
type
:
'
complex
'
,
operator
:
operator
,
query_list
:
query_list2
};
};
var
simpleQuerySetId
=
function
(
query
,
id
)
{
var
i
;
if
(
query
.
type
===
'
complex
'
)
{
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
++
i
)
{
simpleQuerySetId
(
query
.
query_list
[
i
],
id
);
}
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
]
});
}
}
return
true
;
}
}
if
(
query
.
type
===
'
simple
'
&&
!
query
.
id
)
{
query
.
id
=
id
;
return
true
;
}
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
]
});
}
}
}
}
return
false
;
};
var
error_offsets
=
[];
var
error_lookaheads
=
[];
var
error_count
=
0
;
var
result
;
if
(
(
error_count
=
__NODEJS_parse
(
string
,
error_offsets
,
error_lookaheads
)
)
>
0
)
{
}
new_class
=
function
(
spec
,
my
)
{
var
i
;
for
(
i
=
0
;
i
<
error_count
;
++
i
)
{
throw
new
Error
(
"
Parse error near
\"
"
+
string
.
substr
(
error_offsets
[
i
]
)
+
"
\"
, expecting
\"
"
+
error_lookaheads
[
i
].
join
()
+
"
\"
"
);
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
;
}
return
result
;
/**
* Escapes regexp special chars from a string.
*
* @param {String} string The string to escape
* @return {String} The escaped string
*/
function
stringEscapeRegexpCharacters
(
string
)
{
if
(
typeof
string
===
"
string
"
)
{
return
string
.
replace
(
/
([\\\.\$\[\]\(\)\{\}\^\?\*\+\-])
/g
,
"
\\
$1
"
);
}
}
});
Object
.
defineProperty
(
scope
.
ComplexQueries
,
"
serialize
"
,{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
query
){
var
str_list
=
[],
i
;
if
(
query
.
type
===
'
complex
'
)
{
str_list
.
push
(
'
(
'
);
for
(
i
=
0
;
i
<
query
.
query_list
.
length
;
++
i
)
{
str_list
.
push
(
scope
.
ComplexQueries
.
serialize
(
query
.
query_list
[
i
])
);
str_list
.
push
(
query
.
operator
);
}
str_list
.
length
--
;
str_list
.
push
(
'
)
'
);
return
str_list
.
join
(
'
'
);
}
else
if
(
query
.
type
===
'
simple
'
)
{
return
query
.
id
+
(
query
.
id
?
'
:
'
:
''
)
+
query
.
operator
+
'
"
'
+
query
.
value
+
'
"
'
;
_export
(
"
stringEscapeRegexpCharacters
"
,
stringEscapeRegexpCharacters
);
/**
* A sort function to sort items by key
*
* @param {String} key The key to sort on
* @param {String} [way="ascending"] 'ascending' or 'descending'
* @return {Function} The sort function
*/
function
sortFunction
(
key
,
way
)
{
if
(
way
===
'
descending
'
)
{
return
function
(
a
,
b
)
{
return
a
[
key
]
<
b
[
key
]
?
1
:
a
[
key
]
>
b
[
key
]
?
-
1
:
0
;
};
}
return
function
(
a
,
b
)
{
return
a
[
key
]
>
b
[
key
]
?
1
:
a
[
key
]
<
b
[
key
]
?
-
1
:
0
;
};
}
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global _export: true, ComplexQuery: true, SimpleQuery: true,
newClass: true, Query: true */
var
query_class_dict
=
{},
QueryFactory
;
/**
* Provides static methods to create Query object
*
* @class QueryFactory
*/
QueryFactory
=
newClass
({
"
static_methods
"
:
{
/**
* Creates Query object from a search text string or a serialized version
* of a Query.
*
* @method create
* @static
* @param {Object,String} object The search text or the serialized version
* of a Query
* @return {Query} A Query object
*/
"
create
"
:
function
(
object
)
{
if
(
object
===
""
)
{
return
new
Query
();
}
if
(
typeof
object
===
"
string
"
)
{
object
=
Query
.
parseStringToObject
(
object
);
}
if
(
typeof
(
object
||
{}).
type
===
"
string
"
&&
query_class_dict
[
object
.
type
])
{
return
new
query_class_dict
[
object
.
type
](
object
);
}
return
null
;
}
}
},
function
()
{});
_export
(
"
QueryFactory
"
,
QueryFactory
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, sortFunction: true, parseStringToObject: true,
_export: true, stringEscapeRegexpCharacters: true */
/**
* The query to use to filter a list of objects.
* This is an abstract class.
*
* @class Query
* @constructor
*/
var
Query
=
newClass
(
function
()
{
var
that
=
this
,
emptyFunction
=
function
()
{};
/**
* Filter the item list with matching item only
*
* @method exec
* @param {Array} item_list The list of object
* @param {Object} [option] Some operation option
* @param {String} [option.wildcard_character="%"] The wildcard character
* @param {Array} [option.select_list] A object keys to retrieve
* @param {Array} [option.sort_on] Couples of object keys and "ascending"
* or "descending"
* @param {Array} [option.limit] Couple of integer, first is an index and
* second is the length.
*/
that
.
exec
=
function
(
item_list
,
option
)
{
var
i
=
0
;
while
(
i
<
item_list
.
length
)
{
if
(
!
that
.
match
(
item_list
[
i
],
option
.
wildcard_character
))
{
item_list
.
splice
(
i
,
1
);
}
else
{
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!
*
* @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.
*
* @method toString
* @return {String} The string version of this query
*/
that
.
toString
=
function
()
{
return
""
;
};
/**
* Convert this query to an jsonable object in order to be remake thanks to
* QueryFactory class.
*
* @method serialized
* @return {Object} The jsonable object
*/
that
.
serialized
=
function
()
{
return
undefined
;
};
},
{
"
static_methods
"
:
{
/**
* Filter a list of items, modifying them to select only wanted keys.
*
* @method filterListSelect
* @static
* @param {Array} select_option Key list to keep
* @param {Array} list The item list to filter
*/
"
filterListSelect
"
:
function
(
select_option
,
list
)
{
var
i
,
j
,
new_item
;
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
new_item
=
{};
for
(
j
=
0
;
j
<
select_option
.
length
;
j
+=
1
)
{
new_item
[
select_option
[
j
]]
=
list
[
i
][
select_option
[
j
]];
}
for
(
j
in
new_item
)
{
if
(
new_item
.
hasOwnProperty
(
j
))
{
list
[
i
]
=
new_item
;
break
;
}
return
query
;
}
}
},
/**
* Sort a list of items, according to keys and directions.
*
* @method sortOn
* @static
* @param {Array} sort_on_option List of couples [key, direction]
* @param {Array} list The item list to sort
*/
"
sortOn
"
:
function
(
sort_on_option
,
list
)
{
var
sort_index
;
for
(
sort_index
=
sort_on_option
.
length
-
1
;
sort_index
>=
0
;
sort_index
-=
1
)
{
list
.
sort
(
sortFunction
(
sort_on_option
[
sort_index
][
0
],
sort_on_option
[
sort_index
][
1
]
));
}
},
/**
* Parse a text request to a json query object tree
*
* @method parseStringToObject
* @static
* @param {String} string The string to parse
* @return {Object} The json query tree
*/
"
parseStringToObject
"
:
parseStringToObject
,
/**
* Convert a search text to a regexp.
*
* @method convertStringToRegExp
* @static
* @param {String} string The string to convert
* @param {String} [wildcard_character=undefined] The wildcard chararter
* @return {RegExp} The search text regexp
*/
"
convertStringToRegExp
"
:
function
(
string
,
wildcard_character
)
{
return
new
RegExp
(
"
^
"
+
stringEscapeRegexpCharacters
(
string
).
replace
(
stringEscapeRegexpCharacters
(
wildcard_character
),
'
.*
'
)
+
"
$
"
);
}
}});
_export
(
"
Query
"
,
Query
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, Query: true,
query_class_dict: true, _export: true */
/**
* The SimpleQuery inherits from Query, and compares one metadata value
*
* @class SimpleQuery
* @extends Query
* @param {Object} [spec={}] The specifications
* @param {String} [spec.operator="="] The compare method to use
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
var
SimpleQuery
=
newClass
(
Query
,
function
(
spec
)
{
/**
* Operator to use to compare object values
*
* @attribute operator
* @type String
* @default "="
* @optional
*/
this
.
operator
=
spec
.
operator
||
"
=
"
;
/**
* Key of the object which refers to the value to compare
*
* @attribute key
* @type String
*/
this
.
key
=
spec
.
key
;
/**
* Value is used to do the comparison with the object value
*
* @attribute value
* @type String
*/
this
.
value
=
spec
.
value
;
/**
* #crossLink "Query/match:method"
*/
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
[
this
.
key
],
this
.
value
,
wildcard_character
);
};
/**
* #crossLink "Query/toString:method"
*/
this
.
toString
=
function
()
{
return
(
this
.
key
?
this
.
key
+
"
:
"
:
""
)
+
(
this
.
operator
||
"
=
"
)
+
'
"
'
+
this
.
value
+
'
"
'
;
};
/**
* #crossLink "Query/serialized:method"
*/
this
.
serialized
=
function
()
{
return
{
"
type
"
:
"
simple
"
,
"
operator
"
:
this
.
operator
,
"
key
"
:
this
.
key
,
"
value
"
:
this
.
value
};
};
/**
* Comparison operator, test if this query value matches the item value
*
* @method =
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if match, false otherwise
*/
this
[
"
=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
return
Query
.
convertStringToRegExp
(
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
};
/**
* Comparison operator, test if this query value does not match the item value
*
* @method !=
* @param {String} object_value The value to compare
* @param {String} comparison_value The comparison value
* @param {String} wildcard_character The wildcard_character
* @return {Boolean} true if not match, false otherwise
*/
this
[
"
!=
"
]
=
function
(
object_value
,
comparison_value
,
wildcard_character
)
{
return
!
Query
.
convertStringTextToRegExp
(
comparison_value
.
toString
(),
wildcard_character
||
"
%
"
).
test
(
object_value
.
toString
());
};
/**
* Comparison operator, test if this query value is lower than the item value
*
* @method <
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if lower, false otherwise
*/
this
[
"
<
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
<
comparison_value
;
};
/**
* Comparison operator, test if this query value is equal or lower than the
* item value
*
* @method <=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or lower, false otherwise
*/
this
[
"
<=
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
<=
comparison_value
;
};
/**
* Comparison operator, test if this query value is greater than the item
* value
*
* @method >
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if greater, false otherwise
*/
this
[
"
>
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
>
comparison_value
;
};
/**
* Comparison operator, test if this query value is equal or greater than the
* item value
*
* @method >=
* @param {Number, String} object_value The value to compare
* @param {Number, String} comparison_value The comparison value
* @return {Boolean} true if equal or greater, false otherwise
*/
this
[
"
>=
"
]
=
function
(
object_value
,
comparison_value
)
{
return
object_value
>=
comparison_value
;
};
});
Object
.
defineProperty
(
scope
.
ComplexQueries
,
"
query
"
,{
configurable
:
false
,
enumerable
:
false
,
writable
:
false
,
value
:
function
(
query
,
object_list
)
{
var
wildcard_character
=
typeof
query
.
wildcard_character
===
'
string
'
?
query
.
wildcard_character
:
'
%
'
,
operator_actions
=
{
'
=
'
:
function
(
value1
,
value2
)
{
value1
=
''
+
value1
;
return
value1
.
match
(
convertToRegexp
(
value2
,
wildcard_character
))
||
false
&&
true
;
},
'
!=
'
:
function
(
value1
,
value2
)
{
value1
=
''
+
value1
;
return
!
(
value1
.
match
(
convertToRegexp
(
value2
,
wildcard_character
)));
},
'
<
'
:
function
(
value1
,
value2
)
{
return
value1
<
value2
;
},
'
<=
'
:
function
(
value1
,
value2
)
{
return
value1
<=
value2
;
},
'
>
'
:
function
(
value1
,
value2
)
{
return
value1
>
value2
;
},
'
>=
'
:
function
(
value1
,
value2
)
{
return
value1
>=
value2
;
},
'
AND
'
:
function
(
item
,
query_list
)
{
var
i
;
for
(
i
=
0
;
i
<
query_list
.
length
;
++
i
)
{
if
(
!
itemMatchesQuery
(
item
,
query_list
[
i
]))
{
return
false
;
}
}
return
true
;
},
'
OR
'
:
function
(
item
,
query_list
)
{
var
i
;
for
(
i
=
0
;
i
<
query_list
.
length
;
++
i
)
{
if
(
itemMatchesQuery
(
item
,
query_list
[
i
]))
{
return
true
;
}
}
return
false
;
},
'
NOT
'
:
function
(
item
,
query_list
)
{
return
!
itemMatchesQuery
(
item
,
query_list
[
0
]);
}
},
convertToRegexp
=
function
(
string
)
{
return
subString
(
'
^
'
+
string
.
replace
(
new
RegExp
(
'
([
\\
{
\\
}
\\
(
\\
)
\\
^
\\
$
\\
&
\\
.
\\
*
\\
?
\\\
/
\\
+
\\
|
\\
[
\\
]
\\
-
\\\\
])
'
.
replace
(
wildcard_character
?
'
\\
'
+
wildcard_character
:
undefined
,
''
),
'
g
'
),
'
\\
$1
'
)
+
'
$
'
,(
wildcard_character
||
undefined
),
'
.*
'
);
},
subString
=
function
(
string
,
substring
,
newsubstring
)
{
var
res
=
''
,
i
=
0
;
if
(
substring
===
undefined
)
{
return
string
;
}
while
(
1
)
{
var
tmp
=
string
.
indexOf
(
substring
,
i
);
if
(
tmp
===
-
1
)
{
break
;
}
for
(;
i
<
tmp
;
++
i
)
{
res
+=
string
[
i
];
}
res
+=
newsubstring
;
i
+=
substring
.
length
;
}
for
(;
i
<
string
.
length
;
++
i
)
{
res
+=
string
[
i
];
}
return
res
;
},
itemMatchesQuery
=
function
(
item
,
query_object
)
{
var
i
;
if
(
query_object
.
type
===
'
complex
'
)
{
return
operator_actions
[
query_object
.
operator
](
item
,
query_object
.
query_list
);
}
else
{
if
(
query_object
.
id
)
{
if
(
typeof
item
[
query_object
.
id
]
!==
'
undefined
'
)
{
return
operator_actions
[
query_object
.
operator
](
item
[
query_object
.
id
],
query_object
.
value
);
}
else
{
return
false
;
}
}
else
{
return
true
;
}
}
},
select
=
function
(
list
,
select_list
)
{
var
i
;
if
(
select_list
.
length
===
0
)
{
return
;
}
for
(
i
=
0
;
i
<
list
.
length
;
++
i
)
{
var
list_value
=
{},
k
;
for
(
k
=
0
;
k
<
select_list
.
length
;
++
k
)
{
list_value
[
select_list
[
k
]]
=
list
[
i
][
select_list
[
k
]];
}
list
[
i
]
=
list_value
;
}
},
sortFunction
=
function
(
key
,
asc
)
{
if
(
asc
===
'
descending
'
)
{
return
function
(
a
,
b
)
{
return
a
[
key
]
<
b
[
key
]
?
1
:
a
[
key
]
>
b
[
key
]
?
-
1
:
0
;
};
}
return
function
(
a
,
b
)
{
return
a
[
key
]
>
b
[
key
]
?
1
:
a
[
key
]
<
b
[
key
]
?
-
1
:
0
;
};
},
mergeList
=
function
(
list
,
list_to_merge
,
index
)
{
var
i
,
j
;
for
(
i
=
index
,
j
=
0
;
i
<
list_to_merge
.
length
+
index
;
++
i
,
++
j
)
{
list
[
i
]
=
list_to_merge
[
j
];
}
},
sort
=
function
(
list
,
sort_list
)
{
var
i
,
tmp
,
key
,
asc
,
sortAndMerge
=
function
()
{
sort
(
tmp
,
sort_list
.
slice
(
1
));
mergeList
(
list
,
tmp
,
i
-
tmp
.
length
);
tmp
=
[
list
[
i
]];
};
if
(
list
.
length
<
2
)
{
return
;
}
if
(
sort_list
.
length
===
0
)
{
return
;
}
key
=
sort_list
[
0
][
0
];
asc
=
sort_list
[
0
][
1
];
list
.
sort
(
sortFunction
(
key
,
asc
));
tmp
=
[
list
[
0
]];
for
(
i
=
1
;
i
<
list
.
length
;
++
i
)
{
if
(
tmp
[
0
][
key
]
===
list
[
i
][
key
])
{
tmp
.
push
(
list
[
i
]);
}
else
{
sortAndMerge
();
}
}
sortAndMerge
();
},
limit
=
function
(
list
,
limit_list
)
{
var
i
;
if
(
typeof
limit_list
[
0
]
!==
'
undefined
'
)
{
if
(
typeof
limit_list
[
1
]
!==
'
undefined
'
)
{
if
(
list
.
length
>
limit_list
[
1
]
+
limit_list
[
0
])
{
list
.
length
=
limit_list
[
1
]
+
limit_list
[
0
];
}
list
.
splice
(
0
,
limit_list
[
0
]);
}
else
{
list
.
length
=
limit_list
[
0
];
}
}
},
////////////////////////////////////////////////////////////
result_list
=
[],
result_list_tmp
=
[],
j
;
object_list
=
object_list
||
[];
if
(
query
.
query
===
undefined
)
{
result_list
=
object_list
;
}
else
{
for
(
j
=
0
;
j
<
object_list
.
length
;
++
j
)
{
if
(
itemMatchesQuery
(
object_list
[
j
],
scope
.
ComplexQueries
.
parse
(
query
.
query
)
))
{
result_list
.
push
(
object_list
[
j
]);
}
}
}
if
(
query
.
filter
)
{
select
(
result_list
,
query
.
filter
.
select_list
||
[]);
sort
(
result_list
,
query
.
filter
.
sort_on
||
[]);
limit
(
result_list
,
query
.
filter
.
limit
||
[]);
}
return
result_list
;
query_class_dict
.
simple
=
SimpleQuery
;
_export
(
"
SimpleQuery
"
,
SimpleQuery
);
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global newClass: true, Query: true, query_class_dict: true,
_export: true, QueryFactory: true */
/**
* The ComplexQuery inherits from Query, and compares one or several metadata
* values.
*
* @class ComplexQuery
* @extends Query
* @param {Object} [spec={}] The specifications
* @param {String} [spec.operator="AND"] The compare method to use
* @param {String} spec.key The metadata key
* @param {String} spec.value The value of the metadata to compare
*/
var
ComplexQuery
=
newClass
(
Query
,
function
(
spec
)
{
/**
* Logical operator to use to compare object values
*
* @attribute operator
* @type String
* @default "AND"
* @optional
*/
this
.
operator
=
spec
.
operator
||
"
AND
"
;
/**
* The sub Query list which are used to query an item.
*
* @attribute query_list
* @type Array
* @default []
* @optional
*/
this
.
query_list
=
spec
.
query_list
||
[];
this
.
query_list
=
this
.
query_list
.
map
(
QueryFactory
.
create
);
/**
* #crossLink "Query/match:method"
*/
this
.
match
=
function
(
item
,
wildcard_character
)
{
return
this
[
this
.
operator
](
item
,
wildcard_character
);
};
/**
* #crossLink "Query/toString:method"
*/
this
.
toString
=
function
()
{
var
str_list
=
[
"
(
"
],
this_operator
=
this
.
operator
;
this
.
query_list
.
forEach
(
function
(
query
)
{
str_list
.
push
(
query
.
toString
());
str_list
.
push
(
this_operator
);
});
str_list
.
pop
();
// remove last operator
str_list
.
push
(
"
)
"
);
return
str_list
.
join
(
"
"
);
};
/**
* #crossLink "Query/serialized:method"
*/
this
.
serialized
=
function
()
{
var
s
=
{
"
type
"
:
"
complex
"
,
"
operator
"
:
this
.
operator
,
"
query_list
"
:
[]
};
this
.
query_list
.
forEach
(
function
(
query
)
{
s
.
query_list
.
push
(
query
.
serialized
());
});
return
s
;
};
/**
* Comparison operator, test if all sub queries match the
* item value
*
* @method AND
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if all match, false otherwise
*/
this
.
AND
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
!
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
false
;
}
}
return
true
;
};
/**
* Comparison operator, test if one of the sub queries matches the
* item value
*
* @method OR
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
this
.
OR
=
function
(
item
,
wildcard_character
)
{
var
i
;
for
(
i
=
0
;
i
<
this
.
query_list
.
length
;
i
+=
1
)
{
if
(
this
.
query_list
[
i
].
match
(
item
,
wildcard_character
))
{
return
true
;
}
}
return
false
;
};
/**
* Comparison operator, test if the sub query does not match the
* item value
*
* @method NOT
* @param {Object} item The item to match
* @param {String} wildcard_character The wildcard character
* @return {Boolean} true if one match, false otherwise
*/
this
.
NOT
=
function
(
item
,
wildcard_character
)
{
return
!
this
.
query_list
[
0
].
match
(
item
,
wildcard_character
);
};
});
}(
jIO
));
query_class_dict
.
complex
=
ComplexQuery
;
_export
(
"
ComplexQuery
"
,
ComplexQuery
);
if
(
typeof
define
===
"
function
"
&&
define
.
amd
)
{
define
(
to_export
);
}
else
if
(
typeof
window
===
"
object
"
)
{
Object
.
defineProperty
(
window
,
module_name
,
{
configurable
:
false
,
enumerable
:
true
,
writable
:
false
,
value
:
to_export
});
}
else
if
(
typeof
exports
===
"
object
"
)
{
var
i
;
for
(
i
in
to_export
)
{
if
(
to_export
.
hasOwnProperty
(
i
))
{
exports
[
i
]
=
to_export
[
i
];
}
}
}
else
{
complex_queries
=
to_export
;
}
}());
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