mirror of https://gitee.com/bigwinds/arangodb
2134 lines
75 KiB
C
2134 lines
75 KiB
C
static string JS_server_ahuacatl =
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief Ahuacatl, internal query functions \n"
|
|
"///\n"
|
|
"/// @file\n"
|
|
"///\n"
|
|
"/// DISCLAIMER\n"
|
|
"///\n"
|
|
"/// Copyright 2010-2012 triagens GmbH, Cologne, Germany\n"
|
|
"///\n"
|
|
"/// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
|
|
"/// you may not use this file except in compliance with the License.\n"
|
|
"/// You may obtain a copy of the License at\n"
|
|
"///\n"
|
|
"/// http://www.apache.org/licenses/LICENSE-2.0\n"
|
|
"///\n"
|
|
"/// Unless required by applicable law or agreed to in writing, software\n"
|
|
"/// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
|
"/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
|
|
"/// See the License for the specific language governing permissions and\n"
|
|
"/// limitations under the License.\n"
|
|
"///\n"
|
|
"/// Copyright holder is triAGENS GmbH, Cologne, Germany\n"
|
|
"///\n"
|
|
"/// @author Jan Steemann\n"
|
|
"/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"var internal = require(\"internal\");\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief type weight used for sorting and comparing\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"var AHUACATL_TYPEWEIGHT_NULL = 0;\n"
|
|
"var AHUACATL_TYPEWEIGHT_BOOL = 1;\n"
|
|
"var AHUACATL_TYPEWEIGHT_NUMBER = 2;\n"
|
|
"var AHUACATL_TYPEWEIGHT_STRING = 4;\n"
|
|
"var AHUACATL_TYPEWEIGHT_LIST = 8;\n"
|
|
"var AHUACATL_TYPEWEIGHT_DOCUMENT = 16;\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- helper functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief throw a runtime exception\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_THROW (error, data) {\n"
|
|
" var err = new ArangoError\n"
|
|
"\n"
|
|
" err.errorNum = error.code;\n"
|
|
" if (data) {\n"
|
|
" err.errorMessage = error.message.replace(/%s/, data);\n"
|
|
" }\n"
|
|
" else {\n"
|
|
" err.errorMessage = error.message;\n"
|
|
" }\n"
|
|
"\n"
|
|
" throw err;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief find an index of a certain type for a collection\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_INDEX (collection, indexTypes) {\n"
|
|
" var indexes = collection.getIndexes();\n"
|
|
"\n"
|
|
" for (var i = 0; i < indexes.length; ++i) {\n"
|
|
" var index = indexes[i];\n"
|
|
"\n"
|
|
" for (var j = 0; j < indexTypes.length; ++j) {\n"
|
|
" if (index.type == indexTypes[j]) {\n"
|
|
" return index.id;\n"
|
|
" }\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return null;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief normalize a value for comparison, sorting etc.\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_NORMALIZE (value) {\n"
|
|
" if (value === null || value === undefined) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
" if (typeof(value) !== \"object\") {\n"
|
|
" return value;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (Array.isArray(value)) {\n"
|
|
" var result = [ ];\n"
|
|
" var length = value.length;\n"
|
|
" for (var i = 0; i < length; ++i) {\n"
|
|
" result.push(AHUACATL_NORMALIZE(value[i]));\n"
|
|
" }\n"
|
|
" \n"
|
|
" return result;\n"
|
|
" } \n"
|
|
" else {\n"
|
|
" var attributes = [ ];\n"
|
|
" for (var attribute in value) {\n"
|
|
" if (!value.hasOwnProperty(attribute)) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
" attributes.push(attribute);\n"
|
|
" }\n"
|
|
" attributes.sort();\n"
|
|
"\n"
|
|
" var result = { };\n"
|
|
" var length = attributes.length;\n"
|
|
" for (var i = 0; i < length; ++i) {\n"
|
|
" result[attributes[i]] = AHUACATL_NORMALIZE(value[attributes[i]]);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief clone an object\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_CLONE (obj) {\n"
|
|
" if (obj == null) {\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (typeof(obj) != \"object\") {\n"
|
|
" return obj;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (Array.isArray(obj)) {\n"
|
|
" var copy = [];\n"
|
|
" var length = obj.length;\n"
|
|
" for (var i = 0; i < length; ++i) {\n"
|
|
" copy[i] = AHUACATL_CLONE(obj[i]);\n"
|
|
" }\n"
|
|
" return copy;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (obj instanceof Object) {\n"
|
|
" var copy = {};\n"
|
|
" for (var attr in obj) {\n"
|
|
" if (obj.hasOwnProperty(attr)) {\n"
|
|
" copy[attr] = AHUACATL_CLONE(obj[attr]);\n"
|
|
" }\n"
|
|
" }\n"
|
|
" return copy;\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief validate function call argument\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_ARG_CHECK (actualValue, expectedType, functionName) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(actualValue) !== expectedType) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, functionName);\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief call a function\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_FCALL (name, parameters) {\n"
|
|
" return name.apply(null, parameters);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief return the numeric value or undefined if it is out of range\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_NUMERIC_VALUE (value) {\n"
|
|
" if (isNaN(value) || !isFinite(value)) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return value;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief fix a value for a comparison\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_FIX (value) {\n"
|
|
" if (value === undefined) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return value;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get the name for a type\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_TYPENAME (value) {\n"
|
|
" switch (value) {\n"
|
|
" case AHUCATL_TYPEWEIGHT_BOOL:\n"
|
|
" return 'boolean';\n"
|
|
" case AHUCATL_TYPEWEIGHT_NUMBER:\n"
|
|
" return 'number';\n"
|
|
" case AHUCATL_TYPEWEIGHT_STRING:\n"
|
|
" return 'string';\n"
|
|
" case AHUCATL_TYPEWEIGHT_LIST:\n"
|
|
" return 'list';\n"
|
|
" case AHUCATL_TYPEWEIGHT_DOCUMENT:\n"
|
|
" return 'document';\n"
|
|
" case AHUCATL_TYPEWEIGHT_NULL:\n"
|
|
" default:\n"
|
|
" return 'null';\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get the sort type of an operand\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_TYPEWEIGHT (value) {\n"
|
|
" if (value === undefined || value === null) {\n"
|
|
" return AHUACATL_TYPEWEIGHT_NULL;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (Array.isArray(value)) {\n"
|
|
" return AHUACATL_TYPEWEIGHT_LIST;\n"
|
|
" }\n"
|
|
"\n"
|
|
" switch (typeof(value)) {\n"
|
|
" case 'boolean':\n"
|
|
" return AHUACATL_TYPEWEIGHT_BOOL;\n"
|
|
" case 'number':\n"
|
|
" if (isNaN(value) || !isFinite(value)) {\n"
|
|
" // not a number => undefined\n"
|
|
" return AHUACATL_TYPEWEIGHT_NULL; \n"
|
|
" }\n"
|
|
" return AHUACATL_TYPEWEIGHT_NUMBER;\n"
|
|
" case 'string':\n"
|
|
" return AHUACATL_TYPEWEIGHT_STRING;\n"
|
|
" case 'object':\n"
|
|
" return AHUACATL_TYPEWEIGHT_DOCUMENT;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return AHUACATL_TYPEWEIGHT_NULL;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get the keys of an array or object in a comparable way\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_KEYS (value, doSort) {\n"
|
|
" var keys = [];\n"
|
|
" \n"
|
|
" if (Array.isArray(value)) {\n"
|
|
" var n = value.length;\n"
|
|
" for (var j = 0; j < n; ++j) {\n"
|
|
" keys.push(j);\n"
|
|
" }\n"
|
|
" }\n"
|
|
" else {\n"
|
|
" for (var k in value) {\n"
|
|
" if (value.hasOwnProperty(k)) {\n"
|
|
" keys.push(k);\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (doSort) {\n"
|
|
" // object keys need to be sorted by names\n"
|
|
" keys.sort();\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return keys;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get the keys of an array or object in a comparable way\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_KEYLIST (lhs, rhs) {\n"
|
|
" var keys = [];\n"
|
|
" \n"
|
|
" if (Array.isArray(lhs)) {\n"
|
|
" // lhs & rhs are lists\n"
|
|
" var n;\n"
|
|
" if (lhs.length > rhs.length) {\n"
|
|
" n = lhs.length;\n"
|
|
" }\n"
|
|
" else {\n"
|
|
" n = rhs.length;\n"
|
|
" }\n"
|
|
" for (var j = 0; j < n; ++j) {\n"
|
|
" keys.push(j);\n"
|
|
" }\n"
|
|
" return keys;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs & rhs are arrays\n"
|
|
" var k;\n"
|
|
" for (k in lhs) {\n"
|
|
" keys.push(k);\n"
|
|
" }\n"
|
|
" for (k in rhs) {\n"
|
|
" if (lhs.hasOwnProperty(k)) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
" keys.push(k);\n"
|
|
" }\n"
|
|
"\n"
|
|
" // object keys need to be sorted by names\n"
|
|
" keys.sort();\n"
|
|
"\n"
|
|
" return keys;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get an indexed value from an array or document (e.g. users[3])\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_INDEX (value, index) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(value) == AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
" \n"
|
|
" if (AHUACATL_TYPEWEIGHT(value) != AHUACATL_TYPEWEIGHT_LIST &&\n"
|
|
" AHUACATL_TYPEWEIGHT(value) != AHUACATL_TYPEWEIGHT_DOCUMENT) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_LIST_EXPECTED);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = value[index];\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get an attribute from a document (e.g. users.name)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_DOCUMENT_MEMBER (value, attributeName) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(value) == AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(value) != AHUACATL_TYPEWEIGHT_DOCUMENT) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = value[attributeName];\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief assert that a value is a list, fail otherwise\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_LIST (value) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(value) !== AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_LIST_EXPECTED);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return value;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get all documents from the specified collection\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_DOCUMENTS (collection) {\n"
|
|
" return internal.db[collection].all().toArray();\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get documents from the specified collection using the primary index\n"
|
|
"/// (single index value)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_DOCUMENTS_PRIMARY (collection, idx, id) {\n"
|
|
" try {\n"
|
|
" return [ internal.db[collection].document(id) ];\n"
|
|
" }\n"
|
|
" catch (e) {\n"
|
|
" return [ ];\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get documents from the specified collection using the primary index\n"
|
|
"/// (multiple index values)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_DOCUMENTS_PRIMARY_LIST (collection, idx, values) {\n"
|
|
" var result = [ ];\n"
|
|
"\n"
|
|
" for (var i in values) {\n"
|
|
" var id = values[i];\n"
|
|
" try {\n"
|
|
" var d = internal.db[collection].document(id);\n"
|
|
" result.push(d);\n"
|
|
" }\n"
|
|
" catch (e) {\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get documents from the specified collection using a hash index\n"
|
|
"/// (single index value)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_DOCUMENTS_HASH (collection, idx, example) {\n"
|
|
" return internal.db[collection].BY_EXAMPLE_HASH(idx, example).documents;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get documents from the specified collection using a hash index\n"
|
|
"/// (multiple index values)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_DOCUMENTS_HASH_LIST (collection, idx, attribute, values) {\n"
|
|
" var result = [ ];\n"
|
|
"\n"
|
|
" for (var i in values) {\n"
|
|
" var value = values[i];\n"
|
|
" var example = { };\n"
|
|
"\n"
|
|
" example[attribute] = value;\n"
|
|
"\n"
|
|
" var documents = internal.db[collection].BY_EXAMPLE_HASH(idx, example).documents;\n"
|
|
" for (var j in documents) {\n"
|
|
" result.push(documents[j]);\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get documents from the specified collection using a skiplist\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_DOCUMENTS_SKIPLIST (collection, idx, example) {\n"
|
|
" return internal.db[collection].BY_CONDITION_SKIPLIST(idx, example).documents;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get documents from the specified collection using a skiplist\n"
|
|
"/// (multiple index values)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GET_DOCUMENTS_SKIPLIST_LIST (collection, idx, attribute, values) {\n"
|
|
" var result = [ ];\n"
|
|
"\n"
|
|
" for (var i in values) {\n"
|
|
" var value = values[i];\n"
|
|
" var example = { };\n"
|
|
"\n"
|
|
" example[attribute] = value;\n"
|
|
"\n"
|
|
" var documents = internal.db[collection].BY_EXAMPLE_SKIPLIST(idx, example).documents;\n"
|
|
" for (var j in documents) {\n"
|
|
" result.push(documents[j]);\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get names of all collections\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_COLLECTIONS () {\n"
|
|
" var collections = internal.db._collections();\n"
|
|
" var result = [ ];\n"
|
|
"\n"
|
|
" for (var i = 0; i < collections.length; ++i) {\n"
|
|
" result.push({ \"_id\" : collections[i]._id, \"name\" : collections[i].name() });\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- logical operations\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief execute ternary operator\n"
|
|
"///\n"
|
|
"/// the condition operand must be a boolean value, returns either the truepart\n"
|
|
"/// or the falsepart \n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_TERNARY_OPERATOR (condition, truePart, falsePart) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(condition) !== AHUACATL_TYPEWEIGHT_BOOL) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (condition) {\n"
|
|
" return truePart;\n"
|
|
" }\n"
|
|
" return falsePart;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform logical and\n"
|
|
"///\n"
|
|
"/// both operands must be boolean values, returns a boolean, uses short-circuit\n"
|
|
"/// evaluation\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_LOGICAL_AND (lhs, rhs) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_BOOL ||\n"
|
|
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_BOOL) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (!lhs) {\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return rhs;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform logical or\n"
|
|
"///\n"
|
|
"/// both operands must be boolean values, returns a boolean, uses short-circuit\n"
|
|
"/// evaluation\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_LOGICAL_OR (lhs, rhs) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_BOOL ||\n"
|
|
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_BOOL) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);\n"
|
|
" }\n"
|
|
" \n"
|
|
" if (lhs) {\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return rhs;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform logical negation\n"
|
|
"///\n"
|
|
"/// the operand must be a boolean values, returns a boolean\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_LOGICAL_NOT (lhs) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_BOOL) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return !lhs;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- comparison operations\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform equality check \n"
|
|
"///\n"
|
|
"/// returns true if the operands are equal, false otherwise\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_EQUAL (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
"\n"
|
|
" if (leftWeight != rightWeight) {\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs and rhs have the same type\n"
|
|
"\n"
|
|
" if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" // arrays and objects\n"
|
|
" var keys = AHUACATL_KEYLIST(lhs, rhs);\n"
|
|
"\n"
|
|
" for (var i in keys) {\n"
|
|
" var key = keys[i];\n"
|
|
" var result = AHUACATL_RELATIONAL_EQUAL(lhs[key], rhs[key]);\n"
|
|
" if (result === false) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
" }\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // primitive type\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" lhs = null;\n"
|
|
" }\n"
|
|
" if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" rhs = null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return (lhs === rhs);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform inequality check \n"
|
|
"///\n"
|
|
"/// returns true if the operands are unequal, false otherwise\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_UNEQUAL (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
" \n"
|
|
" if (leftWeight != rightWeight) {\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs and rhs have the same type\n"
|
|
"\n"
|
|
" if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" // arrays and objects\n"
|
|
" var keys = AHUACATL_KEYLIST(lhs, rhs);\n"
|
|
"\n"
|
|
" for (var i in keys) {\n"
|
|
" var key = keys[i];\n"
|
|
" var result = AHUACATL_RELATIONAL_UNEQUAL(lhs[key], rhs[key]);\n"
|
|
" if (result === true) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // primitive type\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" lhs = null;\n"
|
|
" }\n"
|
|
" if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" rhs = null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return (lhs !== rhs);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform greater than check (inner function)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_GREATER_REC (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
" \n"
|
|
" if (leftWeight > rightWeight) {\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
" if (leftWeight < rightWeight) {\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs and rhs have the same type\n"
|
|
"\n"
|
|
" if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" // arrays and objects\n"
|
|
" var keys = AHUACATL_KEYLIST(lhs, rhs);\n"
|
|
"\n"
|
|
" for (var i in keys) {\n"
|
|
" var key = keys[i];\n"
|
|
" var result = AHUACATL_RELATIONAL_GREATER_REC(lhs[key], rhs[key]);\n"
|
|
" if (result !== null) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
" }\n"
|
|
" \n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // primitive type\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" lhs = null;\n"
|
|
" }\n"
|
|
" if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" rhs = null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (lhs === rhs) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return (lhs > rhs);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform greater than check \n"
|
|
"///\n"
|
|
"/// returns true if the left operand is greater than the right operand\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_GREATER (lhs, rhs) {\n"
|
|
" var result = AHUACATL_RELATIONAL_GREATER_REC(lhs, rhs);\n"
|
|
"\n"
|
|
" if (result === null) {\n"
|
|
" result = false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform greater equal check (inner function)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_GREATEREQUAL_REC (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
" \n"
|
|
" if (leftWeight > rightWeight) {\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
" if (leftWeight < rightWeight) {\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs and rhs have the same type\n"
|
|
"\n"
|
|
" if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" // arrays and objects\n"
|
|
" var keys = AHUACATL_KEYLIST(lhs, rhs);\n"
|
|
"\n"
|
|
" for (var i in keys) {\n"
|
|
" var key = keys[i];\n"
|
|
" var result = AHUACATL_RELATIONAL_GREATEREQUAL_REC(lhs[key], rhs[key]);\n"
|
|
" if (result !== null) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
" }\n"
|
|
" \n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // primitive type\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" lhs = null;\n"
|
|
" }\n"
|
|
" if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" rhs = null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (lhs === rhs) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return (lhs >= rhs);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform greater equal check \n"
|
|
"///\n"
|
|
"/// returns true if the left operand is greater or equal to the right operand\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_GREATEREQUAL (lhs, rhs) {\n"
|
|
" var result = AHUACATL_RELATIONAL_GREATEREQUAL_REC(lhs, rhs);\n"
|
|
"\n"
|
|
" if (result === null) {\n"
|
|
" result = true;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform less than check (inner function)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_LESS_REC (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
" \n"
|
|
" if (leftWeight < rightWeight) {\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
" if (leftWeight > rightWeight) {\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs and rhs have the same type\n"
|
|
"\n"
|
|
" if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" // arrays and objects\n"
|
|
" var keys = AHUACATL_KEYLIST(lhs, rhs);\n"
|
|
"\n"
|
|
" for (var i in keys) {\n"
|
|
" var key = keys[i];\n"
|
|
" var result = AHUACATL_RELATIONAL_LESS_REC(lhs[key], rhs[key]);\n"
|
|
" if (result !== null) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
" }\n"
|
|
" \n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // primitive type\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" lhs = null;\n"
|
|
" }\n"
|
|
" if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" rhs = null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (lhs === rhs) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return (lhs < rhs);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform less than check \n"
|
|
"///\n"
|
|
"/// returns true if the left operand is less than the right operand\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_LESS (lhs, rhs) {\n"
|
|
" var result = AHUACATL_RELATIONAL_LESS_REC(lhs, rhs);\n"
|
|
"\n"
|
|
" if (result === null) {\n"
|
|
" result = false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform less equal check (inner function)\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_LESSEQUAL_REC (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
" \n"
|
|
" if (leftWeight < rightWeight) {\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
" if (leftWeight > rightWeight) {\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs and rhs have the same type\n"
|
|
"\n"
|
|
" if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" // arrays and objects\n"
|
|
" var keys = AHUACATL_KEYLIST(lhs, rhs);\n"
|
|
"\n"
|
|
" for (var i in keys) {\n"
|
|
" var key = keys[i];\n"
|
|
" var result = AHUACATL_RELATIONAL_LESSEQUAL_REC(lhs[key], rhs[key]);\n"
|
|
" if (result !== null) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
" \n"
|
|
" // primitive type\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" lhs = null;\n"
|
|
" }\n"
|
|
" if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" rhs = null;\n"
|
|
" }\n"
|
|
" \n"
|
|
" if (lhs === rhs) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return (lhs <= rhs);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform less equal check \n"
|
|
"///\n"
|
|
"/// returns true if the left operand is less or equal to the right operand\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_LESSEQUAL (lhs, rhs) {\n"
|
|
" var result = AHUACATL_RELATIONAL_LESSEQUAL_REC(lhs, rhs);\n"
|
|
"\n"
|
|
" if (result === null) {\n"
|
|
" result = true;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform comparison\n"
|
|
"///\n"
|
|
"/// returns -1 if the left operand is less than the right operand, 1 if it is\n"
|
|
"/// greater, 0 if both operands are equal\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_CMP (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
" \n"
|
|
" if (leftWeight < rightWeight) {\n"
|
|
" return -1;\n"
|
|
" }\n"
|
|
" if (leftWeight > rightWeight) {\n"
|
|
" return 1;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // lhs and rhs have the same type\n"
|
|
"\n"
|
|
" if (leftWeight >= AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" // arrays and objects\n"
|
|
" var keys = AHUACATL_KEYLIST(lhs, rhs);\n"
|
|
"\n"
|
|
" for (var i in keys) {\n"
|
|
" var key = keys[i];\n"
|
|
" var result = AHUACATL_RELATIONAL_CMP(lhs[key], rhs[key]);\n"
|
|
" if (result !== 0) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
" }\n"
|
|
" \n"
|
|
" return 0;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // primitive type\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" lhs = null;\n"
|
|
" }\n"
|
|
" if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" rhs = null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (lhs < rhs) {\n"
|
|
" return -1;\n"
|
|
" }\n"
|
|
" \n"
|
|
" if (lhs > rhs) {\n"
|
|
" return 1;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return 0;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform in list check \n"
|
|
"///\n"
|
|
"/// returns true if the left operand is contained in the right operand\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_RELATIONAL_IN (lhs, rhs) {\n"
|
|
" var leftWeight = AHUACATL_TYPEWEIGHT(lhs);\n"
|
|
" var rightWeight = AHUACATL_TYPEWEIGHT(rhs);\n"
|
|
" \n"
|
|
" if (rightWeight !== AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_LIST_EXPECTED);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var numRight = rhs.length;\n"
|
|
" for (var i = 0; i < numRight; ++i) {\n"
|
|
" if (AHUACATL_RELATIONAL_EQUAL(lhs, rhs[i])) {\n"
|
|
" return true;\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return false;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- arithmetic operations\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform unary plus operation\n"
|
|
"///\n"
|
|
"/// the operand must be numeric or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_UNARY_PLUS (value) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(value) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = AHUACATL_NUMERIC_VALUE(value);\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform unary minus operation\n"
|
|
"///\n"
|
|
"/// the operand must be numeric or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_UNARY_MINUS (value) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(value) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = AHUACATL_NUMERIC_VALUE(-value);\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform artithmetic plus\n"
|
|
"///\n"
|
|
"/// both operands must be numeric or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_ARITHMETIC_PLUS (lhs, rhs) { \n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
|
|
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = AHUACATL_NUMERIC_VALUE(lhs + rhs);\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform artithmetic minus\n"
|
|
"///\n"
|
|
"/// both operands must be numeric or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_ARITHMETIC_MINUS (lhs, rhs) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
|
|
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = AHUACATL_NUMERIC_VALUE(lhs - rhs);\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform artithmetic multiplication\n"
|
|
"///\n"
|
|
"/// both operands must be numeric or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_ARITHMETIC_TIMES (lhs, rhs) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
|
|
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = AHUACATL_NUMERIC_VALUE(lhs * rhs);\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform artithmetic division\n"
|
|
"///\n"
|
|
"/// both operands must be numeric or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_ARITHMETIC_DIVIDE (lhs, rhs) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
|
|
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE);\n"
|
|
" }\n"
|
|
" \n"
|
|
" if (rhs == 0) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_DIVISION_BY_ZERO);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = AHUACATL_NUMERIC_VALUE(lhs / rhs);\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform artithmetic modulus\n"
|
|
"///\n"
|
|
"/// both operands must be numeric or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_ARITHMETIC_MODULUS (lhs, rhs) {\n"
|
|
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_NUMBER ||\n"
|
|
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (rhs == 0) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_DIVISION_BY_ZERO);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = AHUACATL_NUMERIC_VALUE(lhs % rhs);\n"
|
|
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- string functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform string concatenation\n"
|
|
"///\n"
|
|
"/// all operands must be strings or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_STRING_CONCAT () {\n"
|
|
" var result = '';\n"
|
|
"\n"
|
|
" for (var i in arguments) {\n"
|
|
" var element = arguments[i];\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(element) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
"\n"
|
|
" AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, \"CONCAT\");\n"
|
|
"\n"
|
|
" result += element;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result; \n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief perform string concatenation using a separator character\n"
|
|
"///\n"
|
|
"/// all operands must be strings or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_STRING_CONCAT_SEPARATOR () {\n"
|
|
" var separator;\n"
|
|
" var found = false;\n"
|
|
" var result = '';\n"
|
|
"\n"
|
|
" for (var i in arguments) {\n"
|
|
" var element = arguments[i];\n"
|
|
"\n"
|
|
" if (i > 0 && AHUACATL_TYPEWEIGHT(element) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
" \n"
|
|
" AHUACATL_ARG_CHECK(element, AHUACATL_TYPEWEIGHT_STRING, \"CONCAT_SEPARATOR\");\n"
|
|
"\n"
|
|
" if (i == 0) {\n"
|
|
" separator = element;\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
" else if (found) {\n"
|
|
" result += separator;\n"
|
|
" }\n"
|
|
"\n"
|
|
" found = true;\n"
|
|
"\n"
|
|
" result += element;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result; \n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief return the length of a string in characters (not bytes)\n"
|
|
"///\n"
|
|
"/// the input operand must be a string or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_STRING_LENGTH (value) {\n"
|
|
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"STRING_LENGTH\");\n"
|
|
"\n"
|
|
" return value.length;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief convert a string to lower case\n"
|
|
"///\n"
|
|
"/// the input operand must be a string or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_STRING_LOWER (value) {\n"
|
|
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"LOWER\");\n"
|
|
"\n"
|
|
" return value.toLowerCase();\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief convert a string to upper case\n"
|
|
"///\n"
|
|
"/// the input operand must be a string or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_STRING_UPPER (value) {\n"
|
|
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"UPPER\");\n"
|
|
"\n"
|
|
" return value.toUpperCase();\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief return a substring of the string\n"
|
|
"///\n"
|
|
"/// the input operand must be a string or this function will fail\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_STRING_SUBSTRING (value, offset, count) {\n"
|
|
" AHUACATL_ARG_CHECK(value, AHUACATL_TYPEWEIGHT_STRING, \"SUBSTRING\");\n"
|
|
" AHUACATL_ARG_CHECK(offset, AHUACATL_TYPEWEIGHT_NUMBER, \"SUBSTRING\");\n"
|
|
"\n"
|
|
" return value.substr(offset, count);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- typecast functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief cast to null\n"
|
|
"///\n"
|
|
"/// the operand can have any type, always returns null\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_CAST_NULL (value) {\n"
|
|
" return null;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief cast to a bool\n"
|
|
"///\n"
|
|
"/// the operand can have any type, always returns a bool\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_CAST_BOOL (value) {\n"
|
|
" switch (AHUACATL_TYPEWEIGHT(value)) {\n"
|
|
" case AHUACATL_TYPEWEIGHT_NULL:\n"
|
|
" return false;\n"
|
|
" case AHUACATL_TYPEWEIGHT_BOOL:\n"
|
|
" return value;\n"
|
|
" case AHUACATL_TYPEWEIGHT_NUMBER:\n"
|
|
" return (value != 0);\n"
|
|
" case AHUACATL_TYPEWEIGHT_STRING: \n"
|
|
" return (value !== '');\n"
|
|
" case AHUACATL_TYPEWEIGHT_LIST:\n"
|
|
" return (value.length > 0);\n"
|
|
" case AHUACATL_TYPEWEIGHT_DOCUMENT:\n"
|
|
" return (AHUACATL_KEYS(value, false).length > 0);\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief cast to a number\n"
|
|
"///\n"
|
|
"/// the operand can have any type, always returns a number\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_CAST_NUMBER (value) {\n"
|
|
" switch (AHUACATL_TYPEWEIGHT(value)) {\n"
|
|
" case AHUACATL_TYPEWEIGHT_NULL:\n"
|
|
" case AHUACATL_TYPEWEIGHT_LIST:\n"
|
|
" case AHUACATL_TYPEWEIGHT_DOCUMENT:\n"
|
|
" return 0.0;\n"
|
|
" case AHUACATL_TYPEWEIGHT_BOOL:\n"
|
|
" return (value ? 1 : 0);\n"
|
|
" case AHUACATL_TYPEWEIGHT_NUMBER:\n"
|
|
" return value;\n"
|
|
" case AHUACATL_TYPEWEIGHT_STRING:\n"
|
|
" var result = parseFloat(value);\n"
|
|
" return ((AHUACATL_TYPEWEIGHT(result) === AHUACATL_TYPEWEIGHT_NUMBER) ? result : 0);\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief cast to a string\n"
|
|
"///\n"
|
|
"/// the operand can have any type, always returns a string\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_CAST_STRING (value) {\n"
|
|
" switch (AHUACATL_TYPEWEIGHT(value)) {\n"
|
|
" case AHUACATL_TYPEWEIGHT_STRING:\n"
|
|
" return value;\n"
|
|
" case AHUACATL_TYPEWEIGHT_NULL:\n"
|
|
" return 'null';\n"
|
|
" case AHUACATL_TYPEWEIGHT_BOOL:\n"
|
|
" return (value ? 'true' : 'false');\n"
|
|
" case AHUACATL_TYPEWEIGHT_NUMBER:\n"
|
|
" case AHUACATL_TYPEWEIGHT_LIST:\n"
|
|
" case AHUACATL_TYPEWEIGHT_DOCUMENT:\n"
|
|
" return value.toString();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- typecheck functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief test if value is of type null\n"
|
|
"///\n"
|
|
"/// returns a bool\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_IS_NULL (value) {\n"
|
|
" return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_NULL);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief test if value is of type bool\n"
|
|
"///\n"
|
|
"/// returns a bool\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_IS_BOOL (value) {\n"
|
|
" return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_BOOL);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief test if value is of type number\n"
|
|
"///\n"
|
|
"/// returns a bool\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_IS_NUMBER (value) {\n"
|
|
" return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_NUMBER);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief test if value is of type string\n"
|
|
"///\n"
|
|
"/// returns a bool\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_IS_STRING (value) {\n"
|
|
" return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_STRING);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief test if value is of type list\n"
|
|
"///\n"
|
|
"/// returns a bool\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_IS_LIST (value) {\n"
|
|
" return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_LIST);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief test if value is of type document\n"
|
|
"///\n"
|
|
"/// returns a bool\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_IS_DOCUMENT (value) {\n"
|
|
" return (AHUACATL_TYPEWEIGHT(value) === AHUACATL_TYPEWEIGHT_DOCUMENT);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- numeric functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief integer closest to value, not greater than value\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_NUMBER_FLOOR (value) {\n"
|
|
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"FLOOR\");\n"
|
|
" }\n"
|
|
" \n"
|
|
" return Math.floor(value);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief integer closest to value and not less than value\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_NUMBER_CEIL (value) {\n"
|
|
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"CEIL\");\n"
|
|
" }\n"
|
|
" \n"
|
|
" return Math.ceil(value);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief integer closest to value \n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_NUMBER_ROUND (value) {\n"
|
|
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"ROUND\");\n"
|
|
" }\n"
|
|
" \n"
|
|
" return Math.round(value);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief absolute value\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_NUMBER_ABS (value) {\n"
|
|
" if (!AHUACATL_IS_NUMBER(value)) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"ABS\");\n"
|
|
" }\n"
|
|
" \n"
|
|
" return Math.abs(value);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief a random value between 0 and 1\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_NUMBER_RAND () {\n"
|
|
" return Math.random();\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- high level query functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief sort the results\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_SORT (value, sortFunction) {\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
" \n"
|
|
" var n = value.length;\n"
|
|
" if (n > 0) {\n"
|
|
" value.sort(sortFunction);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return value;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief group the results\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GROUP (value, sortFunction, groupFunction, into) {\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" var n = value.length;\n"
|
|
" if (n == 0) {\n"
|
|
" return [ ];\n"
|
|
" }\n"
|
|
"\n"
|
|
" AHUACATL_SORT(value, sortFunction);\n"
|
|
"\n"
|
|
" var result = [ ];\n"
|
|
" var currentGroup = undefined;\n"
|
|
" var oldGroup = undefined;\n"
|
|
" \n"
|
|
" for (var i = 0; i < n; ++i) {\n"
|
|
" var row = value[i];\n"
|
|
" var groupValue = groupFunction(row);\n"
|
|
"\n"
|
|
" if (AHUACATL_RELATIONAL_UNEQUAL(oldGroup, groupValue)) {\n"
|
|
" oldGroup = AHUACATL_CLONE(groupValue);\n"
|
|
"\n"
|
|
" if (currentGroup) {\n"
|
|
" result.push(AHUACATL_CLONE(currentGroup));\n"
|
|
" }\n"
|
|
" \n"
|
|
" currentGroup = groupValue;\n"
|
|
" if (into) {\n"
|
|
" currentGroup[into] = [ ];\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (into) {\n"
|
|
" currentGroup[into].push(AHUACATL_CLONE(row));\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (currentGroup) {\n"
|
|
" result.push(AHUACATL_CLONE(currentGroup));\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief limit the number of results\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_LIMIT (value, offset, count) {\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" if (count < 0) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_NUMBER_OUT_OF_RANGE);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return value.slice(offset, offset + count);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- list processing functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get the length of a list\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_LENGTH () {\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" return value.length;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get the first element of a list\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_FIRST () {\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" if (value.length == 0) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return value[0];\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief get the last element of a list\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_LAST () {\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" if (value.length == 0) {\n"
|
|
" return null;\n"
|
|
" }\n"
|
|
"\n"
|
|
" return value[value.length - 1];\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief reverse the elements in a list\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_REVERSE () {\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" return value.reverse();\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief return a list of unique elements from the list\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_UNIQUE () {\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" var length = value.length;\n"
|
|
" var keys = { };\n"
|
|
" for (var i = 0; i < length; ++i) {\n"
|
|
" var normalized = AHUACATL_NORMALIZE(value[i]);\n"
|
|
" keys[JSON.stringify(normalized)] = normalized;\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = [];\n"
|
|
" for (var i in keys) {\n"
|
|
" result.push(keys[i]);\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief create the union (all) of all arguments\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_UNION () {\n"
|
|
" var result = [ ];\n"
|
|
"\n"
|
|
" for (var i in arguments) {\n"
|
|
" var element = arguments[i];\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_LIST) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"UNION\");\n"
|
|
" }\n"
|
|
"\n"
|
|
" for (var k in element) {\n"
|
|
" if (!element.hasOwnProperty(k)) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
"\n"
|
|
" result.push(element[k]);\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result; \n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief maximum of all values\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_MAX () {\n"
|
|
" var result = null;\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" for (var i in value) {\n"
|
|
" var currentValue = value[i];\n"
|
|
" \n"
|
|
" if (AHUACATL_TYPEWEIGHT(currentValue) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (result === null || AHUACATL_RELATIONAL_GREATER(currentValue, result)) {\n"
|
|
" result = currentValue;\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief minimum of all values\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_MIN () {\n"
|
|
" var result = null;\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" for (var i in value) {\n"
|
|
" var currentValue = value[i];\n"
|
|
" \n"
|
|
" if (AHUACATL_TYPEWEIGHT(currentValue) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
" \n"
|
|
" if (result === null || AHUACATL_RELATIONAL_LESS(currentValue, result)) {\n"
|
|
" result = currentValue;\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief sum of all values\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_SUM () {\n"
|
|
" var result = null;\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" AHUACATL_LIST(value);\n"
|
|
"\n"
|
|
" for (var i in value) {\n"
|
|
" var currentValue = value[i];\n"
|
|
" \n"
|
|
" if (AHUACATL_TYPEWEIGHT(currentValue) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(currentValue) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"SUM\");\n"
|
|
" }\n"
|
|
" \n"
|
|
" if (result === null) {\n"
|
|
" result = currentValue;\n"
|
|
" }\n"
|
|
" else {\n"
|
|
" result += currentValue;\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return AHUACATL_NUMERIC_VALUE(result);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- geo functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief return at most <limit> documents near a certain point\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GEO_NEAR () {\n"
|
|
" var collection = arguments[0];\n"
|
|
" var latitude = arguments[1];\n"
|
|
" var longitude = arguments[2];\n"
|
|
" var limit = arguments[3];\n"
|
|
" var distanceAttribute = arguments[4];\n"
|
|
"\n"
|
|
" var idx = AHUACATL_INDEX(internal.db[collection], [ \"geo1\", \"geo2\" ]); \n"
|
|
" if (idx == null) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_GEO_INDEX_MISSING, collection);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = internal.db[collection].NEAR(idx, latitude, longitude, limit);\n"
|
|
" if (distanceAttribute == null) {\n"
|
|
" return result.documents;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // inject distances\n"
|
|
" var documents = result.documents;\n"
|
|
" var distances = result.distances;\n"
|
|
" var n = documents.length;\n"
|
|
" for (var i = 0; i < n; ++i) {\n"
|
|
" documents[i][distanceAttribute] = distances[i];\n"
|
|
" }\n"
|
|
"\n"
|
|
" return documents;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief return documents within <radius> around a certain point\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GEO_WITHIN () {\n"
|
|
" var collection = arguments[0];\n"
|
|
" var latitude = arguments[1];\n"
|
|
" var longitude = arguments[2];\n"
|
|
" var radius = arguments[3];\n"
|
|
" var distanceAttribute = arguments[4];\n"
|
|
"\n"
|
|
" var idx = AHUACATL_INDEX(internal.db[collection], [ \"geo1\", \"geo2\" ]); \n"
|
|
" if (idx == null) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_GEO_INDEX_MISSING, collection);\n"
|
|
" }\n"
|
|
"\n"
|
|
" var result = internal.db[collection].WITHIN(idx, latitude, longitude, radius);\n"
|
|
" if (distanceAttribute == null) {\n"
|
|
" return result.documents;\n"
|
|
" }\n"
|
|
"\n"
|
|
" // inject distances\n"
|
|
" var documents = result.documents;\n"
|
|
" var distances = result.distances;\n"
|
|
" var n = documents.length;\n"
|
|
" for (var i = 0; i < n; ++i) {\n"
|
|
" documents[i][distanceAttribute] = distances[i];\n"
|
|
" }\n"
|
|
"\n"
|
|
" return documents;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- graph functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief find all paths through a graph\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GRAPH_PATHS () {\n"
|
|
" var vertices = arguments[0];\n"
|
|
" var edgeCollection = arguments[1];\n"
|
|
" var direction = arguments[2] != undefined ? arguments[2] : \"outbound\";\n"
|
|
" var followCycles = arguments[3] ? arguments[3] : false;\n"
|
|
"\n"
|
|
" var minLength = 0;\n"
|
|
" var maxLength = 10;\n"
|
|
" var searchDirection;\n"
|
|
"\n"
|
|
" AHUACATL_LIST(vertices);\n"
|
|
"\n"
|
|
" // validate arguments\n"
|
|
" if (direction == \"outbound\") {\n"
|
|
" searchDirection = 1;\n"
|
|
" }\n"
|
|
" else if (direction == \"inbound\") {\n"
|
|
" searchDirection = 2;\n"
|
|
" }\n"
|
|
" else if (direction == \"any\") {\n"
|
|
" searchDirection = 3;\n"
|
|
" maxLength = 3;\n"
|
|
" }\n"
|
|
" else {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"PATHS\");\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (minLength < 0 || maxLength < 0 || minLength > maxLength) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"PATHS\");\n"
|
|
" }\n"
|
|
"\n"
|
|
" var searchAttributes = { \n"
|
|
" \"edgeCollection\" : internal.edges[edgeCollection],\n"
|
|
" \"minLength\" : minLength, \n"
|
|
" \"maxLength\" : maxLength, \n"
|
|
" \"direction\" : searchDirection,\n"
|
|
" \"followCycles\" : followCycles,\n"
|
|
" };\n"
|
|
"\n"
|
|
" // TODO: restrict allEdges to edges with certain _from values etc.\n"
|
|
"\n"
|
|
" var result = [ ];\n"
|
|
" var n = vertices.length;\n"
|
|
" for (var i = 0; i < n; ++i) {\n"
|
|
" var vertex = vertices[i];\n"
|
|
" var visited = { };\n"
|
|
" visited[vertex._id] = true;\n"
|
|
" var connected = AHUACATL_GRAPH_SUBNODES(searchAttributes, vertex._id, visited, [ ], [ vertex ], 0);\n"
|
|
" for (j = 0; j < connected.length; ++j) {\n"
|
|
" result.push(connected[j]);\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief find all paths through a graph, internal part called recursively\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_GRAPH_SUBNODES (searchAttributes, vertexId, visited, edges, vertices, level) {\n"
|
|
" var result = [ ];\n"
|
|
"\n"
|
|
" if (level >= searchAttributes.minLength) {\n"
|
|
" result.push({ \n"
|
|
" \"vertices\" : vertices, \n"
|
|
" \"edges\" : edges,\n"
|
|
" \"source\" : vertices[0],\n"
|
|
" \"destination\" : vertices[vertices.length - 1],\n"
|
|
" });\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (level + 1 > searchAttributes.maxLength) {\n"
|
|
" return result;\n"
|
|
" }\n"
|
|
"\n"
|
|
" var subEdges;\n"
|
|
"\n"
|
|
" if (searchAttributes.direction == 1) {\n"
|
|
" subEdges = searchAttributes.edgeCollection.outEdges(vertexId);\n"
|
|
" }\n"
|
|
" else if (searchAttributes.direction == 2) {\n"
|
|
" subEdges = searchAttributes.edgeCollection.inEdges(vertexId);\n"
|
|
" }\n"
|
|
" else if (searchAttributes.direction == 3) {\n"
|
|
" subEdges = searchAttributes.edgeCollection.edges(vertexId);\n"
|
|
" }\n"
|
|
"\n"
|
|
" for (var i = 0; i < subEdges.length; ++i) {\n"
|
|
" var subEdge = subEdges[i];\n"
|
|
" var targets = [ ];\n"
|
|
"\n"
|
|
" if (searchAttributes.direction & 1) {\n"
|
|
" targets.push(subEdge._to);\n"
|
|
" }\n"
|
|
" if (searchAttributes.direction & 2) {\n"
|
|
" targets.push(subEdge._from);\n"
|
|
" }\n"
|
|
"\n"
|
|
" for (var j = 0; j < targets.length; ++j) {\n"
|
|
" var targetId = targets[j];\n"
|
|
" \n"
|
|
" if (!searchAttributes.followCycles) {\n"
|
|
" if (visited[targetId]) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
" visited[targetId] = true;\n"
|
|
" }\n"
|
|
"\n"
|
|
" var clonedEdges = AHUACATL_CLONE(edges);\n"
|
|
" var clonedVertices = AHUACATL_CLONE(vertices);\n"
|
|
" clonedEdges.push(subEdge);\n"
|
|
" clonedVertices.push(internal.db._document(targetId));\n"
|
|
" \n"
|
|
" var connected = AHUACATL_GRAPH_SUBNODES(searchAttributes, targetId, AHUACATL_CLONE(visited), clonedEdges, clonedVertices, level + 1);\n"
|
|
" for (k = 0; k < connected.length; ++k) {\n"
|
|
" result.push(connected[k]);\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (!searchAttributes.followCycles) {\n"
|
|
" delete visited[targetId];\n"
|
|
" }\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"// --SECTION-- misc functions\n"
|
|
"// -----------------------------------------------------------------------------\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @addtogroup Ahuacatl\n"
|
|
"/// @{\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief check whether a document has an attribute\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_HAS () {\n"
|
|
" var element = arguments[0];\n"
|
|
" var name = arguments[1];\n"
|
|
" \n"
|
|
" if (AHUACATL_TYPEWEIGHT(element) === AHUACATL_TYPEWEIGHT_NULL) {\n"
|
|
" return false;\n"
|
|
" }\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_DOCUMENT) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"HAS\");\n"
|
|
" }\n"
|
|
"\n"
|
|
" return element.hasOwnProperty(name);\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief merge all arguments\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_MERGE () {\n"
|
|
" var result = { };\n"
|
|
"\n"
|
|
" for (var i in arguments) {\n"
|
|
" var element = arguments[i];\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_DOCUMENT) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, \"MERGE\");\n"
|
|
" }\n"
|
|
"\n"
|
|
" for (var k in element) {\n"
|
|
" if (!element.hasOwnProperty(k)) {\n"
|
|
" continue;\n"
|
|
" }\n"
|
|
"\n"
|
|
" result[k] = element[k];\n"
|
|
" }\n"
|
|
" }\n"
|
|
"\n"
|
|
" return result; \n"
|
|
"}\n"
|
|
"\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief passthru the argument\n"
|
|
"///\n"
|
|
"/// this function is marked as non-deterministic so its argument withstands\n"
|
|
"/// query optimisation. this function can be used for testing\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_PASSTHRU () {\n"
|
|
" var value = arguments[0];\n"
|
|
"\n"
|
|
" return value;\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @brief always fail\n"
|
|
"///\n"
|
|
"/// this function is non-deterministic so it is not executed at query \n"
|
|
"/// optimisation time. this function can be used for testing\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
"function AHUACATL_FAIL () {\n"
|
|
" var message = arguments[0];\n"
|
|
"\n"
|
|
" if (AHUACATL_TYPEWEIGHT(message) === AHUACATL_TYPEWEIGHT_STRING) {\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FAIL_CALLED, message);\n"
|
|
" }\n"
|
|
"\n"
|
|
" AHUACATL_THROW(internal.errors.ERROR_QUERY_FAIL_CALLED, \"\");\n"
|
|
"}\n"
|
|
"\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"/// @}\n"
|
|
"////////////////////////////////////////////////////////////////////////////////\n"
|
|
"\n"
|
|
;
|