mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/AvocadoDB into devel
This commit is contained in:
commit
c1c449f441
|
@ -28,6 +28,8 @@ build.h
|
|||
build.info
|
||||
commit.sh
|
||||
config/config.h
|
||||
config/config.guess
|
||||
config/config.sub
|
||||
config.h
|
||||
config.log
|
||||
config/revision.sh
|
||||
|
@ -86,7 +88,7 @@ stamp-h*
|
|||
.svn
|
||||
*.swp
|
||||
tags
|
||||
Ahuacatl/grammar.output
|
||||
Ahuacatl/ahuacatl-grammar.output
|
||||
UnitTests/HttpInterface/logs
|
||||
UnitTests/Jutland/CsvReaderTest.cpp
|
||||
UnitTests/Jutland/Makefile.am
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ahuacatl, bind parameters
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 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 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Ahuacatl/ahuacatl-bind-parameter.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Ahuacatl
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_aql_bind_parameter_t* CreateParameter (const char* const name,
|
||||
const TRI_json_t* const value) {
|
||||
TRI_aql_bind_parameter_t* parameter;
|
||||
|
||||
assert(name);
|
||||
assert(value);
|
||||
|
||||
parameter = (TRI_aql_bind_parameter_t*) TRI_Allocate(sizeof(TRI_aql_bind_parameter_t));
|
||||
if (!parameter) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parameter->_name = TRI_DuplicateString(name);
|
||||
if (!parameter->_name) {
|
||||
TRI_Free(parameter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parameter->_value = TRI_CopyJson((TRI_json_t*) value);
|
||||
if (!parameter->_value) {
|
||||
TRI_Free(parameter->_name);
|
||||
TRI_Free(parameter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Ahuacatl
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hash bind parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t TRI_HashBindParameterAql (TRI_associative_pointer_t* array,
|
||||
void const* element) {
|
||||
TRI_aql_bind_parameter_t* parameter = (TRI_aql_bind_parameter_t*) element;
|
||||
|
||||
return TRI_FnvHashString(parameter->_name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief comparison function used to determine bind parameter equality
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_EqualBindParameterAql (TRI_associative_pointer_t* array,
|
||||
void const* key,
|
||||
void const* element) {
|
||||
TRI_aql_bind_parameter_t* parameter = (TRI_aql_bind_parameter_t*) element;
|
||||
|
||||
return TRI_EqualString(key, parameter->_name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief free bind parameters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FreeBindParametersAql (TRI_aql_parse_context_t* const context) {
|
||||
size_t i;
|
||||
size_t n;
|
||||
|
||||
// iterate thru all parameters allocated
|
||||
n = context->_parameterValues._nrAlloc;
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_aql_bind_parameter_t* parameter;
|
||||
|
||||
parameter = (TRI_aql_bind_parameter_t*) context->_parameterValues._table[i];
|
||||
|
||||
if (!parameter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(parameter->_name);
|
||||
assert(parameter->_value);
|
||||
|
||||
TRI_FreeString(parameter->_name);
|
||||
TRI_FreeJson(parameter->_value);
|
||||
TRI_Free(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add bind parameters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_AddParameterValuesAql (TRI_aql_parse_context_t* const context,
|
||||
const TRI_json_t* const parameters) {
|
||||
size_t i;
|
||||
size_t n;
|
||||
|
||||
assert(context);
|
||||
|
||||
if (parameters == NULL) {
|
||||
// no bind parameters
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parameters->_type != TRI_JSON_ARRAY) {
|
||||
// parameters must be a list
|
||||
TRI_SetErrorAql(context, TRI_ERROR_QUERY_BIND_PARAMETERS_INVALID, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
n = parameters->_value._objects._length;
|
||||
if (n == 0) {
|
||||
// empty list, this is ok
|
||||
return true;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i += 2) {
|
||||
TRI_json_t* name = TRI_AtVector(¶meters->_value._objects, i);
|
||||
TRI_json_t* value = TRI_AtVector(¶meters->_value._objects, i + 1);
|
||||
TRI_aql_bind_parameter_t* parameter;
|
||||
|
||||
assert(name);
|
||||
assert(name->_type == TRI_JSON_STRING);
|
||||
assert(value);
|
||||
|
||||
parameter = CreateParameter(name->_value._string.data, value);
|
||||
if (!parameter) {
|
||||
TRI_SetErrorAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
TRI_InsertKeyAssociativePointer(&context->_parameterValues, parameter->_name, parameter, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief validate bind parameters passed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ValidateBindParametersAql (TRI_aql_parse_context_t* const context) {
|
||||
size_t i;
|
||||
size_t n;
|
||||
|
||||
// iterate thru all parameter names used in the query
|
||||
n = context->_parameterNames._nrAlloc;
|
||||
for (i = 0; i < n; ++i) {
|
||||
char* name = (char*) context->_parameterNames._table[i];
|
||||
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TRI_LookupByKeyAssociativePointer(&context->_parameterValues, name)) {
|
||||
TRI_SetErrorAql(context, TRI_ERROR_QUERY_BIND_PARAMETER_MISSING, name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// iterate thru all parameters that we have values for
|
||||
n = context->_parameterValues._nrAlloc;
|
||||
for (i = 0; i < n; ++i) {
|
||||
TRI_aql_bind_parameter_t* parameter;
|
||||
|
||||
parameter = (TRI_aql_bind_parameter_t*) context->_parameterValues._table[i];
|
||||
|
||||
if (!parameter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(parameter->_name);
|
||||
|
||||
if (!TRI_LookupByKeyAssociativePointer(&context->_parameterNames, parameter->_name)) {
|
||||
TRI_SetErrorAql(context, TRI_ERROR_QUERY_BIND_PARAMETER_UNDECLARED, parameter->_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -0,0 +1,122 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Ahuacatl, bind parameters
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 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 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TRIAGENS_DURHAM_AHUACATL_BIND_PARAMETER_H
|
||||
#define TRIAGENS_DURHAM_AHUACATL_BIND_PARAMETER_H 1
|
||||
|
||||
#include <BasicsC/common.h>
|
||||
#include <BasicsC/strings.h>
|
||||
#include <BasicsC/hashes.h>
|
||||
#include <BasicsC/vector.h>
|
||||
#include <BasicsC/associative.h>
|
||||
#include <BasicsC/json.h>
|
||||
|
||||
#include "Ahuacatl/ahuacatl-parser.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Ahuacatl
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief bind parameter container
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_aql_bind_parameter_s {
|
||||
char* _name;
|
||||
TRI_json_t* _value;
|
||||
}
|
||||
TRI_aql_bind_parameter_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Ahuacatl
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief hash bind parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t TRI_HashBindParameterAql (TRI_associative_pointer_t*, void const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief comparison function used to determine bind parameter equality
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_EqualBindParameterAql (TRI_associative_pointer_t*,
|
||||
void const*,
|
||||
void const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief free bind parameters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FreeBindParametersAql (TRI_aql_parse_context_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add bind parameters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_AddParameterValuesAql (TRI_aql_parse_context_t* const,
|
||||
const TRI_json_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief validate bind parameters passed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ValidateBindParametersAql (TRI_aql_parse_context_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||
// End:
|
|
@ -25,7 +25,7 @@
|
|||
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Ahuacatl/error.h"
|
||||
#include "Ahuacatl/ahuacatl-error.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- defines
|
|
@ -127,13 +127,15 @@ TRI_associative_pointer_t* TRI_InitialiseFunctionsAql (void) {
|
|||
REGISTER_FUNCTION("ISDOCUMENT", "IS_DOCUMENT", true, 1, 1);
|
||||
|
||||
// string concat
|
||||
REGISTER_FUNCTION("CONCAT", "STRING_CONCAT", true, 2, 2);
|
||||
REGISTER_FUNCTION("CONCAT", "STRING_CONCAT", true, 2, 256);
|
||||
|
||||
// numeric functions
|
||||
|
||||
// string functions
|
||||
|
||||
// misc functions
|
||||
REGISTER_FUNCTION("MERGE", "MERGE", true, 2, 256);
|
||||
REGISTER_FUNCTION("UNION", "UNION", true, 2, 256);
|
||||
REGISTER_FUNCTION("LENGTH", "LENGTH", true, 1, 1);
|
||||
|
||||
if (!result) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,133 @@
|
|||
|
||||
/* A Bison parser, made by GNU Bison 2.4.1. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
T_END = 0,
|
||||
T_FOR = 258,
|
||||
T_LET = 259,
|
||||
T_FILTER = 260,
|
||||
T_RETURN = 261,
|
||||
T_COLLECT = 262,
|
||||
T_SORT = 263,
|
||||
T_LIMIT = 264,
|
||||
T_ASC = 265,
|
||||
T_DESC = 266,
|
||||
T_IN = 267,
|
||||
T_INTO = 268,
|
||||
T_NULL = 269,
|
||||
T_TRUE = 270,
|
||||
T_FALSE = 271,
|
||||
T_STRING = 272,
|
||||
T_QUOTED_STRING = 273,
|
||||
T_NUMBER = 274,
|
||||
T_PARAMETER = 275,
|
||||
T_ASSIGN = 276,
|
||||
T_NOT = 277,
|
||||
T_AND = 278,
|
||||
T_OR = 279,
|
||||
T_EQ = 280,
|
||||
T_NE = 281,
|
||||
T_LT = 282,
|
||||
T_GT = 283,
|
||||
T_LE = 284,
|
||||
T_GE = 285,
|
||||
T_PLUS = 286,
|
||||
T_MINUS = 287,
|
||||
T_TIMES = 288,
|
||||
T_DIV = 289,
|
||||
T_MOD = 290,
|
||||
T_QUESTION = 291,
|
||||
T_COLON = 292,
|
||||
T_COMMA = 293,
|
||||
T_OPEN = 294,
|
||||
T_CLOSE = 295,
|
||||
T_DOC_OPEN = 296,
|
||||
T_DOC_CLOSE = 297,
|
||||
T_LIST_OPEN = 298,
|
||||
T_LIST_CLOSE = 299,
|
||||
UPLUS = 300,
|
||||
UMINUS = 301,
|
||||
FUNCCALL = 302,
|
||||
REFERENCE = 303,
|
||||
INDEXED = 304
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 26 "Ahuacatl/ahuacatl-grammar.y"
|
||||
|
||||
TRI_aql_node_t* node;
|
||||
char* strval;
|
||||
bool boolval;
|
||||
int64_t intval;
|
||||
|
||||
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 111 "Ahuacatl/ahuacatl-grammar.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||
typedef struct YYLTYPE
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
} YYLTYPE;
|
||||
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -17,8 +17,8 @@
|
|||
#include <BasicsC/strings.h>
|
||||
|
||||
#include "Ahuacatl/ast-node.h"
|
||||
#include "Ahuacatl/parser.h"
|
||||
#include "Ahuacatl/error.h"
|
||||
#include "Ahuacatl/ahuacatl-parser.h"
|
||||
#include "Ahuacatl/ahuacatl-error.h"
|
||||
|
||||
%}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
|||
%{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief forward for lexer function defined in tokens.l
|
||||
/// @brief forward for lexer function defined in ahuacatl-tokens.l
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int Ahuacatllex (YYSTYPE*, YYLTYPE*, void*);
|
||||
|
@ -810,13 +810,7 @@ value_literal:
|
|||
|
||||
bind_parameter:
|
||||
T_PARAMETER {
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
if (!$1) {
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeParameterAql(context, $1);
|
||||
TRI_aql_node_t* node = TRI_CreateNodeParameterAql(context, $1);
|
||||
if (!node) {
|
||||
YYABORT;
|
||||
}
|
|
@ -25,8 +25,9 @@
|
|||
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Ahuacatl/parser.h"
|
||||
#include "Ahuacatl/ahuacatl-parser.h"
|
||||
#include "Ahuacatl/ast-node.h"
|
||||
#include "Ahuacatl/ahuacatl-bind-parameter.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private macros
|
||||
|
@ -109,6 +110,20 @@ TRI_aql_parse_context_t* TRI_CreateParseContextAql (TRI_vocbase_t* vocbase,
|
|||
|
||||
context->_vocbase = vocbase;
|
||||
|
||||
// actual bind parameter values
|
||||
TRI_InitAssociativePointer(&context->_parameterValues,
|
||||
&TRI_HashStringKeyAssociativePointer,
|
||||
&TRI_HashBindParameterAql,
|
||||
&TRI_EqualBindParameterAql,
|
||||
0);
|
||||
|
||||
// bind parameter names used in the query
|
||||
TRI_InitAssociativePointer(&context->_parameterNames,
|
||||
&TRI_HashStringKeyAssociativePointer,
|
||||
&TRI_HashStringKeyAssociativePointer,
|
||||
&TRI_EqualStringKeyAssociativePointer,
|
||||
0);
|
||||
|
||||
TRI_InitVectorPointer(&context->_stack);
|
||||
TRI_InitVectorPointer(&context->_nodes);
|
||||
TRI_InitVectorPointer(&context->_strings);
|
||||
|
@ -185,6 +200,13 @@ void TRI_FreeParseContextAql (TRI_aql_parse_context_t* const context) {
|
|||
// free the stack
|
||||
TRI_DestroyVectorPointer(&context->_stack);
|
||||
|
||||
// free parameter names hash
|
||||
TRI_DestroyAssociativePointer(&context->_parameterNames);
|
||||
|
||||
// free parameter values
|
||||
TRI_FreeBindParametersAql(context);
|
||||
TRI_DestroyAssociativePointer(&context->_parameterValues);
|
||||
|
||||
// free query string
|
||||
if (context->_query) {
|
||||
TRI_Free(context->_query);
|
||||
|
@ -202,6 +224,33 @@ void TRI_FreeParseContextAql (TRI_aql_parse_context_t* const context) {
|
|||
TRI_Free(context);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add bind parameters to the context
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_AddBindParametersAql (TRI_aql_parse_context_t* const context,
|
||||
const TRI_json_t* const parameters) {
|
||||
return TRI_AddParameterValuesAql(context, parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse & validate the query string
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ParseQueryAql (TRI_aql_parse_context_t* const context) {
|
||||
if (Ahuacatlparse(context)) {
|
||||
// lexing/parsing failed
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TRI_ValidateBindParametersAql(context)) {
|
||||
// invalid bind parameters
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a new variable scope
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -594,6 +643,27 @@ bool TRI_VariableExistsAql (TRI_aql_parse_context_t* const context,
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if a variable name follows the required naming convention
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_IsValidVariableNameAql (const char* const name) {
|
||||
assert(name);
|
||||
|
||||
if (strlen(name) == 0) {
|
||||
// name must be at least one char long
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*name == '_') {
|
||||
// name must not start with an underscore
|
||||
return false;
|
||||
}
|
||||
|
||||
// everything else is allowed
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
|
@ -33,9 +33,11 @@
|
|||
#include <BasicsC/hashes.h>
|
||||
#include <BasicsC/vector.h>
|
||||
#include <BasicsC/associative.h>
|
||||
#include <BasicsC/json.h>
|
||||
|
||||
#include "VocBase/vocbase.h"
|
||||
#include "Ahuacatl/error.h"
|
||||
#include "VocBase/collection.h"
|
||||
#include "Ahuacatl/ahuacatl-error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -94,6 +96,8 @@ typedef struct TRI_aql_parse_context_s {
|
|||
TRI_vector_pointer_t _stack;
|
||||
TRI_aql_error_t _error;
|
||||
TRI_vocbase_t* _vocbase;
|
||||
TRI_associative_pointer_t _parameterValues;
|
||||
TRI_associative_pointer_t _parameterNames;
|
||||
void* _first;
|
||||
char* _query;
|
||||
}
|
||||
|
@ -117,7 +121,7 @@ TRI_aql_parse_context_t;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_parse_context_t* TRI_CreateParseContextAql (TRI_vocbase_t*,
|
||||
const char* const);
|
||||
const char* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief free a parse context
|
||||
|
@ -125,6 +129,19 @@ TRI_aql_parse_context_t* TRI_CreateParseContextAql (TRI_vocbase_t*,
|
|||
|
||||
void TRI_FreeParseContextAql (TRI_aql_parse_context_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add bind parameters to the context
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_AddBindParametersAql (TRI_aql_parse_context_t* const,
|
||||
const TRI_json_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse & validate the query string
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ParseQueryAql (TRI_aql_parse_context_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a new variable scope
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -241,6 +258,12 @@ char* TRI_RegisterStringAql (TRI_aql_parse_context_t* const,
|
|||
|
||||
bool TRI_VariableExistsAql (TRI_aql_parse_context_t* const, const char* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if a variable name follows the required naming convention
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_IsValidVariableNameAql (const char* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
File diff suppressed because it is too large
Load Diff
|
@ -12,8 +12,8 @@
|
|||
#include <BasicsC/strings.h>
|
||||
|
||||
#include "Ahuacatl/ast-node.h"
|
||||
#include "Ahuacatl/parser.h"
|
||||
#include "Ahuacatl/grammar.h"
|
||||
#include "Ahuacatl/ahuacatl-parser.h"
|
||||
#include "Ahuacatl/ahuacatl-grammar.h"
|
||||
|
||||
#define YY_EXTRA_TYPE TRI_aql_parse_context_t*
|
||||
|
|
@ -1222,14 +1222,20 @@ char* TRI_GenerateCodeAql (const void* const data) {
|
|||
if (!generator->_error) {
|
||||
char* funcName = generator->_funcName;
|
||||
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "return ");
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "try {\n");
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, " return ");
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, funcName);
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "( { } );\n");
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "}\n");
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "catch (e) {\n");
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "print(e);\n");
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "}\n");
|
||||
|
||||
TRI_AppendStringStringBuffer(&generator->_buffer, "})();\n");
|
||||
|
||||
code = TRI_DuplicateString(generator->_buffer._buffer);
|
||||
LOG_TRACE("generated code:\n%s\n",code);
|
||||
//printf("generated code:\n%s\n",code);
|
||||
}
|
||||
|
||||
TRI_FreeCodegenAql(generator);
|
||||
|
|
|
@ -139,6 +139,11 @@ TRI_aql_node_t* TRI_CreateNodeForAql (TRI_aql_parse_context_t* const context,
|
|||
if (!name || !expression) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (!TRI_IsValidVariableNameAql(name)) {
|
||||
TRI_SetErrorAql(context, TRI_ERROR_QUERY_VARIABLE_NAME_INVALID, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = (TRI_aql_node_for_t*) TRI_Allocate(sizeof(TRI_aql_node_for_t));
|
||||
|
||||
|
@ -509,7 +514,10 @@ TRI_aql_node_t* TRI_CreateNodeParameterAql (TRI_aql_parse_context_t* const conte
|
|||
if (!name) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
|
||||
// save name of bind parameter for later
|
||||
TRI_InsertKeyAssociativePointer(&context->_parameterNames, name, (void*) name, true);
|
||||
|
||||
node = (TRI_aql_node_parameter_t*) TRI_Allocate(sizeof(TRI_aql_node_parameter_t));
|
||||
|
||||
if (!node) {
|
||||
|
@ -1318,9 +1326,9 @@ TRI_aql_node_t* TRI_CreateNodeArrayAql (TRI_aql_parse_context_t* const context)
|
|||
InitNode(context, (TRI_aql_node_t*) node, AQL_NODE_ARRAY);
|
||||
|
||||
TRI_InitAssociativePointer(&node->_values,
|
||||
TRI_HashStringKeyAssociativePointer,
|
||||
HashArrayElement,
|
||||
EqualArrayElement,
|
||||
&TRI_HashStringKeyAssociativePointer,
|
||||
&HashArrayElement,
|
||||
&EqualArrayElement,
|
||||
0);
|
||||
|
||||
node->_base.free = &FreeNodeArray;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <BasicsC/vector.h>
|
||||
#include <BasicsC/associative.h>
|
||||
|
||||
#include "Ahuacatl/parser.h"
|
||||
#include "Ahuacatl/ahuacatl-parser.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
#include "Ahuacatl/ast-node.h"
|
||||
#include "Ahuacatl/parser.h"
|
||||
#include "Ahuacatl/error.h"
|
||||
#include "Ahuacatl/ahuacatl-error.h"
|
||||
|
||||
|
||||
|
||||
|
@ -216,7 +216,7 @@ typedef struct YYLTYPE
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief forward for lexer function defined in tokens.l
|
||||
/// @brief forward for lexer function defined in ahuacatl-tokens.l
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int Ahuacatllex (YYSTYPE*, YYLTYPE*, void*);
|
||||
|
@ -569,8 +569,8 @@ static const yytype_uint16 yyrline[] =
|
|||
574, 582, 593, 604, 606, 611, 614, 620, 623, 629,
|
||||
629, 642, 644, 649, 654, 662, 662, 675, 677, 682,
|
||||
684, 689, 697, 706, 713, 720, 730, 737, 744, 754,
|
||||
757, 763, 771, 785, 793, 801, 812, 829, 836, 845,
|
||||
851, 858
|
||||
757, 763, 771, 785, 793, 801, 812, 823, 830, 839,
|
||||
845, 852
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -2792,13 +2792,7 @@ yyreduce:
|
|||
/* Line 1455 of yacc.c */
|
||||
#line 812 "Ahuacatl/grammar.y"
|
||||
{
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
if (!(yyvsp[(1) - (1)].strval)) {
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeParameterAql(context, (yyvsp[(1) - (1)].strval));
|
||||
TRI_aql_node_t* node = TRI_CreateNodeParameterAql(context, (yyvsp[(1) - (1)].strval));
|
||||
if (!node) {
|
||||
YYABORT;
|
||||
}
|
||||
|
@ -2810,7 +2804,7 @@ yyreduce:
|
|||
case 97:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 829 "Ahuacatl/grammar.y"
|
||||
#line 823 "Ahuacatl/grammar.y"
|
||||
{
|
||||
if (!(yyvsp[(1) - (1)].strval)) {
|
||||
YYABORT;
|
||||
|
@ -2823,7 +2817,7 @@ yyreduce:
|
|||
case 98:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 836 "Ahuacatl/grammar.y"
|
||||
#line 830 "Ahuacatl/grammar.y"
|
||||
{
|
||||
if (!(yyvsp[(1) - (1)].strval)) {
|
||||
YYABORT;
|
||||
|
@ -2836,7 +2830,7 @@ yyreduce:
|
|||
case 99:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 845 "Ahuacatl/grammar.y"
|
||||
#line 839 "Ahuacatl/grammar.y"
|
||||
{
|
||||
(yyval.strval) = (yyvsp[(1) - (1)].strval);
|
||||
;}
|
||||
|
@ -2845,7 +2839,7 @@ yyreduce:
|
|||
case 100:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 851 "Ahuacatl/grammar.y"
|
||||
#line 845 "Ahuacatl/grammar.y"
|
||||
{
|
||||
if (!(yyvsp[(1) - (1)].strval)) {
|
||||
YYABORT;
|
||||
|
@ -2858,7 +2852,7 @@ yyreduce:
|
|||
case 101:
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 858 "Ahuacatl/grammar.y"
|
||||
#line 852 "Ahuacatl/grammar.y"
|
||||
{
|
||||
if (!(yyvsp[(2) - (2)].strval)) {
|
||||
YYABORT;
|
||||
|
@ -2871,7 +2865,7 @@ yyreduce:
|
|||
|
||||
|
||||
/* Line 1455 of yacc.c */
|
||||
#line 2875 "Ahuacatl/grammar.c"
|
||||
#line 2869 "Ahuacatl/grammar.c"
|
||||
default: break;
|
||||
}
|
||||
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "associative.h"
|
||||
#include "hashes.h"
|
||||
#include "strings.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- ASSOCIATIVE ARRAY
|
||||
|
@ -638,6 +639,16 @@ uint64_t TRI_HashStringKeyAssociativePointer (TRI_associative_pointer_t* array,
|
|||
return TRI_FnvHashString((char const*) key);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief General function to determine equality of two string values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_EqualStringKeyAssociativePointer (TRI_associative_pointer_t* array,
|
||||
void const* key,
|
||||
void const* element) {
|
||||
return TRI_EqualString((char*) key, (char*) element);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lookups an element given a key
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -299,7 +299,13 @@ void TRI_FreeAssociativePointer (TRI_associative_pointer_t*);
|
|||
/// @brief General hash function that can be used to hash a string key
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t TRI_HashStringKeyAssociativePointer (TRI_associative_pointer_t*, void const* key);
|
||||
uint64_t TRI_HashStringKeyAssociativePointer (TRI_associative_pointer_t*, void const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief General function to determine equality of two string values
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_EqualStringKeyAssociativePointer (TRI_associative_pointer_t*, void const*, void const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lookups an element given a key
|
||||
|
|
|
@ -118,6 +118,8 @@ ERROR_QUERY_RUNTIME_ERROR,1520,"runtime error in query","Will be raised when a J
|
|||
ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE,1521,"limit value '%s' is out of range","Will be raised when a limit value in the query is outside the allowed range (e. g. when passing a negative skip value)."
|
||||
ERROR_QUERY_VARIABLE_REDECLARED,1522,"variable '%s' is assigned multiple times","Will be raised when a variable gets re-assigned in a query."
|
||||
ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED,1523,"document attribute '%s' is assigned multiple times","Will be raised when a document attribute is re-assigned."
|
||||
ERROR_QUERY_VARIABLE_NAME_INVALID,1524,"variable name '%s' has an invalid format","Will be raised when an invalid variable name is used."
|
||||
ERROR_QUERY_BIND_PARAMETERS_INVALID,1525,"invalid structure of bind parameters","Will be raised when the structure of bind parameters passed has an unexpected format."
|
||||
|
||||
################################################################################
|
||||
## AvocadoDB cursor errors
|
||||
|
|
|
@ -84,6 +84,8 @@ void TRI_InitialiseErrorMessages (void) {
|
|||
REG_ERROR(ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE, "limit value '%s' is out of range");
|
||||
REG_ERROR(ERROR_QUERY_VARIABLE_REDECLARED, "variable '%s' is assigned multiple times");
|
||||
REG_ERROR(ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED, "document attribute '%s' is assigned multiple times");
|
||||
REG_ERROR(ERROR_QUERY_VARIABLE_NAME_INVALID, "variable name '%s' has an invalid format");
|
||||
REG_ERROR(ERROR_QUERY_BIND_PARAMETERS_INVALID, "invalid structure of bind parameters");
|
||||
REG_ERROR(ERROR_CURSOR_NOT_FOUND, "cursor not found");
|
||||
REG_ERROR(ERROR_SESSION_USERHANDLER_URL_INVALID, "expecting <prefix>/user/<username>");
|
||||
REG_ERROR(ERROR_SESSION_USERHANDLER_CANNOT_CREATE_USER, "cannot create user");
|
||||
|
|
|
@ -184,6 +184,11 @@ extern "C" {
|
|||
/// Will be raised when a variable gets re-assigned in a query.
|
||||
/// - 1523: @CODE{document attribute '\%s' is assigned multiple times}
|
||||
/// Will be raised when a document attribute is re-assigned.
|
||||
/// - 1524: @CODE{variable name '\%s' has an invalid format}
|
||||
/// Will be raised when an invalid variable name is used.
|
||||
/// - 1525: @CODE{invalid structure of bind parameters}
|
||||
/// Will be raised when the structure of bind parameters passed has an
|
||||
/// unexpected format.
|
||||
/// - 1600: @CODE{cursor not found}
|
||||
/// Will be raised when a cursor is requested via its id but a cursor with
|
||||
/// that id cannot be found.
|
||||
|
@ -1027,6 +1032,27 @@ void TRI_InitialiseErrorMessages (void);
|
|||
|
||||
#define TRI_ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED (1523)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1524: ERROR_QUERY_VARIABLE_NAME_INVALID
|
||||
///
|
||||
/// variable name '%s' has an invalid format
|
||||
///
|
||||
/// Will be raised when an invalid variable name is used.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_VARIABLE_NAME_INVALID (1524)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1525: ERROR_QUERY_BIND_PARAMETERS_INVALID
|
||||
///
|
||||
/// invalid structure of bind parameters
|
||||
///
|
||||
/// Will be raised when the structure of bind parameters passed has an
|
||||
/// unexpected format.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_BIND_PARAMETERS_INVALID (1525)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1600: ERROR_CURSOR_NOT_FOUND
|
||||
///
|
||||
|
|
|
@ -146,14 +146,15 @@ avocado_SOURCES = \
|
|||
HttpsServer/HttpsServerImpl.cpp \
|
||||
PriorityQueue/pqueueindex.c \
|
||||
PriorityQueue/priorityqueue.c \
|
||||
Ahuacatl/ahuacatl-bind-parameter.c \
|
||||
Ahuacatl/ahuacatl-error.c \
|
||||
Ahuacatl/ahuacatl-functions.c \
|
||||
Ahuacatl/ahuacatl-grammar.c \
|
||||
Ahuacatl/ahuacatl-parser.c \
|
||||
Ahuacatl/ahuacatl-tokens.c \
|
||||
Ahuacatl/ast-codegen-js.c \
|
||||
Ahuacatl/ast-dump.c \
|
||||
Ahuacatl/ast-node.c \
|
||||
Ahuacatl/error.c \
|
||||
Ahuacatl/grammar.c \
|
||||
Ahuacatl/parser.c \
|
||||
Ahuacatl/tokens.c \
|
||||
QL/ast-query.c \
|
||||
QL/formatter.c \
|
||||
QL/optimize.c \
|
||||
|
@ -302,7 +303,7 @@ BUILT_SOURCES += $(FLEXXX_FILES)
|
|||
|
||||
BISON_FILES = \
|
||||
QL/parser.c \
|
||||
Ahuacatl/grammar.c
|
||||
Ahuacatl/ahuacatl-grammar.c
|
||||
|
||||
BUILT_SOURCES += $(BISON_FILES)
|
||||
|
||||
|
|
63
Makefile.in
63
Makefile.in
|
@ -277,11 +277,14 @@ am_avocado_OBJECTS = Admin/ApplicationAdminServer.$(OBJEXT) \
|
|||
HttpsServer/HttpsServerImpl.$(OBJEXT) \
|
||||
PriorityQueue/pqueueindex.$(OBJEXT) \
|
||||
PriorityQueue/priorityqueue.$(OBJEXT) \
|
||||
Ahuacatl/ahuacatl-bind-parameter.$(OBJEXT) \
|
||||
Ahuacatl/ahuacatl-error.$(OBJEXT) \
|
||||
Ahuacatl/ahuacatl-functions.$(OBJEXT) \
|
||||
Ahuacatl/ahuacatl-grammar.$(OBJEXT) \
|
||||
Ahuacatl/ahuacatl-parser.$(OBJEXT) \
|
||||
Ahuacatl/ahuacatl-tokens.$(OBJEXT) \
|
||||
Ahuacatl/ast-codegen-js.$(OBJEXT) Ahuacatl/ast-dump.$(OBJEXT) \
|
||||
Ahuacatl/ast-node.$(OBJEXT) Ahuacatl/error.$(OBJEXT) \
|
||||
Ahuacatl/grammar.$(OBJEXT) Ahuacatl/parser.$(OBJEXT) \
|
||||
Ahuacatl/tokens.$(OBJEXT) QL/ast-query.$(OBJEXT) \
|
||||
Ahuacatl/ast-node.$(OBJEXT) QL/ast-query.$(OBJEXT) \
|
||||
QL/formatter.$(OBJEXT) QL/optimize.$(OBJEXT) \
|
||||
QL/parser.$(OBJEXT) QL/tokens.$(OBJEXT) \
|
||||
RestHandler/RestActionHandler.$(OBJEXT) \
|
||||
|
@ -752,14 +755,15 @@ avocado_SOURCES = \
|
|||
HttpsServer/HttpsServerImpl.cpp \
|
||||
PriorityQueue/pqueueindex.c \
|
||||
PriorityQueue/priorityqueue.c \
|
||||
Ahuacatl/ahuacatl-bind-parameter.c \
|
||||
Ahuacatl/ahuacatl-error.c \
|
||||
Ahuacatl/ahuacatl-functions.c \
|
||||
Ahuacatl/ahuacatl-grammar.c \
|
||||
Ahuacatl/ahuacatl-parser.c \
|
||||
Ahuacatl/ahuacatl-tokens.c \
|
||||
Ahuacatl/ast-codegen-js.c \
|
||||
Ahuacatl/ast-dump.c \
|
||||
Ahuacatl/ast-node.c \
|
||||
Ahuacatl/error.c \
|
||||
Ahuacatl/grammar.c \
|
||||
Ahuacatl/parser.c \
|
||||
Ahuacatl/tokens.c \
|
||||
QL/ast-query.c \
|
||||
QL/formatter.c \
|
||||
QL/optimize.c \
|
||||
|
@ -892,7 +896,7 @@ FLEXXX_FILES = \
|
|||
################################################################################
|
||||
BISON_FILES = \
|
||||
QL/parser.c \
|
||||
Ahuacatl/grammar.c
|
||||
Ahuacatl/ahuacatl-grammar.c
|
||||
|
||||
|
||||
################################################################################
|
||||
|
@ -1009,7 +1013,10 @@ UNITTESTS_SERVER = $(addprefix --unit-tests ,$(SHELL_SERVER))
|
|||
|
||||
################################################################################
|
||||
################################################################################
|
||||
SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-queries-collection.js \
|
||||
SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-operators.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-escaping.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-functions.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-collection.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-noncollection.js
|
||||
|
||||
UNITTESTS_SERVER_AHUACATL = $(addprefix --unit-tests ,$(SHELL_SERVER_AHUACATL))
|
||||
|
@ -1647,22 +1654,24 @@ Ahuacatl/$(am__dirstamp):
|
|||
Ahuacatl/$(DEPDIR)/$(am__dirstamp):
|
||||
@$(MKDIR_P) Ahuacatl/$(DEPDIR)
|
||||
@: > Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ahuacatl-bind-parameter.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ahuacatl-error.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ahuacatl-functions.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ahuacatl-grammar.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ahuacatl-parser.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ahuacatl-tokens.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ast-codegen-js.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ast-dump.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/ast-node.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/error.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/grammar.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/parser.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
Ahuacatl/tokens.$(OBJEXT): Ahuacatl/$(am__dirstamp) \
|
||||
Ahuacatl/$(DEPDIR)/$(am__dirstamp)
|
||||
QL/$(am__dirstamp):
|
||||
@$(MKDIR_P) QL
|
||||
@: > QL/$(am__dirstamp)
|
||||
|
@ -1901,14 +1910,15 @@ mostlyclean-compile:
|
|||
-rm -f Admin/RestAdminLogHandler.$(OBJEXT)
|
||||
-rm -f Admin/RestBaseHandler.$(OBJEXT)
|
||||
-rm -f Admin/RestVersionHandler.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ahuacatl-bind-parameter.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ahuacatl-error.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ahuacatl-functions.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ahuacatl-grammar.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ahuacatl-parser.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ahuacatl-tokens.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ast-codegen-js.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ast-dump.$(OBJEXT)
|
||||
-rm -f Ahuacatl/ast-node.$(OBJEXT)
|
||||
-rm -f Ahuacatl/error.$(OBJEXT)
|
||||
-rm -f Ahuacatl/grammar.$(OBJEXT)
|
||||
-rm -f Ahuacatl/parser.$(OBJEXT)
|
||||
-rm -f Ahuacatl/tokens.$(OBJEXT)
|
||||
-rm -f ApplicationServer/ApplicationServer.$(OBJEXT)
|
||||
-rm -f ApplicationServer/ApplicationServerImpl.$(OBJEXT)
|
||||
-rm -f ApplicationServer/ApplicationServerSchedulerImpl.$(OBJEXT)
|
||||
|
@ -2128,14 +2138,15 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@Admin/$(DEPDIR)/RestAdminLogHandler.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Admin/$(DEPDIR)/RestBaseHandler.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Admin/$(DEPDIR)/RestVersionHandler.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-bind-parameter.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-error.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-functions.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-grammar.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-parser.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ahuacatl-tokens.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ast-codegen-js.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ast-dump.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/ast-node.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/error.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/grammar.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/parser.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@Ahuacatl/$(DEPDIR)/tokens.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@ApplicationServer/$(DEPDIR)/ApplicationServer.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@ApplicationServer/$(DEPDIR)/ApplicationServerImpl.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@ApplicationServer/$(DEPDIR)/ApplicationServerSchedulerImpl.Po@am__quote@
|
||||
|
@ -2977,7 +2988,7 @@ start-server:
|
|||
unittests-shell-server:
|
||||
@echo
|
||||
@echo "================================================================================"
|
||||
@echo "|| SHELL SERVER TESTS (BASCIS) ||"
|
||||
@echo "|| SHELL SERVER TESTS (BASICS) ||"
|
||||
@echo "================================================================================"
|
||||
@echo
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ unittests-boost:
|
|||
endif
|
||||
|
||||
################################################################################
|
||||
## SHELL SERVER TESTS (BASCIS)
|
||||
## SHELL SERVER TESTS (BASICS)
|
||||
################################################################################
|
||||
|
||||
SHELL_SERVER = @srcdir@/js/common/tests/shell-document.js \
|
||||
|
@ -136,7 +136,7 @@ UNITTESTS_SERVER = $(addprefix --unit-tests ,$(SHELL_SERVER))
|
|||
unittests-shell-server:
|
||||
@echo
|
||||
@echo "================================================================================"
|
||||
@echo "|| SHELL SERVER TESTS (BASCIS) ||"
|
||||
@echo "|| SHELL SERVER TESTS (BASICS) ||"
|
||||
@echo "================================================================================"
|
||||
@echo
|
||||
|
||||
|
@ -153,7 +153,10 @@ unittests-shell-server:
|
|||
## SHELL SERVER TESTS (AHUACATL)
|
||||
################################################################################
|
||||
|
||||
SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-queries-collection.js \
|
||||
SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-operators.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-escaping.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-functions.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-collection.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-noncollection.js
|
||||
|
||||
|
||||
|
|
|
@ -860,7 +860,7 @@ int AvocadoServer::executeShell (bool tests) {
|
|||
char* input = console->prompt("avocado> ");
|
||||
|
||||
if (input == 0) {
|
||||
printf("<ctrl-D>\nBye Bye! Auf Wiedersehen!\n");
|
||||
printf("<ctrl-D>\nBye Bye! Auf Wiedersehen! さようなら\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "SkipLists/sl-operator.h"
|
||||
#include "Ahuacatl/ast-node.h"
|
||||
#include "Ahuacatl/ast-codegen-js.h"
|
||||
#include "Ahuacatl/parser.h"
|
||||
#include "Ahuacatl/ahuacatl-parser.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace triagens::basics;
|
||||
|
@ -2279,6 +2279,8 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
|
|||
}
|
||||
string queryString = TRI_ObjectToString(queryArg);
|
||||
|
||||
/* currently unused, causes compile warnings
|
||||
|
||||
// return number of total records in cursor?
|
||||
bool doCount = false;
|
||||
if (argv.Length() > 0) {
|
||||
|
@ -2293,26 +2295,38 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
|
|||
max = (uint32_t) maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
v8::Handle<v8::Value> result;
|
||||
|
||||
TRI_json_t* parameters = NULL;
|
||||
|
||||
TRI_aql_parse_context_t* context;
|
||||
|
||||
context = TRI_CreateParseContextAql(vocbase, queryString.c_str());
|
||||
context = TRI_CreateParseContextAql(vocbase, queryString.c_str());
|
||||
if (!context) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("out of memory")));
|
||||
}
|
||||
|
||||
if (argv.Length() > 1) {
|
||||
parameters = ConvertHelper(argv[1]);
|
||||
if (!TRI_AddBindParametersAql(context, parameters)) {
|
||||
v8::Handle<v8::Object> errorObject = CreateErrorObjectAhuacatl(&context->_error);
|
||||
TRI_FreeJson(parameters);
|
||||
TRI_FreeParseContextAql(context);
|
||||
return scope.Close(errorObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (Ahuacatlparse(context)) {
|
||||
if (parameters) {
|
||||
TRI_FreeJson(parameters);
|
||||
}
|
||||
|
||||
if (!TRI_ParseQueryAql(context)) {
|
||||
v8::Handle<v8::Object> errorObject = CreateErrorObjectAhuacatl(&context->_error);
|
||||
TRI_FreeParseContextAql(context);
|
||||
return scope.Close(errorObject);
|
||||
}
|
||||
|
||||
if (argv.Length() > 1) {
|
||||
parameters = ConvertHelper(argv[1]);
|
||||
}
|
||||
|
||||
if (context->_first) {
|
||||
char* code = TRI_GenerateCodeAql((TRI_aql_node_t*) context->_first);
|
||||
|
@ -2324,10 +2338,6 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
|
|||
}
|
||||
|
||||
TRI_FreeParseContextAql(context);
|
||||
|
||||
if (parameters) {
|
||||
TRI_FreeJson(parameters);
|
||||
}
|
||||
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ namespace triagens {
|
|||
_separator = ',';
|
||||
regcomp(&_doubleRegex, "^[-+]?([0-9]+\\.?[0-9]*|\\.[0-9]+)([eE][-+]?[0-8]+)?$", REG_ICASE | REG_EXTENDED);
|
||||
regcomp(&_intRegex, "^[-+]?([0-9]+)$", REG_ICASE | REG_EXTENDED);
|
||||
_hasError = false;
|
||||
}
|
||||
|
||||
ImportHelper::~ImportHelper () {
|
||||
|
@ -89,9 +90,17 @@ namespace triagens {
|
|||
_outputBuffer.clear();
|
||||
_lineBuffer.clear();
|
||||
_errorMessage = "";
|
||||
_hasError = false;
|
||||
|
||||
// read and convert
|
||||
int fd = open(fileName.c_str(), O_RDONLY);
|
||||
int fd;
|
||||
|
||||
if (fileName == "-") {
|
||||
fd = STDIN_FILENO;
|
||||
}
|
||||
else {
|
||||
fd = open(fileName.c_str(), O_RDONLY);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
_errorMessage = TRI_LAST_ERROR_STR;
|
||||
|
@ -111,7 +120,7 @@ namespace triagens {
|
|||
|
||||
char buffer[10240];
|
||||
|
||||
while (true) {
|
||||
while (!_hasError) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
ssize_t n = read(fd, buffer, sizeof (buffer));
|
||||
|
@ -134,9 +143,12 @@ namespace triagens {
|
|||
|
||||
TRI_DestroyCsvParser(&parser);
|
||||
|
||||
close(fd);
|
||||
if (fileName != "-") {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return true;
|
||||
_outputBuffer.clear();
|
||||
return !_hasError;
|
||||
}
|
||||
|
||||
bool ImportHelper::importJson (const string& collectionName, const string& fileName) {
|
||||
|
@ -147,9 +159,17 @@ namespace triagens {
|
|||
_numberError = 0;
|
||||
_outputBuffer.clear();
|
||||
_errorMessage = "";
|
||||
_hasError = false;
|
||||
|
||||
// read and convert
|
||||
int fd = open(fileName.c_str(), O_RDONLY);
|
||||
int fd;
|
||||
|
||||
if (fileName == "-") {
|
||||
fd = STDIN_FILENO;
|
||||
}
|
||||
else {
|
||||
fd = open(fileName.c_str(), O_RDONLY);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
_errorMessage = TRI_LAST_ERROR_STR;
|
||||
|
@ -158,7 +178,7 @@ namespace triagens {
|
|||
|
||||
char buffer[10240];
|
||||
|
||||
while (true) {
|
||||
while (!_hasError) {
|
||||
ssize_t n = read(fd, buffer, sizeof(buffer));
|
||||
|
||||
if (n < 0) {
|
||||
|
@ -192,9 +212,12 @@ namespace triagens {
|
|||
|
||||
_numberLines = _numberError + _numberOk;
|
||||
|
||||
close(fd);
|
||||
if (fileName != "-") {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return true;
|
||||
_outputBuffer.clear();
|
||||
return !_hasError;
|
||||
}
|
||||
|
||||
|
||||
|
@ -333,6 +356,10 @@ namespace triagens {
|
|||
}
|
||||
|
||||
void ImportHelper::sendCsvBuffer () {
|
||||
if (_hasError) {
|
||||
return;
|
||||
}
|
||||
|
||||
map<string, string> headerFields;
|
||||
SimpleHttpResult* result = _client->request(SimpleHttpClient::POST, "/_api/import?collection=" + StringUtils::urlEncode(_collectionName), _outputBuffer.c_str(), _outputBuffer.length(), headerFields);
|
||||
|
||||
|
@ -342,12 +369,14 @@ namespace triagens {
|
|||
}
|
||||
|
||||
void ImportHelper::sendJsonBuffer (char const* str, size_t len) {
|
||||
if (_hasError) {
|
||||
return;
|
||||
}
|
||||
|
||||
map<string, string> headerFields;
|
||||
SimpleHttpResult* result = _client->request(SimpleHttpClient::POST, "/_api/import?type=documents&collection=" + StringUtils::urlEncode(_collectionName), str, len, headerFields);
|
||||
|
||||
handleResult(result);
|
||||
|
||||
_outputBuffer.clear();
|
||||
}
|
||||
|
||||
void ImportHelper::handleResult (SimpleHttpResult* result) {
|
||||
|
@ -361,7 +390,11 @@ namespace triagens {
|
|||
VariantBoolean* vb = va->lookupBoolean("error");
|
||||
if (vb && vb->getValue()) {
|
||||
// is error
|
||||
|
||||
_hasError = true;
|
||||
VariantString* vs = va->lookupString("errorMessage");
|
||||
if (vs) {
|
||||
_errorMessage = vs->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
VariantInt64* vi = va->lookupInt64("created");
|
||||
|
|
|
@ -200,6 +200,7 @@ namespace triagens {
|
|||
regex_t _doubleRegex;
|
||||
regex_t _intRegex;
|
||||
|
||||
bool _hasError;
|
||||
string _errorMessage;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "Basics/ProgramOptions.h"
|
||||
#include "Basics/ProgramOptionsDescription.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/FileUtils.h"
|
||||
#include "BasicsC/files.h"
|
||||
#include "BasicsC/init.h"
|
||||
#include "BasicsC/logging.h"
|
||||
|
@ -40,7 +41,6 @@
|
|||
#include "Logger/Logger.h"
|
||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||
|
||||
#include "ImportHelper.h"
|
||||
#include "V8ClientConnection.h"
|
||||
|
||||
|
@ -156,7 +156,7 @@ static void ParseProgramOptions (int argc, char* argv[]) {
|
|||
("help,h", "help message")
|
||||
("log.level,l", &level, "log level")
|
||||
("server", &ServerAddress, "server address and port")
|
||||
("file", &FileName, "file name")
|
||||
("file", &FileName, "file name (\"-\" for STDIN)")
|
||||
("collection", &CollectionName, "collection name")
|
||||
("type", &TypeImport, "type of file (\"csv\" or \"json\")")
|
||||
("quote", &QuoteChar, "quote character")
|
||||
|
@ -271,6 +271,11 @@ int main (int argc, char* argv[]) {
|
|||
cout << "file name is missing." << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (FileName != "-" && !FileUtils::isRegularFile(FileName)) {
|
||||
cout << "file '" << FileName << "' is not a regular file." << endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
if (TypeImport == "csv") {
|
||||
|
|
|
@ -78,6 +78,8 @@ ModuleCache["/internal"].exports.errors = {
|
|||
"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE" : { "code" : 1521, "message" : "limit value '%s' is out of range" },
|
||||
"ERROR_QUERY_VARIABLE_REDECLARED" : { "code" : 1522, "message" : "variable '%s' is assigned multiple times" },
|
||||
"ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED" : { "code" : 1523, "message" : "document attribute '%s' is assigned multiple times" },
|
||||
"ERROR_QUERY_VARIABLE_NAME_INVALID" : { "code" : 1524, "message" : "variable name '%s' has an invalid format" },
|
||||
"ERROR_QUERY_BIND_PARAMETERS_INVALID" : { "code" : 1525, "message" : "invalid structure of bind parameters" },
|
||||
"ERROR_CURSOR_NOT_FOUND" : { "code" : 1600, "message" : "cursor not found" },
|
||||
"ERROR_SESSION_USERHANDLER_URL_INVALID" : { "code" : 1700, "message" : "expecting <prefix>/user/<username>" },
|
||||
"ERROR_SESSION_USERHANDLER_CANNOT_CREATE_USER" : { "code" : 1701, "message" : "cannot create user" },
|
||||
|
|
|
@ -79,6 +79,8 @@ static string JS_common_bootstrap_errors =
|
|||
" \"ERROR_QUERY_LIMIT_VALUE_OUT_OF_RANGE\" : { \"code\" : 1521, \"message\" : \"limit value '%s' is out of range\" }, \n"
|
||||
" \"ERROR_QUERY_VARIABLE_REDECLARED\" : { \"code\" : 1522, \"message\" : \"variable '%s' is assigned multiple times\" }, \n"
|
||||
" \"ERROR_QUERY_DOCUMENT_ATTRIBUTE_REDECLARED\" : { \"code\" : 1523, \"message\" : \"document attribute '%s' is assigned multiple times\" }, \n"
|
||||
" \"ERROR_QUERY_VARIABLE_NAME_INVALID\" : { \"code\" : 1524, \"message\" : \"variable name '%s' has an invalid format\" }, \n"
|
||||
" \"ERROR_QUERY_BIND_PARAMETERS_INVALID\" : { \"code\" : 1525, \"message\" : \"invalid structure of bind parameters\" }, \n"
|
||||
" \"ERROR_CURSOR_NOT_FOUND\" : { \"code\" : 1600, \"message\" : \"cursor not found\" }, \n"
|
||||
" \"ERROR_SESSION_USERHANDLER_URL_INVALID\" : { \"code\" : 1700, \"message\" : \"expecting <prefix>/user/<username>\" }, \n"
|
||||
" \"ERROR_SESSION_USERHANDLER_CANNOT_CREATE_USER\" : { \"code\" : 1701, \"message\" : \"cannot create user\" }, \n"
|
||||
|
|
|
@ -79,7 +79,7 @@ function AHUACATL_CLONE (obj) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_FCALL(name, parameters) {
|
||||
return name(parameters);
|
||||
return name.apply(null, parameters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -350,6 +350,13 @@ function AHUACATL_RELATIONAL_EQUAL (lhs, rhs) {
|
|||
}
|
||||
|
||||
// primitive type
|
||||
if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
lhs = null;
|
||||
}
|
||||
if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
rhs = null;
|
||||
}
|
||||
|
||||
return (lhs === rhs);
|
||||
}
|
||||
|
||||
|
@ -397,6 +404,13 @@ function AHUACATL_RELATIONAL_UNEQUAL (lhs, rhs) {
|
|||
}
|
||||
|
||||
// primitive type
|
||||
if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
lhs = null;
|
||||
}
|
||||
if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
rhs = null;
|
||||
}
|
||||
|
||||
return (lhs !== rhs);
|
||||
}
|
||||
|
||||
|
@ -453,6 +467,13 @@ function AHUACATL_RELATIONAL_GREATER_REC (lhs, rhs) {
|
|||
}
|
||||
|
||||
// primitive type
|
||||
if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
lhs = null;
|
||||
}
|
||||
if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
rhs = null;
|
||||
}
|
||||
|
||||
if (lhs === rhs) {
|
||||
return null;
|
||||
}
|
||||
|
@ -528,6 +549,13 @@ function AHUACATL_RELATIONAL_GREATEREQUAL_REC (lhs, rhs) {
|
|||
}
|
||||
|
||||
// primitive type
|
||||
if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
lhs = null;
|
||||
}
|
||||
if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
rhs = null;
|
||||
}
|
||||
|
||||
if (lhs === rhs) {
|
||||
return null;
|
||||
}
|
||||
|
@ -604,6 +632,13 @@ function AHUACATL_RELATIONAL_LESS_REC (lhs, rhs) {
|
|||
}
|
||||
|
||||
// primitive type
|
||||
if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
lhs = null;
|
||||
}
|
||||
if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
rhs = null;
|
||||
}
|
||||
|
||||
if (lhs === rhs) {
|
||||
return null;
|
||||
}
|
||||
|
@ -677,11 +712,18 @@ function AHUACATL_RELATIONAL_LESSEQUAL_REC (lhs, rhs) {
|
|||
return null;
|
||||
}
|
||||
|
||||
// primitive type
|
||||
if (AHUACATL_TYPEWEIGHT(lhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
lhs = null;
|
||||
}
|
||||
if (AHUACATL_TYPEWEIGHT(rhs) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
rhs = null;
|
||||
}
|
||||
|
||||
if (lhs === rhs) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// primitive type
|
||||
return (lhs <= rhs);
|
||||
}
|
||||
|
||||
|
@ -752,7 +794,11 @@ function AHUACATL_UNARY_PLUS (value) {
|
|||
throw "expecting number for unary plus";
|
||||
}
|
||||
|
||||
return AHUACATL_NUMERIC_VALUE(value);
|
||||
var result = AHUACATL_NUMERIC_VALUE(value);
|
||||
if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {
|
||||
throw "number out of range";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -766,7 +812,11 @@ function AHUACATL_UNARY_MINUS (value) {
|
|||
throw "expecting number for unary minus";
|
||||
}
|
||||
|
||||
return AHUACATL_NUMERIC_VALUE(-value);
|
||||
var result = AHUACATL_NUMERIC_VALUE(-value);
|
||||
if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {
|
||||
throw "number out of range";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -781,7 +831,11 @@ function AHUACATL_ARITHMETIC_PLUS (lhs, rhs) {
|
|||
throw "expecting numbers for plus";
|
||||
}
|
||||
|
||||
return AHUACATL_NUMERIC_VALUE(lhs + rhs);
|
||||
var result = AHUACATL_NUMERIC_VALUE(lhs + rhs);
|
||||
if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {
|
||||
throw "number out of range";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -796,7 +850,11 @@ function AHUACATL_ARITHMETIC_MINUS (lhs, rhs) {
|
|||
throw "expecting numbers for minus";
|
||||
}
|
||||
|
||||
return AHUACATL_NUMERIC_VALUE(lhs - rhs);
|
||||
var result = AHUACATL_NUMERIC_VALUE(lhs - rhs);
|
||||
if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {
|
||||
throw "number out of range";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -811,7 +869,11 @@ function AHUACATL_ARITHMETIC_TIMES (lhs, rhs) {
|
|||
throw "expecting numbers for times";
|
||||
}
|
||||
|
||||
return AHUACATL_NUMERIC_VALUE(lhs * rhs);
|
||||
var result = AHUACATL_NUMERIC_VALUE(lhs * rhs);
|
||||
if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {
|
||||
throw "number out of range";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -830,7 +892,11 @@ function AHUACATL_ARITHMETIC_DIVIDE (lhs, rhs) {
|
|||
throw "division by zero";
|
||||
}
|
||||
|
||||
return AHUACATL_NUMERIC_VALUE(lhs / rhs);
|
||||
var result = AHUACATL_NUMERIC_VALUE(lhs / rhs);
|
||||
if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {
|
||||
throw "number out of range";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -849,7 +915,11 @@ function AHUACATL_ARITHMETIC_MODULUS (lhs, rhs) {
|
|||
throw "division by zero";
|
||||
}
|
||||
|
||||
return AHUACATL_NUMERIC_VALUE(lhs % rhs);
|
||||
var result = AHUACATL_NUMERIC_VALUE(lhs % rhs);
|
||||
if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {
|
||||
throw "number out of range";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -871,13 +941,24 @@ function AHUACATL_ARITHMETIC_MODULUS (lhs, rhs) {
|
|||
/// both operands must be strings or this function will fail
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_STRING_CONCAT (lhs, rhs) {
|
||||
if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_STRING ||
|
||||
AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_STRING) {
|
||||
throw "expecting strings for string concatenation";
|
||||
function AHUACATL_STRING_CONCAT () {
|
||||
var result = '';
|
||||
|
||||
for (var i in arguments) {
|
||||
var element = arguments[i];
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(element) === AHUACATL_TYPEWEIGHT_NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_STRING) {
|
||||
throw "expecting strings for string concatenation";
|
||||
}
|
||||
|
||||
result += element;
|
||||
}
|
||||
|
||||
return (lhs + rhs);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1135,14 +1216,66 @@ function AHUACATL_LIMIT (value, offset, count) {
|
|||
/// @brief get the length of a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_LENGTH (args) {
|
||||
var value = args[0];
|
||||
function AHUACATL_LENGTH () {
|
||||
var value = arguments[0];
|
||||
|
||||
AHUACATL_LIST(value);
|
||||
|
||||
return value.length;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief merge all arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_MERGE () {
|
||||
var result = { };
|
||||
|
||||
for (var i in arguments) {
|
||||
var element = arguments[i];
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_DOCUMENT) {
|
||||
throw "expecting documents for merge";
|
||||
}
|
||||
|
||||
for (var k in element) {
|
||||
if (!element.hasOwnProperty(k)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result[k] = element[k];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the union (all) of all arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function AHUACATL_UNION () {
|
||||
var result = [ ];
|
||||
|
||||
for (var i in arguments) {
|
||||
var element = arguments[i];
|
||||
|
||||
if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_LIST) {
|
||||
throw "expecting lists for union";
|
||||
}
|
||||
|
||||
for (var k in element) {
|
||||
if (!element.hasOwnProperty(k)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push(element[k]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -80,7 +80,7 @@ static string JS_server_ahuacatl =
|
|||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_FCALL(name, parameters) {\n"
|
||||
" return name(parameters);\n"
|
||||
" return name.apply(null, parameters);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -351,6 +351,13 @@ static string JS_server_ahuacatl =
|
|||
" }\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"
|
||||
|
@ -398,6 +405,13 @@ static string JS_server_ahuacatl =
|
|||
" }\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"
|
||||
|
@ -454,6 +468,13 @@ static string JS_server_ahuacatl =
|
|||
" }\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"
|
||||
|
@ -529,6 +550,13 @@ static string JS_server_ahuacatl =
|
|||
" }\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"
|
||||
|
@ -605,6 +633,13 @@ static string JS_server_ahuacatl =
|
|||
" }\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"
|
||||
|
@ -678,11 +713,18 @@ static string JS_server_ahuacatl =
|
|||
" 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"
|
||||
" // primitive type\n"
|
||||
" return (lhs <= rhs);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
@ -753,7 +795,11 @@ static string JS_server_ahuacatl =
|
|||
" throw \"expecting number for unary plus\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return AHUACATL_NUMERIC_VALUE(value);\n"
|
||||
" var result = AHUACATL_NUMERIC_VALUE(value);\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
||||
" throw \"number out of range\";\n"
|
||||
" }\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -767,7 +813,11 @@ static string JS_server_ahuacatl =
|
|||
" throw \"expecting number for unary minus\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return AHUACATL_NUMERIC_VALUE(-value);\n"
|
||||
" var result = AHUACATL_NUMERIC_VALUE(-value);\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
||||
" throw \"number out of range\";\n"
|
||||
" }\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -782,7 +832,11 @@ static string JS_server_ahuacatl =
|
|||
" throw \"expecting numbers for plus\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return AHUACATL_NUMERIC_VALUE(lhs + rhs);\n"
|
||||
" var result = AHUACATL_NUMERIC_VALUE(lhs + rhs);\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
||||
" throw \"number out of range\";\n"
|
||||
" }\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -797,7 +851,11 @@ static string JS_server_ahuacatl =
|
|||
" throw \"expecting numbers for minus\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return AHUACATL_NUMERIC_VALUE(lhs - rhs);\n"
|
||||
" var result = AHUACATL_NUMERIC_VALUE(lhs - rhs);\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
||||
" throw \"number out of range\";\n"
|
||||
" }\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -812,7 +870,11 @@ static string JS_server_ahuacatl =
|
|||
" throw \"expecting numbers for times\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return AHUACATL_NUMERIC_VALUE(lhs * rhs);\n"
|
||||
" var result = AHUACATL_NUMERIC_VALUE(lhs * rhs);\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
||||
" throw \"number out of range\";\n"
|
||||
" }\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -831,7 +893,11 @@ static string JS_server_ahuacatl =
|
|||
" throw \"division by zero\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return AHUACATL_NUMERIC_VALUE(lhs / rhs);\n"
|
||||
" var result = AHUACATL_NUMERIC_VALUE(lhs / rhs);\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
||||
" throw \"number out of range\";\n"
|
||||
" }\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -850,7 +916,11 @@ static string JS_server_ahuacatl =
|
|||
" throw \"division by zero\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return AHUACATL_NUMERIC_VALUE(lhs % rhs);\n"
|
||||
" var result = AHUACATL_NUMERIC_VALUE(lhs % rhs);\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(result) !== AHUACATL_TYPEWEIGHT_NUMBER) {\n"
|
||||
" throw \"number out of range\";\n"
|
||||
" }\n"
|
||||
" return result;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -872,13 +942,24 @@ static string JS_server_ahuacatl =
|
|||
"/// both operands must be strings or this function will fail\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_STRING_CONCAT (lhs, rhs) {\n"
|
||||
" if (AHUACATL_TYPEWEIGHT(lhs) !== AHUACATL_TYPEWEIGHT_STRING ||\n"
|
||||
" AHUACATL_TYPEWEIGHT(rhs) !== AHUACATL_TYPEWEIGHT_STRING) {\n"
|
||||
" throw \"expecting strings for string concatenation\";\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"
|
||||
" if (AHUACATL_TYPEWEIGHT(element) !== AHUACATL_TYPEWEIGHT_STRING) {\n"
|
||||
" throw \"expecting strings for string concatenation\";\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" result += element;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return (lhs + rhs);\n"
|
||||
" return result; \n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
|
@ -1136,8 +1217,8 @@ static string JS_server_ahuacatl =
|
|||
"/// @brief get the length of a list\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
"function AHUACATL_LENGTH (args) {\n"
|
||||
" var value = args[0];\n"
|
||||
"function AHUACATL_LENGTH () {\n"
|
||||
" var value = arguments[0];\n"
|
||||
"\n"
|
||||
" AHUACATL_LIST(value);\n"
|
||||
"\n"
|
||||
|
@ -1145,6 +1226,58 @@ static string JS_server_ahuacatl =
|
|||
"}\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"
|
||||
" throw \"expecting documents for 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"
|
||||
"/// @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"
|
||||
" throw \"expecting lists for 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"
|
||||
"/// @}\n"
|
||||
"////////////////////////////////////////////////////////////////////////////////\n"
|
||||
"\n"
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for query language, escaping
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 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 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ahuacatlEscapingTestSuite () {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute a given query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function executeQuery (query) {
|
||||
var cursor = AHUACATL_RUN(query, undefined);
|
||||
if (cursor instanceof AvocadoQueryError) {
|
||||
print(query, cursor.message);
|
||||
}
|
||||
assertFalse(cursor instanceof AvocadoQueryError);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute a given query and return the results as an array
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getQueryResults (query, isFlat) {
|
||||
var result = executeQuery(query);
|
||||
var results = [ ];
|
||||
|
||||
for (var i in result) {
|
||||
if (!result.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var row = result[i];
|
||||
if (isFlat) {
|
||||
results.push(row);
|
||||
}
|
||||
else {
|
||||
var keys = [ ];
|
||||
for (var k in row) {
|
||||
if (row.hasOwnProperty(k) && k != '_id' && k != '_rev') {
|
||||
keys.push(k);
|
||||
}
|
||||
}
|
||||
|
||||
keys.sort();
|
||||
var resultRow = { };
|
||||
for (var k in keys) {
|
||||
if (keys.hasOwnProperty(k)) {
|
||||
resultRow[keys[k]] = row[keys[k]];
|
||||
}
|
||||
}
|
||||
results.push(resultRow);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test simple name handling
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSimpleName : function () {
|
||||
var expected = [ 1, 2, 3 ];
|
||||
var actual = getQueryResults("FOR `x` IN [ 1, 2, 3 ] RETURN `x`", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test reserved name handling
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReservedNames1 : function () {
|
||||
var expected = [ 1, 2, 3 ];
|
||||
var names = [ "for", "let", "return", "sort", "collect", "limit", "filter", "asc", "desc", "in", "into" ];
|
||||
|
||||
for (var i in names) {
|
||||
if (!names.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var actual = getQueryResults("FOR `" + names[i] + "` IN [ 1, 2, 3 ] RETURN `" + names[i] + "`", true);
|
||||
assertEqual(expected, actual);
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test reserved names handling
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testReservedNames2 : function () {
|
||||
var expected = [ { "let" : 1 }, { "collect" : 2 }, { "sort" : 3 } ];
|
||||
var actual = getQueryResults("FOR `for` IN [ { \"let\" : 1 }, { \"collect\" : 2 }, { \"sort\" : 3 } ] RETURN `for`", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test punctuation names escaping
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPunctuationName1 : function () {
|
||||
var expected = [ 1, 2, 3 ];
|
||||
var actual = getQueryResults("FOR `brown_fox` IN [ 1, 2, 3 ] RETURN `brown_fox`", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test punctuation names escaping
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPunctuationName2 : function () {
|
||||
var expected = [ 1, 2, 3 ];
|
||||
var actual = getQueryResults("FOR `brown_fox__1234_` IN [ 1, 2, 3 ] RETURN `brown_fox__1234_`", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(ahuacatlEscapingTestSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
|
@ -0,0 +1,209 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for query language, functions
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 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 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ahuacatlFunctionsTestSuite () {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute a given query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function executeQuery (query) {
|
||||
var cursor = AHUACATL_RUN(query, undefined);
|
||||
if (cursor instanceof AvocadoQueryError) {
|
||||
print(query, cursor.message);
|
||||
}
|
||||
assertFalse(cursor instanceof AvocadoQueryError);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute a given query and return the results as an array
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getQueryResults (query, isFlat) {
|
||||
var result = executeQuery(query);
|
||||
var results = [ ];
|
||||
|
||||
for (var i in result) {
|
||||
if (!result.hasOwnProperty(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var row = result[i];
|
||||
if (isFlat) {
|
||||
results.push(row);
|
||||
}
|
||||
else {
|
||||
var keys = [ ];
|
||||
for (var k in row) {
|
||||
if (row.hasOwnProperty(k) && k != '_id' && k != '_rev') {
|
||||
keys.push(k);
|
||||
}
|
||||
}
|
||||
|
||||
keys.sort();
|
||||
var resultRow = { };
|
||||
for (var k in keys) {
|
||||
if (keys.hasOwnProperty(k)) {
|
||||
resultRow[keys[k]] = row[keys[k]];
|
||||
}
|
||||
}
|
||||
results.push(resultRow);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test length function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testLength : function () {
|
||||
var expected = [ 4, 4, 4 ];
|
||||
var actual = getQueryResults("FOR year IN [ 2010, 2011, 2012 ] LET quarters = ((FOR q IN [ 1, 2, 3, 4 ] return q)) return LENGTH(quarters)", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test concat function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testConcat : function () {
|
||||
var expected = [ "theQuickBrownFoxJumps" ];
|
||||
var actual = getQueryResults("FOR r IN [ 1 ] return CONCAT('the', 'Quick', null, 'Brown', null, 'Fox', 'Jumps')", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test merge function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMerge1 : function () {
|
||||
var expected = [ { "quarter" : 1, "year" : 2010 }, { "quarter" : 2, "year" : 2010 }, { "quarter" : 3, "year" : 2010 }, { "quarter" : 4, "year" : 2010 }, { "quarter" : 1, "year" : 2011 }, { "quarter" : 2, "year" : 2011 }, { "quarter" : 3, "year" : 2011 }, { "quarter" : 4, "year" : 2011 }, { "quarter" : 1, "year" : 2012 }, { "quarter" : 2, "year" : 2012 }, { "quarter" : 3, "year" : 2012 }, { "quarter" : 4, "year" : 2012 } ];
|
||||
var actual = getQueryResults("FOR year IN [ 2010, 2011, 2012 ] FOR quarter IN [ 1, 2, 3, 4 ] return MERGE({ \"year\" : year }, { \"quarter\" : quarter })", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test merge function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMerge2 : function () {
|
||||
var expected = [ { "age" : 15, "isAbove18" : false, "name" : "John" }, { "age" : 19, "isAbove18" : true, "name" : "Corey" } ];
|
||||
var actual = getQueryResults("FOR u IN [ { \"name\" : \"John\", \"age\" : 15 }, { \"name\" : \"Corey\", \"age\" : 19 } ] return MERGE(u, { \"isAbove18\" : u.age >= 18 })", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test merge function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMerge3 : function () {
|
||||
var expected = [ { "age" : 15, "id" : 9, "name" : "John" }, { "age" : 19, "id" : 9, "name" : "Corey" } ];
|
||||
var actual = getQueryResults("FOR u IN [ { \"id\" : 100, \"name\" : \"John\", \"age\" : 15 }, { \"id\" : 101, \"name\" : \"Corey\", \"age\" : 19 } ] return MERGE(u, { \"id\" : 9 })", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test merge function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testMerge4 : function () {
|
||||
var expected = [ { "age" : 15, "id" : 33, "name" : "foo" }, { "age" : 19, "id" : 33, "name" : "foo" } ];
|
||||
var actual = getQueryResults("FOR u IN [ { \"id\" : 100, \"name\" : \"John\", \"age\" : 15 }, { \"id\" : 101, \"name\" : \"Corey\", \"age\" : 19 } ] return MERGE(u, { \"id\" : 9 }, { \"name\" : \"foo\", \"id\" : 33 })", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test union function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnion1 : function () {
|
||||
var expected = [ [ 1, 2, 3, 1, 2, 3 ], [ 1, 2, 3, 1, 2, 3 ] ];
|
||||
var actual = getQueryResults("FOR u IN [ 1, 2 ] return UNION([ 1, 2, 3 ], [ 1, 2, 3 ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test union function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnion2 : function () {
|
||||
var expected = [ [ 1, 2, 3, 3, 2, 1 ], [ 1, 2, 3, 3, 2, 1 ] ];
|
||||
var actual = getQueryResults("FOR u IN [ 1, 2 ] return UNION([ 1, 2, 3 ], [ 3, 2, 1 ])", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test union function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnion3 : function () {
|
||||
var expected = [ "Fred", "John", "John", "Amy" ];
|
||||
var actual = getQueryResults("FOR u IN UNION([ \"Fred\", \"John\" ], [ \"John\", \"Amy\"]) return u", true);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(ahuacatlFunctionsTestSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
File diff suppressed because it is too large
Load Diff
|
@ -507,18 +507,16 @@ function ahuacatlQueryCollectionTestSuite () {
|
|||
|
||||
testCollectSimple : function () {
|
||||
var expected = [ { "gender" : "f", "numUsers" : 10 }, { "gender" : "m", "numUsers" : 10 } ];
|
||||
|
||||
var actual = getQueryResults("FOR u in " + users.name() + " COLLECT gender = u.gender INTO g SORT gender ASC RETURN { \"gender\" : gender, \"numUsers\" : LENGTH(g) }", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test collect with filter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCollectFiltered : function () {
|
||||
var expected = [ { "gender" : "m", "numUsers" : 8 }, { "gender" : "f", "numUsers" : 8 } ];
|
||||
|
||||
actual = getQueryResults("FOR u in " + users.name() + " FILTER u.active == true COLLECT gender = u.gender INTO g SORT gender DESC RETURN { \"gender\" : gender, \"numUsers\" : LENGTH(g) }", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
@ -529,7 +527,6 @@ function ahuacatlQueryCollectionTestSuite () {
|
|||
|
||||
testCollectMultipleCriteria : function () {
|
||||
var expected = [ { "active" : false, "gender" : "m", "numUsers" : 2 }, { "active" : true, "gender" : "m", "numUsers" : 8 }, { "active" : false, "gender" : "f", "numUsers" : 2 }, { "active" : true, "gender" : "f", "numUsers" : 8 } ];
|
||||
|
||||
actual = getQueryResults("FOR u in " + users.name() + " COLLECT gender = u.gender, active = u.active INTO g SORT gender DESC, active ASC RETURN { \"gender\" : gender, \"active\" : active, \"numUsers\" : LENGTH(g) }", false);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
|
|
@ -32,8 +32,6 @@ var jsunity = require("jsunity");
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function ahuacatlQueryNonCollectionTestSuite () {
|
||||
var users = null;
|
||||
var relations = null;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute a given query
|
||||
|
|
Loading…
Reference in New Issue