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 "VocBase/collection.h"
|
||||
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb::aql;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1413,7 +1416,7 @@ AstNode* Ast::createNodeNaryOperator(AstNodeType type, AstNode const* child) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Ast::injectBindParameters(BindParameters& parameters) {
|
||||
auto p = parameters();
|
||||
auto& p = parameters.get();
|
||||
|
||||
auto func = [&](AstNode* node, void*) -> AstNode* {
|
||||
if (node->type == NODE_TYPE_PARAMETER) {
|
||||
|
@ -1425,7 +1428,7 @@ void Ast::injectBindParameters(BindParameters& parameters) {
|
|||
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()) {
|
||||
// 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
|
||||
(*it).second.second = true;
|
||||
|
||||
auto value = (*it).second.first;
|
||||
auto& value = (*it).second.first;
|
||||
|
||||
if (*param == '@') {
|
||||
// collection parameter
|
||||
TRI_ASSERT(TRI_IsStringJson(value));
|
||||
TRI_ASSERT(value.isString());
|
||||
|
||||
// check if the collection was used in a data-modification query
|
||||
bool isWriteCollection = false;
|
||||
|
@ -1454,9 +1457,11 @@ void Ast::injectBindParameters(BindParameters& parameters) {
|
|||
}
|
||||
|
||||
// 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 =
|
||||
_query->registerString(value->_value._string.data, length);
|
||||
_query->registerString(stringValue, static_cast<size_t>(length));
|
||||
|
||||
node = createNodeCollection(name, isWriteCollection
|
||||
? TRI_TRANSACTION_WRITE
|
||||
|
@ -1474,7 +1479,7 @@ void Ast::injectBindParameters(BindParameters& parameters) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
node = nodeFromJson(value, false);
|
||||
node = nodeFromVPack(value, false);
|
||||
|
||||
if (node != nullptr) {
|
||||
// already mark node as constant here
|
||||
|
@ -3005,6 +3010,70 @@ AstNode* Ast::nodeFromJson(TRI_json_t const* json, bool copyStringValues) {
|
|||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
#include <functional>
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
class Slice;
|
||||
}
|
||||
|
||||
namespace aql {
|
||||
|
||||
class Query;
|
||||
|
@ -674,6 +678,12 @@ class Ast {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
|
|
|
@ -33,34 +33,16 @@
|
|||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t BindParameters::hash() const {
|
||||
if (_json == nullptr) {
|
||||
return 0x12345678abcdef;
|
||||
if (_builder == nullptr) {
|
||||
return 0xdeadbeef;
|
||||
}
|
||||
|
||||
return TRI_FastHashJson(_json);
|
||||
return _builder->slice().hash();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -68,43 +50,35 @@ uint64_t BindParameters::hash() const {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BindParameters::process() {
|
||||
if (_processed || _json == nullptr) {
|
||||
if (_processed || _builder == nullptr) {
|
||||
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);
|
||||
}
|
||||
|
||||
size_t const n = TRI_LengthVector(&_json->_value._objects);
|
||||
|
||||
for (size_t i = 0; i < n; i += 2) {
|
||||
auto key = static_cast<TRI_json_t const*>(
|
||||
TRI_AddressVector(&_json->_value._objects, i));
|
||||
|
||||
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) {
|
||||
for (auto const& it : VPackObjectIterator(slice)) {
|
||||
std::string const key(it.key.copyString());
|
||||
VPackSlice const value(it.value);
|
||||
|
||||
if (value.isNone()) {
|
||||
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
|
||||
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;
|
||||
|
@ -140,35 +114,3 @@ VPackBuilder BindParameters::StripCollectionNames(VPackSlice const& keys,
|
|||
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
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/json.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Slice.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
namespace arangodb {
|
||||
namespace velocypack {
|
||||
class Builder;
|
||||
class Slice;
|
||||
}
|
||||
namespace aql {
|
||||
|
||||
typedef std::unordered_map<std::string, std::pair<TRI_json_t const*, bool>>
|
||||
BindParametersType;
|
||||
typedef std::unordered_map<std::string, std::pair<arangodb::velocypack::Slice, bool>> BindParametersType;
|
||||
|
||||
class BindParameters {
|
||||
public:
|
||||
|
@ -47,20 +45,21 @@ class BindParameters {
|
|||
/// @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
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~BindParameters();
|
||||
~BindParameters() = default;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return all parameters
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BindParametersType const& operator()() {
|
||||
BindParametersType& get() {
|
||||
process();
|
||||
return _parameters;
|
||||
}
|
||||
|
@ -79,13 +78,6 @@ class BindParameters {
|
|||
static arangodb::velocypack::Builder StripCollectionNames(
|
||||
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:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief process the parameters
|
||||
|
@ -98,7 +90,7 @@ class BindParameters {
|
|||
/// @brief the parameter json
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_json_t* _json;
|
||||
std::shared_ptr<arangodb::velocypack::Builder> _builder;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief pointer to collection parameters
|
||||
|
|
|
@ -237,7 +237,7 @@ SortedCollectBlock::SortedCollectBlock(ExecutionEngine* engine,
|
|||
|
||||
// iterate over all our variables
|
||||
if (en->_keepVariables.empty()) {
|
||||
auto&& usedVariableIds = en->getVariableIdsUsedHere();
|
||||
auto usedVariableIds(en->getVariableIdsUsedHere());
|
||||
|
||||
for (auto const& vi : registerPlan) {
|
||||
if (vi.second.depth > 0 || en->getDepth() == 1) {
|
||||
|
|
|
@ -666,14 +666,14 @@ AqlValue Expression::executeSimpleExpressionIndexedAccess(
|
|||
index, &myCollection2, trx, argv, startPos, vars, regs, false);
|
||||
|
||||
if (indexResult.isNumber()) {
|
||||
auto&& indexString = std::to_string(indexResult.toInt64());
|
||||
auto indexString(std::to_string(indexResult.toInt64()));
|
||||
auto j = result.extractObjectMember(trx, myCollection,
|
||||
indexString.c_str(), true, _buffer);
|
||||
indexResult.destroy();
|
||||
result.destroy();
|
||||
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
|
||||
} else if (indexResult.isString()) {
|
||||
auto&& value = indexResult.toString();
|
||||
auto value(indexResult.toString());
|
||||
indexResult.destroy();
|
||||
|
||||
auto j = result.extractObjectMember(trx, myCollection, value.c_str(),
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#include "VocBase/vocbase.h"
|
||||
#include "VocBase/Graphs.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::aql;
|
||||
using Json = arangodb::basics::Json;
|
||||
|
@ -168,7 +171,7 @@ bool Query::DoDisableQueryTracking = false;
|
|||
Query::Query(arangodb::ApplicationV8* applicationV8,
|
||||
bool contextOwnedByExterior, TRI_vocbase_t* vocbase,
|
||||
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),
|
||||
_applicationV8(applicationV8),
|
||||
_vocbase(vocbase),
|
||||
|
@ -312,7 +315,7 @@ Query* Query::clone(QueryPart part, bool withPlan) {
|
|||
std::unique_ptr<Query> clone;
|
||||
|
||||
clone.reset(new Query(_applicationV8, false, _vocbase, _queryString,
|
||||
_queryLength, nullptr, options.get(), part));
|
||||
_queryLength, std::shared_ptr<VPackBuilder>(), options.get(), part));
|
||||
options.release();
|
||||
|
||||
if (_plan != nullptr) {
|
||||
|
|
|
@ -114,7 +114,7 @@ class Query {
|
|||
|
||||
public:
|
||||
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*,
|
||||
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(),
|
||||
queryString.size(), nullptr, nullptr, PART_MAIN);
|
||||
queryString.size(), std::shared_ptr<VPackBuilder>(), nullptr, PART_MAIN);
|
||||
QueryResult res = query->parse();
|
||||
if (res.code != TRI_ERROR_NO_ERROR) {
|
||||
LOG(ERR) << "failed to instantiate the Query: " << res.details;
|
||||
|
@ -212,14 +212,22 @@ void RestAqlHandler::explainQuery() {
|
|||
return;
|
||||
}
|
||||
|
||||
arangodb::basics::Json parameters;
|
||||
parameters = queryJson.get("parameters").copy(); // cannot throw
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
{
|
||||
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;
|
||||
options = queryJson.get("options").copy(); // cannot throw
|
||||
|
||||
auto query = new Query(_applicationV8, false, _vocbase, queryString.c_str(),
|
||||
queryString.size(), parameters.steal(),
|
||||
options.steal(), PART_MAIN);
|
||||
queryString.size(), bindVars, options.steal(), PART_MAIN);
|
||||
QueryResult res = query->explain();
|
||||
if (res.code != TRI_ERROR_NO_ERROR) {
|
||||
LOG(ERR) << "failed to instantiate the Query: " << res.details;
|
||||
|
@ -277,14 +285,23 @@ void RestAqlHandler::createQueryFromString() {
|
|||
return;
|
||||
}
|
||||
|
||||
arangodb::basics::Json parameters;
|
||||
parameters = queryJson.get("parameters").copy(); // cannot throw
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
{
|
||||
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;
|
||||
options = queryJson.get("options").copy(); // cannot throw
|
||||
|
||||
auto query =
|
||||
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));
|
||||
QueryResult res = query->prepare(_queryRegistry);
|
||||
if (res.code != TRI_ERROR_NO_ERROR) {
|
||||
|
|
|
@ -101,6 +101,12 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<VPackBuilder> bindVarsBuilder;
|
||||
if (!bindVars.isNone()) {
|
||||
bindVarsBuilder.reset(new VPackBuilder);
|
||||
bindVarsBuilder->add(bindVars);
|
||||
}
|
||||
|
||||
VPackBuilder optionsBuilder = buildOptions(slice);
|
||||
VPackSlice options = optionsBuilder.slice();
|
||||
|
@ -109,9 +115,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
|
|||
|
||||
arangodb::aql::Query query(
|
||||
_applicationV8, false, _vocbase, queryString, static_cast<size_t>(l),
|
||||
(!bindVars.isNone()
|
||||
? arangodb::basics::VelocyPackHelper::velocyPackToJson(bindVars)
|
||||
: nullptr),
|
||||
bindVarsBuilder,
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(options),
|
||||
arangodb::aql::PART_MAIN);
|
||||
|
||||
|
|
|
@ -191,12 +191,11 @@ void RestSimpleHandler::removeByKeys(VPackSlice const& slice) {
|
|||
}
|
||||
}
|
||||
|
||||
VPackBuilder bindVars;
|
||||
bindVars.openObject();
|
||||
bindVars.add("@collection", VPackValue(collectionName));
|
||||
bindVars.add("keys", keys);
|
||||
bindVars.close();
|
||||
VPackSlice varsSlice = bindVars.slice();
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
bindVars->openObject();
|
||||
bindVars->add("@collection", VPackValue(collectionName));
|
||||
bindVars->add("keys", keys);
|
||||
bindVars->close();
|
||||
|
||||
std::string aql(
|
||||
"FOR key IN @keys REMOVE key IN @@collection OPTIONS { ignoreErrors: "
|
||||
|
@ -206,8 +205,7 @@ void RestSimpleHandler::removeByKeys(VPackSlice const& slice) {
|
|||
|
||||
arangodb::aql::Query query(
|
||||
_applicationV8, false, _vocbase, aql.c_str(), aql.size(),
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(varsSlice),
|
||||
nullptr, arangodb::aql::PART_MAIN);
|
||||
bindVars, nullptr, arangodb::aql::PART_MAIN);
|
||||
|
||||
registerQuery(&query);
|
||||
auto queryResult = query.execute(_queryRegistry);
|
||||
|
@ -304,25 +302,22 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
|
|||
return;
|
||||
}
|
||||
|
||||
VPackBuilder bindVars;
|
||||
bindVars.add(VPackValue(VPackValueType::Object));
|
||||
bindVars.add("@collection", VPackValue(collectionName));
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
bindVars->openObject();
|
||||
bindVars->add("@collection", VPackValue(collectionName));
|
||||
VPackBuilder strippedBuilder =
|
||||
arangodb::aql::BindParameters::StripCollectionNames(
|
||||
keys, collectionName.c_str());
|
||||
VPackSlice stripped = strippedBuilder.slice();
|
||||
|
||||
bindVars.add("keys", stripped);
|
||||
bindVars.close();
|
||||
VPackSlice varsSlice = bindVars.slice();
|
||||
bindVars->add("keys", strippedBuilder.slice());
|
||||
bindVars->close();
|
||||
|
||||
std::string const aql(
|
||||
"FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc");
|
||||
|
||||
arangodb::aql::Query query(
|
||||
_applicationV8, false, _vocbase, aql.c_str(), aql.size(),
|
||||
arangodb::basics::VelocyPackHelper::velocyPackToJson(varsSlice),
|
||||
nullptr, arangodb::aql::PART_MAIN);
|
||||
bindVars, nullptr, arangodb::aql::PART_MAIN);
|
||||
|
||||
registerQuery(&query);
|
||||
auto queryResult = query.execute(_queryRegistry);
|
||||
|
|
|
@ -401,7 +401,7 @@ void Scheduler::setProcessorAffinity(size_t i, size_t c) {
|
|||
Task* Scheduler::lookupTaskById(uint64_t taskId) {
|
||||
MUTEX_LOCKER(mutexLocker, schedulerLock);
|
||||
|
||||
auto&& task = taskRegistered.find(taskId);
|
||||
auto task = taskRegistered.find(taskId);
|
||||
|
||||
if (task == taskRegistered.end()) {
|
||||
return nullptr;
|
||||
|
@ -417,7 +417,7 @@ Task* Scheduler::lookupTaskById(uint64_t taskId) {
|
|||
EventLoop Scheduler::lookupLoopById(uint64_t taskId) {
|
||||
MUTEX_LOCKER(mutexLocker, schedulerLock);
|
||||
|
||||
auto&& task = taskRegistered.find(taskId);
|
||||
auto task = taskRegistered.find(taskId);
|
||||
|
||||
if (task == taskRegistered.end()) {
|
||||
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));
|
||||
|
||||
// set the task id
|
||||
std::string const&& taskId = StringUtils::itoa(request->clientTaskId());
|
||||
std::string const taskId(StringUtils::itoa(request->clientTaskId()));
|
||||
|
||||
// set the connection info
|
||||
const ConnectionInfo& info = request->connectionInfo();
|
||||
|
@ -590,8 +590,7 @@ static HttpResponse* ResponseV8ToCpp(v8::Isolate* isolate,
|
|||
response->body().appendText(V8Buffer::data(obj), V8Buffer::length(obj));
|
||||
} else {
|
||||
// treat body as a string
|
||||
std::string&& obj(TRI_ObjectToString(res->Get(BodyKey)));
|
||||
response->body().appendText(obj);
|
||||
response->body().appendText(TRI_ObjectToString(res->Get(BodyKey)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "VocBase/vocbase.h"
|
||||
#include "VocBase/VocShaper.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Iterator.h>
|
||||
#include <velocypack/Slice.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,
|
||||
std::string const& aql, VPackSlice const& slice) {
|
||||
std::string const& aql, std::shared_ptr<VPackBuilder> bindVars) {
|
||||
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();
|
||||
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);
|
||||
|
||||
auto queryResult = query.executeV8(
|
||||
|
@ -542,17 +534,17 @@ static void EdgesQuery(TRI_edge_direction_e direction,
|
|||
|
||||
TRI_THROW_SHARDING_COLLECTION_NOT_YET_IMPLEMENTED(col);
|
||||
|
||||
VPackBuilder builder;
|
||||
builder.openObject();
|
||||
builder.add("@collection", VPackValue(col->name()));
|
||||
builder.add(VPackValue("value"));
|
||||
int res = TRI_V8ToVPack(isolate, builder, args[0], false);
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
bindVars->openObject();
|
||||
bindVars->add("@collection", VPackValue(col->name()));
|
||||
bindVars->add(VPackValue("value"));
|
||||
int res = TRI_V8ToVPack(isolate, *(bindVars.get()), args[0], false);
|
||||
bindVars->close();
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_V8_THROW_EXCEPTION(res);
|
||||
}
|
||||
|
||||
builder.close();
|
||||
|
||||
std::string filter;
|
||||
// argument is a list of vertices
|
||||
|
@ -577,7 +569,7 @@ static void EdgesQuery(TRI_edge_direction_e direction,
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
TRI_V8_RETURN(result);
|
||||
|
@ -1287,7 +1279,7 @@ static void FulltextQuery(SingleCollectionTransaction& trx,
|
|||
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;
|
||||
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>)");
|
||||
}
|
||||
|
||||
arangodb::basics::Json bindVars(arangodb::basics::Json::Object, 2);
|
||||
bindVars("@collection", arangodb::basics::Json(std::string(col->_name)));
|
||||
bindVars("keys", arangodb::basics::Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
TRI_ObjectToJson(isolate, args[0])));
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
bindVars->openObject();
|
||||
bindVars->add("@collection", VPackValue(std::string(col->_name)));
|
||||
|
||||
std::string const collectionName(col->name());
|
||||
VPackBuilder keys;
|
||||
int res = TRI_V8ToVPack(isolate, keys, args[0], false);
|
||||
|
||||
arangodb::aql::BindParameters::StripCollectionNames(
|
||||
TRI_LookupObjectJson(bindVars.json(), "keys"), collectionName.c_str());
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
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(
|
||||
"FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc");
|
||||
|
||||
TRI_GET_GLOBALS();
|
||||
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);
|
||||
|
||||
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>)");
|
||||
}
|
||||
|
||||
arangodb::basics::Json bindVars(arangodb::basics::Json::Object, 2);
|
||||
bindVars("@collection", arangodb::basics::Json(std::string(col->_name)));
|
||||
bindVars("keys", arangodb::basics::Json(TRI_UNKNOWN_MEM_ZONE,
|
||||
TRI_ObjectToJson(isolate, args[0])));
|
||||
auto bindVars = std::make_shared<VPackBuilder>();
|
||||
bindVars->openObject();
|
||||
bindVars->add("@collection", VPackValue(col->_name));
|
||||
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(
|
||||
"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();
|
||||
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);
|
||||
|
||||
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>");
|
||||
}
|
||||
|
||||
std::string const&& queryString = TRI_ObjectToString(args[0]);
|
||||
std::string const queryString(TRI_ObjectToString(args[0]));
|
||||
|
||||
// bind parameters
|
||||
std::unique_ptr<TRI_json_t> parameters;
|
||||
std::shared_ptr<VPackBuilder> bindVars;
|
||||
|
||||
if (args.Length() > 1) {
|
||||
if (!args[1]->IsUndefined() && !args[1]->IsNull() && !args[1]->IsObject()) {
|
||||
TRI_V8_THROW_TYPE_ERROR("expecting object for <bindvalues>");
|
||||
}
|
||||
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();
|
||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
||||
queryString.c_str(), queryString.size(),
|
||||
parameters.release(), options.release(),
|
||||
bindVars, options.release(),
|
||||
arangodb::aql::PART_MAIN);
|
||||
|
||||
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>");
|
||||
}
|
||||
|
||||
std::string const&& queryString = TRI_ObjectToString(args[0]);
|
||||
std::string const queryString(TRI_ObjectToString(args[0]));
|
||||
|
||||
// bind parameters
|
||||
std::unique_ptr<TRI_json_t> parameters;
|
||||
std::shared_ptr<VPackBuilder> bindVars;
|
||||
|
||||
// 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>");
|
||||
}
|
||||
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();
|
||||
arangodb::aql::Query query(v8g->_applicationV8, true, vocbase,
|
||||
queryString.c_str(), queryString.size(),
|
||||
parameters.get(), options.get(),
|
||||
bindVars, options.get(),
|
||||
arangodb::aql::PART_MAIN);
|
||||
|
||||
options.release();
|
||||
parameters.release();
|
||||
|
||||
auto queryResult = query.executeV8(
|
||||
isolate, static_cast<arangodb::aql::QueryRegistry*>(v8g->_queryRegistry));
|
||||
|
|
|
@ -1308,7 +1308,7 @@ static void JS_GetIndexesVocbaseCol(
|
|||
std::string const& collectionName = std::string(collection->_name);
|
||||
|
||||
// get list of indexes
|
||||
auto&& indexes = TRI_IndexesDocumentCollection(document, withFigures);
|
||||
auto indexes(TRI_IndexesDocumentCollection(document, withFigures));
|
||||
|
||||
trx.finish(res);
|
||||
// READ-LOCK end
|
||||
|
|
|
@ -50,8 +50,6 @@
|
|||
/// concrete sub-class @ref TRI_document_collection_t.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct TRI_json_t;
|
||||
|
||||
namespace arangodb {
|
||||
class CollectionInfo;
|
||||
namespace velocypack {
|
||||
|
|
Loading…
Reference in New Issue