mirror of https://gitee.com/bigwinds/arangodb
some json removal
This commit is contained in:
parent
4c03f4bf8d
commit
06da362f93
|
@ -32,6 +32,9 @@
|
||||||
#include "Basics/tri-strings.h"
|
#include "Basics/tri-strings.h"
|
||||||
#include "VocBase/collection.h"
|
#include "VocBase/collection.h"
|
||||||
|
|
||||||
|
#include <velocypack/Iterator.h>
|
||||||
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
using namespace arangodb::aql;
|
using namespace arangodb::aql;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1413,7 +1416,7 @@ AstNode* Ast::createNodeNaryOperator(AstNodeType type, AstNode const* child) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Ast::injectBindParameters(BindParameters& parameters) {
|
void Ast::injectBindParameters(BindParameters& parameters) {
|
||||||
auto p = parameters();
|
auto& p = parameters.get();
|
||||||
|
|
||||||
auto func = [&](AstNode* node, void*) -> AstNode* {
|
auto func = [&](AstNode* node, void*) -> AstNode* {
|
||||||
if (node->type == NODE_TYPE_PARAMETER) {
|
if (node->type == NODE_TYPE_PARAMETER) {
|
||||||
|
@ -1425,7 +1428,7 @@ void Ast::injectBindParameters(BindParameters& parameters) {
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = p.find(std::string(param, length));
|
auto const& it = p.find(std::string(param, length));
|
||||||
|
|
||||||
if (it == p.end()) {
|
if (it == p.end()) {
|
||||||
// query uses a bind parameter that was not defined by the user
|
// query uses a bind parameter that was not defined by the user
|
||||||
|
@ -1436,11 +1439,11 @@ void Ast::injectBindParameters(BindParameters& parameters) {
|
||||||
// mark the bind parameter as being used
|
// mark the bind parameter as being used
|
||||||
(*it).second.second = true;
|
(*it).second.second = true;
|
||||||
|
|
||||||
auto value = (*it).second.first;
|
auto& value = (*it).second.first;
|
||||||
|
|
||||||
if (*param == '@') {
|
if (*param == '@') {
|
||||||
// collection parameter
|
// collection parameter
|
||||||
TRI_ASSERT(TRI_IsStringJson(value));
|
TRI_ASSERT(value.isString());
|
||||||
|
|
||||||
// check if the collection was used in a data-modification query
|
// check if the collection was used in a data-modification query
|
||||||
bool isWriteCollection = false;
|
bool isWriteCollection = false;
|
||||||
|
@ -1454,9 +1457,11 @@ void Ast::injectBindParameters(BindParameters& parameters) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn node into a collection node
|
// turn node into a collection node
|
||||||
size_t const length = value->_value._string.length - 1;
|
VPackValueLength length;
|
||||||
|
char const* stringValue = value.getString(length);
|
||||||
|
// TODO: can we get away without registering the string value here?
|
||||||
char const* name =
|
char const* name =
|
||||||
_query->registerString(value->_value._string.data, length);
|
_query->registerString(stringValue, static_cast<size_t>(length));
|
||||||
|
|
||||||
node = createNodeCollection(name, isWriteCollection
|
node = createNodeCollection(name, isWriteCollection
|
||||||
? TRI_TRANSACTION_WRITE
|
? TRI_TRANSACTION_WRITE
|
||||||
|
@ -1474,7 +1479,7 @@ void Ast::injectBindParameters(BindParameters& parameters) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node = nodeFromJson(value, false);
|
node = nodeFromVPack(value, false);
|
||||||
|
|
||||||
if (node != nullptr) {
|
if (node != nullptr) {
|
||||||
// already mark node as constant here
|
// already mark node as constant here
|
||||||
|
@ -3005,6 +3010,70 @@ AstNode* Ast::nodeFromJson(TRI_json_t const* json, bool copyStringValues) {
|
||||||
return createNodeValueNull();
|
return createNodeValueNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief create an AST node from vpack
|
||||||
|
/// if copyStringValues is `true`, then string values will be copied and will
|
||||||
|
/// be freed with the query afterwards. when set to `false`, string values
|
||||||
|
/// will not be copied and not freed by the query. the caller needs to make
|
||||||
|
/// sure then that string values are valid through the query lifetime.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
AstNode* Ast::nodeFromVPack(VPackSlice const& slice, bool copyStringValues) {
|
||||||
|
if (slice.isBoolean()) {
|
||||||
|
return createNodeValueBool(slice.getBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slice.isNumber()) {
|
||||||
|
return createNodeValueDouble(slice.getNumber<double>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slice.isString()) {
|
||||||
|
VPackValueLength length;
|
||||||
|
char const* p = slice.getString(length);
|
||||||
|
|
||||||
|
if (copyStringValues) {
|
||||||
|
// we must copy string values!
|
||||||
|
p = _query->registerString(p, static_cast<size_t>(length));
|
||||||
|
}
|
||||||
|
// we can get away without copying string values
|
||||||
|
return createNodeValueString(p, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slice.isArray()) {
|
||||||
|
auto node = createNodeArray();
|
||||||
|
node->members.reserve(slice.length());
|
||||||
|
|
||||||
|
for (auto const& it : VPackArrayIterator(slice)) {
|
||||||
|
node->addMember(nodeFromVPack(it, copyStringValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slice.isObject()) {
|
||||||
|
auto node = createNodeObject();
|
||||||
|
node->members.reserve(slice.length());
|
||||||
|
|
||||||
|
for (auto const& it : VPackObjectIterator(slice)) {
|
||||||
|
VPackValueLength nameLength;
|
||||||
|
char const* attributeName = it.key.getString(nameLength);
|
||||||
|
|
||||||
|
if (copyStringValues) {
|
||||||
|
// create a copy of the string value
|
||||||
|
attributeName =
|
||||||
|
_query->registerString(attributeName, static_cast<size_t>(nameLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
node->addMember(createNodeObjectElement(
|
||||||
|
attributeName, nameLength, nodeFromVPack(it.value, copyStringValues)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createNodeValueNull();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief traverse the AST, using pre- and post-order visitors
|
/// @brief traverse the AST, using pre- and post-order visitors
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
|
namespace velocypack {
|
||||||
|
class Slice;
|
||||||
|
}
|
||||||
|
|
||||||
namespace aql {
|
namespace aql {
|
||||||
|
|
||||||
class Query;
|
class Query;
|
||||||
|
@ -674,6 +678,12 @@ class Ast {
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AstNode* nodeFromJson(TRI_json_t const*, bool);
|
AstNode* nodeFromJson(TRI_json_t const*, bool);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief create an AST node from vpack
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
AstNode* nodeFromVPack(arangodb::velocypack::Slice const&, bool);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief traverse the AST using a depth-first visitor
|
/// @brief traverse the AST using a depth-first visitor
|
||||||
|
|
|
@ -33,34 +33,16 @@
|
||||||
#include <velocypack/velocypack-aliases.h>
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
using namespace arangodb::aql;
|
using namespace arangodb::aql;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief create the parameters
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BindParameters::BindParameters(TRI_json_t* json)
|
|
||||||
: _json(json), _parameters(), _processed(false) {}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief destroy the parameters
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
BindParameters::~BindParameters() {
|
|
||||||
if (_json != nullptr) {
|
|
||||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, _json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief create a hash value for the bind parameters
|
/// @brief create a hash value for the bind parameters
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
uint64_t BindParameters::hash() const {
|
uint64_t BindParameters::hash() const {
|
||||||
if (_json == nullptr) {
|
if (_builder == nullptr) {
|
||||||
return 0x12345678abcdef;
|
return 0xdeadbeef;
|
||||||
}
|
}
|
||||||
|
return _builder->slice().hash();
|
||||||
return TRI_FastHashJson(_json);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -68,43 +50,35 @@ uint64_t BindParameters::hash() const {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void BindParameters::process() {
|
void BindParameters::process() {
|
||||||
if (_processed || _json == nullptr) {
|
if (_processed || _builder == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TRI_IsObjectJson(_json)) {
|
VPackSlice const slice = _builder->slice();
|
||||||
|
if (slice.isNone()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!slice.isObject()) {
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_QUERY_BIND_PARAMETERS_INVALID);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_QUERY_BIND_PARAMETERS_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t const n = TRI_LengthVector(&_json->_value._objects);
|
for (auto const& it : VPackObjectIterator(slice)) {
|
||||||
|
std::string const key(it.key.copyString());
|
||||||
for (size_t i = 0; i < n; i += 2) {
|
VPackSlice const value(it.value);
|
||||||
auto key = static_cast<TRI_json_t const*>(
|
|
||||||
TRI_AddressVector(&_json->_value._objects, i));
|
if (value.isNone()) {
|
||||||
|
|
||||||
if (!TRI_IsStringJson(key)) {
|
|
||||||
// no string, should not happen
|
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string const k(key->_value._string.data,
|
|
||||||
key->_value._string.length - 1);
|
|
||||||
|
|
||||||
auto value = static_cast<TRI_json_t const*>(
|
|
||||||
TRI_AtVector(&_json->_value._objects, i + 1));
|
|
||||||
|
|
||||||
if (value == nullptr) {
|
|
||||||
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE,
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE,
|
||||||
k.c_str());
|
key.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k[0] == '@' && !TRI_IsStringJson(value)) {
|
if (key[0] == '@' && !value.isString()) {
|
||||||
// collection bind parameter
|
// collection bind parameter
|
||||||
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE,
|
THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE,
|
||||||
k.c_str());
|
key.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
_parameters.emplace(std::move(k), std::make_pair(value, false));
|
_parameters.emplace(std::move(key), std::make_pair(value, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
_processed = true;
|
_processed = true;
|
||||||
|
@ -140,35 +114,3 @@ VPackBuilder BindParameters::StripCollectionNames(VPackSlice const& keys,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief strip collection name prefixes from the parameters
|
|
||||||
/// the values must be a JSON array. the array is modified in place
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void BindParameters::StripCollectionNames(TRI_json_t* keys,
|
|
||||||
char const* collectionName) {
|
|
||||||
if (!TRI_IsArrayJson(keys)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t const n = TRI_LengthVectorJson(keys);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n; ++i) {
|
|
||||||
auto key =
|
|
||||||
static_cast<TRI_json_t*>(TRI_AtVector(&keys->_value._objects, i));
|
|
||||||
|
|
||||||
if (TRI_IsStringJson(key)) {
|
|
||||||
auto s = key->_value._string.data;
|
|
||||||
auto p = strchr(s, '/');
|
|
||||||
|
|
||||||
if (p != nullptr && strncmp(s, collectionName, p - s) == 0) {
|
|
||||||
size_t pos = static_cast<size_t>(p - s);
|
|
||||||
// key begins with collection name + '/', now strip it in place for
|
|
||||||
// further comparisons
|
|
||||||
memmove(s, p + 1, key->_value._string.length - 2 - pos);
|
|
||||||
key->_value._string.length -= static_cast<uint32_t>(pos + 1);
|
|
||||||
key->_value._string.data[key->_value._string.length - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,17 +25,15 @@
|
||||||
#define ARANGOD_AQL_BIND_PARAMETERS_H 1
|
#define ARANGOD_AQL_BIND_PARAMETERS_H 1
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
#include "Basics/json.h"
|
|
||||||
|
#include <velocypack/Builder.h>
|
||||||
|
#include <velocypack/Slice.h>
|
||||||
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
namespace velocypack {
|
|
||||||
class Builder;
|
|
||||||
class Slice;
|
|
||||||
}
|
|
||||||
namespace aql {
|
namespace aql {
|
||||||
|
|
||||||
typedef std::unordered_map<std::string, std::pair<TRI_json_t const*, bool>>
|
typedef std::unordered_map<std::string, std::pair<arangodb::velocypack::Slice, bool>> BindParametersType;
|
||||||
BindParametersType;
|
|
||||||
|
|
||||||
class BindParameters {
|
class BindParameters {
|
||||||
public:
|
public:
|
||||||
|
@ -47,20 +45,21 @@ class BindParameters {
|
||||||
/// @brief create the parameters
|
/// @brief create the parameters
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
explicit BindParameters(TRI_json_t*);
|
explicit BindParameters(std::shared_ptr<arangodb::velocypack::Builder> builder)
|
||||||
|
: _builder(builder), _parameters(), _processed(false) {}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief destroy the parameters
|
/// @brief destroy the parameters
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
~BindParameters();
|
~BindParameters() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief return all parameters
|
/// @brief return all parameters
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
BindParametersType const& operator()() {
|
BindParametersType& get() {
|
||||||
process();
|
process();
|
||||||
return _parameters;
|
return _parameters;
|
||||||
}
|
}
|
||||||
|
@ -79,13 +78,6 @@ class BindParameters {
|
||||||
static arangodb::velocypack::Builder StripCollectionNames(
|
static arangodb::velocypack::Builder StripCollectionNames(
|
||||||
arangodb::velocypack::Slice const&, char const*);
|
arangodb::velocypack::Slice const&, char const*);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief strip collection name prefixes from the parameters
|
|
||||||
/// the values must be a JSON array. the array is modified in place
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void StripCollectionNames(TRI_json_t*, char const*);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief process the parameters
|
/// @brief process the parameters
|
||||||
|
@ -98,7 +90,7 @@ class BindParameters {
|
||||||
/// @brief the parameter json
|
/// @brief the parameter json
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TRI_json_t* _json;
|
std::shared_ptr<arangodb::velocypack::Builder> _builder;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief pointer to collection parameters
|
/// @brief pointer to collection parameters
|
||||||
|
|
|
@ -237,7 +237,7 @@ SortedCollectBlock::SortedCollectBlock(ExecutionEngine* engine,
|
||||||
|
|
||||||
// iterate over all our variables
|
// iterate over all our variables
|
||||||
if (en->_keepVariables.empty()) {
|
if (en->_keepVariables.empty()) {
|
||||||
auto&& usedVariableIds = en->getVariableIdsUsedHere();
|
auto usedVariableIds(en->getVariableIdsUsedHere());
|
||||||
|
|
||||||
for (auto const& vi : registerPlan) {
|
for (auto const& vi : registerPlan) {
|
||||||
if (vi.second.depth > 0 || en->getDepth() == 1) {
|
if (vi.second.depth > 0 || en->getDepth() == 1) {
|
||||||
|
|
|
@ -666,14 +666,14 @@ AqlValue Expression::executeSimpleExpressionIndexedAccess(
|
||||||
index, &myCollection2, trx, argv, startPos, vars, regs, false);
|
index, &myCollection2, trx, argv, startPos, vars, regs, false);
|
||||||
|
|
||||||
if (indexResult.isNumber()) {
|
if (indexResult.isNumber()) {
|
||||||
auto&& indexString = std::to_string(indexResult.toInt64());
|
auto indexString(std::to_string(indexResult.toInt64()));
|
||||||
auto j = result.extractObjectMember(trx, myCollection,
|
auto j = result.extractObjectMember(trx, myCollection,
|
||||||
indexString.c_str(), true, _buffer);
|
indexString.c_str(), true, _buffer);
|
||||||
indexResult.destroy();
|
indexResult.destroy();
|
||||||
result.destroy();
|
result.destroy();
|
||||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||||
} else if (indexResult.isString()) {
|
} else if (indexResult.isString()) {
|
||||||
auto&& value = indexResult.toString();
|
auto value(indexResult.toString());
|
||||||
indexResult.destroy();
|
indexResult.destroy();
|
||||||
|
|
||||||
auto j = result.extractObjectMember(trx, myCollection, value.c_str(),
|
auto j = result.extractObjectMember(trx, myCollection, value.c_str(),
|
||||||
|
|
|
@ -45,6 +45,9 @@
|
||||||
#include "VocBase/vocbase.h"
|
#include "VocBase/vocbase.h"
|
||||||
#include "VocBase/Graphs.h"
|
#include "VocBase/Graphs.h"
|
||||||
|
|
||||||
|
#include <velocypack/Builder.h>
|
||||||
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
|
||||||
using namespace arangodb;
|
using namespace arangodb;
|
||||||
using namespace arangodb::aql;
|
using namespace arangodb::aql;
|
||||||
using Json = arangodb::basics::Json;
|
using Json = arangodb::basics::Json;
|
||||||
|
@ -168,7 +171,7 @@ bool Query::DoDisableQueryTracking = false;
|
||||||
Query::Query(arangodb::ApplicationV8* applicationV8,
|
Query::Query(arangodb::ApplicationV8* applicationV8,
|
||||||
bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
|
bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
|
||||||
char const* queryString, size_t queryLength,
|
char const* queryString, size_t queryLength,
|
||||||
TRI_json_t* bindParameters, TRI_json_t* options, QueryPart part)
|
std::shared_ptr<VPackBuilder> bindParameters, TRI_json_t* options, QueryPart part)
|
||||||
: _id(0),
|
: _id(0),
|
||||||
_applicationV8(applicationV8),
|
_applicationV8(applicationV8),
|
||||||
_vocbase(vocbase),
|
_vocbase(vocbase),
|
||||||
|
@ -312,7 +315,7 @@ Query* Query::clone(QueryPart part, bool withPlan) {
|
||||||
std::unique_ptr<Query> clone;
|
std::unique_ptr<Query> clone;
|
||||||
|
|
||||||
clone.reset(new Query(_applicationV8, false, _vocbase, _queryString,
|
clone.reset(new Query(_applicationV8, false, _vocbase, _queryString,
|
||||||
_queryLength, nullptr, options.get(), part));
|
_queryLength, std::shared_ptr<VPackBuilder>(), options.get(), part));
|
||||||
options.release();
|
options.release();
|
||||||
|
|
||||||
if (_plan != nullptr) {
|
if (_plan != nullptr) {
|
||||||
|
|
|
@ -114,7 +114,7 @@ class Query {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, char const*, size_t,
|
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*, char const*, size_t,
|
||||||
struct TRI_json_t*, struct TRI_json_t*, QueryPart);
|
std::shared_ptr<arangodb::velocypack::Builder>, struct TRI_json_t*, QueryPart);
|
||||||
|
|
||||||
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*,
|
Query(arangodb::ApplicationV8*, bool, TRI_vocbase_t*,
|
||||||
arangodb::basics::Json queryStruct, struct TRI_json_t*, QueryPart);
|
arangodb::basics::Json queryStruct, struct TRI_json_t*, QueryPart);
|
||||||
|
|
|
@ -157,7 +157,7 @@ void RestAqlHandler::parseQuery() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto query = new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
auto query = new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
||||||
queryString.size(), nullptr, nullptr, PART_MAIN);
|
queryString.size(), std::shared_ptr<VPackBuilder>(), nullptr, PART_MAIN);
|
||||||
QueryResult res = query->parse();
|
QueryResult res = query->parse();
|
||||||
if (res.code != TRI_ERROR_NO_ERROR) {
|
if (res.code != TRI_ERROR_NO_ERROR) {
|
||||||
LOG(ERR) << "failed to instantiate the Query: " << res.details;
|
LOG(ERR) << "failed to instantiate the Query: " << res.details;
|
||||||
|
@ -212,14 +212,22 @@ void RestAqlHandler::explainQuery() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::basics::Json parameters;
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
parameters = queryJson.get("parameters").copy(); // cannot throw
|
{
|
||||||
|
int res = arangodb::basics::JsonHelper::toVelocyPack(queryJson.get("parameters").json(), *(bindVars.get()));
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
generateError(HttpResponse::BAD, TRI_ERROR_INTERNAL,
|
||||||
|
"could not convert parameters to vpack");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
arangodb::basics::Json options;
|
arangodb::basics::Json options;
|
||||||
options = queryJson.get("options").copy(); // cannot throw
|
options = queryJson.get("options").copy(); // cannot throw
|
||||||
|
|
||||||
auto query = new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
auto query = new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
||||||
queryString.size(), parameters.steal(),
|
queryString.size(), bindVars, options.steal(), PART_MAIN);
|
||||||
options.steal(), PART_MAIN);
|
|
||||||
QueryResult res = query->explain();
|
QueryResult res = query->explain();
|
||||||
if (res.code != TRI_ERROR_NO_ERROR) {
|
if (res.code != TRI_ERROR_NO_ERROR) {
|
||||||
LOG(ERR) << "failed to instantiate the Query: " << res.details;
|
LOG(ERR) << "failed to instantiate the Query: " << res.details;
|
||||||
|
@ -277,14 +285,23 @@ void RestAqlHandler::createQueryFromString() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::basics::Json parameters;
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
parameters = queryJson.get("parameters").copy(); // cannot throw
|
{
|
||||||
|
int res = arangodb::basics::JsonHelper::toVelocyPack(queryJson.get("parameters").json(), *(bindVars.get()));
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
generateError(HttpResponse::BAD, TRI_ERROR_INTERNAL,
|
||||||
|
"could not convert parameters to vpack");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
arangodb::basics::Json options;
|
arangodb::basics::Json options;
|
||||||
options = queryJson.get("options").copy(); // cannot throw
|
options = queryJson.get("options").copy(); // cannot throw
|
||||||
|
|
||||||
auto query =
|
auto query =
|
||||||
new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
||||||
queryString.size(), parameters.steal(), options.steal(),
|
queryString.size(), bindVars, options.steal(),
|
||||||
(part == "main" ? PART_MAIN : PART_DEPENDENT));
|
(part == "main" ? PART_MAIN : PART_DEPENDENT));
|
||||||
QueryResult res = query->prepare(_queryRegistry);
|
QueryResult res = query->prepare(_queryRegistry);
|
||||||
if (res.code != TRI_ERROR_NO_ERROR) {
|
if (res.code != TRI_ERROR_NO_ERROR) {
|
||||||
|
|
|
@ -101,6 +101,12 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VPackBuilder> bindVarsBuilder;
|
||||||
|
if (!bindVars.isNone()) {
|
||||||
|
bindVarsBuilder.reset(new VPackBuilder);
|
||||||
|
bindVarsBuilder->add(bindVars);
|
||||||
|
}
|
||||||
|
|
||||||
VPackBuilder optionsBuilder = buildOptions(slice);
|
VPackBuilder optionsBuilder = buildOptions(slice);
|
||||||
VPackSlice options = optionsBuilder.slice();
|
VPackSlice options = optionsBuilder.slice();
|
||||||
|
@ -109,9 +115,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
||||||
|
|
||||||
arangodb::aql::Query query(
|
arangodb::aql::Query query(
|
||||||
_applicationV8, false, _vocbase, queryString, static_cast<size_t>(l),
|
_applicationV8, false, _vocbase, queryString, static_cast<size_t>(l),
|
||||||
(!bindVars.isNone()
|
bindVarsBuilder,
|
||||||
? arangodb::basics::VelocyPackHelper::velocyPackToJson(bindVars)
|
|
||||||
: nullptr),
|
|
||||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(options),
|
arangodb::basics::VelocyPackHelper::velocyPackToJson(options),
|
||||||
arangodb::aql::PART_MAIN);
|
arangodb::aql::PART_MAIN);
|
||||||
|
|
||||||
|
|
|
@ -191,12 +191,11 @@ void RestSimpleHandler::removeByKeys(VPackSlice const& slice) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackBuilder bindVars;
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
bindVars.openObject();
|
bindVars->openObject();
|
||||||
bindVars.add("@collection", VPackValue(collectionName));
|
bindVars->add("@collection", VPackValue(collectionName));
|
||||||
bindVars.add("keys", keys);
|
bindVars->add("keys", keys);
|
||||||
bindVars.close();
|
bindVars->close();
|
||||||
VPackSlice varsSlice = bindVars.slice();
|
|
||||||
|
|
||||||
std::string aql(
|
std::string aql(
|
||||||
"FOR key IN @keys REMOVE key IN @@collection OPTIONS { ignoreErrors: "
|
"FOR key IN @keys REMOVE key IN @@collection OPTIONS { ignoreErrors: "
|
||||||
|
@ -206,8 +205,7 @@ void RestSimpleHandler::removeByKeys(VPackSlice const& slice) {
|
||||||
|
|
||||||
arangodb::aql::Query query(
|
arangodb::aql::Query query(
|
||||||
_applicationV8, false, _vocbase, aql.c_str(), aql.size(),
|
_applicationV8, false, _vocbase, aql.c_str(), aql.size(),
|
||||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(varsSlice),
|
bindVars, nullptr, arangodb::aql::PART_MAIN);
|
||||||
nullptr, arangodb::aql::PART_MAIN);
|
|
||||||
|
|
||||||
registerQuery(&query);
|
registerQuery(&query);
|
||||||
auto queryResult = query.execute(_queryRegistry);
|
auto queryResult = query.execute(_queryRegistry);
|
||||||
|
@ -304,25 +302,22 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackBuilder bindVars;
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
bindVars.add(VPackValue(VPackValueType::Object));
|
bindVars->openObject();
|
||||||
bindVars.add("@collection", VPackValue(collectionName));
|
bindVars->add("@collection", VPackValue(collectionName));
|
||||||
VPackBuilder strippedBuilder =
|
VPackBuilder strippedBuilder =
|
||||||
arangodb::aql::BindParameters::StripCollectionNames(
|
arangodb::aql::BindParameters::StripCollectionNames(
|
||||||
keys, collectionName.c_str());
|
keys, collectionName.c_str());
|
||||||
VPackSlice stripped = strippedBuilder.slice();
|
|
||||||
|
|
||||||
bindVars.add("keys", stripped);
|
bindVars->add("keys", strippedBuilder.slice());
|
||||||
bindVars.close();
|
bindVars->close();
|
||||||
VPackSlice varsSlice = bindVars.slice();
|
|
||||||
|
|
||||||
std::string const aql(
|
std::string const aql(
|
||||||
"FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc");
|
"FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc");
|
||||||
|
|
||||||
arangodb::aql::Query query(
|
arangodb::aql::Query query(
|
||||||
_applicationV8, false, _vocbase, aql.c_str(), aql.size(),
|
_applicationV8, false, _vocbase, aql.c_str(), aql.size(),
|
||||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(varsSlice),
|
bindVars, nullptr, arangodb::aql::PART_MAIN);
|
||||||
nullptr, arangodb::aql::PART_MAIN);
|
|
||||||
|
|
||||||
registerQuery(&query);
|
registerQuery(&query);
|
||||||
auto queryResult = query.execute(_queryRegistry);
|
auto queryResult = query.execute(_queryRegistry);
|
||||||
|
|
|
@ -401,7 +401,7 @@ void Scheduler::setProcessorAffinity(size_t i, size_t c) {
|
||||||
Task* Scheduler::lookupTaskById(uint64_t taskId) {
|
Task* Scheduler::lookupTaskById(uint64_t taskId) {
|
||||||
MUTEX_LOCKER(mutexLocker, schedulerLock);
|
MUTEX_LOCKER(mutexLocker, schedulerLock);
|
||||||
|
|
||||||
auto&& task = taskRegistered.find(taskId);
|
auto task = taskRegistered.find(taskId);
|
||||||
|
|
||||||
if (task == taskRegistered.end()) {
|
if (task == taskRegistered.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -417,7 +417,7 @@ Task* Scheduler::lookupTaskById(uint64_t taskId) {
|
||||||
EventLoop Scheduler::lookupLoopById(uint64_t taskId) {
|
EventLoop Scheduler::lookupLoopById(uint64_t taskId) {
|
||||||
MUTEX_LOCKER(mutexLocker, schedulerLock);
|
MUTEX_LOCKER(mutexLocker, schedulerLock);
|
||||||
|
|
||||||
auto&& task = taskRegistered.find(taskId);
|
auto task = taskRegistered.find(taskId);
|
||||||
|
|
||||||
if (task == taskRegistered.end()) {
|
if (task == taskRegistered.end()) {
|
||||||
return static_cast<EventLoop>(nrThreads);
|
return static_cast<EventLoop>(nrThreads);
|
||||||
|
|
|
@ -360,7 +360,7 @@ static v8::Handle<v8::Object> RequestCppToV8(v8::Isolate* isolate,
|
||||||
req->ForceSet(ProtocolKey, TRI_V8_STD_STRING(protocol));
|
req->ForceSet(ProtocolKey, TRI_V8_STD_STRING(protocol));
|
||||||
|
|
||||||
// set the task id
|
// set the task id
|
||||||
std::string const&& taskId = StringUtils::itoa(request->clientTaskId());
|
std::string const taskId(StringUtils::itoa(request->clientTaskId()));
|
||||||
|
|
||||||
// set the connection info
|
// set the connection info
|
||||||
const ConnectionInfo& info = request->connectionInfo();
|
const ConnectionInfo& info = request->connectionInfo();
|
||||||
|
@ -590,8 +590,7 @@ static HttpResponse* ResponseV8ToCpp(v8::Isolate* isolate,
|
||||||
response->body().appendText(V8Buffer::data(obj), V8Buffer::length(obj));
|
response->body().appendText(V8Buffer::data(obj), V8Buffer::length(obj));
|
||||||
} else {
|
} else {
|
||||||
// treat body as a string
|
// treat body as a string
|
||||||
std::string&& obj(TRI_ObjectToString(res->Get(BodyKey)));
|
response->body().appendText(TRI_ObjectToString(res->Get(BodyKey)));
|
||||||
response->body().appendText(obj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "VocBase/vocbase.h"
|
#include "VocBase/vocbase.h"
|
||||||
#include "VocBase/VocShaper.h"
|
#include "VocBase/VocShaper.h"
|
||||||
|
|
||||||
|
#include <velocypack/Builder.h>
|
||||||
#include <velocypack/Iterator.h>
|
#include <velocypack/Iterator.h>
|
||||||
#include <velocypack/Slice.h>
|
#include <velocypack/Slice.h>
|
||||||
#include <velocypack/velocypack-aliases.h>
|
#include <velocypack/velocypack-aliases.h>
|
||||||
|
@ -61,21 +62,12 @@ using namespace arangodb::basics;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static v8::Handle<v8::Value> AqlQuery(v8::Isolate* isolate, TRI_vocbase_col_t const* col,
|
static v8::Handle<v8::Value> AqlQuery(v8::Isolate* isolate, TRI_vocbase_col_t const* col,
|
||||||
std::string const& aql, VPackSlice const& slice) {
|
std::string const& aql, std::shared_ptr<VPackBuilder> bindVars) {
|
||||||
TRI_ASSERT(col != nullptr);
|
TRI_ASSERT(col != nullptr);
|
||||||
|
|
||||||
arangodb::basics::Json bindVars(arangodb::basics::Json::Object, 2);
|
|
||||||
|
|
||||||
VPackObjectIterator it(slice);
|
|
||||||
while (it.valid()) {
|
|
||||||
bindVars(it.key().copyString().c_str(), arangodb::basics::Json(TRI_UNKNOWN_MEM_ZONE, VelocyPackHelper::velocyPackToJson(it.value())));
|
|
||||||
it.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TRI_GET_GLOBALS();
|
TRI_GET_GLOBALS();
|
||||||
arangodb::aql::Query query(v8g->_applicationV8, true, col->_vocbase,
|
arangodb::aql::Query query(v8g->_applicationV8, true, col->_vocbase,
|
||||||
aql.c_str(), aql.size(), bindVars.steal(), nullptr,
|
aql.c_str(), aql.size(), bindVars, nullptr,
|
||||||
arangodb::aql::PART_MAIN);
|
arangodb::aql::PART_MAIN);
|
||||||
|
|
||||||
auto queryResult = query.executeV8(
|
auto queryResult = query.executeV8(
|
||||||
|
@ -542,17 +534,17 @@ static void EdgesQuery(TRI_edge_direction_e direction,
|
||||||
|
|
||||||
TRI_THROW_SHARDING_COLLECTION_NOT_YET_IMPLEMENTED(col);
|
TRI_THROW_SHARDING_COLLECTION_NOT_YET_IMPLEMENTED(col);
|
||||||
|
|
||||||
VPackBuilder builder;
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
builder.openObject();
|
bindVars->openObject();
|
||||||
builder.add("@collection", VPackValue(col->name()));
|
bindVars->add("@collection", VPackValue(col->name()));
|
||||||
builder.add(VPackValue("value"));
|
bindVars->add(VPackValue("value"));
|
||||||
int res = TRI_V8ToVPack(isolate, builder, args[0], false);
|
int res = TRI_V8ToVPack(isolate, *(bindVars.get()), args[0], false);
|
||||||
|
bindVars->close();
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
TRI_V8_THROW_EXCEPTION(res);
|
TRI_V8_THROW_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.close();
|
|
||||||
|
|
||||||
std::string filter;
|
std::string filter;
|
||||||
// argument is a list of vertices
|
// argument is a list of vertices
|
||||||
|
@ -577,7 +569,7 @@ static void EdgesQuery(TRI_edge_direction_e direction,
|
||||||
}
|
}
|
||||||
|
|
||||||
trx.lockRead();
|
trx.lockRead();
|
||||||
v8::Handle<v8::Value> result = AqlQuery(isolate, col, "FOR doc IN @@collection " + filter + " RETURN doc", builder.slice());
|
v8::Handle<v8::Value> result = AqlQuery(isolate, col, "FOR doc IN @@collection " + filter + " RETURN doc", bindVars);
|
||||||
trx.finish(res);
|
trx.finish(res);
|
||||||
|
|
||||||
TRI_V8_RETURN(result);
|
TRI_V8_RETURN(result);
|
||||||
|
@ -1287,7 +1279,7 @@ static void FulltextQuery(SingleCollectionTransaction& trx,
|
||||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_NO_INDEX);
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_NO_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const&& queryString = TRI_ObjectToString(args[1]);
|
std::string queryString(TRI_ObjectToString(args[1]));
|
||||||
bool isSubstringQuery = false;
|
bool isSubstringQuery = false;
|
||||||
size_t maxResults = 0; // 0 means "all results"
|
size_t maxResults = 0; // 0 means "all results"
|
||||||
|
|
||||||
|
@ -1628,22 +1620,29 @@ static void JS_LookupByKeys(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE("documents(<keys>)");
|
TRI_V8_THROW_EXCEPTION_USAGE("documents(<keys>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::basics::Json bindVars(arangodb::basics::Json::Object, 2);
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
bindVars("@collection", arangodb::basics::Json(std::string(col->_name)));
|
bindVars->openObject();
|
||||||
bindVars("keys", arangodb::basics::Json(TRI_UNKNOWN_MEM_ZONE,
|
bindVars->add("@collection", VPackValue(std::string(col->_name)));
|
||||||
TRI_ObjectToJson(isolate, args[0])));
|
|
||||||
|
|
||||||
std::string const collectionName(col->name());
|
VPackBuilder keys;
|
||||||
|
int res = TRI_V8ToVPack(isolate, keys, args[0], false);
|
||||||
|
|
||||||
arangodb::aql::BindParameters::StripCollectionNames(
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
TRI_LookupObjectJson(bindVars.json(), "keys"), collectionName.c_str());
|
TRI_V8_THROW_EXCEPTION(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
VPackBuilder strippedBuilder =
|
||||||
|
arangodb::aql::BindParameters::StripCollectionNames(keys.slice(), col->_name.c_str());
|
||||||
|
|
||||||
|
bindVars->add("keys", strippedBuilder.slice());
|
||||||
|
bindVars->close();
|
||||||
|
|
||||||
std::string const aql(
|
std::string const aql(
|
||||||
"FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc");
|
"FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc");
|
||||||
|
|
||||||
TRI_GET_GLOBALS();
|
TRI_GET_GLOBALS();
|
||||||
arangodb::aql::Query query(v8g->_applicationV8, true, col->_vocbase,
|
arangodb::aql::Query query(v8g->_applicationV8, true, col->_vocbase,
|
||||||
aql.c_str(), aql.size(), bindVars.steal(), nullptr,
|
aql.c_str(), aql.size(), bindVars, nullptr,
|
||||||
arangodb::aql::PART_MAIN);
|
arangodb::aql::PART_MAIN);
|
||||||
|
|
||||||
auto queryResult = query.executeV8(
|
auto queryResult = query.executeV8(
|
||||||
|
@ -1684,10 +1683,16 @@ static void JS_RemoveByKeys(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_V8_THROW_EXCEPTION_USAGE("removeByKeys(<keys>)");
|
TRI_V8_THROW_EXCEPTION_USAGE("removeByKeys(<keys>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::basics::Json bindVars(arangodb::basics::Json::Object, 2);
|
auto bindVars = std::make_shared<VPackBuilder>();
|
||||||
bindVars("@collection", arangodb::basics::Json(std::string(col->_name)));
|
bindVars->openObject();
|
||||||
bindVars("keys", arangodb::basics::Json(TRI_UNKNOWN_MEM_ZONE,
|
bindVars->add("@collection", VPackValue(col->_name));
|
||||||
TRI_ObjectToJson(isolate, args[0])));
|
bindVars->add(VPackValue("keys"));
|
||||||
|
|
||||||
|
int res = TRI_V8ToVPack(isolate, *(bindVars.get()), args[0], false);
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_V8_THROW_EXCEPTION(res);
|
||||||
|
}
|
||||||
|
bindVars->close();
|
||||||
|
|
||||||
std::string const aql(
|
std::string const aql(
|
||||||
"FOR key IN @keys REMOVE key IN @@collection OPTIONS { ignoreErrors: "
|
"FOR key IN @keys REMOVE key IN @@collection OPTIONS { ignoreErrors: "
|
||||||
|
@ -1695,7 +1700,7 @@ static void JS_RemoveByKeys(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
TRI_GET_GLOBALS();
|
TRI_GET_GLOBALS();
|
||||||
arangodb::aql::Query query(v8g->_applicationV8, true, col->_vocbase,
|
arangodb::aql::Query query(v8g->_applicationV8, true, col->_vocbase,
|
||||||
aql.c_str(), aql.size(), bindVars.steal(), nullptr,
|
aql.c_str(), aql.size(), bindVars, nullptr,
|
||||||
arangodb::aql::PART_MAIN);
|
arangodb::aql::PART_MAIN);
|
||||||
|
|
||||||
auto queryResult = query.executeV8(
|
auto queryResult = query.executeV8(
|
||||||
|
|
|
@ -1098,17 +1098,23 @@ static void JS_ExplainAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting string for <querystring>");
|
TRI_V8_THROW_TYPE_ERROR("expecting string for <querystring>");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const&& queryString = TRI_ObjectToString(args[0]);
|
std::string const queryString(TRI_ObjectToString(args[0]));
|
||||||
|
|
||||||
// bind parameters
|
// bind parameters
|
||||||
std::unique_ptr<TRI_json_t> parameters;
|
std::shared_ptr<VPackBuilder> bindVars;
|
||||||
|
|
||||||
if (args.Length() > 1) {
|
if (args.Length() > 1) {
|
||||||
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
|
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindvalues>");
|
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindvalues>");
|
||||||
}
|
}
|
||||||
if (args[1]->IsObject()) {
|
if (args[1]->IsObject()) {
|
||||||
parameters.reset(TRI_ObjectToJson(isolate, args[1]));
|
bindVars.reset(new VPackBuilder);
|
||||||
|
|
||||||
|
int res = TRI_V8ToVPack(isolate, *(bindVars.get()), args[1], false);
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_V8_THROW_EXCEPTION(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,7 +1133,7 @@ static void JS_ExplainAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_GET_GLOBALS();
|
TRI_GET_GLOBALS();
|
||||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
||||||
queryString.c_str(), queryString.size(),
|
queryString.c_str(), queryString.size(),
|
||||||
parameters.release(), options.release(),
|
bindVars, options.release(),
|
||||||
arangodb::aql::PART_MAIN);
|
arangodb::aql::PART_MAIN);
|
||||||
|
|
||||||
auto queryResult = query.explain();
|
auto queryResult = query.explain();
|
||||||
|
@ -1277,10 +1283,10 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting string for <querystring>");
|
TRI_V8_THROW_TYPE_ERROR("expecting string for <querystring>");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const&& queryString = TRI_ObjectToString(args[0]);
|
std::string const queryString(TRI_ObjectToString(args[0]));
|
||||||
|
|
||||||
// bind parameters
|
// bind parameters
|
||||||
std::unique_ptr<TRI_json_t> parameters;
|
std::shared_ptr<VPackBuilder> bindVars;
|
||||||
|
|
||||||
// options
|
// options
|
||||||
std::unique_ptr<TRI_json_t> options;
|
std::unique_ptr<TRI_json_t> options;
|
||||||
|
@ -1290,7 +1296,12 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindvalues>");
|
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindvalues>");
|
||||||
}
|
}
|
||||||
if (args[1]->IsObject()) {
|
if (args[1]->IsObject()) {
|
||||||
parameters.reset(TRI_ObjectToJson(isolate, args[1]));
|
bindVars.reset(new VPackBuilder);
|
||||||
|
int res = TRI_V8ToVPack(isolate, *(bindVars.get()), args[1], false);
|
||||||
|
|
||||||
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
TRI_V8_THROW_EXCEPTION(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1307,11 +1318,10 @@ static void JS_ExecuteAql(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_GET_GLOBALS();
|
TRI_GET_GLOBALS();
|
||||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
||||||
queryString.c_str(), queryString.size(),
|
queryString.c_str(), queryString.size(),
|
||||||
parameters.get(), options.get(),
|
bindVars, options.get(),
|
||||||
arangodb::aql::PART_MAIN);
|
arangodb::aql::PART_MAIN);
|
||||||
|
|
||||||
options.release();
|
options.release();
|
||||||
parameters.release();
|
|
||||||
|
|
||||||
auto queryResult = query.executeV8(
|
auto queryResult = query.executeV8(
|
||||||
isolate, static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry));
|
isolate, static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry));
|
||||||
|
|
|
@ -1308,7 +1308,7 @@ static void JS_GetIndexesVocbaseCol(
|
||||||
std::string const& collectionName = std::string(collection->_name);
|
std::string const& collectionName = std::string(collection->_name);
|
||||||
|
|
||||||
// get list of indexes
|
// get list of indexes
|
||||||
auto&& indexes = TRI_IndexesDocumentCollection(document, withFigures);
|
auto indexes(TRI_IndexesDocumentCollection(document, withFigures));
|
||||||
|
|
||||||
trx.finish(res);
|
trx.finish(res);
|
||||||
// READ-LOCK end
|
// READ-LOCK end
|
||||||
|
|
|
@ -50,8 +50,6 @@
|
||||||
/// concrete sub-class @ref TRI_document_collection_t.
|
/// concrete sub-class @ref TRI_document_collection_t.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct TRI_json_t;
|
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
class CollectionInfo;
|
class CollectionInfo;
|
||||||
namespace velocypack {
|
namespace velocypack {
|
||||||
|
|
Loading…
Reference in New Issue