1
0
Fork 0

Merge branch 'devel' of github.com:arangodb/arangodb into devel

This commit is contained in:
Michael Hackstein 2015-12-04 11:21:28 +01:00
commit 9a724cd5a6
6 changed files with 139 additions and 0 deletions

View File

@ -1,6 +1,17 @@
v2.8.0 (XXXX-XX-XX)
-------------------
* added AQL function `IS_DATESTRING(value)`
Returns true if *value* is a string that can be used in a date function.
This includes partial dates such as *2015* or *2015-10* and strings containing
invalid dates such as *2015-02-31*. The function will return false for all
non-string values, even if some of them may be usable in date functions.
v2.8.0-alpha1 (2015-12-03)
--------------------------
* added AQL keywords `GRAPH`, `OUTBOUND`, `INBOUND` and `ANY` for use in graph
traversals, reserved AQL keyword `ALL` for future use

View File

@ -370,6 +370,11 @@ DATE_FORMAT("2016", "%%l = %l") // "%l = 1" (2016 is a leap year)
DATE_FORMAT("2016-03-01", "%xxx%") // "063", trailing % ignored
```
- *IS_DATESTRING(value)*: Returns true if *value* is a string that can be used
in a date function. This includes partial dates such as *2015* or *2015-10* and
strings containing invalid dates such as *2015-02-31*. The function will return
false for all non-string values, even if some of them may be usable in date functions.
!SECTION Working with dates and indices
There are two recommended ways to store timestamps in ArangoDB:

View File

@ -80,3 +80,8 @@ The following type check functions are available:
- *IS_OBJECT(value)*: Checks whether *value* is an *object* / *document* value
- *IS_DOCUMENT(value)*: This is an alias for *IS_OBJECT*
- *IS_DATESTRING(value)*: Checks whether *value* is a string that can be used
in a date function. This includes partial dates such as *2015* or *2015-10* and
strings containing invalid dates such as *2015-02-31*. The function will return
false for all non-string values, even if some of them may be usable in date functions.

View File

@ -111,6 +111,7 @@ std::unordered_map<std::string, Function const> const Executor::FunctionNames{
{ "IS_OBJECT", Function("IS_OBJECT", "AQL_IS_OBJECT", ".", true, true, false, true, true, &Functions::IsObject) },
// IS_DOCUMENT is an alias for IS_OBJECT
{ "IS_DOCUMENT", Function("IS_DOCUMENT", "AQL_IS_DOCUMENT", ".", true, true, false, true, true, &Functions::IsObject) },
{ "IS_DATESTRING", Function("IS_DATESTRING", "AQL_IS_DATESTRING", ".", true, true, false, true, true) },
// type cast functions
{ "TO_NUMBER", Function("TO_NUMBER", "AQL_TO_NUMBER", ".", true, true, false, true, true, &Functions::ToNumber) },

View File

@ -2703,6 +2703,35 @@ function AQL_IS_OBJECT (value) {
return (TYPEWEIGHT(value) === TYPEWEIGHT_OBJECT);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief test if value is of a valid datestring
///
/// returns a bool
////////////////////////////////////////////////////////////////////////////////
function AQL_IS_DATESTRING (value) {
'use strict';
if (TYPEWEIGHT(value) !== TYPEWEIGHT_STRING) {
return false;
}
// argument is a string
// append zulu time specifier if no other present
if (! value.match(/([zZ]|[+\-]\d+(:\d+)?)$/) ||
(value.match(/-\d+(:\d+)?$/) && ! value.match(/[tT ]/))) {
value += 'Z';
}
// detect invalid dates ("foo" -> "fooZ" -> getTime() == NaN)
var date = new Date(value);
if (isNaN(date)) {
return false;
}
return true;
}
// -----------------------------------------------------------------------------
// --SECTION-- numeric functions
// -----------------------------------------------------------------------------
@ -9158,6 +9187,7 @@ exports.AQL_IS_ARRAY = AQL_IS_ARRAY;
exports.AQL_IS_LIST = AQL_IS_ARRAY; // alias
exports.AQL_IS_OBJECT = AQL_IS_OBJECT;
exports.AQL_IS_DOCUMENT = AQL_IS_OBJECT; // alias
exports.AQL_IS_DATESTRING = AQL_IS_DATESTRING;
exports.AQL_FLOOR = AQL_FLOOR;
exports.AQL_CEIL = AQL_CEIL;
exports.AQL_ROUND = AQL_ROUND;

View File

@ -42,6 +42,93 @@ var assertQueryWarningAndNull = helper.assertQueryWarningAndNull;
function ahuacatlDateFunctionsTestSuite () {
return {
////////////////////////////////////////////////////////////////////////////////
/// @brief test is_datestring function
////////////////////////////////////////////////////////////////////////////////
testIsDateString : function () {
var values = [
[ "2000-04-29", true ],
[ "2000-04-29Z", true ],
[ "2012-02-12 13:24:12", true ],
[ "2012-02-12 13:24:12Z", true ],
[ "2012-02-12 23:59:59.991", true ],
[ "2012-02-12 23:59:59.991Z", true ],
[ "2012-02-12", true ],
[ "2012-02-12Z", true ],
[ "2012-02-12T13:24:12Z", true ],
[ "2012-02-12Z", true ],
[ "2012-2-12Z", true ],
[ "1910-01-02T03:04:05Z", true ],
[ "1910-01-02 03:04:05Z", true ],
[ "1910-01-02", true ],
[ "1910-01-02Z", true ],
[ "1970-01-01T01:05:27", true ],
[ "1970-01-01T01:05:27Z", true ],
[ "1970-01-01 01:05:27Z", true ],
[ "1970-1-1Z", true ],
[ "1970-1-1", true ],
[ "1221-02-28T23:59:59Z", true ],
[ "1221-02-28 23:59:59Z", true ],
[ "1221-02-28Z", true ],
[ "1221-2-28Z", true ],
[ "1000-12-24T04:12:00Z", true ],
[ "1000-12-24Z", true ],
[ "1000-12-24 04:12:00Z", true ],
[ "6789-12-31T23:59:58.99Z", true ],
[ "6789-12-31Z", true ],
[ "9999-12-31T23:59:59.999Z", true ],
[ "9999-12-31Z", true ],
[ "9999-12-31z", true ],
[ "9999-12-31", true ],
[ "2012Z", true ],
[ "2012z", true ],
[ "2012", true ],
[ "2012-1Z", true ],
[ "2012-1z", true ],
[ "2012-1-1z", true ],
[ "2012-01-01Z", true ],
[ "2012-01-01Z", true ],
[ " 2012-01-01Z", true ],
[ " 2012-01-01z", true ],
[ "foo2012-01-01z", false ],
[ "2012-01-01foo", false ],
[ "foo", false ],
[ "bar", false ],
[ "2015-foobar", false ],
[ "", false ],
[ -95674000, false ],
[ 1399395674000, false ],
[ 60123, false ],
[ 1, false ],
[ 0, false ],
[ -4, false ],
[ true, false ],
[ false, false ],
[ null, false ],
[ [ ], false ],
[ [ 1 ], false ],
[ [ "foo" ], false ],
[ [ "foo", "bar" ], false ],
[ [ "2015-01-23" ], false ],
[ { }, false ]
];
values.forEach(function (value) {
var actual = getQueryResults("RETURN IS_DATESTRING(@value)", { value: value[0] });
assertEqual([ value[1] ], actual, value);
});
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test is_datestring function
////////////////////////////////////////////////////////////////////////////////
testIsDateStringInvalid : function () {
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN IS_DATESTRING()");
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN IS_DATESTRING('foo', 'bar')");
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test date_now function
////////////////////////////////////////////////////////////////////////////////