1
0
Fork 0

some json removal

This commit is contained in:
Jan Steemann 2016-03-02 17:51:05 +01:00
parent 4c03f4bf8d
commit 06da362f93
17 changed files with 230 additions and 186 deletions

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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';
}
}
}
}

View File

@ -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

View File

@ -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) {

View File

@ -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(),

View File

@ -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) {

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)));
}
}
}

View File

@ -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(

View File

@ -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));

View File

@ -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

View File

@ -50,8 +50,6 @@
/// concrete sub-class @ref TRI_document_collection_t.
////////////////////////////////////////////////////////////////////////////////
struct TRI_json_t;
namespace arangodb {
class CollectionInfo;
namespace velocypack {