1
0
Fork 0

Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2

This commit is contained in:
Max Neunhoeffer 2014-07-29 13:41:37 +02:00
commit 1de4492bec
12 changed files with 558 additions and 10 deletions

View File

@ -29,6 +29,7 @@
#include "Aql/AstNode.h" #include "Aql/AstNode.h"
#include "Aql/Scopes.h" #include "Aql/Scopes.h"
#include "Basics/StringBuffer.h"
using namespace triagens::aql; using namespace triagens::aql;
@ -310,6 +311,105 @@ std::string AstNode::typeString () const {
return ""; return "";
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief stringify the node into a string buffer
////////////////////////////////////////////////////////////////////////////////
void AstNode::append (triagens::basics::StringBuffer* buffer) const {
if (type == NODE_TYPE_VALUE) {
appendValue(buffer);
return;
}
if (type == NODE_TYPE_LIST) {
buffer->appendText("[ ");
size_t const n = numMembers();
for (size_t i = 0; i < n; ++i) {
if (i > 0) {
buffer->appendText(", ");
}
AstNode* member = getMember(i);
if (member != nullptr) {
member->append(buffer);
}
}
buffer->appendText(" ]");
return;
}
if (type == NODE_TYPE_ARRAY) {
buffer->appendText("{ ");
size_t const n = numMembers();
for (size_t i = 0; i < n; ++i) {
if (i > 0) {
buffer->appendText(", ");
}
AstNode* member = getMember(i);
if (member != nullptr) {
TRI_ASSERT(member->type == NODE_TYPE_ARRAY_ELEMENT);
TRI_ASSERT(member->numMembers() == 1);
buffer->appendChar('"');
buffer->appendJsonEncoded(member->getStringValue());
buffer->appendText("\" : ");
member->getMember(0)->append(buffer);
}
}
buffer->appendText(" }");
return;
}
}
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief stringify the value of a node into a string buffer
////////////////////////////////////////////////////////////////////////////////
void AstNode::appendValue (triagens::basics::StringBuffer* buffer) const {
TRI_ASSERT(type == NODE_TYPE_VALUE);
switch (value.type) {
case VALUE_TYPE_BOOL: {
if (value.value._bool) {
buffer->appendText("true", 4);
}
else {
buffer->appendText("false", 5);
}
break;
}
case VALUE_TYPE_INT: {
buffer->appendInteger(value.value._int);
break;
}
case VALUE_TYPE_DOUBLE: {
buffer->appendDecimal(value.value._double);
break;
}
case VALUE_TYPE_STRING: {
buffer->appendChar('"');
buffer->appendJsonEncoded(value.value._string);
buffer->appendChar('"');
break;
}
case VALUE_TYPE_NULL:
default: {
buffer->appendText("null", 4);
break;
}
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE // --SECTION-- END-OF-FILE
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -36,6 +36,10 @@
#include "Utils/Exception.h" #include "Utils/Exception.h"
namespace triagens { namespace triagens {
namespace basics {
class StringBuffer;
}
namespace aql { namespace aql {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -351,6 +355,22 @@ namespace triagens {
std::string typeString () const; std::string typeString () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief stringify the node into a string buffer
////////////////////////////////////////////////////////////////////////////////
void append (triagens::basics::StringBuffer*) const;
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief stringify the value of a node into a string buffer
////////////////////////////////////////////////////////////////////////////////
void appendValue (triagens::basics::StringBuffer*) const;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public variables // --SECTION-- public variables
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -56,7 +56,7 @@ Parser::Parser (Query* query)
Aqllex_init(&_scanner); Aqllex_init(&_scanner);
Aqlset_extra(this, _scanner); Aqlset_extra(this, _scanner);
_ast = new QueryAst(this); _ast = new QueryAst(query, this);
_stack.reserve(16); _stack.reserve(16);
} }

View File

@ -29,6 +29,7 @@
#include "Aql/Query.h" #include "Aql/Query.h"
#include "Aql/Parser.h" #include "Aql/Parser.h"
#include "Aql/V8Executor.h"
#include "BasicsC/json.h" #include "BasicsC/json.h"
#include "Utils/Exception.h" #include "Utils/Exception.h"
#include "VocBase/vocbase.h" #include "VocBase/vocbase.h"
@ -50,11 +51,14 @@ Query::Query (TRI_vocbase_t* vocbase,
size_t queryLength, size_t queryLength,
TRI_json_t* bindParameters) TRI_json_t* bindParameters)
: _vocbase(vocbase), : _vocbase(vocbase),
_executor(nullptr),
_queryString(queryString), _queryString(queryString),
_queryLength(queryLength), _queryLength(queryLength),
_type(AQL_QUERY_READ), _type(AQL_QUERY_READ),
_bindParameters(bindParameters), _bindParameters(bindParameters),
_error() { _error() {
TRI_ASSERT(_vocbase != nullptr);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -62,6 +66,10 @@ Query::Query (TRI_vocbase_t* vocbase,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Query::~Query () { Query::~Query () {
if (_executor != nullptr) {
delete _executor;
_executor = nullptr;
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -209,6 +217,19 @@ ParseResult Query::parse () {
void Query::explain () { void Query::explain () {
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief get v8 executor
////////////////////////////////////////////////////////////////////////////////
V8Executor* Query::getExecutor () {
if (_executor == nullptr) {
_executor = new V8Executor;
}
TRI_ASSERT(_executor != nullptr);
return _executor;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE // --SECTION-- END-OF-FILE
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -42,6 +42,8 @@ struct TRI_vocbase_s;
namespace triagens { namespace triagens {
namespace aql { namespace aql {
class V8Executor;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public types // --SECTION-- public types
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -165,6 +167,12 @@ namespace triagens {
void explain (); void explain ();
////////////////////////////////////////////////////////////////////////////////
/// @brief get v8 executor
////////////////////////////////////////////////////////////////////////////////
V8Executor* getExecutor ();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private methods // --SECTION-- private methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -179,6 +187,8 @@ namespace triagens {
struct TRI_vocbase_s* _vocbase; struct TRI_vocbase_s* _vocbase;
V8Executor* _executor;
char const* _queryString; char const* _queryString;
size_t const _queryLength; size_t const _queryLength;
QueryType _type; QueryType _type;

View File

@ -29,12 +29,23 @@
#include "Aql/QueryAst.h" #include "Aql/QueryAst.h"
#include "Aql/Parser.h" #include "Aql/Parser.h"
#include "Aql/V8Executor.h"
#include "BasicsC/tri-strings.h" #include "BasicsC/tri-strings.h"
#include "Utils/Exception.h" #include "Utils/Exception.h"
#include "VocBase/collection.h" #include "VocBase/collection.h"
using namespace triagens::aql; using namespace triagens::aql;
std::unordered_map<int, std::string> const QueryAst::FunctionNames{
{ static_cast<int>(NODE_TYPE_OPERATOR_BINARY_EQ), "EQUAL" },
{ static_cast<int>(NODE_TYPE_OPERATOR_BINARY_NE), "UNEQUAL" },
{ static_cast<int>(NODE_TYPE_OPERATOR_BINARY_GT), "GREATER" },
{ static_cast<int>(NODE_TYPE_OPERATOR_BINARY_GE), "GREATEREQUAL" },
{ static_cast<int>(NODE_TYPE_OPERATOR_BINARY_LT), "LESS" },
{ static_cast<int>(NODE_TYPE_OPERATOR_BINARY_LE), "LESSEQUAL" },
{ static_cast<int>(NODE_TYPE_OPERATOR_BINARY_IN), "IN" }
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors // --SECTION-- constructors / destructors
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -43,8 +54,10 @@ using namespace triagens::aql;
/// @brief create the AST /// @brief create the AST
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
QueryAst::QueryAst (Parser* parser) QueryAst::QueryAst (Query* query,
: _parser(parser), Parser* parser)
: _query(query),
_parser(parser),
_nodes(), _nodes(),
_strings(), _strings(),
_scopes(), _scopes(),
@ -55,6 +68,9 @@ QueryAst::QueryAst (Parser* parser)
_writeOptions(nullptr), _writeOptions(nullptr),
_nopNode() { _nopNode() {
TRI_ASSERT(_query != nullptr);
TRI_ASSERT(_parser != nullptr);
_nodes.reserve(32); _nodes.reserve(32);
_root = createNode(NODE_TYPE_ROOT); _root = createNode(NODE_TYPE_ROOT);
} }
@ -656,6 +672,7 @@ AstNode* QueryAst::createNodeRange (AstNode const* start,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AstNode* QueryAst::createNodeNop () { AstNode* QueryAst::createNodeNop () {
// the nop node is a singleton inside a query
if (_nopNode == nullptr) { if (_nopNode == nullptr) {
_nopNode = createNode(NODE_TYPE_NOP); _nopNode = createNode(NODE_TYPE_NOP);
} }
@ -787,6 +804,35 @@ void QueryAst::optimize () {
// --SECTION-- private methods // --SECTION-- private methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a comparison function using two constant values
////////////////////////////////////////////////////////////////////////////////
AstNode* QueryAst::executeConstComparison (std::string const& func,
AstNode const* lhs,
AstNode const* rhs) {
TRI_json_t* result = _query->getExecutor()->executeComparison(func, lhs, rhs);
if (result == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
AstNode* node = nullptr;
try {
node = nodeFromJson(result);
}
catch (...) {
}
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, result);
if (node == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
return node;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief optimizes a FILTER node /// @brief optimizes a FILTER node
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -808,10 +854,12 @@ AstNode* QueryAst::optimizeFilter (AstNode* node) {
} }
if (operand->getBoolValue()) { if (operand->getBoolValue()) {
// FILTER is always true, optimise it away // FILTER is always true, optimize it away
return createNodeNop(); return createNodeNop();
} }
// TODO: optimize FILTERs that are always false
return node; return node;
} }
@ -970,13 +1018,29 @@ AstNode* QueryAst::optimizeBinaryOperatorRelational (AstNode* node) {
if (lhs == nullptr || rhs == nullptr) { if (lhs == nullptr || rhs == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
} }
/*
bool const lhsIsConst = lhs->isConstant(); bool const lhsIsConst = lhs->isConstant();
bool const rhsIsConst = rhs->isConstant(); bool const rhsIsConst = rhs->isConstant();
// TODO if (! lhsIsConst || ! rhsIsConst) {
*/ return node;
return node; }
auto it = FunctionNames.find(static_cast<int>(node->type));
if (it == FunctionNames.end()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
if (node->type == NODE_TYPE_OPERATOR_BINARY_IN &&
rhs->type != NODE_TYPE_LIST) {
// right operand of IN must be a list
_parser->registerError(TRI_ERROR_QUERY_LIST_EXPECTED);
return node;
}
std::string const& func((*it).second);
return executeConstComparison(func, lhs, rhs);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -44,6 +44,7 @@ namespace triagens {
namespace aql { namespace aql {
class Parser; class Parser;
class Query;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- class QueryAst // --SECTION-- class QueryAst
@ -65,7 +66,8 @@ namespace triagens {
/// @brief create the AST /// @brief create the AST
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
QueryAst (Parser*); QueryAst (Query*,
Parser*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the AST /// @brief destroy the AST
@ -410,6 +412,14 @@ namespace triagens {
private: private:
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a comparison function using two constant values
////////////////////////////////////////////////////////////////////////////////
AstNode* executeConstComparison (std::string const&,
AstNode const*,
AstNode const*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief optimizes a FILTER node /// @brief optimizes a FILTER node
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -486,6 +496,12 @@ namespace triagens {
private: private:
////////////////////////////////////////////////////////////////////////////////
/// @brief the query
////////////////////////////////////////////////////////////////////////////////
Query* _query;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief the query parser /// @brief the query parser
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -546,6 +562,12 @@ namespace triagens {
AstNode* _nopNode; AstNode* _nopNode;
////////////////////////////////////////////////////////////////////////////////
/// @brief AQL function names
////////////////////////////////////////////////////////////////////////////////
static std::unordered_map<int, std::string> const FunctionNames;
}; };
} }

180
arangod/Aql/V8Executor.cpp Normal file
View File

@ -0,0 +1,180 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, v8 context executor
///
/// @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/V8Executor.h"
#include "Aql/AstNode.h"
#include "Basics/StringBuffer.h"
#include "Utils/Exception.h"
#include "V8/v8-conv.h"
#include "V8/v8-globals.h"
using namespace triagens::aql;
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief creates an executor
////////////////////////////////////////////////////////////////////////////////
V8Executor::V8Executor () :
_buffer(nullptr) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an executor
////////////////////////////////////////////////////////////////////////////////
V8Executor::~V8Executor () {
if (_buffer != nullptr) {
delete _buffer;
_buffer = nullptr;
}
}
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a comparison operation using V8
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* V8Executor::executeComparison (std::string const& func,
AstNode const* lhs,
AstNode const* rhs) {
triagens::basics::StringBuffer* buffer = getBuffer();
TRI_ASSERT(buffer != nullptr);
_buffer->appendText("(function(){ var aql = require(\"org/arangodb/ahuacatl\"); return aql.RELATIONAL_");
_buffer->appendText(func);
_buffer->appendText("(");
lhs->append(buffer);
_buffer->appendText(", ");
rhs->append(buffer);
_buffer->appendText("); })");
return execute();
}
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief create the string buffer
////////////////////////////////////////////////////////////////////////////////
triagens::basics::StringBuffer* V8Executor::getBuffer () {
if (_buffer == nullptr) {
_buffer = new triagens::basics::StringBuffer(TRI_UNKNOWN_MEM_ZONE);
if (_buffer == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
_buffer->reserve(256);
}
else {
_buffer->clear();
}
return _buffer;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the contents of the string buffer
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* V8Executor::execute () {
TRI_ASSERT(_buffer != nullptr);
v8::Handle<v8::Script> compiled = v8::Script::Compile(v8::String::New(_buffer->c_str(), (int) _buffer->length()),
v8::String::New("--script--"));
if (compiled.IsEmpty()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
v8::TryCatch tryCatch;
v8::Handle<v8::Value> func = compiled->Run();
if (tryCatch.HasCaught()) {
if (tryCatch.CanContinue()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
else {
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
v8g->_canceled = true;
THROW_ARANGO_EXCEPTION(TRI_ERROR_REQUEST_CANCELED);
}
}
if (func.IsEmpty() || ! func->IsFunction()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
// execute the function
v8::Handle<v8::Value> args[] = { };
v8::Handle<v8::Value> result = v8::Handle<v8::Function>::Cast(func)->Call(v8::Object::New(), 0, args);
if (tryCatch.HasCaught()) {
if (tryCatch.CanContinue()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
else {
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
v8g->_canceled = true;
THROW_ARANGO_EXCEPTION(TRI_ERROR_REQUEST_CANCELED);
}
}
if (result.IsEmpty()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
return TRI_ObjectToJson(result);
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

120
arangod/Aql/V8Executor.h Normal file
View File

@ -0,0 +1,120 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, v8 context executor
///
/// @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
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_AQL_V8_EXECUTOR_H
#define ARANGODB_AQL_V8_EXECUTOR_H 1
#include "Basics/Common.h"
struct TRI_json_s;
namespace triagens {
namespace basics {
class StringBuffer;
}
namespace aql {
struct AstNode;
// -----------------------------------------------------------------------------
// --SECTION-- class V8Executor
// -----------------------------------------------------------------------------
class V8Executor {
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
public:
V8Executor ();
~V8Executor ();
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a comparison operation using V8
////////////////////////////////////////////////////////////////////////////////
struct TRI_json_s* executeComparison (std::string const&,
AstNode const*,
AstNode const*);
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief create the string buffer
////////////////////////////////////////////////////////////////////////////////
triagens::basics::StringBuffer* getBuffer ();
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the contents of the string buffer
////////////////////////////////////////////////////////////////////////////////
struct TRI_json_s* execute ();
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief a string buffer used for operations
////////////////////////////////////////////////////////////////////////////////
triagens::basics::StringBuffer* _buffer;
};
}
}
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -67,6 +67,7 @@ add_executable(
Aql/QueryAst.cpp Aql/QueryAst.cpp
Aql/Scopes.cpp Aql/Scopes.cpp
Aql/tokens.cpp Aql/tokens.cpp
Aql/V8Executor.cpp
BitIndexes/bitarray.cpp BitIndexes/bitarray.cpp
BitIndexes/bitarrayIndex.cpp BitIndexes/bitarrayIndex.cpp
CapConstraint/cap-constraint.cpp CapConstraint/cap-constraint.cpp

View File

@ -48,6 +48,7 @@ arangod_libarangod_a_SOURCES = \
arangod/Aql/QueryAst.cpp \ arangod/Aql/QueryAst.cpp \
arangod/Aql/Scopes.cpp \ arangod/Aql/Scopes.cpp \
arangod/Aql/tokens.cpp \ arangod/Aql/tokens.cpp \
arangod/Aql/V8Executor.cpp \
arangod/BitIndexes/bitarray.cpp \ arangod/BitIndexes/bitarray.cpp \
arangod/BitIndexes/bitarrayIndex.cpp \ arangod/BitIndexes/bitarrayIndex.cpp \
arangod/CapConstraint/cap-constraint.cpp \ arangod/CapConstraint/cap-constraint.cpp \

View File

@ -111,7 +111,7 @@ namespace triagens {
/// @brief ensure the string buffer has a specific capacity /// @brief ensure the string buffer has a specific capacity
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int reserve (const size_t length) { int reserve (size_t length) {
return TRI_ReserveStringBuffer(&_buffer, length); return TRI_ReserveStringBuffer(&_buffer, length);
} }
@ -445,6 +445,15 @@ namespace triagens {
return *this; return *this;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief appends as json-encoded
////////////////////////////////////////////////////////////////////////////////
StringBuffer& appendJsonEncoded (const char * str) {
TRI_AppendJsonEncodedStringStringBuffer(&_buffer, str, true);
return *this;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief appends characters /// @brief appends characters
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////