mirror of https://gitee.com/bigwinds/arangodb
stringification of function parameters
This commit is contained in:
parent
720285acfe
commit
8e229ec2b2
|
@ -1025,6 +1025,7 @@ namespace triagens {
|
|||
AggregateNode (std::vector<std::pair<Variable const*, Variable const*>> aggregateVariables,
|
||||
Variable const* outVariable)
|
||||
: ExecutionNode(), _aggregateVariables(aggregateVariables), _outVariable(outVariable) {
|
||||
// outVariable can be a nullptr
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1068,7 +1069,7 @@ namespace triagens {
|
|||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief input/output variables for the aggregation (out = in)
|
||||
/// @brief input/output variables for the aggregation (out, in)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<std::pair<Variable const*, Variable const*>> _aggregateVariables;
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Aql, built-in AQL function
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Aql/Function.h"
|
||||
#include "Utils/Exception.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Function::Function (std::string const& name,
|
||||
std::string const& arguments,
|
||||
bool isDeterministic)
|
||||
: name(name),
|
||||
arguments(arguments),
|
||||
isDeterministic(isDeterministic),
|
||||
containsCollectionParameter(false) {
|
||||
|
||||
initArguments();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Function::~Function () {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not a positional argument needs to be converted from a
|
||||
/// collection parameter to a collection name parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Function::mustConvertArgument (size_t position) const {
|
||||
bool foundArg = false;
|
||||
size_t i = 0;
|
||||
char const* p = arguments.c_str();
|
||||
|
||||
while (true) {
|
||||
char const c = *p++;
|
||||
|
||||
switch (c) {
|
||||
case '\0':
|
||||
return false;
|
||||
|
||||
case '|':
|
||||
case ',':
|
||||
if (foundArg) {
|
||||
if (++i > position) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foundArg = false;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
if (i == position) {
|
||||
// found an argument to convert
|
||||
return true;
|
||||
}
|
||||
foundArg = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
foundArg = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse the argument list and set the minimum and maximum number of
|
||||
/// arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Function::initArguments () {
|
||||
minRequiredArguments = maxRequiredArguments = 0;
|
||||
|
||||
// setup some parsing state
|
||||
bool inOptional = false;
|
||||
bool foundArg = false;
|
||||
|
||||
char const* p = arguments.c_str();
|
||||
while (true) {
|
||||
char const c = *p++;
|
||||
|
||||
switch (c) {
|
||||
case '\0':
|
||||
// end of argument list
|
||||
if (foundArg) {
|
||||
if (! inOptional) {
|
||||
++minRequiredArguments;
|
||||
}
|
||||
++maxRequiredArguments;
|
||||
}
|
||||
return;
|
||||
|
||||
case '|':
|
||||
// beginning of optional arguments
|
||||
TRI_ASSERT(! inOptional);
|
||||
if (foundArg) {
|
||||
++minRequiredArguments;
|
||||
++maxRequiredArguments;
|
||||
}
|
||||
inOptional = true;
|
||||
foundArg = false;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
// next argument
|
||||
TRI_ASSERT(foundArg);
|
||||
|
||||
if (! inOptional) {
|
||||
++minRequiredArguments;
|
||||
}
|
||||
++maxRequiredArguments;
|
||||
foundArg = false;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
// repeated optional argument
|
||||
TRI_ASSERT(inOptional);
|
||||
maxRequiredArguments = MaxArguments;
|
||||
return;
|
||||
|
||||
default:
|
||||
if (c == 'h') {
|
||||
// note that we found a collection parameter
|
||||
containsCollectionParameter = true;
|
||||
}
|
||||
foundArg = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -1,5 +1,5 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Aql, built-in function
|
||||
/// @brief Aql, built-in AQL function
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
|
@ -43,19 +43,20 @@ namespace triagens {
|
|||
|
||||
Function () = delete;
|
||||
|
||||
Function (std::string const& name,
|
||||
std::string const& arguments,
|
||||
bool isDeterministic)
|
||||
: name(name),
|
||||
arguments(arguments),
|
||||
isDeterministic(isDeterministic) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
initArguments();
|
||||
}
|
||||
Function (std::string const&,
|
||||
std::string const&,
|
||||
bool);
|
||||
|
||||
~Function () {
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~Function ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -77,67 +78,20 @@ namespace triagens {
|
|||
return std::make_pair(minRequiredArguments, maxRequiredArguments);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not a positional argument needs to be converted from a
|
||||
/// collection parameter to a collection name parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool mustConvertArgument (size_t) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse the argument list and set the minimum and maximum number of
|
||||
/// arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void initArguments () {
|
||||
minRequiredArguments = maxRequiredArguments = 0;
|
||||
|
||||
// setup some parsing state
|
||||
bool inOptional = false;
|
||||
bool foundArg = false;
|
||||
|
||||
char const* p = arguments.c_str();
|
||||
while (true) {
|
||||
char const c = *p++;
|
||||
|
||||
switch (c) {
|
||||
case '\0':
|
||||
// end of argument list
|
||||
if (foundArg) {
|
||||
if (! inOptional) {
|
||||
++minRequiredArguments;
|
||||
}
|
||||
++maxRequiredArguments;
|
||||
}
|
||||
return;
|
||||
|
||||
case '|':
|
||||
// beginning of optional arguments
|
||||
TRI_ASSERT(! inOptional);
|
||||
if (foundArg) {
|
||||
++minRequiredArguments;
|
||||
++maxRequiredArguments;
|
||||
}
|
||||
inOptional = true;
|
||||
foundArg = false;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
// next argument
|
||||
TRI_ASSERT(foundArg);
|
||||
|
||||
if (! inOptional) {
|
||||
++minRequiredArguments;
|
||||
}
|
||||
++maxRequiredArguments;
|
||||
foundArg = false;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
// repeated optional argument
|
||||
TRI_ASSERT(inOptional);
|
||||
maxRequiredArguments = MaxArguments;
|
||||
return;
|
||||
|
||||
default:
|
||||
foundArg = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initArguments ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -161,6 +115,13 @@ namespace triagens {
|
|||
|
||||
bool const isDeterministic;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the function contains a collection parameter that
|
||||
/// will cause some special conversion during function calls
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool containsCollectionParameter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief minimum number of required arguments
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -404,6 +404,18 @@ void V8Executor::generateCodeExpression (AstNode const* node) {
|
|||
_buffer->appendText("; })");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generates code for a string value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void V8Executor::generateCodeString (char const* value) {
|
||||
TRI_ASSERT(value != nullptr);
|
||||
|
||||
_buffer->appendChar('"');
|
||||
_buffer->appendJsonEncoded(value);
|
||||
_buffer->appendChar('"');
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate JavaScript code for a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -440,11 +452,12 @@ void V8Executor::generateCodeArray (AstNode const* node) {
|
|||
}
|
||||
|
||||
auto member = node->getMember(i);
|
||||
|
||||
_buffer->appendText("\"");
|
||||
_buffer->appendJsonEncoded(member->getStringValue());
|
||||
_buffer->appendText("\" : ");
|
||||
generateCodeNode(member->getMember(0));
|
||||
|
||||
if (member != nullptr) {
|
||||
generateCodeString(member->getStringValue());
|
||||
_buffer->appendText(" : ");
|
||||
generateCodeNode(member->getMember(0));
|
||||
}
|
||||
}
|
||||
_buffer->appendText(" }");
|
||||
}
|
||||
|
@ -547,9 +560,9 @@ void V8Executor::generateCodeReference (AstNode const* node) {
|
|||
|
||||
auto variable = static_cast<Variable*>(node->getData());
|
||||
|
||||
_buffer->appendText("vars[\"");
|
||||
_buffer->appendJsonEncoded(variable->name.c_str());
|
||||
_buffer->appendText("\"]");
|
||||
_buffer->appendText("vars[");
|
||||
generateCodeString(variable->name.c_str());
|
||||
_buffer->appendText("]");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -561,10 +574,10 @@ void V8Executor::generateCodeVariable (AstNode const* node) {
|
|||
TRI_ASSERT(node->numMembers() == 0);
|
||||
|
||||
auto variable = static_cast<Variable*>(node->getData());
|
||||
|
||||
_buffer->appendText("vars[\"");
|
||||
_buffer->appendJsonEncoded(variable->name.c_str());
|
||||
_buffer->appendText("\"]");
|
||||
|
||||
_buffer->appendText("vars[");
|
||||
generateCodeString(variable->name.c_str());
|
||||
_buffer->appendText("]");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -577,9 +590,9 @@ void V8Executor::generateCodeCollection (AstNode const* node) {
|
|||
|
||||
char const* name = node->getStringValue();
|
||||
|
||||
_buffer->appendText("aql.GET_DOCUMENTS(\"");
|
||||
_buffer->appendJsonEncoded(name);
|
||||
_buffer->appendText("\")");
|
||||
_buffer->appendText("aql.GET_DOCUMENTS(");
|
||||
generateCodeString(name);
|
||||
_buffer->appendText(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -606,7 +619,20 @@ void V8Executor::generateCodeFunctionCall (AstNode const* node) {
|
|||
_buffer->appendText(", ");
|
||||
}
|
||||
|
||||
generateCodeNode(args->getMember(i));
|
||||
auto member = args->getMember(i);
|
||||
|
||||
if (member != nullptr) {
|
||||
if (member->type == NODE_TYPE_COLLECTION &&
|
||||
func->containsCollectionParameter) {
|
||||
// do a parameter conversion from a collection parameter to a collection name parameter
|
||||
char const* name = member->getStringValue();
|
||||
generateCodeString(name);
|
||||
}
|
||||
else {
|
||||
// generate regular code for the node
|
||||
generateCodeNode(args->getMember(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
_buffer->appendText(")");
|
||||
}
|
||||
|
@ -626,9 +652,9 @@ void V8Executor::generateCodeUserFunctionCall (AstNode const* node) {
|
|||
TRI_ASSERT(args != nullptr);
|
||||
TRI_ASSERT(args->type == NODE_TYPE_LIST);
|
||||
|
||||
_buffer->appendText("aql.FCALL_USER(\"");
|
||||
_buffer->appendJsonEncoded(name);
|
||||
_buffer->appendText("\", [");
|
||||
_buffer->appendText("aql.FCALL_USER(");
|
||||
generateCodeString(name);
|
||||
_buffer->appendText(", [");
|
||||
|
||||
size_t const n = args->numMembers();
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
|
@ -693,9 +719,9 @@ void V8Executor::generateCodeNamedAccess (AstNode const* node) {
|
|||
|
||||
_buffer->appendText("aql.DOCUMENT_MEMBER(");
|
||||
generateCodeNode(node->getMember(0));
|
||||
_buffer->appendText(", \"");
|
||||
_buffer->appendJsonEncoded(node->getStringValue());
|
||||
_buffer->appendText("\")");
|
||||
_buffer->appendText(", ");
|
||||
generateCodeString(node->getStringValue());
|
||||
_buffer->appendText(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -114,6 +114,12 @@ namespace triagens {
|
|||
|
||||
void generateCodeExpression (AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generates code for a string value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void generateCodeString (char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate JavaScript code for a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Aql, V8 expression
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Aql/V8Expression.h"
|
||||
#include "Aql/V8Executor.h"
|
||||
#include "BasicsC/json.h"
|
||||
#include "V8/v8-conv.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the v8 expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
V8Expression::V8Expression (v8::Isolate* isolate,
|
||||
v8::Persistent<v8::Function> func)
|
||||
: isolate(isolate),
|
||||
func(func) {
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the v8 expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
V8Expression::~V8Expression () {
|
||||
func.Dispose(isolate);
|
||||
func.Clear();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute the expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue V8Expression::execute (AQL_TRANSACTION_V8* trx,
|
||||
std::vector<TRI_document_collection_t const*>& docColls,
|
||||
std::vector<AqlValue>& argv,
|
||||
size_t startPos,
|
||||
std::vector<Variable*> const& vars,
|
||||
std::vector<RegisterId> const& regs) {
|
||||
size_t const n = vars.size();
|
||||
TRI_ASSERT(regs.size() == n); // assert same vector length
|
||||
|
||||
v8::Handle<v8::Object> values = v8::Object::New();
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
auto varname = vars[i]->name;
|
||||
auto reg = regs[i];
|
||||
|
||||
TRI_ASSERT(! argv[reg].isEmpty());
|
||||
|
||||
values->Set(v8::String::New(varname.c_str(), (int) varname.size()), argv[startPos + reg].toV8(trx, docColls[reg]));
|
||||
}
|
||||
|
||||
// set function arguments
|
||||
v8::Handle<v8::Value> args[] = { values };
|
||||
|
||||
// execute the function
|
||||
v8::TryCatch tryCatch;
|
||||
v8::Handle<v8::Value> result = func->Call(func, 1, args);
|
||||
|
||||
V8Executor::HandleV8Error(tryCatch, result);
|
||||
|
||||
TRI_json_t* json = TRI_ObjectToJson(result);
|
||||
|
||||
if (json == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return AqlValue(new triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, json));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -1,5 +1,5 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Aql, V8 execution context
|
||||
/// @brief Aql, V8 expression
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
|
@ -31,10 +31,7 @@
|
|||
#define ARANGODB_AQL_V8_EXPRESSION_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "BasicsC/json.h"
|
||||
#include "Aql/Types.h"
|
||||
#include "V8/v8-conv.h"
|
||||
#include <v8.h>
|
||||
|
||||
namespace triagens {
|
||||
|
@ -46,73 +43,46 @@ namespace triagens {
|
|||
|
||||
struct V8Expression {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create the v8 expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
V8Expression (v8::Isolate* isolate,
|
||||
v8::Persistent<v8::Function> func)
|
||||
: isolate(isolate),
|
||||
func(func) {
|
||||
}
|
||||
V8Expression (v8::Isolate*,
|
||||
v8::Persistent<v8::Function>);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the v8 expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~V8Expression () {
|
||||
func.Dispose(isolate);
|
||||
func.Clear();
|
||||
}
|
||||
~V8Expression ();
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute the expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AqlValue execute (AQL_TRANSACTION_V8* trx,
|
||||
std::vector<TRI_document_collection_t const*>& docColls,
|
||||
std::vector<AqlValue>& argv,
|
||||
size_t startPos,
|
||||
std::vector<Variable*> const& vars,
|
||||
std::vector<RegisterId> const& regs) {
|
||||
// TODO: decide whether a separate handle scope is needed
|
||||
AqlValue execute (AQL_TRANSACTION_V8*,
|
||||
std::vector<TRI_document_collection_t const*>&,
|
||||
std::vector<AqlValue>&,
|
||||
size_t,
|
||||
std::vector<Variable*> const&,
|
||||
std::vector<RegisterId> const&);
|
||||
|
||||
size_t const n = vars.size();
|
||||
TRI_ASSERT(regs.size() == n); // assert same vector length
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
v8::Handle<v8::Object> values = v8::Object::New();
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
auto varname = vars[i]->name;
|
||||
auto reg = regs[i];
|
||||
v8::Isolate* isolate;
|
||||
|
||||
TRI_ASSERT(! argv[reg].isEmpty());
|
||||
|
||||
values->Set(v8::String::New(varname.c_str(), (int) varname.size()), argv[startPos + reg].toV8(trx, docColls[reg]));
|
||||
}
|
||||
|
||||
// set function arguments
|
||||
v8::Handle<v8::Value> args[] = { values };
|
||||
|
||||
// execute the function
|
||||
v8::TryCatch tryCatch;
|
||||
v8::Handle<v8::Value> result = func->Call(func, 1, args);
|
||||
v8::Persistent<v8::Function> func;
|
||||
|
||||
V8Executor::HandleV8Error(tryCatch, result);
|
||||
|
||||
TRI_json_t* json = TRI_ObjectToJson(result);
|
||||
|
||||
if (json == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return AqlValue(new triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, json));
|
||||
}
|
||||
|
||||
|
||||
v8::Isolate* isolate;
|
||||
|
||||
v8::Persistent<v8::Function> func;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ add_executable(
|
|||
Aql/ExecutionNode.cpp
|
||||
Aql/ExecutionPlan.cpp
|
||||
Aql/Expression.cpp
|
||||
Aql/Function.cpp
|
||||
Aql/grammar.cpp
|
||||
Aql/Parser.cpp
|
||||
Aql/Query.cpp
|
||||
|
@ -72,6 +73,7 @@ add_executable(
|
|||
Aql/Types.cpp
|
||||
Aql/tokens.cpp
|
||||
Aql/V8Executor.cpp
|
||||
Aql/V8Expression.cpp
|
||||
Aql/Variable.cpp
|
||||
Aql/VariableGenerator.cpp
|
||||
BitIndexes/bitarray.cpp
|
||||
|
|
|
@ -46,6 +46,7 @@ arangod_libarangod_a_SOURCES = \
|
|||
arangod/Aql/ExecutionNode.cpp \
|
||||
arangod/Aql/ExecutionPlan.cpp \
|
||||
arangod/Aql/Expression.cpp \
|
||||
arangod/Aql/Function.cpp \
|
||||
arangod/Aql/grammar.cpp \
|
||||
arangod/Aql/Parser.cpp \
|
||||
arangod/Aql/Query.cpp \
|
||||
|
@ -53,6 +54,7 @@ arangod_libarangod_a_SOURCES = \
|
|||
arangod/Aql/Types.cpp \
|
||||
arangod/Aql/tokens.cpp \
|
||||
arangod/Aql/V8Executor.cpp \
|
||||
arangod/Aql/V8Expression.cpp \
|
||||
arangod/Aql/Variable.cpp \
|
||||
arangod/Aql/VariableGenerator.cpp \
|
||||
arangod/BitIndexes/bitarray.cpp \
|
||||
|
|
Loading…
Reference in New Issue