mirror of https://gitee.com/bigwinds/arangodb
694 lines
22 KiB
C++
694 lines
22 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Ahuacatl, conversions
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
|
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
|
///
|
|
/// @author Jan Steemann
|
|
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
|
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Ahuacatl/ahuacatl-conversions.h"
|
|
|
|
#include "Basics/conversions.h"
|
|
#include "Basics/json.h"
|
|
#include "Basics/logging.h"
|
|
#include "Basics/string-buffer.h"
|
|
#include "Basics/tri-strings.h"
|
|
|
|
#include "Ahuacatl/ahuacatl-context.h"
|
|
#include "Ahuacatl/ahuacatl-functions.h"
|
|
#include "Ahuacatl/ahuacatl-node.h"
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- private types
|
|
// -----------------------------------------------------------------------------
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief typedef for value list iteration callback function
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef bool (*convert_f) (TRI_string_buffer_t* const, const TRI_aql_node_t* const);
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- private functions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
static const char* GetStringOperator (const TRI_aql_node_type_e type) {
|
|
switch (type) {
|
|
case TRI_AQL_NODE_OPERATOR_UNARY_PLUS:
|
|
return " + ";
|
|
case TRI_AQL_NODE_OPERATOR_UNARY_MINUS:
|
|
return " - ";
|
|
case TRI_AQL_NODE_OPERATOR_UNARY_NOT:
|
|
return " ! ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_AND:
|
|
return " && ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_OR:
|
|
return " || ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_PLUS:
|
|
return " + ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_MINUS:
|
|
return " - ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_TIMES:
|
|
return " * ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_DIV:
|
|
return " / ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_MOD:
|
|
return " % ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_EQ:
|
|
return " == ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_NE:
|
|
return " != ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_LT:
|
|
return " < ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_LE:
|
|
return " <= ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_GT:
|
|
return " > ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_GE:
|
|
return " >= ";
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_IN:
|
|
return " in ";
|
|
default:
|
|
TRI_ASSERT(false);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief append list values to a string buffer
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static bool AppendListValues (TRI_string_buffer_t* const buffer,
|
|
const TRI_aql_node_t* const node,
|
|
convert_f func) {
|
|
size_t i, n;
|
|
|
|
n = node->_members._length;
|
|
for (i = 0; i < n; ++i) {
|
|
if (i > 0) {
|
|
if (TRI_AppendString2StringBuffer(buffer, ", ", 2) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (! func(buffer, TRI_AQL_NODE_MEMBER(node, i))) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- public functions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief create a json struct from a value node
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TRI_json_t* TRI_NodeJsonAql (TRI_aql_context_t* const context,
|
|
const TRI_aql_node_t* const node) {
|
|
switch (node->_type) {
|
|
case TRI_AQL_NODE_VALUE: {
|
|
switch (node->_value._type) {
|
|
case TRI_AQL_TYPE_FAIL:
|
|
case TRI_AQL_TYPE_NULL:
|
|
return TRI_CreateNullJson(TRI_UNKNOWN_MEM_ZONE);
|
|
case TRI_AQL_TYPE_BOOL:
|
|
return TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._bool);
|
|
case TRI_AQL_TYPE_INT:
|
|
return TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) node->_value._value._int);
|
|
case TRI_AQL_TYPE_DOUBLE:
|
|
return TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._double);
|
|
case TRI_AQL_TYPE_STRING:
|
|
return TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, node->_value._value._string);
|
|
}
|
|
TRI_ASSERT(false);
|
|
return NULL;
|
|
}
|
|
case TRI_AQL_NODE_LIST: {
|
|
const size_t n = node->_members._length;
|
|
TRI_json_t* result = TRI_CreateList2Json(TRI_UNKNOWN_MEM_ZONE, n);
|
|
|
|
if (result != NULL) {
|
|
size_t i;
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(node, i));
|
|
|
|
if (subValue != NULL) {
|
|
TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, result, subValue);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
case TRI_AQL_NODE_ARRAY: {
|
|
const size_t n = node->_members._length;
|
|
TRI_json_t* result = TRI_CreateArray2Json(TRI_UNKNOWN_MEM_ZONE, n);
|
|
|
|
if (result != NULL) {
|
|
size_t i;
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
TRI_aql_node_t* element = TRI_AQL_NODE_MEMBER(node, i);
|
|
TRI_json_t* subValue = TRI_NodeJsonAql(context, TRI_AQL_NODE_MEMBER(element, 0));
|
|
|
|
if (subValue) {
|
|
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
|
|
result,
|
|
TRI_AQL_NODE_STRING(element),
|
|
subValue);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
default: {
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief create a value node from a json struct
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
TRI_aql_node_t* TRI_JsonNodeAql (TRI_aql_context_t* const context,
|
|
const TRI_json_t* const json) {
|
|
TRI_aql_node_t* node = NULL;
|
|
char* value;
|
|
|
|
switch (json->_type) {
|
|
case TRI_JSON_UNUSED:
|
|
break;
|
|
|
|
case TRI_JSON_NULL:
|
|
node = TRI_CreateNodeValueNullAql(context);
|
|
break;
|
|
|
|
case TRI_JSON_BOOLEAN:
|
|
node = TRI_CreateNodeValueBoolAql(context, json->_value._boolean);
|
|
break;
|
|
|
|
case TRI_JSON_NUMBER:
|
|
node = TRI_CreateNodeValueDoubleAql(context, json->_value._number);
|
|
break;
|
|
|
|
case TRI_JSON_STRING:
|
|
case TRI_JSON_STRING_REFERENCE:
|
|
// the conversion is the same for both...
|
|
value = TRI_RegisterStringAql(context,
|
|
json->_value._string.data,
|
|
json->_value._string.length - 1,
|
|
false);
|
|
node = TRI_CreateNodeValueStringAql(context, value);
|
|
break;
|
|
|
|
case TRI_JSON_LIST: {
|
|
node = TRI_CreateNodeListAql(context);
|
|
|
|
if (node != NULL) {
|
|
size_t i, n;
|
|
|
|
n = json->_value._objects._length;
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
TRI_json_t* subJson;
|
|
TRI_aql_node_t* member;
|
|
|
|
subJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
|
|
member = TRI_JsonNodeAql(context, subJson);
|
|
|
|
if (member) {
|
|
TRI_PushBackVectorPointer(&node->_members, (void*) member);
|
|
}
|
|
else {
|
|
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case TRI_JSON_ARRAY: {
|
|
node = TRI_CreateNodeArrayAql(context);
|
|
|
|
if (node != NULL) {
|
|
size_t i, n;
|
|
|
|
n = json->_value._objects._length;
|
|
|
|
for (i = 0; i < n; i += 2) {
|
|
TRI_json_t* nameJson;
|
|
TRI_json_t* valueJson;
|
|
TRI_aql_node_t* member;
|
|
TRI_aql_node_t* valueNode;
|
|
char* name;
|
|
|
|
// json_t containing the array element name
|
|
nameJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i);
|
|
|
|
TRI_ASSERT(TRI_IsStringJson(nameJson));
|
|
name = TRI_RegisterStringAql(context,
|
|
nameJson->_value._string.data,
|
|
nameJson->_value._string.length - 1,
|
|
false);
|
|
if (name == NULL) {
|
|
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
|
return NULL;
|
|
}
|
|
|
|
// json_t containing the array element value
|
|
valueJson = (TRI_json_t*) TRI_AtVector(&json->_value._objects, i + 1);
|
|
TRI_ASSERT(valueJson);
|
|
|
|
valueNode = TRI_JsonNodeAql(context, valueJson);
|
|
if (! valueNode) {
|
|
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
|
return NULL;
|
|
}
|
|
|
|
member = TRI_CreateNodeArrayElementAql(context, name, valueNode);
|
|
if (member) {
|
|
TRI_PushBackVectorPointer(&node->_members, (void*) member);
|
|
}
|
|
else {
|
|
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (node == NULL) {
|
|
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
|
}
|
|
|
|
return node;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief convert a value node to its Javascript representation
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TRI_ValueJavascriptAql (TRI_string_buffer_t* const buffer,
|
|
const TRI_aql_value_t* const value,
|
|
const TRI_aql_value_type_e type) {
|
|
switch (type) {
|
|
case TRI_AQL_TYPE_FAIL: {
|
|
return (TRI_AppendString2StringBuffer(buffer, "fail", 4) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_NULL: {
|
|
return (TRI_AppendString2StringBuffer(buffer, "null", 4) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_BOOL: {
|
|
if (value->_value._bool) {
|
|
return (TRI_AppendString2StringBuffer(buffer, "true", 4) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
else {
|
|
return (TRI_AppendString2StringBuffer(buffer, "false", 5) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
case TRI_AQL_TYPE_INT: {
|
|
return (TRI_AppendInt64StringBuffer(buffer, value->_value._int) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_DOUBLE: {
|
|
return (TRI_AppendDoubleStringBuffer(buffer, value->_value._double) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_STRING: {
|
|
if (TRI_AppendCharStringBuffer(buffer, '"') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendJsonEncodedStringStringBuffer(buffer, value->_value._string, false) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return (TRI_AppendCharStringBuffer(buffer, '"') == TRI_ERROR_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief convert a node to its Javascript representation
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TRI_NodeJavascriptAql (TRI_string_buffer_t* const buffer,
|
|
const TRI_aql_node_t* const node) {
|
|
switch (node->_type) {
|
|
case TRI_AQL_NODE_VALUE:
|
|
return TRI_ValueJavascriptAql(buffer, &node->_value, node->_value._type);
|
|
case TRI_AQL_NODE_ARRAY_ELEMENT:
|
|
if (! TRI_ValueJavascriptAql(buffer, &node->_value, TRI_AQL_TYPE_STRING)) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendCharStringBuffer(buffer, ':') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_NodeJavascriptAql(buffer, TRI_AQL_NODE_MEMBER(node, 0));
|
|
case TRI_AQL_NODE_LIST:
|
|
if (TRI_AppendCharStringBuffer(buffer, '[') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! AppendListValues(buffer, node, &TRI_NodeJavascriptAql)) {
|
|
return false;
|
|
}
|
|
|
|
return (TRI_AppendCharStringBuffer(buffer, ']') == TRI_ERROR_NO_ERROR);
|
|
case TRI_AQL_NODE_ARRAY:
|
|
if (TRI_AppendCharStringBuffer(buffer, '{') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! AppendListValues(buffer, node, &TRI_NodeJavascriptAql)) {
|
|
return false;
|
|
}
|
|
|
|
return (TRI_AppendCharStringBuffer(buffer, '}') == TRI_ERROR_NO_ERROR);
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief convert a value node to a string representation, used for printing it
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TRI_ValueStringAql (TRI_string_buffer_t* const buffer,
|
|
const TRI_aql_value_t* const value,
|
|
const TRI_aql_value_type_e type) {
|
|
switch (type) {
|
|
case TRI_AQL_TYPE_FAIL: {
|
|
return (TRI_AppendString2StringBuffer(buffer, "fail", 4) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_NULL: {
|
|
return (TRI_AppendString2StringBuffer(buffer, "null", 4) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_BOOL: {
|
|
if (value->_value._bool) {
|
|
return (TRI_AppendString2StringBuffer(buffer, "true", 4) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
else {
|
|
return (TRI_AppendString2StringBuffer(buffer, "false", 5) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
case TRI_AQL_TYPE_INT: {
|
|
return (TRI_AppendInt64StringBuffer(buffer, value->_value._int) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_DOUBLE: {
|
|
return (TRI_AppendDoubleStringBuffer(buffer, value->_value._double) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_TYPE_STRING: {
|
|
if (TRI_AppendCharStringBuffer(buffer, '"') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendStringStringBuffer(buffer, value->_value._string) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return (TRI_AppendCharStringBuffer(buffer, '"') == TRI_ERROR_NO_ERROR);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief convert a node to its string representation, used for printing it
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool TRI_NodeStringAql (TRI_string_buffer_t* const buffer,
|
|
const TRI_aql_node_t* const node) {
|
|
switch (node->_type) {
|
|
case TRI_AQL_NODE_VALUE: {
|
|
return TRI_ValueStringAql(buffer, &node->_value, node->_value._type);
|
|
}
|
|
|
|
case TRI_AQL_NODE_PARAMETER: {
|
|
return TRI_AppendStringStringBuffer(buffer, TRI_AQL_NODE_STRING(node)) == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_ARRAY_ELEMENT: {
|
|
if (! TRI_ValueStringAql(buffer, &node->_value, TRI_AQL_TYPE_STRING)) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendString2StringBuffer(buffer, " : ", 3) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0));
|
|
}
|
|
|
|
case TRI_AQL_NODE_LIST: {
|
|
if (TRI_AppendString2StringBuffer(buffer, "[ ", 2) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! AppendListValues(buffer, node, &TRI_NodeStringAql)) {
|
|
return false;
|
|
}
|
|
|
|
return (TRI_AppendString2StringBuffer(buffer, " ]", 2) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_NODE_ARRAY: {
|
|
if (TRI_AppendString2StringBuffer(buffer, "{ ", 2) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! AppendListValues(buffer, node, &TRI_NodeStringAql)) {
|
|
return false;
|
|
}
|
|
|
|
return (TRI_AppendString2StringBuffer(buffer, " }", 2) == TRI_ERROR_NO_ERROR);
|
|
}
|
|
|
|
case TRI_AQL_NODE_OPERATOR_UNARY_PLUS:
|
|
case TRI_AQL_NODE_OPERATOR_UNARY_MINUS:
|
|
case TRI_AQL_NODE_OPERATOR_UNARY_NOT: {
|
|
if (TRI_AppendStringStringBuffer(buffer, GetStringOperator(node->_type)) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0));
|
|
}
|
|
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_AND:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_OR:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_PLUS:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_MINUS:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_TIMES:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_DIV:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_MOD:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_EQ:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_NE:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_LT:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_LE:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_GT:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_GE:
|
|
case TRI_AQL_NODE_OPERATOR_BINARY_IN: {
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendStringStringBuffer(buffer, GetStringOperator(node->_type)) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 1));
|
|
}
|
|
|
|
case TRI_AQL_NODE_OPERATOR_TERNARY: {
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendString2StringBuffer(buffer, " ? ", 3) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 1))) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendString2StringBuffer(buffer, " : ", 3) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 2));
|
|
}
|
|
|
|
case TRI_AQL_NODE_ATTRIBUTE_ACCESS: {
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendCharStringBuffer(buffer, '.') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_AppendStringStringBuffer(buffer, TRI_AQL_NODE_STRING(node)) == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_BOUND_ATTRIBUTE_ACCESS: {
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendCharStringBuffer(buffer, '.') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 1));
|
|
}
|
|
|
|
case TRI_AQL_NODE_INDEXED: {
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendCharStringBuffer(buffer, '[') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 1))) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_AppendCharStringBuffer(buffer, ']') == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_FCALL: {
|
|
TRI_aql_function_t* function = (TRI_aql_function_t*) TRI_AQL_NODE_DATA(node);
|
|
|
|
if (TRI_AppendStringStringBuffer(buffer, function->_externalName) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendCharStringBuffer(buffer, '(') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_AppendCharStringBuffer(buffer, ')') == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_FCALL_USER: {
|
|
if (TRI_AppendStringStringBuffer(buffer, TRI_AQL_NODE_STRING(node)) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendCharStringBuffer(buffer, '(') != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_AppendCharStringBuffer(buffer, ')') == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_EXPAND: {
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 3));
|
|
}
|
|
|
|
case TRI_AQL_NODE_REFERENCE: {
|
|
return TRI_AppendStringStringBuffer(buffer, TRI_AQL_NODE_STRING(node)) == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_COLLECTION: {
|
|
TRI_aql_node_t* nameNode = TRI_AQL_NODE_MEMBER(node, 0);
|
|
char* name = TRI_AQL_NODE_STRING(nameNode);
|
|
|
|
return TRI_AppendStringStringBuffer(buffer, name) == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_SORT: {
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0));
|
|
}
|
|
|
|
case TRI_AQL_NODE_SORT_ELEMENT: {
|
|
if (! TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 0))) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_AppendStringStringBuffer(buffer, (TRI_AQL_NODE_BOOL(node) ? " ASC" : " DESC")) == TRI_ERROR_NO_ERROR;
|
|
}
|
|
|
|
case TRI_AQL_NODE_ASSIGN: {
|
|
TRI_aql_node_t* nameNode = TRI_AQL_NODE_MEMBER(node, 0);
|
|
char* name = TRI_AQL_NODE_STRING(nameNode);
|
|
|
|
if (TRI_AppendStringStringBuffer(buffer, name) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
if (TRI_AppendString2StringBuffer(buffer, " = ", 3) != TRI_ERROR_NO_ERROR) {
|
|
return false;
|
|
}
|
|
|
|
return TRI_NodeStringAql(buffer, TRI_AQL_NODE_MEMBER(node, 1));
|
|
}
|
|
|
|
default: {
|
|
// nada
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- END-OF-FILE
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// Local Variables:
|
|
// mode: outline-minor
|
|
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
|
// End:
|