mirror of https://gitee.com/bigwinds/arangodb
DML for AQL
This commit is contained in:
parent
3f22fa03be
commit
d9653bc462
|
@ -78,6 +78,30 @@
|
|||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static void SetWriteOperation (TRI_aql_context_t* context,
|
||||
TRI_aql_node_t const* collection,
|
||||
TRI_aql_query_type_e type,
|
||||
bool ignore) {
|
||||
if (context->_writeCollection != NULL ||
|
||||
context->_type != TRI_AQL_QUERY_READ) {
|
||||
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_QUERY_MULTI_MODIFY, NULL);
|
||||
}
|
||||
else if (context->_subQueries > 0) {
|
||||
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_QUERY_MODIFY_IN_SUBQUERY, NULL);
|
||||
}
|
||||
else {
|
||||
TRI_aql_node_t* nameNode = TRI_AQL_NODE_MEMBER(collection, 0);
|
||||
|
||||
if (nameNode == NULL) {
|
||||
TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
}
|
||||
else {
|
||||
context->_writeCollection = TRI_AQL_NODE_STRING(nameNode);
|
||||
context->_writeIgnore = ignore;
|
||||
context->_type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST function call node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -341,6 +365,74 @@ TRI_aql_node_t* TRI_CreateNodeReturnAql (TRI_aql_context_t* const context,
|
|||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST remove node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeRemoveAql (TRI_aql_context_t* const context,
|
||||
const TRI_aql_node_t* const expression,
|
||||
const TRI_aql_node_t* const collection,
|
||||
bool ignore) {
|
||||
CREATE_NODE(TRI_AQL_NODE_REMOVE)
|
||||
|
||||
ADD_MEMBER(expression)
|
||||
|
||||
SetWriteOperation(context, collection, TRI_AQL_QUERY_REMOVE, ignore);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST save node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeSaveAql (TRI_aql_context_t* const context,
|
||||
const TRI_aql_node_t* const expression,
|
||||
const TRI_aql_node_t* const collection,
|
||||
bool ignore) {
|
||||
CREATE_NODE(TRI_AQL_NODE_SAVE)
|
||||
|
||||
ADD_MEMBER(expression)
|
||||
|
||||
SetWriteOperation(context, collection, TRI_AQL_QUERY_SAVE, ignore);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST update node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeUpdateAql (TRI_aql_context_t* const context,
|
||||
const TRI_aql_node_t* const expression,
|
||||
const TRI_aql_node_t* const collection,
|
||||
bool ignore) {
|
||||
CREATE_NODE(TRI_AQL_NODE_UPDATE)
|
||||
|
||||
ADD_MEMBER(expression)
|
||||
|
||||
SetWriteOperation(context, collection, TRI_AQL_QUERY_UPDATE, ignore);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST replace node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeReplaceAql (TRI_aql_context_t* const context,
|
||||
const TRI_aql_node_t* const expression,
|
||||
const TRI_aql_node_t* const collection,
|
||||
bool ignore) {
|
||||
CREATE_NODE(TRI_AQL_NODE_REPLACE)
|
||||
|
||||
ADD_MEMBER(expression)
|
||||
|
||||
SetWriteOperation(context, collection, TRI_AQL_QUERY_REMOVE, ignore);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST collect node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -97,6 +97,42 @@ TRI_aql_node_t* TRI_CreateNodeFilterAql (struct TRI_aql_context_s* const,
|
|||
TRI_aql_node_t* TRI_CreateNodeReturnAql (struct TRI_aql_context_s* const,
|
||||
const TRI_aql_node_t* const);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST remove node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeRemoveAql (struct TRI_aql_context_s* const,
|
||||
const TRI_aql_node_t* const,
|
||||
const TRI_aql_node_t* const,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST save node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeSaveAql (struct TRI_aql_context_s* const,
|
||||
const TRI_aql_node_t* const,
|
||||
const TRI_aql_node_t* const,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST update node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeUpdateAql (struct TRI_aql_context_s* const,
|
||||
const TRI_aql_node_t* const,
|
||||
const TRI_aql_node_t* const,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST replace node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* TRI_CreateNodeReplaceAql (struct TRI_aql_context_s* const,
|
||||
const TRI_aql_node_t* const,
|
||||
const TRI_aql_node_t* const,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST collect node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2638,6 +2638,98 @@ static void ProcessReturnEmpty (TRI_aql_codegen_js_t* const generator,
|
|||
CloseLoops(generator);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate code for remove keyword
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void ProcessRemove (TRI_aql_codegen_js_t* const generator,
|
||||
const TRI_aql_node_t* const node) {
|
||||
TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
|
||||
|
||||
if (scope == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopeOutput(generator, "aql.REMOVE_DOCUMENT(ops, ");
|
||||
|
||||
// expression
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
|
||||
|
||||
ScopeOutput(generator, ");\n");
|
||||
|
||||
// }
|
||||
CloseLoops(generator);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate code for save keyword
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void ProcessSave (TRI_aql_codegen_js_t* const generator,
|
||||
const TRI_aql_node_t* const node) {
|
||||
TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
|
||||
|
||||
if (scope == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopeOutput(generator, "aql.SAVE_DOCUMENT(ops, ");
|
||||
|
||||
// expression
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
|
||||
|
||||
ScopeOutput(generator, ");\n");
|
||||
|
||||
// }
|
||||
CloseLoops(generator);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate code for update keyword
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void ProcessUpdate (TRI_aql_codegen_js_t* const generator,
|
||||
const TRI_aql_node_t* const node) {
|
||||
TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
|
||||
|
||||
if (scope == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopeOutput(generator, "aql.UPDATE_DOCUMENT(ops, ");
|
||||
|
||||
// expression
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
|
||||
|
||||
ScopeOutput(generator, ");\n");
|
||||
|
||||
// }
|
||||
CloseLoops(generator);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate code for replace keyword
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void ProcessReplace (TRI_aql_codegen_js_t* const generator,
|
||||
const TRI_aql_node_t* const node) {
|
||||
TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
|
||||
|
||||
if (scope == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopeOutput(generator, "aql.UPDATE_DOCUMENT(ops, ");
|
||||
|
||||
// expression
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
|
||||
|
||||
ScopeOutput(generator, ");\n");
|
||||
|
||||
// }
|
||||
CloseLoops(generator);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate code for let keyword
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2870,6 +2962,18 @@ static void ProcessNode (TRI_aql_codegen_js_t* const generator, const TRI_aql_no
|
|||
case TRI_AQL_NODE_RETURN:
|
||||
ProcessReturn(generator, node);
|
||||
break;
|
||||
case TRI_AQL_NODE_REMOVE:
|
||||
ProcessRemove(generator, node);
|
||||
break;
|
||||
case TRI_AQL_NODE_SAVE:
|
||||
ProcessSave(generator, node);
|
||||
break;
|
||||
case TRI_AQL_NODE_UPDATE:
|
||||
ProcessUpdate(generator, node);
|
||||
break;
|
||||
case TRI_AQL_NODE_REPLACE:
|
||||
ProcessReplace(generator, node);
|
||||
break;
|
||||
case TRI_AQL_NODE_RETURN_EMPTY:
|
||||
ProcessReturnEmpty(generator, node);
|
||||
break;
|
||||
|
@ -3012,8 +3116,7 @@ char* TRI_GenerateCodeAql (TRI_aql_context_t* const context,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
OutputString(&generator->_functionBuffer, "(function () {\nvar aql = require(\"org/arangodb/ahuacatl\"), extra = { };\n");
|
||||
|
||||
OutputString(&generator->_functionBuffer, "(function () {\nvar aql = require(\"org/arangodb/ahuacatl\"), extra = { };\nvar ops = [ ];\n");
|
||||
if (context->_userOptions != NULL && context->_userOptions->_type == TRI_JSON_ARRAY) {
|
||||
OutputString(&generator->_functionBuffer, "var options = ");
|
||||
TRI_StringifyJson(&generator->_functionBuffer, context->_userOptions);
|
||||
|
@ -3022,12 +3125,44 @@ char* TRI_GenerateCodeAql (TRI_aql_context_t* const context,
|
|||
|
||||
resultRegister = CreateCode(generator);
|
||||
|
||||
if (context->_type != TRI_AQL_QUERY_READ) {
|
||||
assert(context->_writeCollection != NULL);
|
||||
|
||||
OutputString(&generator->_buffer, "extra.operations = aql.EXECUTE_");
|
||||
|
||||
switch (context->_type) {
|
||||
case TRI_AQL_QUERY_REMOVE:
|
||||
OutputString(&generator->_buffer, "REMOVE");
|
||||
break;
|
||||
case TRI_AQL_QUERY_SAVE:
|
||||
OutputString(&generator->_buffer, "SAVE");
|
||||
break;
|
||||
case TRI_AQL_QUERY_UPDATE:
|
||||
OutputString(&generator->_buffer, "UPDATE");
|
||||
break;
|
||||
case TRI_AQL_QUERY_REPLACE:
|
||||
OutputString(&generator->_buffer, "REPLACE");
|
||||
break;
|
||||
case TRI_AQL_QUERY_READ:
|
||||
// cannot happen, but the compiler is unhappy otherwise
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
OutputString(&generator->_buffer, "(ops, '");
|
||||
OutputString(&generator->_buffer, context->_writeCollection);
|
||||
OutputString(&generator->_buffer, "', ");
|
||||
OutputString(&generator->_buffer, context->_writeIgnore ? "true" : "false");
|
||||
OutputString(&generator->_buffer, ");\n");
|
||||
}
|
||||
|
||||
// append result
|
||||
OutputString(&generator->_buffer, "return {\n");
|
||||
OutputString(&generator->_buffer, "docs: ");
|
||||
OutputString(&generator->_buffer, REGISTER_PREFIX);
|
||||
OutputInt(&generator->_buffer, (int64_t) resultRegister);
|
||||
OutputString(&generator->_buffer, ",\n");
|
||||
|
||||
OutputString(&generator->_buffer, "extra: extra");
|
||||
OutputString(&generator->_buffer, "\n};\n");
|
||||
|
||||
|
|
|
@ -179,11 +179,14 @@ TRI_aql_context_t* TRI_CreateContextAql (TRI_vocbase_t* vocbase,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
context->_vocbase = vocbase;
|
||||
context->_userOptions = userOptions;
|
||||
context->_type = TRI_AQL_QUERY_READ;
|
||||
context->_vocbase = vocbase;
|
||||
context->_userOptions = userOptions;
|
||||
context->_writeCollection = NULL;
|
||||
|
||||
context->_variableIndex = 0;
|
||||
context->_scopeIndex = 0;
|
||||
context->_subQueries = 0;
|
||||
|
||||
// actual bind parameter values
|
||||
res = TRI_InitAssociativePointer(&context->_parameters._values,
|
||||
|
|
|
@ -48,6 +48,19 @@ struct TRI_vocbase_s;
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the type of query to execute
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef enum {
|
||||
TRI_AQL_QUERY_READ,
|
||||
TRI_AQL_QUERY_REMOVE,
|
||||
TRI_AQL_QUERY_SAVE,
|
||||
TRI_AQL_QUERY_UPDATE,
|
||||
TRI_AQL_QUERY_REPLACE
|
||||
}
|
||||
TRI_aql_query_type_e;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the context for parsing a query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -79,10 +92,15 @@ typedef struct TRI_aql_context_s {
|
|||
|
||||
size_t _variableIndex;
|
||||
size_t _scopeIndex;
|
||||
size_t _subQueries;
|
||||
|
||||
TRI_aql_query_type_e _type;
|
||||
char* _writeCollection;
|
||||
|
||||
struct TRI_json_s* _userOptions;
|
||||
bool _fullCount;
|
||||
bool _isCoordinator;
|
||||
bool _writeIgnore;
|
||||
}
|
||||
TRI_aql_context_t;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -57,46 +57,52 @@ extern int Ahuacatldebug;
|
|||
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_INTEGER = 274,
|
||||
T_DOUBLE = 275,
|
||||
T_PARAMETER = 276,
|
||||
T_ASSIGN = 277,
|
||||
T_NOT = 278,
|
||||
T_AND = 279,
|
||||
T_OR = 280,
|
||||
T_EQ = 281,
|
||||
T_NE = 282,
|
||||
T_LT = 283,
|
||||
T_GT = 284,
|
||||
T_LE = 285,
|
||||
T_GE = 286,
|
||||
T_PLUS = 287,
|
||||
T_MINUS = 288,
|
||||
T_TIMES = 289,
|
||||
T_DIV = 290,
|
||||
T_MOD = 291,
|
||||
T_EXPAND = 292,
|
||||
T_QUESTION = 293,
|
||||
T_COLON = 294,
|
||||
T_SCOPE = 295,
|
||||
T_RANGE = 296,
|
||||
T_COMMA = 297,
|
||||
T_OPEN = 298,
|
||||
T_CLOSE = 299,
|
||||
T_DOC_OPEN = 300,
|
||||
T_DOC_CLOSE = 301,
|
||||
T_LIST_OPEN = 302,
|
||||
T_LIST_CLOSE = 303,
|
||||
UMINUS = 304,
|
||||
UPLUS = 305,
|
||||
FUNCCALL = 306,
|
||||
REFERENCE = 307,
|
||||
INDEXED = 308
|
||||
T_FROM = 269,
|
||||
T_IGNORE = 270,
|
||||
T_REMOVE = 271,
|
||||
T_SAVE = 272,
|
||||
T_UPDATE = 273,
|
||||
T_REPLACE = 274,
|
||||
T_NULL = 275,
|
||||
T_TRUE = 276,
|
||||
T_FALSE = 277,
|
||||
T_STRING = 278,
|
||||
T_QUOTED_STRING = 279,
|
||||
T_INTEGER = 280,
|
||||
T_DOUBLE = 281,
|
||||
T_PARAMETER = 282,
|
||||
T_ASSIGN = 283,
|
||||
T_NOT = 284,
|
||||
T_AND = 285,
|
||||
T_OR = 286,
|
||||
T_EQ = 287,
|
||||
T_NE = 288,
|
||||
T_LT = 289,
|
||||
T_GT = 290,
|
||||
T_LE = 291,
|
||||
T_GE = 292,
|
||||
T_PLUS = 293,
|
||||
T_MINUS = 294,
|
||||
T_TIMES = 295,
|
||||
T_DIV = 296,
|
||||
T_MOD = 297,
|
||||
T_EXPAND = 298,
|
||||
T_QUESTION = 299,
|
||||
T_COLON = 300,
|
||||
T_SCOPE = 301,
|
||||
T_RANGE = 302,
|
||||
T_COMMA = 303,
|
||||
T_OPEN = 304,
|
||||
T_CLOSE = 305,
|
||||
T_DOC_OPEN = 306,
|
||||
T_DOC_CLOSE = 307,
|
||||
T_LIST_OPEN = 308,
|
||||
T_LIST_CLOSE = 309,
|
||||
UMINUS = 310,
|
||||
UPLUS = 311,
|
||||
FUNCCALL = 312,
|
||||
REFERENCE = 313,
|
||||
INDEXED = 314
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -112,7 +118,7 @@ union YYSTYPE
|
|||
bool boolval;
|
||||
int64_t intval;
|
||||
|
||||
#line 116 "arangod/Ahuacatl/ahuacatl-grammar.h" /* yacc.c:1909 */
|
||||
#line 122 "arangod/Ahuacatl/ahuacatl-grammar.h" /* yacc.c:1909 */
|
||||
};
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
|
|
@ -71,6 +71,13 @@ void Ahuacatlerror (YYLTYPE* locp, TRI_aql_context_t* const context, const char*
|
|||
%token T_DESC "DESC keyword"
|
||||
%token T_IN "IN keyword"
|
||||
%token T_INTO "INTO keyword"
|
||||
%token T_FROM "FROM keyword"
|
||||
%token T_IGNORE "IGNORE hint"
|
||||
|
||||
%token T_REMOVE "REMOVE command"
|
||||
%token T_SAVE "SAVE command"
|
||||
%token T_UPDATE "UPDATE command"
|
||||
%token T_REPLACE "REPLACE command"
|
||||
|
||||
%token T_NULL "null"
|
||||
%token T_TRUE "true"
|
||||
|
@ -182,6 +189,19 @@ void Ahuacatlerror (YYLTYPE* locp, TRI_aql_context_t* const context, const char*
|
|||
|
||||
query:
|
||||
optional_statement_block_statements return_statement {
|
||||
context->_type = TRI_AQL_QUERY_READ;
|
||||
}
|
||||
| optional_statement_block_statements remove_statement {
|
||||
context->_type = TRI_AQL_QUERY_REMOVE;
|
||||
}
|
||||
| optional_statement_block_statements save_statement {
|
||||
context->_type = TRI_AQL_QUERY_SAVE;
|
||||
}
|
||||
| optional_statement_block_statements update_statement {
|
||||
context->_type = TRI_AQL_QUERY_UPDATE;
|
||||
}
|
||||
| optional_statement_block_statements replace_statement {
|
||||
context->_type = TRI_AQL_QUERY_REPLACE;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -416,11 +436,196 @@ return_statement:
|
|||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
// $$ = node;
|
||||
}
|
||||
;
|
||||
|
||||
remove_statement:
|
||||
T_REMOVE expression T_FROM T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $4);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeRemoveAql(context, $2, coll, false);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
| T_REMOVE T_IGNORE expression T_FROM T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $5);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeRemoveAql(context, $3, coll, true);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
save_statement:
|
||||
T_SAVE expression T_INTO T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $4);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeSaveAql(context, $2, coll, false);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
| T_SAVE T_IGNORE expression T_INTO T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $5);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeSaveAql(context, $3, coll, true);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
update_statement:
|
||||
T_UPDATE expression T_IN T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $4);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeUpdateAql(context, $2, coll, false);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
| T_UPDATE T_IGNORE expression T_IN T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $5);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeUpdateAql(context, $3, coll, true);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
replace_statement:
|
||||
T_REPLACE expression T_IN T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $4);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeReplaceAql(context, $2, coll, false);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
| T_REPLACE T_IGNORE expression T_IN T_STRING {
|
||||
TRI_aql_node_t* coll;
|
||||
TRI_aql_node_t* node;
|
||||
|
||||
coll = TRI_CreateNodeCollectionAql(context, $5);
|
||||
if (coll == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
node = TRI_CreateNodeReplaceAql(context, $3, coll, true);
|
||||
if (node == NULL) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_AppendStatementListAql(context->_statements, node)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
if (! TRI_EndScopeByReturnAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
expression:
|
||||
T_OPEN expression T_CLOSE {
|
||||
|
@ -430,11 +635,16 @@ expression:
|
|||
if (! TRI_StartScopeAql(context, TRI_AQL_SCOPE_SUBQUERY)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
||||
context->_subQueries++;
|
||||
|
||||
} query T_CLOSE {
|
||||
TRI_aql_node_t* result;
|
||||
TRI_aql_node_t* subQuery;
|
||||
TRI_aql_node_t* nameNode;
|
||||
|
||||
context->_subQueries--;
|
||||
|
||||
if (! TRI_EndScopeAql(context)) {
|
||||
ABORT_OOM
|
||||
}
|
||||
|
|
|
@ -48,7 +48,11 @@ bool TRI_IsTopLevelTypeAql (const TRI_aql_node_type_e type) {
|
|||
type == TRI_AQL_NODE_SORT ||
|
||||
type == TRI_AQL_NODE_LIMIT ||
|
||||
type == TRI_AQL_NODE_COLLECT ||
|
||||
type == TRI_AQL_NODE_RETURN) {
|
||||
type == TRI_AQL_NODE_RETURN ||
|
||||
type == TRI_AQL_NODE_REMOVE ||
|
||||
type == TRI_AQL_NODE_SAVE ||
|
||||
type == TRI_AQL_NODE_UPDATE ||
|
||||
type == TRI_AQL_NODE_REPLACE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -110,6 +114,14 @@ const char* TRI_NodeNameAql (const TRI_aql_node_type_e type) {
|
|||
return "filter";
|
||||
case TRI_AQL_NODE_RETURN:
|
||||
return "return";
|
||||
case TRI_AQL_NODE_REMOVE:
|
||||
return "remove";
|
||||
case TRI_AQL_NODE_SAVE:
|
||||
return "save";
|
||||
case TRI_AQL_NODE_UPDATE:
|
||||
return "update";
|
||||
case TRI_AQL_NODE_REPLACE:
|
||||
return "replace";
|
||||
case TRI_AQL_NODE_COLLECT:
|
||||
return "collect";
|
||||
case TRI_AQL_NODE_SORT:
|
||||
|
|
|
@ -142,6 +142,10 @@ typedef enum {
|
|||
TRI_AQL_NODE_LET,
|
||||
TRI_AQL_NODE_FILTER,
|
||||
TRI_AQL_NODE_RETURN,
|
||||
TRI_AQL_NODE_REMOVE,
|
||||
TRI_AQL_NODE_SAVE,
|
||||
TRI_AQL_NODE_UPDATE,
|
||||
TRI_AQL_NODE_REPLACE,
|
||||
TRI_AQL_NODE_COLLECT,
|
||||
TRI_AQL_NODE_SORT,
|
||||
TRI_AQL_NODE_SORT_ELEMENT,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -96,6 +96,30 @@
|
|||
return T_INTO;
|
||||
}
|
||||
|
||||
(?i:FROM) {
|
||||
return T_FROM;
|
||||
}
|
||||
|
||||
(?i:REMOVE) {
|
||||
return T_REMOVE;
|
||||
}
|
||||
|
||||
(?i:SAVE) {
|
||||
return T_SAVE;
|
||||
}
|
||||
|
||||
(?i:UPDATE) {
|
||||
return T_UPDATE;
|
||||
}
|
||||
|
||||
(?i:REPLACE) {
|
||||
return T_REPLACE;
|
||||
}
|
||||
|
||||
(?i:IGNORE) {
|
||||
return T_IGNORE;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* predefined type literals
|
||||
* --------------------------------------------------------------------------- */
|
||||
|
|
|
@ -53,11 +53,6 @@ namespace triagens {
|
|||
// --SECTION-- constructors and destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup ArangoDB
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -66,14 +61,15 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AhuacatlTransaction (struct TRI_vocbase_s* vocbase,
|
||||
TRI_aql_context_t* context) :
|
||||
Transaction<T>(vocbase, TRI_GetIdServer(), false) {
|
||||
TRI_aql_context_t* context)
|
||||
: Transaction<T>(vocbase, TRI_GetIdServer(), false),
|
||||
_context(context) {
|
||||
|
||||
this->addHint(TRI_TRANSACTION_HINT_LOCK_ENTIRELY);
|
||||
|
||||
TRI_vector_pointer_t* collections = &context->_collections;
|
||||
|
||||
const size_t n = collections->_length;
|
||||
size_t const n = collections->_length;
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_aql_collection_t* collection = (TRI_aql_collection_t*) TRI_AtVectorPointer(collections, i);
|
||||
|
@ -109,7 +105,7 @@ namespace triagens {
|
|||
void processCollectionCoordinator (TRI_aql_collection_t* collection) {
|
||||
TRI_voc_cid_t cid = this->resolver()->getCollectionIdCluster(collection->_name);
|
||||
|
||||
this->addCollection(cid, collection->_name, TRI_TRANSACTION_READ);
|
||||
this->addCollection(cid, collection->_name, getCollectionAccessType(collection));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -120,21 +116,41 @@ namespace triagens {
|
|||
TRI_vocbase_col_t const* col = this->resolver()->getCollectionStruct(collection->_name);
|
||||
TRI_voc_cid_t cid = 0;
|
||||
|
||||
if (col != 0) {
|
||||
if (col != nullptr) {
|
||||
cid = col->_cid;
|
||||
}
|
||||
|
||||
int res = this->addCollection(cid, collection->_name, TRI_TRANSACTION_READ);
|
||||
int res = this->addCollection(cid, collection->_name, getCollectionAccessType(collection));
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR && col != 0) {
|
||||
if (res == TRI_ERROR_NO_ERROR && col != nullptr) {
|
||||
collection->_collection = const_cast<TRI_vocbase_col_t*>(col);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
/// @brief determine the access type (read | write) for a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_transaction_type_e getCollectionAccessType (TRI_aql_collection_t const* collection) const {
|
||||
if (_context->_type == TRI_AQL_QUERY_READ ||
|
||||
(_context->_writeCollection != nullptr &&
|
||||
strcmp(collection->_name, _context->_writeCollection) != 0)) {
|
||||
// read-only query or write-query with a different write-to collection
|
||||
return TRI_TRANSACTION_READ;
|
||||
}
|
||||
|
||||
// data-modifying query
|
||||
return TRI_TRANSACTION_WRITE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
|
||||
TRI_aql_context_t* _context;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3364,11 +3364,18 @@ static v8::Handle<v8::Value> ExecuteQueryNativeAhuacatl (TRI_aql_context_t* cont
|
|||
v8::String::New(code, (int) codeLength),
|
||||
TRI_V8_SYMBOL("query"),
|
||||
false);
|
||||
|
||||
trx.finish(TRI_ERROR_NO_ERROR);
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, code);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
// force a rollback
|
||||
trx.abort();
|
||||
}
|
||||
else {
|
||||
// commit / finish
|
||||
trx.finish(TRI_ERROR_NO_ERROR);
|
||||
}
|
||||
|
||||
// return the result as a javascript array
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
|
|
@ -169,6 +169,8 @@
|
|||
"ERROR_QUERY_GEO_INDEX_MISSING" : { "code" : 1570, "message" : "no suitable geo index found for geo restriction on '%s'" },
|
||||
"ERROR_QUERY_FULLTEXT_INDEX_MISSING" : { "code" : 1571, "message" : "no suitable fulltext index found for fulltext query on '%s'" },
|
||||
"ERROR_QUERY_INVALID_DATE_VALUE" : { "code" : 1572, "message" : "invalid date value" },
|
||||
"ERROR_QUERY_MULTI_MODIFY" : { "code" : 1573, "message" : "multi-modify query" },
|
||||
"ERROR_QUERY_MODIFY_IN_SUBQUERY" : { "code" : 1574, "message" : "modify in subquery" },
|
||||
"ERROR_QUERY_FUNCTION_INVALID_NAME" : { "code" : 1580, "message" : "invalid user function name" },
|
||||
"ERROR_QUERY_FUNCTION_INVALID_CODE" : { "code" : 1581, "message" : "invalid user function code" },
|
||||
"ERROR_QUERY_FUNCTION_NOT_FOUND" : { "code" : 1582, "message" : "user function '%s()' not found" },
|
||||
|
@ -207,12 +209,8 @@
|
|||
"ERROR_GRAPH_COULD_NOT_CHANGE_EDGE" : { "code" : 1908, "message" : "could not change edge" },
|
||||
"ERROR_GRAPH_TOO_MANY_ITERATIONS" : { "code" : 1909, "message" : "too many iterations" },
|
||||
"ERROR_GRAPH_INVALID_FILTER_RESULT" : { "code" : 1910, "message" : "invalid filter result" },
|
||||
"ERROR_GRAPH_COLLECTION_MULTI_USE" : { "code" : 1920, "message" : "an edge collection may only be used once in one edge definition of a graph." },
|
||||
"ERROR_GRAPH_COLLECTION_USE_IN_MULTI_GRAPHS" : { "code" : 1921, "message" : " is already used by another graph in a different edge definition." },
|
||||
"ERROR_GRAPH_CREATE_MISSING_NAME" : { "code" : 1922, "message" : "a graph name is required to create a graph." },
|
||||
"ERROR_GRAPH_CREATE_MISSING_EDGE_DEFINITION" : { "code" : 1923, "message" : "at least one edge definition is required to create a graph." },
|
||||
"ERROR_SESSION_UNKNOWN" : { "code" : 1950, "message" : "unknown session" },
|
||||
"ERROR_SESSION_EXPIRED" : { "code" : 1951, "message" : "session expired" },
|
||||
"ERROR_SESSION_UNKNOWN" : { "code" : 1950, "message" : "unknown session" },
|
||||
"ERROR_SESSION_EXPIRED" : { "code" : 1951, "message" : "session expired" },
|
||||
"SIMPLE_CLIENT_UNKNOWN_ERROR" : { "code" : 2000, "message" : "unknown client error" },
|
||||
"SIMPLE_CLIENT_COULD_NOT_CONNECT" : { "code" : 2001, "message" : "could not connect to server" },
|
||||
"SIMPLE_CLIENT_COULD_NOT_WRITE" : { "code" : 2002, "message" : "could not write to server" },
|
||||
|
|
|
@ -169,6 +169,8 @@
|
|||
"ERROR_QUERY_GEO_INDEX_MISSING" : { "code" : 1570, "message" : "no suitable geo index found for geo restriction on '%s'" },
|
||||
"ERROR_QUERY_FULLTEXT_INDEX_MISSING" : { "code" : 1571, "message" : "no suitable fulltext index found for fulltext query on '%s'" },
|
||||
"ERROR_QUERY_INVALID_DATE_VALUE" : { "code" : 1572, "message" : "invalid date value" },
|
||||
"ERROR_QUERY_MULTI_MODIFY" : { "code" : 1573, "message" : "multi-modify query" },
|
||||
"ERROR_QUERY_MODIFY_IN_SUBQUERY" : { "code" : 1574, "message" : "modify in subquery" },
|
||||
"ERROR_QUERY_FUNCTION_INVALID_NAME" : { "code" : 1580, "message" : "invalid user function name" },
|
||||
"ERROR_QUERY_FUNCTION_INVALID_CODE" : { "code" : 1581, "message" : "invalid user function code" },
|
||||
"ERROR_QUERY_FUNCTION_NOT_FOUND" : { "code" : 1582, "message" : "user function '%s()' not found" },
|
||||
|
@ -207,12 +209,8 @@
|
|||
"ERROR_GRAPH_COULD_NOT_CHANGE_EDGE" : { "code" : 1908, "message" : "could not change edge" },
|
||||
"ERROR_GRAPH_TOO_MANY_ITERATIONS" : { "code" : 1909, "message" : "too many iterations" },
|
||||
"ERROR_GRAPH_INVALID_FILTER_RESULT" : { "code" : 1910, "message" : "invalid filter result" },
|
||||
"ERROR_GRAPH_COLLECTION_MULTI_USE" : { "code" : 1920, "message" : "an edge collection may only be used once in one edge definition of a graph." },
|
||||
"ERROR_GRAPH_COLLECTION_USE_IN_MULTI_GRAPHS" : { "code" : 1921, "message" : " is already used by another graph in a different edge definition." },
|
||||
"ERROR_GRAPH_CREATE_MISSING_NAME" : { "code" : 1922, "message" : "a graph name is required to create a graph." },
|
||||
"ERROR_GRAPH_CREATE_MISSING_EDGE_DEFINITION" : { "code" : 1923, "message" : "at least one edge definition is required to create a graph." },
|
||||
"ERROR_SESSION_UNKNOWN" : { "code" : 1950, "message" : "unknown session" },
|
||||
"ERROR_SESSION_EXPIRED" : { "code" : 1951, "message" : "session expired" },
|
||||
"ERROR_SESSION_UNKNOWN" : { "code" : 1950, "message" : "unknown session" },
|
||||
"ERROR_SESSION_EXPIRED" : { "code" : 1951, "message" : "session expired" },
|
||||
"SIMPLE_CLIENT_UNKNOWN_ERROR" : { "code" : 2000, "message" : "unknown client error" },
|
||||
"SIMPLE_CLIENT_COULD_NOT_CONNECT" : { "code" : 2001, "message" : "could not connect to server" },
|
||||
"SIMPLE_CLIENT_COULD_NOT_WRITE" : { "code" : 2002, "message" : "could not write to server" },
|
||||
|
@ -222,7 +220,6 @@
|
|||
"ERROR_ARANGO_INDEX_BITARRAY_INSERT_ITEM_UNSUPPORTED_VALUE" : { "code" : 3413, "message" : "bitarray index insert failure - document attribute value unsupported in index" },
|
||||
"ERROR_ARANGO_INDEX_BITARRAY_CREATION_FAILURE_DUPLICATE_ATTRIBUTES" : { "code" : 3415, "message" : "bitarray index creation failure - one or more index attributes are duplicated." },
|
||||
"ERROR_ARANGO_INDEX_BITARRAY_CREATION_FAILURE_DUPLICATE_VALUES" : { "code" : 3417, "message" : "bitarray index creation failure - one or more index attribute values are duplicated." },
|
||||
"ERROR_APP_ALREADY_EXISTS" : { "code": 4000, "message": "App is already installed" },
|
||||
"RESULT_KEY_EXISTS" : { "code" : 10000, "message" : "element not inserted into structure, because key already exists" },
|
||||
"RESULT_ELEMENT_EXISTS" : { "code" : 10001, "message" : "element not inserted into structure, because it already exists" },
|
||||
"RESULT_KEY_NOT_FOUND" : { "code" : 10002, "message" : "key not found in structure" },
|
||||
|
|
|
@ -465,6 +465,166 @@ function COMPILE_REGEX (regex, modifiers) {
|
|||
return new RegExp('^' + pattern + '$', modifiers);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief remove a document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function REMOVE_DOCUMENT (ops, document) {
|
||||
"use strict";
|
||||
|
||||
var weight = TYPEWEIGHT(document);
|
||||
if (weight === TYPEWEIGHT_STRING) {
|
||||
ops.push(document);
|
||||
return;
|
||||
}
|
||||
if (weight === TYPEWEIGHT_DOCUMENT &&
|
||||
document.hasOwnProperty("_key")) {
|
||||
ops.push(document._key);
|
||||
return;
|
||||
}
|
||||
|
||||
THROW(INTERNAL.errors.ERROR_ARANGO_DOCUMENT_KEY_MISSING);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief save a document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function SAVE_DOCUMENT (ops, document) {
|
||||
"use strict";
|
||||
|
||||
if (TYPEWEIGHT(document) === TYPEWEIGHT_DOCUMENT) {
|
||||
ops.push(document);
|
||||
return;
|
||||
}
|
||||
|
||||
THROW(INTERNAL.errors.ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief update a document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function UPDATE_DOCUMENT (ops, document) {
|
||||
"use strict";
|
||||
|
||||
if (TYPEWEIGHT(document) === TYPEWEIGHT_DOCUMENT &&
|
||||
document.hasOwnProperty("_key")) {
|
||||
ops.push(document);
|
||||
return;
|
||||
}
|
||||
|
||||
THROW(INTERNAL.errors.ERROR_ARANGO_DOCUMENT_KEY_MISSING);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute buffered remove operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function EXECUTE_REMOVE (ops, collection, ignore) {
|
||||
var removed = 0, i, n = ops.length, c = COLLECTION(collection);
|
||||
|
||||
if (ignore) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
try {
|
||||
c.remove(ops[i]);
|
||||
++removed;
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < n; ++i) {
|
||||
c.remove(ops[i]);
|
||||
++removed;
|
||||
}
|
||||
}
|
||||
|
||||
return { total: n, executed: removed };
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute buffered save operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function EXECUTE_SAVE (ops, collection, ignore) {
|
||||
var saved = 0, i, n = ops.length, c = COLLECTION(collection);
|
||||
|
||||
if (ignore) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
try {
|
||||
c.save(ops[i]);
|
||||
++saved;
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < n; ++i) {
|
||||
c.save(ops[i]);
|
||||
++saved;
|
||||
}
|
||||
}
|
||||
|
||||
return { total: n, executed: saved };
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute buffered update operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function EXECUTE_UPDATE (ops, collection, ignore) {
|
||||
var updated = 0, i, n = ops.length, c = COLLECTION(collection);
|
||||
|
||||
if (ignore) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
try {
|
||||
c.update(ops[i]._key, ops[i]);
|
||||
++updated;
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < n; ++i) {
|
||||
c.update(ops[i]._key, ops[i]);
|
||||
++updated;
|
||||
}
|
||||
}
|
||||
|
||||
return { total: n, executed: updated };
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute buffered replace operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function EXECUTE_REPLACE (ops, collection, ignore) {
|
||||
var replaced = 0, i, n = ops.length, c = COLLECTION(collection);
|
||||
|
||||
if (ignore) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
try {
|
||||
c.replace(ops[i]._key, ops[i]);
|
||||
++replaced;
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < n; ++i) {
|
||||
c.replace(ops[i]._key, ops[i]);
|
||||
++replaced;
|
||||
}
|
||||
}
|
||||
|
||||
return { total: n, executed: removed };
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief call a function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -5680,6 +5840,13 @@ function GENERAL_GRAPH_DIAMETER (graphName, options) {
|
|||
// --SECTION-- MODULE EXPORTS
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
exports.REMOVE_DOCUMENT = REMOVE_DOCUMENT;
|
||||
exports.SAVE_DOCUMENT = SAVE_DOCUMENT;
|
||||
exports.UPDATE_DOCUMENT = UPDATE_DOCUMENT;
|
||||
exports.EXECUTE_REMOVE = EXECUTE_REMOVE;
|
||||
exports.EXECUTE_SAVE = EXECUTE_SAVE;
|
||||
exports.EXECUTE_UPDATE = EXECUTE_UPDATE;
|
||||
exports.EXECUTE_REPLACE = EXECUTE_REPLACE;
|
||||
exports.FCALL = FCALL;
|
||||
exports.FCALL_USER = FCALL_USER;
|
||||
exports.KEYS = KEYS;
|
||||
|
|
|
@ -209,6 +209,8 @@ ERROR_QUERY_FAIL_CALLED,1569,"FAIL(%s) called","Will be raised when the function
|
|||
ERROR_QUERY_GEO_INDEX_MISSING,1570,"no suitable geo index found for geo restriction on '%s'","Will be raised when a geo restriction was specified but no suitable geo index is found to resolve it."
|
||||
ERROR_QUERY_FULLTEXT_INDEX_MISSING,1571,"no suitable fulltext index found for fulltext query on '%s'","Will be raised when a fulltext query is performed on a collection without a suitable fulltext index."
|
||||
ERROR_QUERY_INVALID_DATE_VALUE,1572,"invalid date value","Will be raised when a value cannot be converted to a date."
|
||||
ERROR_QUERY_MULTI_MODIFY,1573,"multi-modify query", "Will be raised when an AQL query contains more than one data-modifying operation."
|
||||
ERROR_QUERY_MODIFY_IN_SUBQUERY,1574,"modify in subquery", "Will be raised when an AQL query contains a data-modifying operation inside a subquery."
|
||||
|
||||
################################################################################
|
||||
## AQL user functions
|
||||
|
|
|
@ -165,6 +165,8 @@ void TRI_InitialiseErrorMessages (void) {
|
|||
REG_ERROR(ERROR_QUERY_GEO_INDEX_MISSING, "no suitable geo index found for geo restriction on '%s'");
|
||||
REG_ERROR(ERROR_QUERY_FULLTEXT_INDEX_MISSING, "no suitable fulltext index found for fulltext query on '%s'");
|
||||
REG_ERROR(ERROR_QUERY_INVALID_DATE_VALUE, "invalid date value");
|
||||
REG_ERROR(ERROR_QUERY_MULTI_MODIFY, "multi-modify query");
|
||||
REG_ERROR(ERROR_QUERY_MODIFY_IN_SUBQUERY, "modify in subquery");
|
||||
REG_ERROR(ERROR_QUERY_FUNCTION_INVALID_NAME, "invalid user function name");
|
||||
REG_ERROR(ERROR_QUERY_FUNCTION_INVALID_CODE, "invalid user function code");
|
||||
REG_ERROR(ERROR_QUERY_FUNCTION_NOT_FOUND, "user function '%s()' not found");
|
||||
|
|
|
@ -395,6 +395,12 @@ extern "C" {
|
|||
/// a suitable fulltext index.
|
||||
/// - 1572: @LIT{invalid date value}
|
||||
/// Will be raised when a value cannot be converted to a date.
|
||||
/// - 1573: @LIT{multi-modify query}
|
||||
/// "Will be raised when an AQL query contains more than one data-modifying
|
||||
/// operation."
|
||||
/// - 1574: @LIT{modify in subquery}
|
||||
/// "Will be raised when an AQL query contains a data-modifying operation
|
||||
/// inside a subquery."
|
||||
/// - 1580: @LIT{invalid user function name}
|
||||
/// Will be raised when a user function with an invalid name is registered.
|
||||
/// - 1581: @LIT{invalid user function code}
|
||||
|
@ -2142,6 +2148,28 @@ void TRI_InitialiseErrorMessages (void);
|
|||
|
||||
#define TRI_ERROR_QUERY_INVALID_DATE_VALUE (1572)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1573: ERROR_QUERY_MULTI_MODIFY
|
||||
///
|
||||
/// multi-modify query
|
||||
///
|
||||
/// "Will be raised when an AQL query contains more than one data-modifying
|
||||
/// operation."
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_MULTI_MODIFY (1573)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1574: ERROR_QUERY_MODIFY_IN_SUBQUERY
|
||||
///
|
||||
/// modify in subquery
|
||||
///
|
||||
/// "Will be raised when an AQL query contains a data-modifying operation
|
||||
/// inside a subquery."
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TRI_ERROR_QUERY_MODIFY_IN_SUBQUERY (1574)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief 1580: ERROR_QUERY_FUNCTION_INVALID_NAME
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue