1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into agency

This commit is contained in:
Kaveh Vahedipour 2016-02-17 09:44:09 +01:00
commit 388ca14aa7
94 changed files with 7191 additions and 1773 deletions

View File

@ -16,6 +16,20 @@ macro(import_target tname tdep tinclude tpath)
)
endmacro()
# ETCD
if (MSVC)
set (ETCD_BUILD_COMMAND build.bat)
else()
set (ETCD_BUILD_COMMAND ./build)
endif()
ExternalProject_Add(etcd_build
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/etcd
CONFIGURE_COMMAND ""
BUILD_IN_SOURCE TRUE
BUILD_COMMAND "${ETCD_BUILD_COMMAND}"
INSTALL_COMMAND "")
# ZLIB
if (UNIX)
ExternalProject_Add(zlib_build

View File

@ -1,6 +1,14 @@
v3.0.0 (XXXX-XX-XX)
-------------------
* The order of AQL functions VALUES and KEYS has never been guaranteed and
by accident it had the "correct" ordering when iteratoring over Objects that
were not loaded from the database. This behaviour is now changed by
introduction of VelocyPack and no ordering is guaranteed unless you specify
the do sort parameter.
* removed configure option `--enable-logger`
* added AQL array comparison operators
All AQL comparison operators now lso exist in an array variant. In the
@ -294,7 +302,9 @@ v2.8.0-beta7 (2016-01-06)
FOR doc IN collection
COLLECT AGGREGATE minAge = MIN(doc.age), maxAge = MAX(doc.age)
RETURN { minAge, maxAge }
RETURN {
minAge, maxAge
}
Only specific expressions are allowed on the right-hand side of each `AGGREGATE`
assignment:

View File

@ -103,13 +103,28 @@ endif()
# TODO: Exclude non-supported?
## Compiler flags --------------------------------------------------------------
# Build types
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_TL)
message (${CMAKE_BUILD_TYPE_TL})
if(CMAKE_BUILD_TYPE_TL MATCHES debug)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g")
elseif(CMAKE_BUILD_TYPE_TL MATCHES relwithdebinfo)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -g")
elseif(CMAKE_BUILD_TYPE_TL MATCHES release)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif()
# GCC
if (CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu89 -g -O2")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -g -O2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu89")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
endif ()
if (CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -O2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@ -122,7 +137,7 @@ endif()
# OSX
if (APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O2 -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if (CMAKE_COMPILER_IS_CLANG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
add_definitions("-Wno-deprecated-declarations")
@ -756,3 +771,4 @@ endif ()
# Finally: user cpack
include(CPack)

View File

@ -113,7 +113,7 @@ AQL supports the following functions to operate on document values:
- *VALUES(document, removeInternal)*: Returns the attribute values of the *document*
as an array. If *removeInternal* is set to *true*, then all internal attributes (such
as *_id*, *_key* etc.) are removed from the result.
as *_id*, *_key* etc.) are removed from the result. The values will be returned in any order.
- *ZIP(attributes, values)*: Returns a document object assembled from the
separate parameters *attributes* and *values*. *attributes* and *values* must be

View File

@ -37,6 +37,11 @@ using namespace arangodb::aql;
using Json = arangodb::basics::Json;
using JsonHelper = arangodb::basics::JsonHelper;
AqlValue::AqlValue(AqlValue$ const& other) : _json(nullptr), _type(JSON) {
_json = new Json(TRI_UNKNOWN_MEM_ZONE, arangodb::basics::VelocyPackHelper::velocyPackToJson(other.slice()));
TRI_ASSERT(_json != nullptr);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief a quick method to decide whether a value is true
////////////////////////////////////////////////////////////////////////////////
@ -723,20 +728,165 @@ Json AqlValue::toJson(arangodb::AqlTransaction* trx,
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
// NOTE IMPORTANT: During the moving Process of shaped => VPACK
// This function is slower than toJson().
// It is just used for validation purposes of the callers
std::shared_ptr<VPackBuffer<uint8_t>> AqlValue::toVelocyPack(
arangodb::AqlTransaction* trx, TRI_document_collection_t const* document,
bool copy) const {
////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor
////////////////////////////////////////////////////////////////////////////////
AqlValue$::AqlValue$(VPackBuilder const& data) {
TRI_ASSERT(data.isClosed());
VPackValueLength l = data.size();
if (l < 16) {
// Use internal
memcpy(_data.internal, data.data(), l);
_data.internal[15] = AqlValueType::INTERNAL;
} else {
// Use external
_data.external = new VPackBuffer<uint8_t>(l);
memcpy(_data.external->data(), data.data(), l);
_data.internal[15] = AqlValueType::EXTERNAL;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor
////////////////////////////////////////////////////////////////////////////////
AqlValue$::AqlValue$(VPackBuilder const* data) : AqlValue$(*data){};
////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor
////////////////////////////////////////////////////////////////////////////////
AqlValue$::AqlValue$(VPackSlice const& data) {
VPackValueLength l = data.byteSize();
if (l < 16) {
// Use internal
memcpy(_data.internal, data.start(), l);
_data.internal[15] = AqlValueType::INTERNAL;
} else {
// Use external
_data.external = new VPackBuffer<uint8_t>(l);
memcpy(_data.external->data(), data.start(), l);
_data.internal[15] = AqlValueType::EXTERNAL;
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Copy Constructor.
////////////////////////////////////////////////////////////////////////////////
AqlValue$::AqlValue$(AqlValue$ const& other) {
VPackSlice s = other.slice();
VPackValueLength length = s.byteSize();
if (other.type()) {
// Isse external
_data.external = new VPackBuffer<uint8_t>(length);
memcpy(_data.external->data(), other._data.external->data(), length);
_data.internal[15] = AqlValueType::EXTERNAL;
} else {
memcpy(_data.internal, other._data.internal, length);
_data.internal[15] = AqlValueType::INTERNAL;
}
}
// Temporary constructor to transform an old AqlValue to a new VPackBased
// AqlValue
AqlValue$::AqlValue$(AqlValue const& other, arangodb::AqlTransaction* trx,
TRI_document_collection_t const* document) {
VPackBuilder builder;
toVelocyPack(trx, document, copy, builder);
return builder.steal();
switch (other._type) {
case AqlValue::JSON: {
TRI_ASSERT(other._json != nullptr);
// TODO: Internal is still JSON. We always copy.
int res = arangodb::basics::JsonHelper::toVelocyPack(other._json->json(), builder);
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
break;
}
case AqlValue::SHAPED: {
TRI_ASSERT(document != nullptr);
TRI_ASSERT(other._marker != nullptr);
auto shaper = document->getShaper();
Json tmp = TRI_ExpandShapedJson(shaper, trx->resolver(),
document->_info.id(), other._marker);
int res = arangodb::basics::JsonHelper::toVelocyPack(tmp.json(), builder);
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
break;
}
case AqlValue::DOCVEC: {
TRI_ASSERT(other._vector != nullptr);
try {
VPackArrayBuilder b(&builder);
for (auto const& current : *other._vector) {
size_t const n = current->size();
auto vecCollection = current->getDocumentCollection(0);
for (size_t i = 0; i < n; ++i) {
current->getValueReference(i, 0)
.toVelocyPack(trx, vecCollection, builder);
}
}
} catch (...) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
break;
}
case AqlValue::RANGE: {
// TODO Has to be replaced by VPackCustom Type
TRI_ASSERT(other._range != nullptr);
try {
VPackArrayBuilder b(&builder);
size_t const n = other._range->size();
for (size_t i = 0; i < n; ++i) {
builder.add(VPackValue(other._range->at(i)));
}
} catch (...) {
}
break;
}
case AqlValue::EMPTY: {
builder.add(VPackValue(VPackValueType::Null));
break;
}
default: {
TRI_ASSERT(false);
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
}
VPackValueLength length = builder.size();
if (length < 16) {
// Small enough for local
// copy memory from the builder into the internal data.
memcpy(_data.internal, builder.data(), length);
_data.internal[15] = AqlValueType::INTERNAL;
} else {
// We need a large external buffer
// TODO: Replace by SlimBuffer
_data.external = new VPackBuffer<uint8_t>(length);
memcpy(_data.external->data(), builder.data(), length);
_data.internal[15] = AqlValueType::EXTERNAL;
}
}
AqlValue$::AqlValueType AqlValue$::type() const {
return static_cast<AqlValueType>(_data.internal[15]);
}
VPackSlice AqlValue$::slice() const {
if (type()) {
// Use External
return VPackSlice(_data.external->data());
} else {
return VPackSlice(_data.internal);
}
}
void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx,
TRI_document_collection_t const* document,
bool copy, VPackBuilder& builder) const {
VPackBuilder& builder) const {
switch (_type) {
case JSON: {
TRI_ASSERT(_json != nullptr);
@ -745,17 +895,19 @@ void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx,
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
break;
}
case SHAPED: {
TRI_ASSERT(document != nullptr);
TRI_ASSERT(_marker != nullptr);
auto shaper = document->getShaper();
Json tmp = TRI_ExpandShapedJson(shaper, trx->resolver(),
document->_info.id(), _marker);
document->_info.id(), _marker);
int res = arangodb::basics::JsonHelper::toVelocyPack(tmp.json(), builder);
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
break;
}
case DOCVEC: {
TRI_ASSERT(_vector != nullptr);
@ -766,14 +918,16 @@ void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx,
auto vecCollection = current->getDocumentCollection(0);
for (size_t i = 0; i < n; ++i) {
current->getValueReference(i, 0)
.toVelocyPack(trx, vecCollection, true, builder);
.toVelocyPack(trx, vecCollection, builder);
}
}
} catch (...) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
break;
}
case RANGE: {
// TODO Has to be replaced by VPackCustom Type
TRI_ASSERT(_range != nullptr);
try {
VPackArrayBuilder b(&builder);
@ -784,9 +938,11 @@ void AqlValue::toVelocyPack(arangodb::AqlTransaction* trx,
} catch (...) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
break;
}
case EMPTY: {
builder.add(VPackValue(VPackValueType::Null));
break;
}
default: {
TRI_ASSERT(false);

View File

@ -46,6 +46,9 @@ namespace aql {
class AqlItemBlock;
// Temporary Forward
struct AqlValue$;
////////////////////////////////////////////////////////////////////////////////
/// @brief a struct to hold a value, registers hole AqlValue* during the
/// execution
@ -89,6 +92,8 @@ struct AqlValue {
_range = new Range(low, high);
}
explicit AqlValue(AqlValue$ const& other);
//////////////////////////////////////////////////////////////////////////////
/// @brief destructor, doing nothing automatically!
//////////////////////////////////////////////////////////////////////////////
@ -284,15 +289,8 @@ struct AqlValue {
arangodb::basics::Json toJson(arangodb::AqlTransaction*,
TRI_document_collection_t const*, bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief toVelocyPack method
//////////////////////////////////////////////////////////////////////////////
std::shared_ptr<arangodb::velocypack::Buffer<uint8_t>> toVelocyPack(
arangodb::AqlTransaction*, TRI_document_collection_t const*, bool) const;
void toVelocyPack(arangodb::AqlTransaction*, TRI_document_collection_t const*,
bool, arangodb::velocypack::Builder&) const;
arangodb::velocypack::Builder&) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief creates a hash value for the AqlValue
@ -364,6 +362,69 @@ struct AqlValue {
AqlValueType _type;
};
struct AqlValue$ {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief AqlValueType, indicates what sort of value we have
//////////////////////////////////////////////////////////////////////////////
enum AqlValueType { INTERNAL, EXTERNAL };
//////////////////////////////////////////////////////////////////////////////
/// @brief Holds the actual data for this AqlValue it has the following
/// semantics:
///
/// All values with a size less than 16 will be stored directly in this
/// AqlValue using the data.internal structure.
/// All values of a larger size will be store in data.external.
/// The last bit of this union will be used to identify if we have to use
/// internal or external.
/// Delete of the Buffer should free every structure that is not using the
/// VPack external value type.
//////////////////////////////////////////////////////////////////////////////
private:
union {
char internal[16];
arangodb::velocypack::Buffer<uint8_t>* external;
} _data;
public:
AqlValue$(arangodb::velocypack::Builder const&);
AqlValue$(arangodb::velocypack::Builder const*);
AqlValue$(arangodb::velocypack::Slice const&);
AqlValue$(AqlValue const&, arangodb::AqlTransaction*,
TRI_document_collection_t const*);
~AqlValue$() {
if (type() && _data.external != nullptr) {
delete _data.external;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Copy Constructor.
////////////////////////////////////////////////////////////////////////////////
AqlValue$(AqlValue$ const& other);
//////////////////////////////////////////////////////////////////////////////
/// @brief Returns the type of this value. If true it uses an external pointer
/// if false it uses the internal data structure
//////////////////////////////////////////////////////////////////////////////
// Read last bit of the union
AqlValueType type() const;
//////////////////////////////////////////////////////////////////////////////
/// @brief Returns a slice to read this Value's data
//////////////////////////////////////////////////////////////////////////////
arangodb::velocypack::Slice slice() const;
};
static_assert(sizeof(AqlValue$) < 17, "invalid AqlValue size.");
} // closes namespace arangodb::aql
} // closes namespace arangodb

View File

@ -1285,11 +1285,88 @@ TRI_json_t* AstNode::toJson(TRI_memory_zone_t* zone, bool verbose) const {
//////////////////////////////////////////////////////////////////////////////
std::shared_ptr<VPackBuilder> AstNode::toVelocyPackValue() const {
std::unique_ptr<TRI_json_t> tmp(toJsonValue(TRI_UNKNOWN_MEM_ZONE));
if (tmp == nullptr) {
auto builder = std::make_shared<VPackBuilder>();
if (builder == nullptr) {
return nullptr;
}
return arangodb::basics::JsonHelper::toVelocyPack(tmp.get());
toVelocyPackValue(*builder);
return builder;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief build a VelocyPack representation of the node value
/// Can throw Out of Memory Error
//////////////////////////////////////////////////////////////////////////////
void AstNode::toVelocyPackValue(VPackBuilder& builder) const {
if (type == NODE_TYPE_VALUE) {
// dump value of "value" node
switch (value.type) {
case VALUE_TYPE_NULL:
builder.add(VPackValue(VPackValueType::Null));
break;
case VALUE_TYPE_BOOL:
builder.add(VPackValue(value.value._bool));
break;
case VALUE_TYPE_INT:
builder.add(VPackValue(static_cast<double>(value.value._int)));
break;
case VALUE_TYPE_DOUBLE:
builder.add(VPackValue(value.value._double));
break;
case VALUE_TYPE_STRING:
builder.add(VPackValue(std::string(value.value._string, value.length)));
break;
}
return;
}
if (type == NODE_TYPE_ARRAY) {
{
VPackArrayBuilder guard(&builder);
size_t const n = numMembers();
for (size_t i = 0; i < n; ++i) {
auto member = getMemberUnchecked(i);
if (member != nullptr) {
member->toVelocyPackValue(builder);
}
}
}
return;
}
if (type == NODE_TYPE_OBJECT) {
{
size_t const n = numMembers();
VPackObjectBuilder guard(&builder);
for (size_t i = 0; i < n; ++i) {
auto member = getMemberUnchecked(i);
if (member != nullptr) {
builder.add(VPackValue(member->getStringValue()));
member->getMember(0)->toVelocyPackValue(builder);
}
}
}
return;
}
if (type == NODE_TYPE_ATTRIBUTE_ACCESS) {
// TODO Could this be done more efficiently in the builder in place?
auto tmp = getMember(0)->toVelocyPackValue();
if (tmp != nullptr) {
VPackSlice slice = tmp->slice();
if (slice.isObject()) {
slice = slice.get(getStringValue());
if (!slice.isNone()) {
builder.add(slice);
return;
}
}
builder.add(VPackValue(VPackValueType::Null));
}
}
// Do not add anything.
}
//////////////////////////////////////////////////////////////////////////////
@ -1297,8 +1374,93 @@ std::shared_ptr<VPackBuilder> AstNode::toVelocyPackValue() const {
//////////////////////////////////////////////////////////////////////////////
std::shared_ptr<VPackBuilder> AstNode::toVelocyPack(bool verbose) const {
std::unique_ptr<TRI_json_t> tmp(toJson(TRI_UNKNOWN_MEM_ZONE, verbose));
return arangodb::basics::JsonHelper::toVelocyPack(tmp.get());
auto builder = std::make_shared<VPackBuilder>();
if (builder == nullptr) {
return nullptr;
}
toVelocyPack(*builder, verbose);
return builder;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief Create a VelocyPack representation of the node
//////////////////////////////////////////////////////////////////////////////
void AstNode::toVelocyPack(VPackBuilder& builder, bool verbose) const {
try {
VPackObjectBuilder guard(&builder);
// dump node type
builder.add("type", VPackValue(getTypeString()));
if (verbose) {
builder.add("typeID", VPackValue(static_cast<int>(type)));
}
if (type == NODE_TYPE_COLLECTION || type == NODE_TYPE_PARAMETER ||
type == NODE_TYPE_ATTRIBUTE_ACCESS ||
type == NODE_TYPE_OBJECT_ELEMENT || type == NODE_TYPE_FCALL_USER) {
// dump "name" of node
builder.add("name", VPackValue(getStringValue()));
}
if (type == NODE_TYPE_FCALL) {
auto func = static_cast<Function*>(getData());
builder.add("name", VPackValue(func->externalName));
// arguments are exported via node members
}
if (type == NODE_TYPE_ARRAY && hasFlag(DETERMINED_SORTED)) {
// transport information about a node's sortedness
builder.add("sorted", VPackValue(hasFlag(VALUE_SORTED)));
}
if (type == NODE_TYPE_VALUE) {
// dump value of "value" node
builder.add(VPackValue("value"));
toVelocyPackValue(builder);
if (verbose) {
builder.add("vType", VPackValue(getValueTypeString()));
builder.add("vTypeID", VPackValue(static_cast<int>(value.type)));
}
}
if (type == NODE_TYPE_OPERATOR_BINARY_IN ||
type == NODE_TYPE_OPERATOR_BINARY_NIN ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_IN ||
type == NODE_TYPE_OPERATOR_BINARY_ARRAY_NIN) {
builder.add("sorted", VPackValue(getBoolValue()));
}
if (type == NODE_TYPE_QUANTIFIER) {
std::string const quantifier(Quantifier::Stringify(getIntValue(true)));
builder.add("quantifier", VPackValue(quantifier));
}
if (type == NODE_TYPE_VARIABLE || type == NODE_TYPE_REFERENCE) {
auto variable = static_cast<Variable*>(getData());
TRI_ASSERT(variable != nullptr);
builder.add("name", VPackValue(variable->name));
builder.add("id", VPackValue(static_cast<double>(variable->id)));
}
if (type == NODE_TYPE_EXPANSION) {
builder.add("levels", VPackValue(static_cast<double>(getIntValue(true))));
}
// dump sub-nodes
size_t const n = members.size();
if (n > 0) {
builder.add(VPackValue("subNodes"));
VPackArrayBuilder guard(&builder);
for (size_t i = 0; i < n; ++i) {
AstNode* member = getMemberUnchecked(i);
if (member != nullptr) {
member->toVelocyPack(builder, verbose);
}
}
}
} catch (...) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -361,12 +361,25 @@ struct AstNode {
std::shared_ptr<arangodb::velocypack::Builder> toVelocyPackValue() const;
//////////////////////////////////////////////////////////////////////////////
/// @brief build a VelocyPack representation of the node value
/// Can throw Out of Memory Error
//////////////////////////////////////////////////////////////////////////////
void toVelocyPackValue(arangodb::velocypack::Builder&) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief return a VelocyPack representation of the node
//////////////////////////////////////////////////////////////////////////////
std::shared_ptr<arangodb::velocypack::Builder> toVelocyPack(bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief Create a VelocyPack representation of the node
//////////////////////////////////////////////////////////////////////////////
void toVelocyPack(arangodb::velocypack::Builder&, bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief adds a JSON representation of the node to the JSON array specified
/// in the first argument

View File

@ -45,29 +45,26 @@ RemoteNode::RemoteNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
base.json(), "isResponsibleForInitCursor")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for RemoteNode
/// @brief toVelocyPack, for RemoteNode
////////////////////////////////////////////////////////////////////////////////
void RemoteNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
void RemoteNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
json("database", arangodb::basics::Json(_vocbase->_name))(
"collection", arangodb::basics::Json(_collection->getName()))(
"server", arangodb::basics::Json(_server))(
"ownName", arangodb::basics::Json(_ownName))(
"queryId", arangodb::basics::Json(_queryId))(
"isResponsibleForInitCursor",
arangodb::basics::Json(_isResponsibleForInitCursor));
nodes.add("database", VPackValue(_vocbase->_name));
nodes.add("collection", VPackValue(_collection->getName()));
nodes.add("server", VPackValue(_server));
nodes.add("ownName", VPackValue(_ownName));
nodes.add("queryId", VPackValue(_queryId));
nodes.add("isResponsibleForInitCursor",
VPackValue(_isResponsibleForInitCursor));
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief estimateCost
////////////////////////////////////////////////////////////////////////////////
@ -97,22 +94,17 @@ ScatterNode::ScatterNode(ExecutionPlan* plan,
JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for ScatterNode
/// @brief toVelocyPack, for ScatterNode
////////////////////////////////////////////////////////////////////////////////
void ScatterNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
void ScatterNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose); // call base class method
json("database", arangodb::basics::Json(_vocbase->_name))(
"collection", arangodb::basics::Json(_collection->getName()));
nodes.add("database", VPackValue(_vocbase->_name));
nodes.add("collection", VPackValue(_collection->getName()));
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////
@ -145,26 +137,26 @@ DistributeNode::DistributeNode(ExecutionPlan* plan,
_allowKeyConversionToObject(JsonHelper::checkAndGetBooleanValue(
base.json(), "allowKeyConversionToObject")) {}
void DistributeNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
////////////////////////////////////////////////////////////////////////////////
/// @brief toVelocyPack, for DistributedNode
////////////////////////////////////////////////////////////////////////////////
if (json.isEmpty()) {
return;
}
void DistributeNode::toVelocyPackHelper(VPackBuilder& nodes,
bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
json("database", arangodb::basics::Json(_vocbase->_name))(
"collection", arangodb::basics::Json(_collection->getName()))(
"varId", arangodb::basics::Json(static_cast<int>(_varId)))(
"alternativeVarId",
arangodb::basics::Json(static_cast<int>(_alternativeVarId)))(
"createKeys", arangodb::basics::Json(_createKeys))(
"allowKeyConversionToObject",
arangodb::basics::Json(_allowKeyConversionToObject));
nodes.add("database", VPackValue(_vocbase->_name));
nodes.add("collection", VPackValue(_collection->getName()));
nodes.add("varId", VPackValue(static_cast<int>(_varId)));
nodes.add("alternativeVarId",
VPackValue(static_cast<int>(_alternativeVarId)));
nodes.add("createKeys", VPackValue(_createKeys));
nodes.add("allowKeyConversionToObject",
VPackValue(_allowKeyConversionToObject));
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////
@ -189,32 +181,29 @@ GatherNode::GatherNode(ExecutionPlan* plan, arangodb::basics::Json const& base,
JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for GatherNode
/// @brief toVelocyPack, for GatherNode
////////////////////////////////////////////////////////////////////////////////
void GatherNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
void GatherNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
nodes.add("database", VPackValue(_vocbase->_name));
nodes.add("collection", VPackValue(_collection->getName()));
nodes.add(VPackValue("elements"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& it : _elements) {
VPackObjectBuilder obj(&nodes);
nodes.add(VPackValue("inVariable"));
it.first->toVelocyPack(nodes);
nodes.add("ascending", VPackValue(it.second));
}
}
json("database", arangodb::basics::Json(_vocbase->_name))(
"collection", arangodb::basics::Json(_collection->getName()));
arangodb::basics::Json values(arangodb::basics::Json::Array,
_elements.size());
for (auto it = _elements.begin(); it != _elements.end(); ++it) {
arangodb::basics::Json element(arangodb::basics::Json::Object);
element("inVariable", (*it).first->toJson())(
"ascending", arangodb::basics::Json((*it).second));
values(element);
}
json("elements", values);
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -92,11 +92,11 @@ class RemoteNode : public ExecutionNode {
NodeType getType() const override final { return REMOTE; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -240,11 +240,11 @@ class ScatterNode : public ExecutionNode {
NodeType getType() const override final { return SCATTER; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -333,11 +333,11 @@ class DistributeNode : public ExecutionNode {
NodeType getType() const override final { return DISTRIBUTE; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -438,11 +438,11 @@ class GatherNode : public ExecutionNode {
NodeType getType() const override final { return GATHER; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively

View File

@ -54,76 +54,72 @@ CollectNode::CollectNode(
CollectNode::~CollectNode() {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for CollectNode
/// @brief toVelocyPack, for CollectNode
////////////////////////////////////////////////////////////////////////////////
void CollectNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
void CollectNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
// group variables
nodes.add(VPackValue("groups"));
{
arangodb::basics::Json values(arangodb::basics::Json::Array,
_groupVariables.size());
VPackArrayBuilder guard(&nodes);
for (auto const& groupVariable : _groupVariables) {
arangodb::basics::Json variable(arangodb::basics::Json::Object);
variable("outVariable", groupVariable.first->toJson())(
"inVariable", groupVariable.second->toJson());
values(variable);
VPackObjectBuilder obj(&nodes);
nodes.add(VPackValue("outVariable"));
groupVariable.first->toVelocyPack(nodes);
nodes.add(VPackValue("inVariable"));
groupVariable.second->toVelocyPack(nodes);
}
json("groups", values);
}
// aggregate variables
nodes.add(VPackValue("aggregates"));
{
arangodb::basics::Json values(arangodb::basics::Json::Array,
_aggregateVariables.size());
VPackArrayBuilder guard(&nodes);
for (auto const& aggregateVariable : _aggregateVariables) {
arangodb::basics::Json variable(arangodb::basics::Json::Object);
variable("outVariable", aggregateVariable.first->toJson())(
"inVariable", aggregateVariable.second.first->toJson());
variable("type", arangodb::basics::Json(aggregateVariable.second.second));
values(variable);
VPackObjectBuilder obj(&nodes);
nodes.add(VPackValue("outVariable"));
aggregateVariable.first->toVelocyPack(nodes);
nodes.add(VPackValue("inVariable"));
aggregateVariable.second.first->toVelocyPack(nodes);
nodes.add("type", VPackValue(aggregateVariable.second.second));
}
json("aggregates", values);
}
// expression variable might be empty
if (_expressionVariable != nullptr) {
json("expressionVariable", _expressionVariable->toJson());
nodes.add(VPackValue("expressionVariable"));
_expressionVariable->toVelocyPack(nodes);
}
// output variable might be empty
if (_outVariable != nullptr) {
json("outVariable", _outVariable->toJson());
nodes.add(VPackValue("outVariable"));
_outVariable->toVelocyPack(nodes);
}
if (!_keepVariables.empty()) {
arangodb::basics::Json values(arangodb::basics::Json::Array,
_keepVariables.size());
for (auto it = _keepVariables.begin(); it != _keepVariables.end(); ++it) {
arangodb::basics::Json variable(arangodb::basics::Json::Object);
variable("variable", (*it)->toJson());
values(variable);
nodes.add(VPackValue("keepVariables"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& it : _keepVariables) {
VPackObjectBuilder obj(&nodes);
nodes.add(VPackValue("variable"));
it->toVelocyPack(nodes);
}
}
json("keepVariables", values);
}
json("count", arangodb::basics::Json(_count));
json("isDistinctCommand", arangodb::basics::Json(_isDistinctCommand));
json("specialized", arangodb::basics::Json(_specialized));
nodes.add("count", VPackValue(_count));
nodes.add("isDistinctCommand", VPackValue(_isDistinctCommand));
nodes.add("specialized", VPackValue(_specialized));
nodes.add(VPackValue("collectOptions"));
_options.toVelocyPack(nodes);
_options.toJson(json, zone);
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -145,11 +145,11 @@ class CollectNode : public ExecutionNode {
CollectOptions& getOptions() { return _options; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively

View File

@ -24,6 +24,8 @@
#include "Aql/CollectOptions.h"
#include "Basics/Exceptions.h"
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql;
using Json = arangodb::basics::Json;
using JsonHelper = arangodb::basics::JsonHelper;
@ -61,6 +63,15 @@ void CollectOptions::toJson(arangodb::basics::Json& json,
json("collectOptions", options);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the options to VelocyPack
////////////////////////////////////////////////////////////////////////////////
void CollectOptions::toVelocyPack(VPackBuilder& builder) const {
VPackObjectBuilder guard(&builder);
builder.add("method", VPackValue(methodToString(method)));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the aggregation method from a string
////////////////////////////////////////////////////////////////////////////////

View File

@ -69,6 +69,13 @@ struct CollectOptions {
void toJson(arangodb::basics::Json&, TRI_memory_zone_t*) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief convert the options to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toVelocyPack(arangodb::velocypack::Builder&) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief get the aggregation method from a string
//////////////////////////////////////////////////////////////////////////////

View File

@ -284,6 +284,19 @@ Condition::~Condition() {
// all nodes belong to the AST
}
//////////////////////////////////////////////////////////////////////////////
/// @brief export the condition as VelocyPack
//////////////////////////////////////////////////////////////////////////////
void Condition::toVelocyPack(arangodb::velocypack::Builder& builder,
bool verbose) const {
if (_root == nullptr) {
VPackObjectBuilder guard(&builder);
} else {
_root->toVelocyPack(builder, verbose);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create a condition from JSON
////////////////////////////////////////////////////////////////////////////////

View File

@ -237,6 +237,12 @@ class Condition {
return arangodb::basics::Json(zone, _root->toJson(zone, verbose));
}
//////////////////////////////////////////////////////////////////////////////
/// @brief export the condition as VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toVelocyPack(arangodb::velocypack::Builder&, bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief create a condition from JSON
//////////////////////////////////////////////////////////////////////////////

View File

@ -426,11 +426,9 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
/// @brief generatePlanForOneShard
//////////////////////////////////////////////////////////////////////////////
arangodb::basics::Json generatePlanForOneShard(size_t nr,
EngineInfo const& info,
QueryId& connectedId,
std::string const& shardId,
bool verbose) {
void generatePlanForOneShard(VPackBuilder& builder, size_t nr,
EngineInfo const& info, QueryId& connectedId,
std::string const& shardId, bool verbose) {
// copy the relevant fragment of the plan for each shard
// Note that in these parts of the query there are no SubqueryNodes,
// since they are all on the coordinator!
@ -462,7 +460,7 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
}
plan.root(previous);
plan.setVarUsageComputed();
return plan.root()->toJson(TRI_UNKNOWN_MEM_ZONE, verbose);
return plan.root()->toVelocyPack(builder, verbose);
}
//////////////////////////////////////////////////////////////////////////////
@ -605,11 +603,13 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
for (auto const& shardId : *shardIds) {
// inject the current shard id into the collection
collection->setCurrentShard(shardId);
auto jsonPlan =
generatePlanForOneShard(nr++, info, connectedId, shardId, true);
VPackBuilder b;
generatePlanForOneShard(b, nr++, info, connectedId, shardId, true);
std::unique_ptr<TRI_json_t> tmp(arangodb::basics::VelocyPackHelper::velocyPackToJson(b.slice()));
distributePlanToShard(coordTransactionID, info, collection, connectedId,
shardId, jsonPlan.steal());
shardId, tmp.release());
}
// fix collection

View File

@ -428,23 +428,22 @@ ExecutionNode::ExecutionNode(ExecutionPlan* plan,
}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, export an ExecutionNode to JSON
/// @brief toVelocyPack, export an ExecutionNode to VelocyPack
////////////////////////////////////////////////////////////////////////////////
arangodb::basics::Json ExecutionNode::toJson(TRI_memory_zone_t* zone,
bool verbose) const {
void ExecutionNode::toVelocyPack(VPackBuilder& builder, bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json nodes =
arangodb::basics::Json(arangodb::basics::Json::Array, 10);
toJsonHelper(nodes, zone, verbose);
arangodb::basics::Json json =
arangodb::basics::Json(arangodb::basics::Json::Object, 1)("nodes", nodes);
return json;
VPackObjectBuilder obj(&builder);
builder.add(VPackValue("nodes"));
{
VPackArrayBuilder guard(&builder);
toVelocyPackHelper(builder, verbose);
}
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
/// @brief execution Node clone utility to be called by derives
////////////////////////////////////////////////////////////////////////////////
@ -656,117 +655,119 @@ Variable* ExecutionNode::varFromJson(Ast* ast,
}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJsonHelper, for a generic node
/// @brief toVelocyPackHelper, for a generic node
/// Note: The input nodes has to be an Array Element that is still Open.
/// At the end of this function the current-nodes Object is OPEN and
/// has to be closed. The initial caller of toVelocyPackHelper
/// has to close the array.
////////////////////////////////////////////////////////////////////////////////
arangodb::basics::Json ExecutionNode::toJsonHelperGeneric(
arangodb::basics::Json& nodes, TRI_memory_zone_t* zone,
bool verbose) const {
void ExecutionNode::toVelocyPackHelperGeneric(VPackBuilder& nodes,
bool verbose) const {
ENTER_BLOCK
TRI_ASSERT(nodes.isOpenArray());
size_t const n = _dependencies.size();
for (size_t i = 0; i < n; i++) {
_dependencies[i]->toJsonHelper(nodes, zone, verbose);
_dependencies[i]->toVelocyPackHelper(nodes, verbose);
}
arangodb::basics::Json json(arangodb::basics::Json::Object, 5);
json("type", arangodb::basics::Json(getTypeString()));
nodes.openObject();
nodes.add("type", VPackValue(getTypeString()));
if (verbose) {
json("typeID", arangodb::basics::Json(static_cast<int>(getType())));
nodes.add("typeID", VPackValue(static_cast<int>(getType())));
}
arangodb::basics::Json deps(arangodb::basics::Json::Array, n);
for (size_t i = 0; i < n; i++) {
deps(arangodb::basics::Json(static_cast<double>(_dependencies[i]->id())));
}
json("dependencies", deps);
if (verbose) {
arangodb::basics::Json parents(arangodb::basics::Json::Array,
_parents.size());
for (size_t i = 0; i < _parents.size(); i++) {
parents(arangodb::basics::Json(static_cast<double>(_parents[i]->id())));
nodes.add(VPackValue("dependencies")); // Open Key
{
VPackArrayBuilder guard(&nodes);
for (auto const& it : _dependencies) {
nodes.add(VPackValue(static_cast<double>(it->id())));
}
json("parents", parents);
}
json("id", arangodb::basics::Json(static_cast<double>(id())));
if (verbose) {
nodes.add(VPackValue("parents")); // Open Key
VPackArrayBuilder guard(&nodes);
for (auto const& it : _parents) {
nodes.add(VPackValue(static_cast<double>(it->id())));
}
}
nodes.add("id", VPackValue(static_cast<double>(id())));
size_t nrItems = 0;
json("estimatedCost", arangodb::basics::Json(getCost(nrItems)));
json("estimatedNrItems",
arangodb::basics::Json(static_cast<double>(nrItems)));
nodes.add("estimatedCost", VPackValue(getCost(nrItems)));
nodes.add("estimatedNrItems", VPackValue(nrItems));
if (verbose) {
json("depth", arangodb::basics::Json(static_cast<double>(_depth)));
nodes.add("depth", VPackValue(static_cast<double>(_depth)));
if (_registerPlan) {
arangodb::basics::Json jsonVarInfoList(arangodb::basics::Json::Array,
_registerPlan->varInfo.size());
for (auto const& oneVarInfo : _registerPlan->varInfo) {
arangodb::basics::Json jsonOneVarInfoArray(
arangodb::basics::Json::Object, 2);
jsonOneVarInfoArray(
"VariableId",
arangodb::basics::Json(static_cast<double>(oneVarInfo.first)))(
"depth", arangodb::basics::Json(
static_cast<double>(oneVarInfo.second.depth)))(
"RegisterId", arangodb::basics::Json(static_cast<double>(
oneVarInfo.second.registerId)));
jsonVarInfoList(jsonOneVarInfoArray);
nodes.add(VPackValue("varInfoList"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& oneVarInfo : _registerPlan->varInfo) {
VPackObjectBuilder guardInner(&nodes);
nodes.add("VariableId",
VPackValue(static_cast<double>(oneVarInfo.first)));
nodes.add("depth",
VPackValue(static_cast<double>(oneVarInfo.second.depth)));
nodes.add(
"RegisterId",
VPackValue(static_cast<double>(oneVarInfo.second.registerId)));
}
}
json("varInfoList", jsonVarInfoList);
arangodb::basics::Json jsonNRRegsList(arangodb::basics::Json::Array,
_registerPlan->nrRegs.size());
for (auto const& oneRegisterID : _registerPlan->nrRegs) {
jsonNRRegsList(
arangodb::basics::Json(static_cast<double>(oneRegisterID)));
nodes.add(VPackValue("nrRegs"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& oneRegisterID : _registerPlan->nrRegs) {
nodes.add(VPackValue(static_cast<double>(oneRegisterID)));
}
}
json("nrRegs", jsonNRRegsList);
arangodb::basics::Json jsonNRRegsHereList(
arangodb::basics::Json::Array, _registerPlan->nrRegsHere.size());
for (auto const& oneRegisterID : _registerPlan->nrRegsHere) {
jsonNRRegsHereList(
arangodb::basics::Json(static_cast<double>(oneRegisterID)));
nodes.add(VPackValue("nrRegsHere"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& oneRegisterID : _registerPlan->nrRegsHere) {
nodes.add(VPackValue(static_cast<double>(oneRegisterID)));
}
}
json("nrRegsHere", jsonNRRegsHereList);
json("totalNrRegs", arangodb::basics::Json(
static_cast<double>(_registerPlan->totalNrRegs)));
nodes.add("totalNrRegs", VPackValue(_registerPlan->totalNrRegs));
} else {
json("varInfoList",
arangodb::basics::Json(arangodb::basics::Json::Array));
json("nrRegs", arangodb::basics::Json(arangodb::basics::Json::Array));
json("nrRegsHere", arangodb::basics::Json(arangodb::basics::Json::Array));
json("totalNrRegs", arangodb::basics::Json(0.0));
nodes.add(VPackValue("varInfoList"));
{
VPackArrayBuilder guard(&nodes);
}
nodes.add(VPackValue("nrRegs"));
{
VPackArrayBuilder guard(&nodes);
}
nodes.add(VPackValue("nrRegsHere"));
{
VPackArrayBuilder guard(&nodes);
}
nodes.add("totalNrRegs", VPackValue(0));
}
arangodb::basics::Json jsonRegsToClearList(arangodb::basics::Json::Array,
_regsToClear.size());
for (auto const& oneRegisterID : _regsToClear) {
jsonRegsToClearList(
arangodb::basics::Json(static_cast<double>(oneRegisterID)));
}
json("regsToClear", jsonRegsToClearList);
arangodb::basics::Json jsonVarsUsedLaterList(arangodb::basics::Json::Array,
_varsUsedLater.size());
for (auto const& oneVarUsedLater : _varsUsedLater) {
jsonVarsUsedLaterList.add(oneVarUsedLater->toJson());
nodes.add(VPackValue("regsToClear"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& oneRegisterID : _regsToClear) {
nodes.add(VPackValue(static_cast<double>(oneRegisterID)));
}
}
json("varsUsedLater", jsonVarsUsedLaterList);
arangodb::basics::Json jsonvarsValidList(arangodb::basics::Json::Array,
_varsValid.size());
for (auto const& oneVarUsedLater : _varsValid) {
jsonvarsValidList.add(oneVarUsedLater->toJson());
nodes.add(VPackValue("varsUsedLater"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& oneVar : _varsUsedLater) {
oneVar->toVelocyPack(nodes);
}
}
json("varsValid", jsonvarsValidList);
nodes.add(VPackValue("varsValid"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& oneVar : _varsValid) {
oneVar->toVelocyPack(nodes);
}
}
}
return json;
TRI_ASSERT(nodes.isOpenObject());
LEAVE_BLOCK
}
@ -1216,21 +1217,22 @@ SingletonNode::SingletonNode(ExecutionPlan* plan,
arangodb::basics::Json const& base)
: ExecutionNode(plan, base) {}
void SingletonNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
////////////////////////////////////////////////////////////////////////////////
/// @brief toVelocyPack, for SingletonNode
////////////////////////////////////////////////////////////////////////////////
void SingletonNode::toVelocyPackHelper(VPackBuilder& nodes,
bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
// And add it:
nodes(json);
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
// This node has no own information.
nodes.close();
LEAVE_BLOCK
}
////////////////////////////////////////////////////////////////////////////////
/// @brief the cost of a singleton is 1, it produces one item only
////////////////////////////////////////////////////////////////////////////////
@ -1250,28 +1252,24 @@ EnumerateCollectionNode::EnumerateCollectionNode(
_random(JsonHelper::checkAndGetBooleanValue(base.json(), "random")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for EnumerateCollectionNode
/// @brief toVelocyPack, for EnumerateCollectionNode
////////////////////////////////////////////////////////////////////////////////
void EnumerateCollectionNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone,
bool verbose) const {
void EnumerateCollectionNode::toVelocyPackHelper(VPackBuilder& nodes,
bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
// Now put info about vocbase and cid in there
json("database", arangodb::basics::Json(_vocbase->_name))(
"collection", arangodb::basics::Json(_collection->getName()))(
"outVariable", _outVariable->toJson())("random",
arangodb::basics::Json(_random));
nodes.add("database", VPackValue(_vocbase->_name));
nodes.add("collection", VPackValue(_collection->getName()));
nodes.add(VPackValue("outVariable"));
_outVariable->toVelocyPack(nodes);
nodes.add("random", VPackValue(_random));
// And add it:
nodes(json);
// And close it:
nodes.close();
LEAVE_BLOCK
}
@ -1320,23 +1318,22 @@ EnumerateListNode::EnumerateListNode(ExecutionPlan* plan,
_outVariable(varFromJson(plan->getAst(), base, "outVariable")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for EnumerateListNode
/// @brief toVelocyPack, for EnumerateListNode
////////////////////////////////////////////////////////////////////////////////
void EnumerateListNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone,
bool verbose) const {
void EnumerateListNode::toVelocyPackHelper(VPackBuilder& nodes,
bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
json("inVariable", _inVariable->toJson())("outVariable",
_outVariable->toJson());
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
nodes.add(VPackValue("inVariable"));
_inVariable->toVelocyPack(nodes);
// And add it:
nodes(json);
nodes.add(VPackValue("outVariable"));
_outVariable->toVelocyPack(nodes);
// And close it:
nodes.close();
LEAVE_BLOCK
}
@ -1429,24 +1426,19 @@ LimitNode::LimitNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
JsonHelper::checkAndGetBooleanValue(base.json(), "fullCount")) {}
////////////////////////////////////////////////////////////////////////////////
// @brief toJson, for LimitNode
// @brief toVelocyPack, for LimitNode
////////////////////////////////////////////////////////////////////////////////
void LimitNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
void LimitNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
// Now put info about offset and limit in
json("offset", arangodb::basics::Json(static_cast<double>(_offset)))(
"limit", arangodb::basics::Json(static_cast<double>(_limit)))(
"fullCount", arangodb::basics::Json(_fullCount));
// And add it:
nodes(json);
ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose); // call base class method
nodes.add("offset", VPackValue(static_cast<double>(_offset)));
nodes.add("limit", VPackValue(static_cast<double>(_limit)));
nodes.add("fullCount", VPackValue(_fullCount));
// And close it:
nodes.close();
LEAVE_BLOCK
}
@ -1475,32 +1467,31 @@ CalculationNode::CalculationNode(ExecutionPlan* plan,
_canRemoveIfThrows(false) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for CalculationNode
/// @brief toVelocyPack, for CalculationNode
////////////////////////////////////////////////////////////////////////////////
void CalculationNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone,
bool verbose) const {
void CalculationNode::toVelocyPackHelper(VPackBuilder& nodes,
bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
nodes.add(VPackValue("expression"));
_expression->toVelocyPack(nodes, verbose);
if (json.isEmpty()) {
return;
}
nodes.add(VPackValue("outVariable"));
_outVariable->toVelocyPack(nodes);
json("expression", _expression->toJson(TRI_UNKNOWN_MEM_ZONE, verbose))(
"outVariable", _outVariable->toJson())(
"canThrow", arangodb::basics::Json(_expression->canThrow()));
nodes.add("canThrow", VPackValue(_expression->canThrow()));
if (_conditionVariable != nullptr) {
json("conditionVariable", _conditionVariable->toJson());
nodes.add(VPackValue("conditionVariable"));
_conditionVariable->toVelocyPack(nodes);
}
json("expressionType", arangodb::basics::Json(_expression->typeString()));
nodes.add("expressionType", VPackValue(_expression->typeString()));
// And add it:
nodes(json);
// And close it
nodes.close();
LEAVE_BLOCK
}
@ -1546,22 +1537,21 @@ SubqueryNode::SubqueryNode(ExecutionPlan* plan,
_outVariable(varFromJson(plan->getAst(), base, "outVariable")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for SubqueryNode
/// @brief toVelocyPack, for SubqueryNode
////////////////////////////////////////////////////////////////////////////////
void SubqueryNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
void SubqueryNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
json("subquery", _subquery->toJson(TRI_UNKNOWN_MEM_ZONE, verbose))(
"outVariable", _outVariable->toJson());
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
nodes.add(VPackValue("subquery"));
_subquery->toVelocyPack(nodes, verbose);
nodes.add(VPackValue("outVariable"));
_outVariable->toVelocyPack(nodes);
// And add it:
nodes(json);
nodes.close();
LEAVE_BLOCK
}
@ -1741,22 +1731,19 @@ FilterNode::FilterNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
_inVariable(varFromJson(plan->getAst(), base, "inVariable")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for FilterNode
/// @brief toVelocyPack, for FilterNode
////////////////////////////////////////////////////////////////////////////////
void FilterNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
void FilterNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
json("inVariable", _inVariable->toJson());
nodes.add(VPackValue("inVariable"));
_inVariable->toVelocyPack(nodes);
// And add it:
nodes(json);
// And close it:
nodes.close();
LEAVE_BLOCK
}
@ -1799,23 +1786,20 @@ ReturnNode::ReturnNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
_inVariable(varFromJson(plan->getAst(), base, "inVariable")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for ReturnNode
/// @brief toVelocyPack, for ReturnNode
////////////////////////////////////////////////////////////////////////////////
void ReturnNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
void ReturnNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
if (json.isEmpty()) {
return;
}
json("inVariable", _inVariable->toJson());
nodes.add(VPackValue("inVariable"));
_inVariable->toVelocyPack(nodes);
// And add it:
nodes(json);
// And close it:
nodes.close();
LEAVE_BLOCK
}
@ -1850,21 +1834,16 @@ double ReturnNode::estimateCost(size_t& nrItems) const {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for NoResultsNode
/// @brief toVelocyPack, for NoResultsNode
////////////////////////////////////////////////////////////////////////////////
void NoResultsNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
void NoResultsNode::toVelocyPackHelper(VPackBuilder& nodes,
bool verbose) const {
ENTER_BLOCK
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose);
if (json.isEmpty()) {
return;
}
// And add it:
nodes(json);
//And close it
nodes.close();
LEAVE_BLOCK
}

View File

@ -35,6 +35,10 @@
#include "VocBase/vocbase.h"
namespace arangodb {
namespace velocypack {
class Builder;
}
namespace aql {
class Ast;
struct Collection;
@ -448,18 +452,18 @@ class ExecutionNode {
bool walk(WalkerWorker<ExecutionNode>* worker);
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON, returns an AUTOFREE Json object
//////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// @brief toVelocyPack, export an ExecutionNode to VelocyPack
///////////////////////////////////////////////////////////////////////////////
arangodb::basics::Json toJson(TRI_memory_zone_t*, bool) const;
void toVelocyPack(arangodb::velocypack::Builder&, bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief toJson
/// @brief toVelocyPack
//////////////////////////////////////////////////////////////////////////////
virtual void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const = 0;
virtual void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const = 0;
//////////////////////////////////////////////////////////////////////////////
/// @brief getVariablesUsedHere, returning a vector
@ -699,11 +703,10 @@ class ExecutionNode {
char const* which);
//////////////////////////////////////////////////////////////////////////////
/// @brief toJsonHelper, for a generic node
/// @brief toVelocyPackHelper, for a generic node
//////////////////////////////////////////////////////////////////////////////
arangodb::basics::Json toJsonHelperGeneric(arangodb::basics::Json&,
TRI_memory_zone_t*, bool) const;
void toVelocyPackHelperGeneric(arangodb::velocypack::Builder&, bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief set regs to be deleted
@ -829,11 +832,11 @@ class SingletonNode : public ExecutionNode {
NodeType getType() const override final { return SINGLETON; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -892,11 +895,11 @@ class EnumerateCollectionNode : public ExecutionNode {
NodeType getType() const override final { return ENUMERATE_COLLECTION; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -1000,11 +1003,11 @@ class EnumerateListNode : public ExecutionNode {
NodeType getType() const override final { return ENUMERATE_LIST; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -1101,11 +1104,11 @@ class LimitNode : public ExecutionNode {
NodeType getType() const override final { return LIMIT; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -1206,11 +1209,11 @@ class CalculationNode : public ExecutionNode {
NodeType getType() const override final { return CALCULATION; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -1365,11 +1368,11 @@ class SubqueryNode : public ExecutionNode {
Variable const* outVariable() const { return _outVariable; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -1484,11 +1487,11 @@ class FilterNode : public ExecutionNode {
NodeType getType() const override final { return FILTER; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -1613,11 +1616,11 @@ class ReturnNode : public ExecutionNode {
NodeType getType() const override final { return RETURN; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -1684,11 +1687,12 @@ class NoResultsNode : public ExecutionNode {
NodeType getType() const override final { return NORESULTS; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively

View File

@ -214,7 +214,11 @@ ExecutionPlan* ExecutionPlan::clone(Query const& query) {
arangodb::basics::Json ExecutionPlan::toJson(Ast* ast, TRI_memory_zone_t* zone,
bool verbose) const {
arangodb::basics::Json result = _root->toJson(zone, verbose);
// TODO
VPackBuilder b;
_root->toVelocyPack(b, verbose);
TRI_json_t* tmp = arangodb::basics::VelocyPackHelper::velocyPackToJson(b.slice());
arangodb::basics::Json result(zone, tmp);
// set up rules
auto appliedRules(Optimizer::translateRules(_appliedRules));

View File

@ -153,6 +153,14 @@ class Expression {
return arangodb::basics::Json(zone, _node->toJson(zone, verbose));
}
//////////////////////////////////////////////////////////////////////////////
/// @brief return a VelocyPack representation of the expression
//////////////////////////////////////////////////////////////////////////////
void toVelocyPack(arangodb::velocypack::Builder& builder, bool verbose) const {
_node->toVelocyPack(builder, verbose);
}
//////////////////////////////////////////////////////////////////////////////
/// @brief execute the expression
//////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,8 @@
#include <functional>
#define TMPUSEVPACK 1
namespace arangodb {
namespace aql {
@ -40,6 +42,8 @@ typedef std::function<bool()> ExecutionCondition;
typedef std::vector<std::pair<AqlValue, TRI_document_collection_t const*>>
FunctionParameters;
typedef std::vector<AqlValue$> VPackFunctionParameters;
typedef std::function<AqlValue(arangodb::aql::Query*, arangodb::AqlTransaction*,
FunctionParameters const&)>
FunctionImplementation;
@ -61,12 +65,8 @@ struct Functions {
static AqlValue IsNull(arangodb::aql::Query*, arangodb::AqlTransaction*,
FunctionParameters const&);
static AqlValue IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
FunctionParameters const&);
static AqlValue IsBool(arangodb::aql::Query*, arangodb::AqlTransaction*,
FunctionParameters const&);
static AqlValue IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
FunctionParameters const&);
static AqlValue IsNumber(arangodb::aql::Query*, arangodb::AqlTransaction*,
FunctionParameters const&);
static AqlValue IsString(arangodb::aql::Query*, arangodb::AqlTransaction*,
@ -223,6 +223,194 @@ struct Functions {
FunctionParameters const&);
static AqlValue IsSameCollection(arangodb::aql::Query*, arangodb::AqlTransaction*,
FunctionParameters const&);
static AqlValue$ IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ IsNumberVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ IsStringVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ IsArrayVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ IsObjectVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ToNumberVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ToStringVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ToArrayVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ LengthVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ FirstVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ LastVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ NthVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ConcatVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ LikeVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ PassthruVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ UnsetVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ UnsetRecursiveVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ KeepVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ MergeVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ MergeRecursiveVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ HasVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ AttributesVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ValuesVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ MinVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ MaxVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ SumVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ AverageVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ Md5VPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ Sha1VPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ UniqueVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ SortedUniqueVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ UnionVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ UnionDistinctVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ IntersectionVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ NeighborsVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ NearVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ WithinVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ FlattenVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ZipVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ParseIdentifierVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ MinusVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ DocumentVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ EdgesVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ RoundVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ AbsVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ CeilVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ FloorVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ SqrtVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ PowVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ RandVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ FirstDocumentVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ FirstListVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ PushVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ PopVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ AppendVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ UnshiftVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ ShiftVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ RemoveValueVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ RemoveValuesVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ RemoveNthVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ NotNullVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ CurrentDatabaseVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ CollectionCountVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ VarianceSampleVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ VariancePopulationVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ StdDevSampleVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ StdDevPopulationVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ MedianVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ PercentileVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ RangeVPack(arangodb::aql::Query*, arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ PositionVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ FulltextVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
static AqlValue$ IsSameCollectionVPack(arangodb::aql::Query*,
arangodb::AqlTransaction*,
VPackFunctionParameters const&);
};
}
}

View File

@ -24,6 +24,8 @@
#include "Graphs.h"
#include "Basics/JsonHelper.h"
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::basics;
using namespace arangodb::aql;
@ -79,6 +81,26 @@ arangodb::basics::Json Graph::toJson(TRI_memory_zone_t* z, bool verbose) const {
return json;
}
void Graph::toVelocyPack(VPackBuilder& builder, bool verbose) const {
VPackObjectBuilder guard(&builder);
if (!_vertexColls.empty()) {
builder.add(VPackValue("vertexCollectionNames"));
VPackArrayBuilder guard2(&builder);
for (auto const& cn : _vertexColls) {
builder.add(VPackValue(cn));
}
}
if (!_edgeColls.empty()) {
builder.add(VPackValue("edgeCollectionNames"));
VPackArrayBuilder guard2(&builder);
for (auto const& cn : _edgeColls) {
builder.add(VPackValue(cn));
}
}
}
Graph::Graph(arangodb::basics::Json const& j) : _vertexColls(), _edgeColls() {
auto jsonDef = j.get(_attrEdgeDefs);

View File

@ -105,6 +105,12 @@ class Graph {
//////////////////////////////////////////////////////////////////////////////
arangodb::basics::Json toJson(TRI_memory_zone_t*, bool) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief return a VelocyPack representation of the graph
//////////////////////////////////////////////////////////////////////////////
void toVelocyPack(arangodb::velocypack::Builder&, bool) const;
};
} // namespace aql

View File

@ -40,6 +40,33 @@ Index::~Index() {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Create a VelocyPack representation of the index
////////////////////////////////////////////////////////////////////////////////
void Index::toVelocyPack(VPackBuilder& builder) const {
VPackObjectBuilder guard(&builder);
builder.add("type", VPackValue(arangodb::Index::typeName(type)));
builder.add("id", VPackValue(arangodb::basics::StringUtils::itoa(id)));
builder.add("unique", VPackValue(unique));
builder.add("sparse", VPackValue(sparse));
if (hasSelectivityEstimate()) {
builder.add("selectivityEstimate", VPackValue(selectivityEstimate()));
}
builder.add(VPackValue("fields"));
{
VPackArrayBuilder arrayGuard(&builder);
for (auto const& field : fields) {
std::string tmp;
TRI_AttributeNamesToString(field, tmp);
builder.add(VPackValue(tmp));
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the index internals
////////////////////////////////////////////////////////////////////////////////

View File

@ -125,6 +125,12 @@ struct Index {
return json;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Create a VelocyPack representation of the index
////////////////////////////////////////////////////////////////////////////////
void toVelocyPack(VPackBuilder&) const;
bool hasSelectivityEstimate() const {
if (!hasInternals()) {
return false;

View File

@ -33,36 +33,32 @@ using namespace arangodb::aql;
using JsonHelper = arangodb::basics::JsonHelper;
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for IndexNode
/// @brief toVelocyPack, for IndexNode
////////////////////////////////////////////////////////////////////////////////
void IndexNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(
ExecutionNode::toJsonHelperGeneric(nodes, zone, verbose));
// call base class method
if (json.isEmpty()) {
return;
}
void IndexNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
// Now put info about vocbase and cid in there
json("database", arangodb::basics::Json(_vocbase->_name))(
"collection", arangodb::basics::Json(_collection->getName()))(
"outVariable", _outVariable->toJson());
nodes.add("database", VPackValue(_vocbase->_name));
nodes.add("collection", VPackValue(_collection->getName()));
nodes.add(VPackValue("outVariable"));
_outVariable->toVelocyPack(nodes);
arangodb::basics::Json indexes(arangodb::basics::Json::Array,
_indexes.size());
for (auto& index : _indexes) {
indexes.add(index->toJson());
nodes.add(VPackValue("indexes"));
{
VPackArrayBuilder guard(&nodes);
for (auto& index : _indexes) {
index->toVelocyPack(nodes);
}
}
nodes.add(VPackValue("condition"));
_condition->toVelocyPack(nodes, verbose);
nodes.add("reverse", VPackValue(_reverse));
json("indexes", indexes);
json("condition", _condition->toJson(TRI_UNKNOWN_MEM_ZONE, verbose));
json("reverse", arangodb::basics::Json(_reverse));
// And add it:
nodes(json);
// And close it:
nodes.close();
}
ExecutionNode* IndexNode::clone(ExecutionPlan* plan, bool withDependencies,

View File

@ -108,11 +108,11 @@ class IndexNode : public ExecutionNode {
bool reverse() const { return _reverse; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively

View File

@ -47,24 +47,28 @@ ModificationNode::ModificationNode(ExecutionPlan* plan,
}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson
/// @brief toVelocyPack
////////////////////////////////////////////////////////////////////////////////
void ModificationNode::toJsonHelper(arangodb::basics::Json& json,
TRI_memory_zone_t* zone, bool) const {
void ModificationNode::toVelocyPackHelper(VPackBuilder& builder,
bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(builder,
verbose); // call base class method
// Now put info about vocbase and cid in there
json("database", arangodb::basics::Json(_vocbase->_name))(
"collection", arangodb::basics::Json(_collection->getName()));
builder.add("database", VPackValue(_vocbase->_name));
builder.add("collection", VPackValue(_collection->getName()));
// add out variables
if (_outVariableOld != nullptr) {
json("outVariableOld", _outVariableOld->toJson());
builder.add(VPackValue("outVariableOld"));
_outVariableOld->toVelocyPack(builder);
}
if (_outVariableNew != nullptr) {
json("outVariableNew", _outVariableNew->toJson());
builder.add(VPackValue("outVariableNew"));
_outVariableNew->toVelocyPack(builder);
}
_options.toJson(json, zone);
builder.add(VPackValue("modificationFlags"));
_options.toVelocyPack(builder);
}
////////////////////////////////////////////////////////////////////////////////
@ -94,22 +98,13 @@ RemoveNode::RemoveNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
/// @brief toJson
////////////////////////////////////////////////////////////////////////////////
void RemoveNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
void RemoveNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ModificationNode::toVelocyPackHelper(nodes, verbose);
nodes.add(VPackValue("inVariable"));
_inVariable->toVelocyPack(nodes);
if (json.isEmpty()) {
return;
}
// Now put info about vocbase and cid in there
json("inVariable", _inVariable->toJson());
ModificationNode::toJsonHelper(json, zone, verbose);
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////
@ -142,25 +137,19 @@ InsertNode::InsertNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
_inVariable(varFromJson(plan->getAst(), base, "inVariable")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson
/// @brief toVelocyPack
////////////////////////////////////////////////////////////////////////////////
void InsertNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
void InsertNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ModificationNode::toVelocyPackHelper(nodes,
verbose); // call base class method
// Now put info about vocbase and cid in there
json("inVariable", _inVariable->toJson());
nodes.add(VPackValue("inVariable"));
_inVariable->toVelocyPack(nodes);
ModificationNode::toJsonHelper(json, zone, verbose);
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////
@ -195,30 +184,23 @@ UpdateNode::UpdateNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
varFromJson(plan->getAst(), base, "inKeyVariable", Optional)) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson
/// @brief toVelocyPack
////////////////////////////////////////////////////////////////////////////////
void UpdateNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
// Now put info about vocbase and cid in there
json("inDocVariable", _inDocVariable->toJson());
ModificationNode::toJsonHelper(json, zone, verbose);
void UpdateNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ModificationNode::toVelocyPackHelper(nodes, verbose);
nodes.add(VPackValue("inDocVariable"));
_inDocVariable->toVelocyPack(nodes);
// inKeyVariable might be empty
if (_inKeyVariable != nullptr) {
json("inKeyVariable", _inKeyVariable->toJson());
nodes.add(VPackValue("inKeyVariable"));
_inKeyVariable->toVelocyPack(nodes);
}
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////
@ -265,30 +247,23 @@ ReplaceNode::ReplaceNode(ExecutionPlan* plan,
varFromJson(plan->getAst(), base, "inKeyVariable", Optional)) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson
/// @brief toVelocyPack
////////////////////////////////////////////////////////////////////////////////
void ReplaceNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
// Now put info about vocbase and cid in there
json("inDocVariable", _inDocVariable->toJson());
ModificationNode::toJsonHelper(json, zone, verbose);
void ReplaceNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ModificationNode::toVelocyPackHelper(nodes, verbose);
nodes.add(VPackValue("inDocVariable"));
_inDocVariable->toVelocyPack(nodes);
// inKeyVariable might be empty
if (_inKeyVariable != nullptr) {
json("inKeyVariable", _inKeyVariable->toJson());
nodes.add(VPackValue("inKeyVariable"));
_inKeyVariable->toVelocyPack(nodes);
}
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////
@ -336,27 +311,23 @@ UpsertNode::UpsertNode(ExecutionPlan* plan, arangodb::basics::Json const& base)
JsonHelper::checkAndGetBooleanValue(base.json(), "isReplace")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson
/// @brief toVelocyPack
////////////////////////////////////////////////////////////////////////////////
void UpsertNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
void UpsertNode::toVelocyPackHelper(VPackBuilder& nodes,
bool verbose) const {
ModificationNode::toVelocyPackHelper(nodes, verbose);
if (json.isEmpty()) {
return;
}
nodes.add(VPackValue("inDocVariable"));
_inDocVariable->toVelocyPack(nodes);
nodes.add(VPackValue("insertVariable"));
_insertVariable->toVelocyPack(nodes);
nodes.add(VPackValue("updateVariable"));
_updateVariable->toVelocyPack(nodes);
nodes.add("isReplace", VPackValue(_isReplace));
ModificationNode::toJsonHelper(json, zone, verbose);
json("inDocVariable", _inDocVariable->toJson());
json("insertVariable", _insertVariable->toJson());
json("updateVariable", _updateVariable->toJson());
json("isReplace", arangodb::basics::Json(_isReplace));
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -70,11 +70,11 @@ class ModificationNode : public ExecutionNode {
ModificationNode(ExecutionPlan*, arangodb::basics::Json const& json);
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
virtual void toJsonHelper(arangodb::basics::Json& json,
TRI_memory_zone_t* zone, bool) const override;
virtual void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override;
public:
//////////////////////////////////////////////////////////////////////////////
@ -214,11 +214,11 @@ class RemoveNode : public ModificationNode {
NodeType getType() const override final { return REMOVE; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -281,11 +281,11 @@ class InsertNode : public ModificationNode {
NodeType getType() const override final { return INSERT; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -354,11 +354,11 @@ class UpdateNode : public ModificationNode {
NodeType getType() const override final { return UPDATE; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -444,11 +444,11 @@ class ReplaceNode : public ModificationNode {
NodeType getType() const override final { return REPLACE; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively
@ -540,11 +540,11 @@ class UpsertNode : public ModificationNode {
NodeType getType() const override final { return UPSERT; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively

View File

@ -23,6 +23,8 @@
#include "Aql/ModificationOptions.h"
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql;
using Json = arangodb::basics::Json;
using JsonHelper = arangodb::basics::JsonHelper;
@ -54,3 +56,13 @@ void ModificationOptions::toJson(arangodb::basics::Json& json,
json("modificationFlags", flags);
}
void ModificationOptions::toVelocyPack(VPackBuilder& builder) const {
VPackObjectBuilder guard(&builder);
builder.add("ignoreErrors", VPackValue(ignoreErrors));
builder.add("waitForSync", VPackValue(waitForSync));
builder.add("nullMeansRemove", VPackValue(nullMeansRemove));
builder.add("mergeObjects", VPackValue(mergeObjects));
builder.add("ignoreDocumentNotFound", VPackValue(ignoreDocumentNotFound));
builder.add("readCompleteInput", VPackValue(readCompleteInput));
}

View File

@ -51,6 +51,8 @@ struct ModificationOptions {
void toJson(arangodb::basics::Json&, TRI_memory_zone_t*) const;
void toVelocyPack(arangodb::velocypack::Builder&) const;
bool ignoreErrors;
bool waitForSync;
bool nullMeansRemove;

View File

@ -1470,6 +1470,15 @@ std::string Query::getStateString() const {
return std::string(" (while " + StateNames[_state] + ")");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get a shared builder for in-place VelocyPack construction
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<VPackBuilder> Query::getSharedBuilder () {
// TODO Proper memory efficient implementation
return std::make_shared<VPackBuilder>();
};
////////////////////////////////////////////////////////////////////////////////
/// @brief cleanup plan and engine for current query
////////////////////////////////////////////////////////////////////////////////

View File

@ -417,6 +417,12 @@ class Query {
std::string getStateString () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief get a shared builder for in-place VelocyPack construction
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<arangodb::velocypack::Builder> getSharedBuilder ();
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------

View File

@ -35,30 +35,27 @@ SortNode::SortNode(ExecutionPlan* plan, arangodb::basics::Json const& base,
: ExecutionNode(plan, base), _elements(elements), _stable(stable) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for SortNode
/// @brief toVelocyPack, for SortNode
////////////////////////////////////////////////////////////////////////////////
void SortNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
void SortNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
if (json.isEmpty()) {
return;
nodes.add(VPackValue("elements"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& it : _elements) {
VPackObjectBuilder obj(&nodes);
nodes.add(VPackValue("inVariable"));
it.first->toVelocyPack(nodes);
nodes.add("ascending", VPackValue(it.second));
}
}
arangodb::basics::Json values(arangodb::basics::Json::Array,
_elements.size());
for (auto it = _elements.begin(); it != _elements.end(); ++it) {
arangodb::basics::Json element(arangodb::basics::Json::Object);
element("inVariable", (*it).first->toJson())(
"ascending", arangodb::basics::Json((*it).second));
values(element);
}
json("elements", values);
json("stable", arangodb::basics::Json(_stable));
nodes.add("stable", VPackValue(_stable));
// And add it:
nodes(json);
// And close it:
nodes.close();
}
class SortNodeFindMyExpressions : public WalkerWorker<ExecutionNode> {

View File

@ -73,11 +73,11 @@ class SortNode : public ExecutionNode {
inline bool isStable() const { return _stable; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively

View File

@ -87,6 +87,25 @@ void SimpleTraverserExpression::toJson(arangodb::basics::Json& json,
"compareTo", compareToNode->toJson(zone, true));
}
void SimpleTraverserExpression::toVelocyPack(VPackBuilder& builder) const {
TRI_ASSERT(builder.isOpenObject());
auto op = arangodb::aql::AstNode::Operators.find(comparisonType);
if (op == arangodb::aql::AstNode::Operators.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(
TRI_ERROR_QUERY_PARSE,
"invalid operator for simpleTraverserExpression");
}
std::string const operatorStr = op->second;
builder.add("isEdgeAccess", VPackValue(isEdgeAccess));
builder.add("comparisonTypeStr", VPackValue(operatorStr));
builder.add("comparisonType", VPackValue(comparisonType));
builder.add(VPackValue("varAccess"));
varAccess->toVelocyPack(builder, true);
builder.add(VPackValue("compareTo"));
compareToNode->toVelocyPack(builder, true);
}
static TRI_edge_direction_e parseDirection (AstNode const* node) {
TRI_ASSERT(node->isIntValue());
auto dirNum = node->getIntValue();
@ -445,75 +464,81 @@ int TraversalNode::checkIsOutVariable(size_t variableId) const {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for TraversalNode
/// @brief toVelocyPack, for TraversalNode
////////////////////////////////////////////////////////////////////////////////
void TraversalNode::toJsonHelper(arangodb::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
void TraversalNode::toVelocyPackHelper(arangodb::velocypack::Builder& nodes,
bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
verbose); // call base class method
if (json.isEmpty()) {
return;
nodes.add("database", VPackValue(_vocbase->_name));
nodes.add("minDepth", VPackValue(_minDepth));
nodes.add("maxDepth", VPackValue(_maxDepth));
{
// TODO Remove _graphJson
auto tmp = arangodb::basics::JsonHelper::toVelocyPack(_graphJson.json());
nodes.add("graph", tmp->slice());
}
json("database", arangodb::basics::Json(_vocbase->_name))(
"minDepth", arangodb::basics::Json(static_cast<double>(_minDepth)))(
"maxDepth", arangodb::basics::Json(static_cast<double>(_maxDepth)))(
"graph", _graphJson.copy());
arangodb::basics::Json dirJson = arangodb::basics::Json(arangodb::basics::Json::Array, _directions.size());
for (auto const& d : _directions) {
dirJson.add(arangodb::basics::Json(static_cast<int32_t>(d)));
nodes.add(VPackValue("directions"));
{
VPackArrayBuilder guard(&nodes);
for (auto const& d : _directions) {
nodes.add(VPackValue(d));
}
}
json("directions", dirJson);
// In variable
if (usesInVariable()) {
json("inVariable", inVariable()->toJson());
nodes.add(VPackValue("inVariable"));
inVariable()->toVelocyPack(nodes);
} else {
json("vertexId", arangodb::basics::Json(_vertexId));
nodes.add("vertexId", VPackValue(_vertexId));
}
if (_condition != nullptr) {
json("condition", _condition->toJson(TRI_UNKNOWN_MEM_ZONE, verbose));
nodes.add(VPackValue("condition"));
_condition->toVelocyPack(nodes, verbose);
}
if (_graphObj != nullptr) {
json("graphDefinition", _graphObj->toJson(TRI_UNKNOWN_MEM_ZONE, verbose));
nodes.add(VPackValue("graphDefinition"));
_graphObj->toVelocyPack(nodes, verbose);
}
// Out variables
if (usesVertexOutVariable()) {
json("vertexOutVariable", vertexOutVariable()->toJson());
nodes.add(VPackValue("vertexOutVariable"));
vertexOutVariable()->toVelocyPack(nodes);
}
if (usesEdgeOutVariable()) {
json("edgeOutVariable", edgeOutVariable()->toJson());
nodes.add(VPackValue("edgeOutVariable"));
edgeOutVariable()->toVelocyPack(nodes);
}
if (usesPathOutVariable()) {
json("pathOutVariable", pathOutVariable()->toJson());
nodes.add(VPackValue("pathOutVariable"));
pathOutVariable()->toVelocyPack(nodes);
}
if (!_expressions.empty()) {
arangodb::basics::Json expressionObject = arangodb::basics::Json(
arangodb::basics::Json::Object, _expressions.size());
nodes.add(VPackValue("simpleExpressions"));
VPackObjectBuilder guard(&nodes);
for (auto const& map : _expressions) {
arangodb::basics::Json expressionArray = arangodb::basics::Json(
arangodb::basics::Json::Array, map.second.size());
nodes.add(VPackValue(std::to_string(map.first)));
VPackArrayBuilder guard2(&nodes);
for (auto const& x : map.second) {
arangodb::basics::Json exp(zone, arangodb::basics::Json::Object);
VPackObjectBuilder guard3(&nodes);
auto tmp = dynamic_cast<SimpleTraverserExpression*>(x);
if (tmp != nullptr) {
tmp->toJson(exp, zone);
tmp->toVelocyPack(nodes);
}
expressionArray(exp);
}
expressionObject.set(std::to_string(map.first), expressionArray);
}
json("simpleExpressions", expressionObject);
}
// And add it:
nodes(json);
// And close it:
nodes.close();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -53,6 +53,8 @@ class SimpleTraverserExpression
~SimpleTraverserExpression();
void toJson(arangodb::basics::Json& json, TRI_memory_zone_t* zone) const;
void toVelocyPack(arangodb::velocypack::Builder&) const;
};
////////////////////////////////////////////////////////////////////////////////
@ -103,11 +105,11 @@ class TraversalNode : public ExecutionNode {
NodeType getType() const override final { return TRAVERSAL; }
//////////////////////////////////////////////////////////////////////////////
/// @brief export to JSON
/// @brief export to VelocyPack
//////////////////////////////////////////////////////////////////////////////
void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*,
bool) const override final;
void toVelocyPackHelper(arangodb::velocypack::Builder&,
bool) const override final;
//////////////////////////////////////////////////////////////////////////////
/// @brief clone ExecutionNode recursively

View File

@ -24,6 +24,8 @@
#include "Variable.h"
#include "Basics/JsonHelper.h"
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql;
using JsonHelper = arangodb::basics::JsonHelper;
@ -75,6 +77,16 @@ arangodb::basics::Json Variable::toJson() const {
return json;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return a VelocyPack representation of the variable
////////////////////////////////////////////////////////////////////////////////
void Variable::toVelocyPack(VPackBuilder& builder) const {
VPackObjectBuilder b(&builder);
builder.add("id", VPackValue(static_cast<double>(id)));
builder.add("name", VPackValue(name));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief replace a variable by another
////////////////////////////////////////////////////////////////////////////////

View File

@ -86,6 +86,12 @@ struct Variable {
arangodb::basics::Json toJson() const;
//////////////////////////////////////////////////////////////////////////////
/// @brief return a VelocyPack representation of the variable
//////////////////////////////////////////////////////////////////////////////
void toVelocyPack(arangodb::velocypack::Builder&) const;
//////////////////////////////////////////////////////////////////////////////
/// @brief replace a variable by another
//////////////////////////////////////////////////////////////////////////////

View File

@ -175,6 +175,22 @@ bool shardKeysChanged(std::string const& dbname, std::string const& collname,
return false;
}
bool shardKeysChanged(std::string const& dbname, std::string const& collname,
VPackSlice const& oldSlice, VPackSlice const& newSlice,
bool isPatch) {
std::unique_ptr<TRI_json_t> tmpOld(
arangodb::basics::VelocyPackHelper::velocyPackToJson(oldSlice));
if (tmpOld == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
std::unique_ptr<TRI_json_t> tmpNew(
arangodb::basics::VelocyPackHelper::velocyPackToJson(newSlice));
if (tmpNew == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
return shardKeysChanged(dbname, collname, tmpOld.get(), tmpNew.get(), isPatch);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns users
////////////////////////////////////////////////////////////////////////////////

View File

@ -68,6 +68,10 @@ bool shardKeysChanged(std::string const& dbname, std::string const& collname,
struct TRI_json_t const* oldJson,
struct TRI_json_t const* newJson, bool isPatch);
bool shardKeysChanged(std::string const& dbname, std::string const& collname,
VPackSlice const& oldSlice, VPackSlice const& newSlice,
bool isPatch);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns users
////////////////////////////////////////////////////////////////////////////////

View File

@ -23,7 +23,6 @@
////////////////////////////////////////////////////////////////////////////////
#include "PeriodicTask.h"
#include "Basics/json.h"
#include "Scheduler/Scheduler.h"
#include <velocypack/Builder.h>

View File

@ -296,6 +296,23 @@ void BasicOptions::addEdgeFilter(Json const& example, VocShaper* shaper,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Insert a new edge matcher object
////////////////////////////////////////////////////////////////////////////////
void BasicOptions::addEdgeFilter(VPackSlice const& example, VocShaper* shaper,
TRI_voc_cid_t const& cid,
CollectionNameResolver const* resolver) {
useEdgeFilter = true;
auto it = _edgeFilter.find(cid);
if (it == _edgeFilter.end()) {
_edgeFilter.emplace(cid,
new ExampleMatcher(example, shaper, resolver, true));
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Checks if an edge matches to given examples
////////////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,10 @@
#include "VocBase/Traverser.h"
namespace arangodb {
namespace velocypack {
class Slice;
}
class Transaction;
}
@ -117,6 +121,10 @@ struct BasicOptions {
TRI_voc_cid_t const& cid,
arangodb::CollectionNameResolver const* resolver);
void addEdgeFilter(arangodb::velocypack::Slice const& example, VocShaper* shaper,
TRI_voc_cid_t const& cid,
arangodb::CollectionNameResolver const* resolver);
void addVertexFilter(v8::Isolate* isolate,
v8::Handle<v8::Value> const& example,
arangodb::ExplicitTransaction* trx,

View File

@ -689,8 +689,9 @@ static void ModifyVocbaseColCoordinator(
TRI_V8_THROW_EXCEPTION(error);
}
std::unique_ptr<TRI_json_t> json(TRI_ObjectToJson(isolate, args[1]));
if (!TRI_IsObjectJson(json.get())) {
VPackBuilder builder;
int res = TRI_V8ToVPack(isolate, builder, args[1], false);
if (res != TRI_ERROR_NO_ERROR || !builder.slice().isObject()) {
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
@ -702,7 +703,8 @@ static void ModifyVocbaseColCoordinator(
error = arangodb::modifyDocumentOnCoordinator(
dbname, collname, key, rev, policy, waitForSync, isPatch, keepNull,
mergeObjects, json, headers, responseCode, resultHeaders, resultBody);
mergeObjects, builder.slice(), headers, responseCode, resultHeaders,
resultBody);
if (error != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(error);
@ -710,29 +712,24 @@ static void ModifyVocbaseColCoordinator(
// report what the DBserver told us: this could now be 201/202 or
// 400/404
json.reset(TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, resultBody.c_str()));
std::shared_ptr<VPackBuilder> resBuilder = VPackParser::fromJson(resultBody);
VPackSlice resSlice = resBuilder->slice();
if (responseCode >= arangodb::rest::HttpResponse::BAD) {
if (!TRI_IsObjectJson(json.get())) {
if (!resSlice.isObject()) {
TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL);
}
int errorNum = 0;
TRI_json_t* subjson = TRI_LookupObjectJson(json.get(), "errorNum");
if (TRI_IsNumberJson(subjson)) {
errorNum = static_cast<int>(subjson->_value._number);
}
std::string errorMessage;
subjson = TRI_LookupObjectJson(json.get(), "errorMessage");
if (TRI_IsStringJson(subjson)) {
errorMessage = std::string(subjson->_value._string.data,
subjson->_value._string.length - 1);
}
int errorNum = arangodb::basics::VelocyPackHelper::getNumericValue<int>(
resSlice, "errorNum", 0);
std::string errorMessage =
arangodb::basics::VelocyPackHelper::getStringValue(resSlice,
"errorMessage", "");
TRI_V8_THROW_EXCEPTION_MESSAGE(errorNum, errorMessage);
}
if (silent) {
TRI_V8_RETURN_TRUE();
} else {
v8::Handle<v8::Value> ret = TRI_ObjectJson(isolate, json.get());
v8::Handle<v8::Value> ret = TRI_VPackToV8(isolate, resSlice);
TRI_V8_RETURN(ret);
}
}
@ -872,40 +869,40 @@ static void ReplaceVocbaseCol(bool useCollection,
// compare attributes in shardKeys
std::string const cidString = StringUtils::itoa(document->_info.planId());
TRI_json_t* json = TRI_ObjectToJson(isolate, args[1]);
VPackBuilder builder;
res = TRI_V8ToVPack(isolate, builder, args[1], false);
if (json == nullptr) {
TRI_V8_THROW_EXCEPTION_MEMORY();
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
}
res = trx.read(&mptr, key.get());
if (res != TRI_ERROR_NO_ERROR ||
mptr.getDataPtr() == nullptr) { // PROTECTED by trx here
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION(res);
}
TRI_shaped_json_t shaped;
TRI_EXTRACT_SHAPED_JSON_MARKER(shaped,
mptr.getDataPtr()); // PROTECTED by trx here
TRI_json_t* old = TRI_JsonShapedJson(document->getShaper(),
&shaped); // PROTECTED by trx here
std::shared_ptr<VPackBuilder> oldBuilder = TRI_VelocyPackShapedJson(
document->getShaper(), &shaped); // PROTECTED by trx here
if (old == nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
if (oldBuilder == nullptr) {
TRI_V8_THROW_EXCEPTION_MEMORY();
}
if (shardKeysChanged(col->_dbName, cidString, old, json, false)) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, old);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
VPackSlice const old = oldBuilder->slice();
if (old.isNone()) {
TRI_V8_THROW_EXCEPTION_MEMORY();
}
if (shardKeysChanged(col->_dbName, cidString, old, builder.slice(), false)) {
TRI_V8_THROW_EXCEPTION(
TRI_ERROR_CLUSTER_MUST_NOT_CHANGE_SHARDING_ATTRIBUTES);
}
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, old);
}
TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object(
@ -1339,9 +1336,17 @@ static void UpdateVocbaseCol(bool useCollection,
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
TRI_json_t* json = TRI_ObjectToJson(isolate, args[1]);
VPackBuilder builder;
{
int res = TRI_V8ToVPack(isolate, builder, args[1], false);
if (json == nullptr) {
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
}
}
VPackSlice slice = builder.slice();
if (slice.isNone()) {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_errno(), "<data> is no valid JSON");
}
@ -1350,7 +1355,6 @@ static void UpdateVocbaseCol(bool useCollection,
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION(res);
}
@ -1362,27 +1366,27 @@ static void UpdateVocbaseCol(bool useCollection,
res = trx.read(&mptr, key.get());
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION(res);
}
if (trx.orderDitch(trx.trxCollection()) == nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION_MEMORY();
}
TRI_document_collection_t* document = trx.documentCollection();
TRI_memory_zone_t* zone =
document->getShaper()->memoryZone(); // PROTECTED by trx here
TRI_shaped_json_t shaped;
TRI_EXTRACT_SHAPED_JSON_MARKER(shaped,
mptr.getDataPtr()); // PROTECTED by trx here
TRI_json_t* old = TRI_JsonShapedJson(document->getShaper(),
&shaped); // PROTECTED by trx here
std::shared_ptr<VPackBuilder> oldBuilder =
TRI_VelocyPackShapedJson(document->getShaper(),
&shaped); // PROTECTED by trx here
if (oldBuilder == nullptr) {
TRI_V8_THROW_EXCEPTION_MEMORY();
}
if (old == nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
VPackSlice old = oldBuilder->slice();
if (old.isNone()) {
TRI_V8_THROW_EXCEPTION_MEMORY();
}
@ -1390,32 +1394,25 @@ static void UpdateVocbaseCol(bool useCollection,
// compare attributes in shardKeys
std::string const cidString = StringUtils::itoa(document->_info.planId());
if (shardKeysChanged(col->_dbName, cidString, old, json, true)) {
TRI_FreeJson(document->getShaper()->memoryZone(),
old); // PROTECTED by trx here
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
if (shardKeysChanged(col->_dbName, cidString, old, slice, true)) {
TRI_V8_THROW_EXCEPTION(
TRI_ERROR_CLUSTER_MUST_NOT_CHANGE_SHARDING_ATTRIBUTES);
}
}
TRI_json_t* patchedJson = TRI_MergeJson(
TRI_UNKNOWN_MEM_ZONE, old, json, !options.keepNull, options.mergeObjects);
TRI_FreeJson(zone, old);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
VPackBuilder patchedBuilder = arangodb::basics::VelocyPackHelper::merge(
old, slice, !options.keepNull, options.mergeObjects);
if (patchedJson == nullptr) {
VPackSlice patchedSlice = patchedBuilder.slice();
if (patchedSlice.isNone()) {
TRI_V8_THROW_EXCEPTION_MEMORY();
}
res = trx.updateDocument(key.get(), &mptr, patchedJson, policy,
res = trx.updateDocument(key.get(), &mptr, patchedSlice, policy,
options.waitForSync, rid, &actualRevision);
res = trx.finish(res);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, patchedJson);
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
}

View File

@ -31,6 +31,9 @@
#include "V8Server/v8-vocbaseprivate.h"
#include "VocBase/VocShaper.h"
#include <velocypack/Iterator.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb;
using namespace arangodb::basics;
@ -231,6 +234,85 @@ void ExampleMatcher::fillExampleDefinition(
}
}
void ExampleMatcher::fillExampleDefinition(
VPackSlice const& example, CollectionNameResolver const* resolver,
ExampleDefinition& def) {
if (example.isString()) {
// Example is an _id value
std::string tmp = example.copyString();
char const* _key = strchr(tmp.c_str(), '/');
if (_key != nullptr) {
_key += 1;
def._internal.insert(
std::make_pair(internalAttr::key, DocumentId(0, _key)));
return;
}
THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND);
}
TRI_ASSERT(example.isObject());
size_t n = static_cast<size_t>(example.length());
def._pids.reserve(n);
def._values.reserve(n);
try {
for (auto const& it : VPackObjectIterator(example)) {
TRI_ASSERT(it.key.isString());
std::string key = it.key.copyString();
auto pid = _shaper->lookupAttributePathByName(key.c_str());
if (pid == 0) {
// Internal attributes do have pid == 0.
if (key.at(0) != '_') {
// no attribute path found. this means the result will be empty
THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND);
}
if (!it.value.isString()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_TYPE_ERROR);
}
std::string keyVal = it.value.copyString();
if (key == TRI_VOC_ATTRIBUTE_KEY) {
def._internal.insert(
std::make_pair(internalAttr::key, DocumentId(0, keyVal)));
} else if (key == TRI_VOC_ATTRIBUTE_REV) {
def._internal.insert(
std::make_pair(internalAttr::rev, DocumentId(0, keyVal)));
} else {
std::string colName = keyVal.substr(0, keyVal.find("/"));
keyVal = keyVal.substr(keyVal.find("/") + 1, keyVal.length());
if (TRI_VOC_ATTRIBUTE_ID == key) {
def._internal.insert(std::make_pair(
internalAttr::id,
DocumentId(resolver->getCollectionId(colName), keyVal)));
} else if (TRI_VOC_ATTRIBUTE_FROM == key) {
def._internal.insert(std::make_pair(
internalAttr::from,
DocumentId(resolver->getCollectionId(colName), keyVal)));
} else if (TRI_VOC_ATTRIBUTE_TO == key) {
def._internal.insert(std::make_pair(
internalAttr::to,
DocumentId(resolver->getCollectionId(colName), keyVal)));
} else {
// no attribute path found. this means the result will be empty
THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND);
}
}
} else {
def._pids.push_back(pid);
auto value = TRI_ShapedJsonVelocyPack(_shaper, it.value, false);
if (value == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND);
}
def._values.push_back(value);
}
}
} catch (std::bad_alloc const&) {
ExampleMatcher::cleanup();
throw;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor using a v8::Object example
////////////////////////////////////////////////////////////////////////////////
@ -331,6 +413,55 @@ ExampleMatcher::ExampleMatcher(TRI_json_t const* example, VocShaper* shaper,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor using a VelocyPack object
/// Note: allowStrings is used to define if strings in example-array
/// should be matched to _id
////////////////////////////////////////////////////////////////////////////////
ExampleMatcher::ExampleMatcher(VPackSlice const& example, VocShaper* shaper,
CollectionNameResolver const* resolver,
bool allowStrings)
: _shaper(shaper) {
if (example.isObject() || example.isString()) {
ExampleDefinition def;
try {
ExampleMatcher::fillExampleDefinition(example, resolver, def);
} catch (...) {
CleanupShapes(def._values);
ExampleMatcher::cleanup();
throw;
}
definitions.emplace_back(std::move(def));
} else if (example.isArray()) {
for (auto const& e : VPackArrayIterator(example)) {
ExampleDefinition def;
if (!allowStrings && e.isString()) {
// We do not match strings in Array
continue;
}
try {
ExampleMatcher::fillExampleDefinition(e, resolver, def);
definitions.emplace_back(std::move(def));
} catch (arangodb::basics::Exception& e) {
if (e.code() != TRI_RESULT_ELEMENT_NOT_FOUND) {
CleanupShapes(def._values);
ExampleMatcher::cleanup();
throw;
}
// Result not found might happen. Ignore here because all other elemens
// might be matched.
}
}
if (definitions.empty()) {
// None of the given examples could ever match.
// Throw result not found so client can short circuit.
THROW_ARANGO_EXCEPTION(TRI_RESULT_ELEMENT_NOT_FOUND);
}
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief Checks if the given mptr matches the examples in this class
////////////////////////////////////////////////////////////////////////////////

View File

@ -33,6 +33,10 @@ class VocShaper;
namespace arangodb {
namespace velocypack {
class Slice;
}
class ExampleMatcher {
struct DocumentId {
TRI_voc_cid_t cid;
@ -60,6 +64,10 @@ class ExampleMatcher {
arangodb::CollectionNameResolver const* resolver,
ExampleDefinition& def);
void fillExampleDefinition(arangodb::velocypack::Slice const& example,
arangodb::CollectionNameResolver const* resolver,
ExampleDefinition& def);
void fillExampleDefinition(v8::Isolate* isolate,
v8::Handle<v8::Object> const& example,
v8::Handle<v8::Array> const& names, size_t& n,
@ -75,6 +83,10 @@ class ExampleMatcher {
ExampleMatcher(TRI_json_t const* example, VocShaper* shaper,
arangodb::CollectionNameResolver const* resolver);
ExampleMatcher(arangodb::velocypack::Slice const& example, VocShaper* shaper,
arangodb::CollectionNameResolver const* resolver,
bool allowStrings);
~ExampleMatcher() { cleanup(); }
bool matches(TRI_voc_cid_t cid, TRI_doc_mptr_t const* mptr) const;

View File

@ -70,7 +70,7 @@ KeyGenerator::KeyGenerator(bool allowUserKeys)
KeyGenerator::~KeyGenerator() {}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the generator type from JSON
/// @brief get the generator type from VelocyPack
////////////////////////////////////////////////////////////////////////////////
KeyGenerator::GeneratorType KeyGenerator::generatorType(

View File

@ -76,7 +76,7 @@ class KeyGenerator {
static void Initialize();
//////////////////////////////////////////////////////////////////////////////
/// @brief get the generator type from JSON
/// @brief get the generator type from VelocyPack
//////////////////////////////////////////////////////////////////////////////
static GeneratorType generatorType(arangodb::velocypack::Slice const&);

View File

@ -2123,6 +2123,17 @@ TRI_json_t* TRI_JsonShapedJson(VocShaper* shaper,
return dst;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a shaped json object into a VelocyPack Object
/// NOTE: Transforms via TRI_json_t.
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<VPackBuilder> TRI_VelocyPackShapedJson(
VocShaper* shaper, TRI_shaped_json_t const* shaped) {
std::unique_ptr<TRI_json_t> tmp(TRI_JsonShapedJson(shaper, shaped));
return arangodb::basics::JsonHelper::toVelocyPack(tmp.get());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief prints a shaped json to a string buffer, without the outer braces
/// this can only be used to stringify shapes of type array

View File

@ -30,6 +30,7 @@
namespace arangodb {
namespace velocypack {
class Builder;
class Slice;
}
}
@ -901,6 +902,14 @@ TRI_shaped_json_t* TRI_ShapedJsonJson(VocShaper*, TRI_json_t const*, bool);
TRI_json_t* TRI_JsonShapedJson(VocShaper*, TRI_shaped_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief converts a shaped json object into a VelocyPack Object
/// NOTE: Transforms via TRI_json_t.
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<arangodb::velocypack::Builder> TRI_VelocyPackShapedJson(
VocShaper*, TRI_shaped_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief prints a shaped json to a string buffer, without the outer braces
/// this can only be used to stringify shapes of type array

View File

@ -24,11 +24,9 @@
#include "LogfileManager.h"
#include "Basics/files.h"
#include "Basics/hashes.h"
#include "Basics/json.h"
#include "Basics/Logger.h"
#include "Basics/Exceptions.h"
#include "Basics/FileUtils.h"
#include "Basics/JsonHelper.h"
#include "Basics/MutexLocker.h"
#include "Basics/ReadLocker.h"
#include "Basics/StringUtils.h"

View File

@ -406,15 +406,15 @@
});
if (found) {
this.deleteAardvarkJob(aardvark.id);
}
else {
array.push({
collection: aardvark.collection,
id: aardvark.id,
type: aardvark.type
});
}
else {
window.arangoHelper.deleteAardvarkJob(aardvark.id);
}
}
});
}

File diff suppressed because one or more lines are too long

View File

@ -2907,8 +2907,33 @@ div .tile, div .bigtile {
position: relative;
text-align: center;
z-index: 1; }
div .tile progress[value], div .bigtile progress[value] {
color: #5bc0de; }
div .tile progress::-webkit-progress-bar-value, div .bigtile progress::-webkit-progress-bar-value {
background: #5bc0de; }
div .tile progress::-webkit-progress-value, div .bigtile progress::-webkit-progress-value {
background: #5bc0de; }
div .tile progress::-moz-progress-bar, div .bigtile progress::-moz-progress-bar {
background: #5bc0de; }
div .tile progress, div .bigtile progress {
-webkit-appearance: none;
border-radius: 0;
height: 2px;
margin-top: 16px;
position: relative;
width: 100%;
z-index: 10; }
div .tile:hover, div .bigtile:hover {
cursor: pointer; }
div .locked.tile, div .locked.bigtile {
cursor: not-allowed;
opacity: .5; }
div .locked.tile .iconSet span:hover, div .locked.bigtile .iconSet span:hover {
background-color: #fff !important;
color: #000;
cursor: not-allowed !important; }
div .locked.tile .iconSet:hover, div .locked.bigtile .iconSet:hover {
cursor: not-allowed !important; }
div .tile .warning-icons, div .bigtile .warning-icons {
background-color: #da4f49;
border-radius: 3px;
@ -2980,6 +3005,8 @@ div .tile, div .bigtile {
padding: 4px 8px;
text-overflow: ellipsis !important;
white-space: nowrap !important; }
div .tile h5.inProgress, div .bigtile h5.inProgress {
color: #5bc0de; }
div .tile .tileSelects, div .bigtile .tileSelects {
margin-left: 40px;
position: relative;
@ -5498,7 +5525,7 @@ div.headerBar {
z-index: 9999999; }
.modal-tabbar {
border-bottom: 1px solid #000; }
border-bottom: 1px solid #666; }
.modal-body {
color: #736b68;
@ -5923,8 +5950,33 @@ div .tile, div .bigtile {
position: relative;
text-align: center;
z-index: 1; }
div .tile progress[value], div .bigtile progress[value] {
color: #5bc0de; }
div .tile progress::-webkit-progress-bar-value, div .bigtile progress::-webkit-progress-bar-value {
background: #5bc0de; }
div .tile progress::-webkit-progress-value, div .bigtile progress::-webkit-progress-value {
background: #5bc0de; }
div .tile progress::-moz-progress-bar, div .bigtile progress::-moz-progress-bar {
background: #5bc0de; }
div .tile progress, div .bigtile progress {
-webkit-appearance: none;
border-radius: 0;
height: 2px;
margin-top: 16px;
position: relative;
width: 100%;
z-index: 10; }
div .tile:hover, div .bigtile:hover {
cursor: pointer; }
div .locked.tile, div .locked.bigtile {
cursor: not-allowed;
opacity: .5; }
div .locked.tile .iconSet span:hover, div .locked.bigtile .iconSet span:hover {
background-color: #fff !important;
color: #000;
cursor: not-allowed !important; }
div .locked.tile .iconSet:hover, div .locked.bigtile .iconSet:hover {
cursor: not-allowed !important; }
div .tile .warning-icons, div .bigtile .warning-icons {
background-color: #da4f49;
border-radius: 3px;
@ -5996,6 +6048,8 @@ div .tile, div .bigtile {
padding: 4px 8px;
text-overflow: ellipsis !important;
white-space: nowrap !important; }
div .tile h5.inProgress, div .bigtile h5.inProgress {
color: #5bc0de; }
div .tile .tileSelects, div .bigtile .tileSelects {
margin-left: 40px;
position: relative;

View File

@ -10756,15 +10756,15 @@ function GraphViewer(svg, width, height, adapterConfig, config) {
});
if (found) {
this.deleteAardvarkJob(aardvark.id);
}
else {
array.push({
collection: aardvark.collection,
id: aardvark.id,
type: aardvark.type
});
}
else {
window.arangoHelper.deleteAardvarkJob(aardvark.id);
}
}
});
}
@ -16435,7 +16435,8 @@ var __fs__=require("fs");var __rcf__=__fs__.join(__fs__.home(),".arangosh.rc");i
status: "",
type: "",
isSystem: false,
picture: ""
picture: "",
locked: false
},
getProperties: function () {
@ -16553,14 +16554,14 @@ var __fs__=require("fs");var __rcf__=__fs__.join(__fs__.home(),".arangosh.rc");i
cache: false,
type: 'DELETE',
url: "/_api/index/"+ this.get("name") +"/"+encodeURIComponent(id),
async: false,
async: true,
success: function () {
callback(false);
},
error: function (data) {
callback(true, data);
}
});
});
callback();
},
@ -19530,19 +19531,29 @@ window.ArangoUsers = Backbone.Collection.extend({
},
render: function () {
if (this.model.get("locked")) {
$(this.el).addClass('locked');
}
$(this.el).html(this.template.render({
model: this.model
}));
$(this.el).attr('id', 'collection_' + this.model.get('name'));
return this;
},
editProperties: function (event) {
if (this.model.get("locked")) {
return 0;
}
event.stopPropagation();
this.createEditPropertiesModal();
},
showProperties: function(event) {
if (this.model.get("locked")) {
return 0;
}
event.stopPropagation();
this.createInfoModal();
},
@ -19553,6 +19564,9 @@ window.ArangoUsers = Backbone.Collection.extend({
if ($(event.target).hasClass("disabled")) {
return 0;
}
if (this.model.get("locked")) {
return 0;
}
window.App.navigate(
"collection/" + encodeURIComponent(this.model.get("name")) + "/documents/1", {trigger: true}
@ -19863,7 +19877,12 @@ window.ArangoUsers = Backbone.Collection.extend({
this.events, null,
tabBar
);
this.getIndex();
if (this.model.get("status") === 'loaded') {
this.getIndex();
}
else {
$($('#infoTab').children()[1]).remove();
}
this.bindIndexEvents();
},
@ -19895,6 +19914,7 @@ window.ArangoUsers = Backbone.Collection.extend({
});
$('#infoTab a').bind('click', function(e) {
$('#indexDeleteModal').remove();
if ($(e.currentTarget).html() === 'Indices' && !$(e.currentTarget).parent().hasClass('active')) {
$('#newIndexView').hide();
@ -20019,7 +20039,6 @@ window.ArangoUsers = Backbone.Collection.extend({
break;
}
var callback = function(error, msg){
if (error) {
if (msg) {
var message = JSON.parse(msg.responseText);
@ -20032,10 +20051,15 @@ window.ArangoUsers = Backbone.Collection.extend({
};
window.modalView.hide();
this.getIndex();
this.createEditPropertiesModal();
$($('#infoTab').children()[1]).find('a').click();
//this.getIndex();
//this.createEditPropertiesModal();
//$($('#infoTab').children()[1]).find('a').click();
self.model.createIndex(postParameter, callback);
window.App.arangoCollectionsStore.fetch({
success: function () {
self.collectionsView.render();
}
});
},
lastTarget: null,
@ -20051,27 +20075,47 @@ window.ArangoUsers = Backbone.Collection.extend({
children().
first().
text();
window.modalView.hide();
//window.modalView.hide();
//delete modal
$("#indexDeleteModal").modal('show');
$('#confirmDeleteIndexBtn').unbind('click');
$('#confirmDeleteIndexBtn').bind('click', function() {
$("#modal-dialog .modal-footer").after(
'<div id="indexDeleteModal" style="display:block;" class="alert alert-error modal-delete-confirmation">' +
'<strong>Really delete?</strong>' +
'<button id="indexConfirmDelete" class="button-danger pull-right modal-confirm-delete">Yes</button>' +
'<button id="indexAbortDelete" class="button-neutral pull-right">No</button>' +
'</div>');
$('#indexConfirmDelete').unbind('click');
$('#indexConfirmDelete').bind('click', function() {
$('#indexDeleteModal').remove();
self.deleteIndex();
});
$('#indexAbortDelete').unbind('click');
$('#indexAbortDelete').bind('click', function() {
$('#indexDeleteModal').remove();
});
},
deleteIndex: function () {
var callback = function(error) {
if (error) {
arangoHelper.arangoError("Could not delete index");
$("tr th:contains('"+ this.lastId+"')").parent().children().last().html(
'<span class="deleteIndex icon_arangodb_roundminus"' +
' data-original-title="Delete index" title="Delete index"></span>'
);
}
};
else {
$("tr th:contains('"+ this.lastId+"')").parent().remove();
}
}.bind(this);
$("#indexDeleteModal").modal('hide');
this.model.deleteIndex(this.lastId, callback);
this.createEditPropertiesModal();
$($('#infoTab').children()[1]).find('a').click();
$("tr th:contains('"+ this.lastId+"')").parent().children().last().html(
'<i class="fa fa-circle-o-notch fa-spin"></i>'
);
},
selectIndexType: function () {
@ -20138,7 +20182,6 @@ window.ArangoUsers = Backbone.Collection.extend({
}
else {
console.log("toggle else");
$('#indexEditView').show();
$('#newIndexView').hide();
$('#addIndex').detach().appendTo('#modal-dialog .modal-footer');
@ -20179,13 +20222,51 @@ window.ArangoUsers = Backbone.Collection.extend({
el2: '#collectionsThumbnailsIn',
searchTimeout: null,
refreshRate: 2000,
template: templateEngine.createTemplate("collectionsView.ejs"),
checkLockedCollections: function() {
var self = this,
lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index');
this.collection.each(function(model) {
model.set('locked', false);
});
_.each(lockedCollections, function(locked) {
var model = self.collection.findWhere({
id: locked.collection
});
model.set('locked', true);
model.set('lockType', locked.type);
});
this.collection.each(function(model) {
if (model.get("locked")) {
$('#collection_' + model.get("name")).addClass('locked');
}
else {
$('#collection_' + model.get("name")).removeClass('locked');
}
});
},
initialize: function() {
var self = this;
window.setInterval(function() {
self.checkLockedCollections();
}, self.refreshRate);
},
render: function () {
var dropdownVisible = false,
lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index');
this.checkLockedCollections();
var dropdownVisible = false;
if ($('#collectionsDropdown').is(':visible')) {
dropdownVisible = true;
@ -20231,6 +20312,7 @@ window.ArangoUsers = Backbone.Collection.extend({
arangoHelper.fixTooltips(".icon_arangodb, .arangoicon", "left");
return this;
},
@ -20457,7 +20539,7 @@ window.ArangoUsers = Backbone.Collection.extend({
var returnobj = this.collection.newCollection(
collName, wfs, isSystem, collSize, collType, shards, shardBy
);
if (returnobj.status !== true) {console.log(returnobj);
if (returnobj.status !== true) {
arangoHelper.arangoError("Collection error", returnobj.errorMessage);
}
this.updateCollectionsView();

View File

@ -264,7 +264,13 @@
</div>
</span>
</div>
<h5 class="collectionName"><%= model.get('name') %></h5></script><script id="collectionsView.ejs" type="text/template"><div class="headerBar">
<% if(model.get('lockType') === "index") { %>
<!-- <progress max="100" value="80"></progress>-->
<h5 class="collectionName"><%= model.get('name') %></h5>
<% } else { %>
<h5 class="collectionName"><%= model.get('name') %></h5>
<% } %></script><script id="collectionsView.ejs" type="text/template"><div class="headerBar">
<div class="search-field">
<input type="text" id="searchInput" class="search-input" placeholder="Search..."/>
<!-- <img id="searchSubmit" class="search-submit-icon"/> -->
@ -378,21 +384,6 @@
</div>
</div>
</div>
</div>
<!-- Delete Index Modal -->
<div id="indexDeleteModal" style="display:none" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Delete Index?</a>
</div>
<div class="modal-body" id="deleteIndex">
<p>There is no way back…</p>
</div>
<div class="modal-footer">
<button class="button-close" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="confirmDeleteIndexBtn" class="button-danger" style="float:right">Delete</button>
</div>
</div></script><script id="dashboardView.ejs" type="text/template"><% var subBar = function(title) { %>
<div class="dashboard-sub-bar">
<div class="dashboard-sub-bar-title"><%= title %></div>

View File

@ -300,7 +300,13 @@
</div>
</span>
</div>
<h5 class="collectionName"><%= model.get('name') %></h5>
<% if(model.get('lockType') === "index") { %>
<!-- <progress max="100" value="80"></progress>-->
<h5 class="collectionName"><%= model.get('name') %></h5>
<% } else { %>
<h5 class="collectionName"><%= model.get('name') %></h5>
<% } %>
</script>
<script id="collectionsView.ejs" type="text/template">
@ -420,21 +426,6 @@
</div>
</div>
<!-- Delete Index Modal -->
<div id="indexDeleteModal" style="display:none" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Delete Index?</a>
</div>
<div class="modal-body" id="deleteIndex">
<p>There is no way back…</p>
</div>
<div class="modal-footer">
<button class="button-close" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="confirmDeleteIndexBtn" class="button-danger" style="float:right">Delete</button>
</div>
</div>
</script>
<script id="dashboardView.ejs" type="text/template">

File diff suppressed because one or more lines are too long

View File

@ -2897,8 +2897,33 @@ div .tile, div .bigtile {
position: relative;
text-align: center;
z-index: 1; }
div .tile progress[value], div .bigtile progress[value] {
color: #5bc0de; }
div .tile progress::-webkit-progress-bar-value, div .bigtile progress::-webkit-progress-bar-value {
background: #5bc0de; }
div .tile progress::-webkit-progress-value, div .bigtile progress::-webkit-progress-value {
background: #5bc0de; }
div .tile progress::-moz-progress-bar, div .bigtile progress::-moz-progress-bar {
background: #5bc0de; }
div .tile progress, div .bigtile progress {
-webkit-appearance: none;
border-radius: 0;
height: 2px;
margin-top: 16px;
position: relative;
width: 100%;
z-index: 10; }
div .tile:hover, div .bigtile:hover {
cursor: pointer; }
div .locked.tile, div .locked.bigtile {
cursor: not-allowed;
opacity: .5; }
div .locked.tile .iconSet span:hover, div .locked.bigtile .iconSet span:hover {
background-color: #fff !important;
color: #000;
cursor: not-allowed !important; }
div .locked.tile .iconSet:hover, div .locked.bigtile .iconSet:hover {
cursor: not-allowed !important; }
div .tile .warning-icons, div .bigtile .warning-icons {
background-color: #da4f49;
border-radius: 3px;
@ -2970,6 +2995,8 @@ div .tile, div .bigtile {
padding: 4px 8px;
text-overflow: ellipsis !important;
white-space: nowrap !important; }
div .tile h5.inProgress, div .bigtile h5.inProgress {
color: #5bc0de; }
div .tile .tileSelects, div .bigtile .tileSelects {
margin-left: 40px;
position: relative;
@ -5488,7 +5515,7 @@ div.headerBar {
z-index: 9999999; }
.modal-tabbar {
border-bottom: 1px solid #000; }
border-bottom: 1px solid #666; }
.modal-body {
color: #736b68;
@ -7292,6 +7319,10 @@ input.gv-radio-button {
#graphTab li,
#collectionTab li {
float: right; }
#infoTab li.disabled a,
#graphTab li.disabled a,
#collectionTab li.disabled a {
cursor: not-allowed; }
#infoTab a,
#graphTab a,
@ -8034,8 +8065,7 @@ table .sorting {
margin-top: 20px; }
.new-index-view input[type='checkbox'] {
float: left;
margin-top: -9px; }
float: left; }
.new-index-view table tr {
width: 600px !important; }
@ -8071,7 +8101,14 @@ table .sorting {
border-bottom: 1px solid #e5e5e5; }
.newIndexClass table {
border-top: 1px solid #f7f3f2;
margin-bottom: 60px; }
.newIndexClass table select {
margin-right: 7px; }
.newIndexClass table .arangoicon {
float: right;
margin-right: -12px;
margin-top: 5px; }
.index-button-bar {
bottom: 0;

View File

@ -406,15 +406,15 @@
});
if (found) {
this.deleteAardvarkJob(aardvark.id);
}
else {
array.push({
collection: aardvark.collection,
id: aardvark.id,
type: aardvark.type
});
}
else {
window.arangoHelper.deleteAardvarkJob(aardvark.id);
}
}
});
}

View File

@ -257,31 +257,14 @@
"SIMPLE_CLIENT_COULD_NOT_READ" : { "code" : 2003, "message" : "could not read from server" },
"ERROR_MALFORMED_MANIFEST_FILE" : { "code" : 3000, "message" : "malformed manifest file" },
"ERROR_INVALID_APPLICATION_MANIFEST" : { "code" : 3001, "message" : "manifest file is invalid" },
"ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING" : { "code" : 3002, "message" : "missing manifest attribute" },
"ERROR_CANNOT_EXTRACT_APPLICATION_ROOT" : { "code" : 3003, "message" : "unable to extract app root path" },
"ERROR_INVALID_FOXX_OPTIONS" : { "code" : 3004, "message" : "invalid foxx options" },
"ERROR_FAILED_TO_EXECUTE_SCRIPT" : { "code" : 3005, "message" : "failed to execute script" },
"ERROR_SYNTAX_ERROR_IN_SCRIPT" : { "code" : 3006, "message" : "syntax error in script" },
"ERROR_INVALID_MOUNTPOINT" : { "code" : 3007, "message" : "mountpoint is invalid" },
"ERROR_NO_FOXX_FOUND" : { "code" : 3008, "message" : "No foxx found at this location" },
"ERROR_APP_NOT_FOUND" : { "code" : 3009, "message" : "App not found" },
"ERROR_APP_NEEDS_CONFIGURATION" : { "code" : 3010, "message" : "App not configured" },
"ERROR_MODULE_NOT_FOUND" : { "code" : 3100, "message" : "cannot locate module" },
"ERROR_MODULE_SYNTAX_ERROR" : { "code" : 3101, "message" : "syntax error in module" },
"ERROR_MODULE_BAD_WRAPPER" : { "code" : 3102, "message" : "failed to wrap module" },
"ERROR_MODULE_FAILURE" : { "code" : 3103, "message" : "failed to invoke module" },
"ERROR_MODULE_UNKNOWN_FILE_TYPE" : { "code" : 3110, "message" : "unknown file type" },
"ERROR_MODULE_PATH_MUST_BE_ABSOLUTE" : { "code" : 3111, "message" : "path must be absolute" },
"ERROR_MODULE_CAN_NOT_ESCAPE" : { "code" : 3112, "message" : "cannot use '..' to escape top-level-directory" },
"ERROR_MODULE_DRIVE_LETTER" : { "code" : 3113, "message" : "drive local path is not supported" },
"ERROR_MODULE_BAD_MODULE_ORIGIN" : { "code" : 3120, "message" : "corrupted module origin" },
"ERROR_MODULE_BAD_PACKAGE_ORIGIN" : { "code" : 3121, "message" : "corrupted package origin" },
"ERROR_MODULE_DOCUMENT_IS_EMPTY" : { "code" : 3125, "message" : "no content" },
"ERROR_MODULE_MAIN_NOT_READABLE" : { "code" : 3130, "message" : "cannot read main file" },
"ERROR_MODULE_MAIN_NOT_JS" : { "code" : 3131, "message" : "main file is not of type 'js'" },
"RESULT_ELEMENT_EXISTS" : { "code" : 10000, "message" : "element not inserted into structure, because it already exists" },
"RESULT_ELEMENT_NOT_FOUND" : { "code" : 10001, "message" : "element not found in structure" },
"ERROR_APP_ALREADY_EXISTS" : { "code" : 20000, "message" : "newest version of app already installed" },
"ERROR_QUEUE_ALREADY_EXISTS" : { "code" : 21000, "message" : "named queue already exists" },
"ERROR_DISPATCHER_IS_STOPPING" : { "code" : 21001, "message" : "dispatcher stopped" },
"ERROR_QUEUE_UNKNOWN" : { "code" : 21002, "message" : "named queue does not exist" },

View File

@ -49,22 +49,27 @@ if (global.ArangoError) {
this.errorNum = error.errorNum;
this.errorMessage = error.errorMessage;
}
this.message = this.toString();
};
exports.ArangoError.prototype = new Error();
}
Object.defineProperty(exports.ArangoError.prototype, 'message', {
configurable: true,
enumerable: true,
get() {
return this.errorMessage;
}
});
exports.ArangoError.prototype.name = 'ArangoError';
exports.ArangoError.prototype._PRINT = function(context) {
context.output += this.toString();
context.output += '[' + this.toString() + ']';
};
exports.ArangoError.prototype.toString = function() {
var errorNum = this.errorNum;
var errorMessage = this.errorMessage || this.message;
return '[ArangoError ' + errorNum + ': ' + errorMessage + ']';
return `${this.name} ${this.errorNum}: ${this.message}`;
};

View File

@ -14,7 +14,8 @@
status: "",
type: "",
isSystem: false,
picture: ""
picture: "",
locked: false
},
getProperties: function () {
@ -132,14 +133,14 @@
cache: false,
type: 'DELETE',
url: "/_api/index/"+ this.get("name") +"/"+encodeURIComponent(id),
async: false,
async: true,
success: function () {
callback(false);
},
error: function (data) {
callback(true, data);
}
});
});
callback();
},

View File

@ -96,7 +96,9 @@ exports.checkRequestResult = function (requestResult) {
throw new TypeError(requestResult.errorMessage);
}
throw new ArangoError(requestResult);
const error = new ArangoError(requestResult);
error.message = requestResult.message;
throw error;
}
// remove the property from the original object

View File

@ -18,5 +18,11 @@
</div>
</span>
</div>
<h5 class="collectionName"><%= model.get('name') %></h5>
<% if(model.get('lockType') === "index") { %>
<!-- <progress max="100" value="80"></progress>-->
<h5 class="collectionName"><%= model.get('name') %></h5>
<% } else { %>
<h5 class="collectionName"><%= model.get('name') %></h5>
<% } %>
</script>

View File

@ -115,19 +115,4 @@
</div>
</div>
<!-- Delete Index Modal -->
<div id="indexDeleteModal" style="display:none" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<a class="arangoHeader">Delete Index?</a>
</div>
<div class="modal-body" id="deleteIndex">
<p>There is no way back…</p>
</div>
<div class="modal-footer">
<button class="button-close" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="confirmDeleteIndexBtn" class="button-danger" style="float:right">Delete</button>
</div>
</div>
</script>

View File

@ -24,19 +24,29 @@
},
render: function () {
if (this.model.get("locked")) {
$(this.el).addClass('locked');
}
$(this.el).html(this.template.render({
model: this.model
}));
$(this.el).attr('id', 'collection_' + this.model.get('name'));
return this;
},
editProperties: function (event) {
if (this.model.get("locked")) {
return 0;
}
event.stopPropagation();
this.createEditPropertiesModal();
},
showProperties: function(event) {
if (this.model.get("locked")) {
return 0;
}
event.stopPropagation();
this.createInfoModal();
},
@ -47,6 +57,9 @@
if ($(event.target).hasClass("disabled")) {
return 0;
}
if (this.model.get("locked")) {
return 0;
}
window.App.navigate(
"collection/" + encodeURIComponent(this.model.get("name")) + "/documents/1", {trigger: true}
@ -357,7 +370,12 @@
this.events, null,
tabBar
);
this.getIndex();
if (this.model.get("status") === 'loaded') {
this.getIndex();
}
else {
$($('#infoTab').children()[1]).remove();
}
this.bindIndexEvents();
},
@ -389,6 +407,7 @@
});
$('#infoTab a').bind('click', function(e) {
$('#indexDeleteModal').remove();
if ($(e.currentTarget).html() === 'Indices' && !$(e.currentTarget).parent().hasClass('active')) {
$('#newIndexView').hide();
@ -513,7 +532,6 @@
break;
}
var callback = function(error, msg){
if (error) {
if (msg) {
var message = JSON.parse(msg.responseText);
@ -526,10 +544,15 @@
};
window.modalView.hide();
this.getIndex();
this.createEditPropertiesModal();
$($('#infoTab').children()[1]).find('a').click();
//this.getIndex();
//this.createEditPropertiesModal();
//$($('#infoTab').children()[1]).find('a').click();
self.model.createIndex(postParameter, callback);
window.App.arangoCollectionsStore.fetch({
success: function () {
self.collectionsView.render();
}
});
},
lastTarget: null,
@ -545,27 +568,47 @@
children().
first().
text();
window.modalView.hide();
//window.modalView.hide();
//delete modal
$("#indexDeleteModal").modal('show');
$('#confirmDeleteIndexBtn').unbind('click');
$('#confirmDeleteIndexBtn').bind('click', function() {
$("#modal-dialog .modal-footer").after(
'<div id="indexDeleteModal" style="display:block;" class="alert alert-error modal-delete-confirmation">' +
'<strong>Really delete?</strong>' +
'<button id="indexConfirmDelete" class="button-danger pull-right modal-confirm-delete">Yes</button>' +
'<button id="indexAbortDelete" class="button-neutral pull-right">No</button>' +
'</div>');
$('#indexConfirmDelete').unbind('click');
$('#indexConfirmDelete').bind('click', function() {
$('#indexDeleteModal').remove();
self.deleteIndex();
});
$('#indexAbortDelete').unbind('click');
$('#indexAbortDelete').bind('click', function() {
$('#indexDeleteModal').remove();
});
},
deleteIndex: function () {
var callback = function(error) {
if (error) {
arangoHelper.arangoError("Could not delete index");
$("tr th:contains('"+ this.lastId+"')").parent().children().last().html(
'<span class="deleteIndex icon_arangodb_roundminus"' +
' data-original-title="Delete index" title="Delete index"></span>'
);
}
};
else {
$("tr th:contains('"+ this.lastId+"')").parent().remove();
}
}.bind(this);
$("#indexDeleteModal").modal('hide');
this.model.deleteIndex(this.lastId, callback);
this.createEditPropertiesModal();
$($('#infoTab').children()[1]).find('a').click();
$("tr th:contains('"+ this.lastId+"')").parent().children().last().html(
'<i class="fa fa-circle-o-notch fa-spin"></i>'
);
},
selectIndexType: function () {
@ -632,7 +675,6 @@
}
else {
console.log("toggle else");
$('#indexEditView').show();
$('#newIndexView').hide();
$('#addIndex').detach().appendTo('#modal-dialog .modal-footer');

View File

@ -9,13 +9,51 @@
el2: '#collectionsThumbnailsIn',
searchTimeout: null,
refreshRate: 2000,
template: templateEngine.createTemplate("collectionsView.ejs"),
checkLockedCollections: function() {
var self = this,
lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index');
this.collection.each(function(model) {
model.set('locked', false);
});
_.each(lockedCollections, function(locked) {
var model = self.collection.findWhere({
id: locked.collection
});
model.set('locked', true);
model.set('lockType', locked.type);
});
this.collection.each(function(model) {
if (model.get("locked")) {
$('#collection_' + model.get("name")).addClass('locked');
}
else {
$('#collection_' + model.get("name")).removeClass('locked');
}
});
},
initialize: function() {
var self = this;
window.setInterval(function() {
self.checkLockedCollections();
}, self.refreshRate);
},
render: function () {
var dropdownVisible = false,
lockedCollections = window.arangoHelper.syncAndReturnUninishedAardvarkJobs('index');
this.checkLockedCollections();
var dropdownVisible = false;
if ($('#collectionsDropdown').is(':visible')) {
dropdownVisible = true;
@ -61,6 +99,7 @@
arangoHelper.fixTooltips(".icon_arangodb, .arangoicon", "left");
return this;
},
@ -287,7 +326,7 @@
var returnobj = this.collection.newCollection(
collName, wfs, isSystem, collSize, collType, shards, shardBy
);
if (returnobj.status !== true) {console.log(returnobj);
if (returnobj.status !== true) {
arangoHelper.arangoError("Collection error", returnobj.errorMessage);
}
this.updateCollectionsView();

View File

@ -117,12 +117,19 @@
margin-bottom: 1px;
padding-bottom: 0;
padding-right: 10px;
}
#infoTab li,
#graphTab li,
#collectionTab li {
float: right;
&.disabled {
a {
cursor: not-allowed;
}
}
}
#infoTab a,

View File

@ -148,6 +148,7 @@ $c-sh-string: #ce2f30;
$c-sh-object: #00f;
$c-sh-array: #00f;
$c-progress-bar: #5bc0de;
$c-progress-shadow: #353c39;
$c-progress-shadow-2: #8cdb8b;
$c-progress-bg: #363c39;

View File

@ -5,7 +5,6 @@
.new-index-view {
input[type='checkbox'] {
float: left;
margin-top: -9px;
}
table {
@ -67,7 +66,18 @@
.newIndexClass {
table {
border-top: 1px solid $c-modal-table-border-bottom;
margin-bottom: 60px;
select {
margin-right: 7px;
}
.arangoicon {
float: right;
margin-right: -12px;
margin-top: 5px;
}
}
}

View File

@ -39,7 +39,7 @@
}
.modal-tabbar {
border-bottom: 1px solid $c-black;
border-bottom: 1px solid $c-darker-grey;
}
.modal-body {

View File

@ -39,10 +39,53 @@ $iconsize: 50px;
z-index: 1;
progress[value] {
color: $c-progress-bar;
}
progress::-webkit-progress-bar-value {
background: $c-progress-bar;
}
progress::-webkit-progress-value {
background: $c-progress-bar;
}
progress::-moz-progress-bar {
background: $c-progress-bar;
}
progress {
-webkit-appearance: none;
border-radius: 0;
height: 2px;
margin-top: 16px;
position: relative;
width: 100%;
z-index: 10;
}
&:hover {
cursor: pointer;
}
&.locked {
cursor: not-allowed;
opacity: .5;
.iconSet {
span:hover {
background-color: $c-white !important;
color: $c-black;
cursor: not-allowed !important;
}
}
.iconSet:hover {
cursor: not-allowed !important;
}
}
.warning-icons {
background-color: $c-negative;
border-radius: 3px;
@ -153,6 +196,10 @@ $iconsize: 50px;
padding: 4px 8px;
text-overflow: ellipsis !important;
white-space: nowrap !important;
&.inProgress {
color: $c-progress-bar;
}
}
.tileSelects {

View File

@ -257,31 +257,14 @@
"SIMPLE_CLIENT_COULD_NOT_READ" : { "code" : 2003, "message" : "could not read from server" },
"ERROR_MALFORMED_MANIFEST_FILE" : { "code" : 3000, "message" : "malformed manifest file" },
"ERROR_INVALID_APPLICATION_MANIFEST" : { "code" : 3001, "message" : "manifest file is invalid" },
"ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING" : { "code" : 3002, "message" : "missing manifest attribute" },
"ERROR_CANNOT_EXTRACT_APPLICATION_ROOT" : { "code" : 3003, "message" : "unable to extract app root path" },
"ERROR_INVALID_FOXX_OPTIONS" : { "code" : 3004, "message" : "invalid foxx options" },
"ERROR_FAILED_TO_EXECUTE_SCRIPT" : { "code" : 3005, "message" : "failed to execute script" },
"ERROR_SYNTAX_ERROR_IN_SCRIPT" : { "code" : 3006, "message" : "syntax error in script" },
"ERROR_INVALID_MOUNTPOINT" : { "code" : 3007, "message" : "mountpoint is invalid" },
"ERROR_NO_FOXX_FOUND" : { "code" : 3008, "message" : "No foxx found at this location" },
"ERROR_APP_NOT_FOUND" : { "code" : 3009, "message" : "App not found" },
"ERROR_APP_NEEDS_CONFIGURATION" : { "code" : 3010, "message" : "App not configured" },
"ERROR_MODULE_NOT_FOUND" : { "code" : 3100, "message" : "cannot locate module" },
"ERROR_MODULE_SYNTAX_ERROR" : { "code" : 3101, "message" : "syntax error in module" },
"ERROR_MODULE_BAD_WRAPPER" : { "code" : 3102, "message" : "failed to wrap module" },
"ERROR_MODULE_FAILURE" : { "code" : 3103, "message" : "failed to invoke module" },
"ERROR_MODULE_UNKNOWN_FILE_TYPE" : { "code" : 3110, "message" : "unknown file type" },
"ERROR_MODULE_PATH_MUST_BE_ABSOLUTE" : { "code" : 3111, "message" : "path must be absolute" },
"ERROR_MODULE_CAN_NOT_ESCAPE" : { "code" : 3112, "message" : "cannot use '..' to escape top-level-directory" },
"ERROR_MODULE_DRIVE_LETTER" : { "code" : 3113, "message" : "drive local path is not supported" },
"ERROR_MODULE_BAD_MODULE_ORIGIN" : { "code" : 3120, "message" : "corrupted module origin" },
"ERROR_MODULE_BAD_PACKAGE_ORIGIN" : { "code" : 3121, "message" : "corrupted package origin" },
"ERROR_MODULE_DOCUMENT_IS_EMPTY" : { "code" : 3125, "message" : "no content" },
"ERROR_MODULE_MAIN_NOT_READABLE" : { "code" : 3130, "message" : "cannot read main file" },
"ERROR_MODULE_MAIN_NOT_JS" : { "code" : 3131, "message" : "main file is not of type 'js'" },
"RESULT_ELEMENT_EXISTS" : { "code" : 10000, "message" : "element not inserted into structure, because it already exists" },
"RESULT_ELEMENT_NOT_FOUND" : { "code" : 10001, "message" : "element not found in structure" },
"ERROR_APP_ALREADY_EXISTS" : { "code" : 20000, "message" : "newest version of app already installed" },
"ERROR_QUEUE_ALREADY_EXISTS" : { "code" : 21000, "message" : "named queue already exists" },
"ERROR_DISPATCHER_IS_STOPPING" : { "code" : 21001, "message" : "dispatcher stopped" },
"ERROR_QUEUE_UNKNOWN" : { "code" : 21002, "message" : "named queue does not exist" },

View File

@ -497,7 +497,14 @@ function StatementSuite () {
while (result.hasNext()) {
var doc = result.next();
assertEqual([ { b: 2 } ], doc.missing);
assertEqual([ { foo: { "old": "bar", "new": "baz" } }, { a: { "old" : 1, "new": 2 } } ], doc.changed);
var changed = doc.changed;
if (changed[0].hasOwnProperty("foo")) {
assertEqual({ foo: { "old": "bar", "new": "baz" } }, changed[0]);
assertEqual({ a: { "old" : 1, "new": 2 } }, doc.changed[1]);
} else {
assertEqual({ a: { "old" : 1, "new": 2 } }, changed[0]);
assertEqual({ foo: { "old": "bar", "new": "baz" } }, changed[1]);
}
assertEqual([ { c: 3 } ], doc.added);
}
},

View File

@ -138,13 +138,23 @@ function ahuacatlNumericFunctionsTestSuite () {
testAbs : function () {
var expected = [ 99.999, 3, 2.1, 2.01, 2, 1.99, 1.1, 1.01, 1, 0.9, 0.6, 0.5, 0.4, 0.1, 0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ];
var actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return ABS(r)");
assertEqual(expected, actual);
var i = 0;
assertEqual(actual.length, expected.length);
for (i = 0; i < expected.length; ++i) {
assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5));
}
actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return NOOPT(ABS(r))");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
for (i = 0; i < expected.length; ++i) {
assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5));
}
actual = getQueryResults("FOR r IN [ -99.999, -3, -2.1, -2.01, -2, -1.99, -1.1, -1.01, -1, -0.9, -0.6, -0.5, -0.4, -0.1, -0.01, 0, 0.01, 0.1, 0.4, 0.5, 0.6, 0.9, 1, 1.01, 1.1, 1.99, 2, 2.01, 2.1, 3, 99.999 ] return NOOPT(V8(ABS(r)))");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
for (i = 0; i < expected.length; ++i) {
assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5));
}
},
////////////////////////////////////////////////////////////////////////////////

View File

@ -498,9 +498,13 @@ function ahuacatlTypesFunctionsTestSuite () {
////////////////////////////////////////////////////////////////////////////////
testToArray5 : function () {
var expected = [ [ -0.635 ] ];
var expected = -0.635;
var actual = getQueryResults("RETURN NOOPT(TO_ARRAY(-0.635))");
assertEqual(expected, actual);
assertEqual(actual.length, 1);
assertEqual(actual[0].length, 1);
var value = actual[0][0];
// Double precission
assertEqual(expected.toPrecision(5), value.toPrecision(5));
},
////////////////////////////////////////////////////////////////////////////////

View File

@ -3272,7 +3272,10 @@ function ahuacatlFunctionsTestSuite () {
testAttributes1 : function () {
var expected = [ [ "foo", "bar", "meow", "_id" ], [ "foo" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN ATTRIBUTES(u)");
assertEqual(expected, actual);
// Order is not guaranteed order here in-place
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3282,7 +3285,10 @@ function ahuacatlFunctionsTestSuite () {
testAttributes2 : function () {
var expected = [ [ "foo", "bar", "meow" ], [ "foo" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN ATTRIBUTES(u, true)");
assertEqual(expected, actual);
// Order is not guaranteed order here in-place
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3312,7 +3318,10 @@ function ahuacatlFunctionsTestSuite () {
testAttributesCxx1 : function () {
var expected = [ [ "foo", "bar", "meow", "_id" ], [ "foo" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(ATTRIBUTES(u))");
assertEqual(expected, actual);
// Order is not guaranteed order here in-place
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3322,7 +3331,10 @@ function ahuacatlFunctionsTestSuite () {
testAttributesCxx2 : function () {
var expected = [ [ "foo", "bar", "meow" ], [ "foo" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(ATTRIBUTES(u, true))");
assertEqual(expected, actual);
// Order is not guaranteed order here in-place
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3352,7 +3364,9 @@ function ahuacatlFunctionsTestSuite () {
testValues1 : function () {
var expected = [ [ "bar", "baz", true, "123/456" ], [ "bar" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN VALUES(u)");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3362,7 +3376,9 @@ function ahuacatlFunctionsTestSuite () {
testValues2 : function () {
var expected = [ [ "bar", "baz", true ], [ "bar" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN VALUES(u, true)");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3372,7 +3388,8 @@ function ahuacatlFunctionsTestSuite () {
testValues3 : function () {
var expected = [ [ "test/1123", "test/abc", "1234", "test", "", [ 1, 2, 3, 4, [ true ] ], null, { d: 42, e: null, f: [ "test!" ] } ] ];
var actual = getQueryResults("RETURN VALUES({ _from: \"test/1123\", _to: \"test/abc\", _rev: \"1234\", _key: \"test\", void: \"\", a: [ 1, 2, 3, 4, [ true ] ], b : null, c: { d: 42, e: null, f: [ \"test!\" ] } })");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3382,7 +3399,9 @@ function ahuacatlFunctionsTestSuite () {
testValuesCxx1 : function () {
var expected = [ [ "bar", "baz", true, "123/456" ], [ "bar" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(VALUES(u))");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3392,7 +3411,9 @@ function ahuacatlFunctionsTestSuite () {
testValuesCxx2 : function () {
var expected = [ [ "bar", "baz", true ], [ "bar" ] ];
var actual = getQueryResults("FOR u IN [ { foo: \"bar\", bar: \"baz\", meow: true, _id: \"123/456\" }, { foo: \"bar\" } ] RETURN NOOPT(VALUES(u, true))");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
assertEqual(actual[1].sort(), expected[1].sort());
},
////////////////////////////////////////////////////////////////////////////////
@ -3402,7 +3423,8 @@ function ahuacatlFunctionsTestSuite () {
testValuesCxx3 : function () {
var expected = [ [ "test/1123", "test/abc", "1234", "test", "", [ 1, 2, 3, 4, [ true ] ], null, { d: 42, e: null, f: [ "test!" ] } ] ];
var actual = getQueryResults("RETURN NOOPT(VALUES({ _from: \"test/1123\", _to: \"test/abc\", _rev: \"1234\", _key: \"test\", void: \"\", a: [ 1, 2, 3, 4, [ true ] ], b : null, c: { d: 42, e: null, f: [ \"test!\" ] } }))");
assertEqual(expected, actual);
assertEqual(actual.length, expected.length);
assertEqual(actual[0].sort(), expected[0].sort());
},
////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -512,6 +512,20 @@ class LoggerStream {
return *this;
}
template <typename T>
LoggerStream& operator<<(std::vector<T> const& v) {
for (auto const& i : v)
_out << i << " ";
return *this;
}
template <typename T>
LoggerStream& operator<<(std::unordered_set<T> const& us) {
for (auto const& i : us)
_out << i;
return *this;
}
private:
std::stringstream _out;
size_t _topicId;

View File

@ -37,10 +37,17 @@
using VelocyPackHelper = arangodb::basics::VelocyPackHelper;
struct AttributeSorter {
bool operator()(std::string const& l, std::string const& r) const {
return TRI_compare_utf8(l.c_str(), l.size(), r.c_str(), r.size()) < 0;
}
bool VelocyPackHelper::AttributeSorter::operator()(std::string const& l,
std::string const& r) const {
return TRI_compare_utf8(l.c_str(), l.size(), r.c_str(), r.size()) < 0;
}
size_t VelocyPackHelper::VPackHash::operator()(VPackSlice const& slice) const {
return slice.hash();
};
bool VelocyPackHelper::VPackEqual::operator()(VPackSlice const& lhs, VPackSlice const& rhs) const {
return VelocyPackHelper::compare(lhs, rhs, false) == 0;
};
static int TypeWeight(VPackSlice const& slice) {
@ -431,7 +438,66 @@ int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs,
}
}
VPackBuilder VelocyPackHelper::merge(VPackSlice const& lhs,
VPackSlice const& rhs,
bool nullMeansRemove, bool mergeObjects) {
return VPackCollection::merge(lhs, rhs, mergeObjects, nullMeansRemove);
}
double VelocyPackHelper::toDouble(VPackSlice const& slice, bool& failed) {
TRI_ASSERT(!slice.isNone());
failed = false;
switch (slice.type()) {
case VPackValueType::None:
case VPackValueType::Null:
return 0.0;
case VPackValueType::Bool:
return (slice.getBoolean() ? 1.0 : 0.0);
case VPackValueType::Double:
case VPackValueType::Int:
case VPackValueType::UInt:
case VPackValueType::SmallInt:
return slice.getNumericValue<double>();
case VPackValueType::String:
{
std::string tmp = slice.copyString();
try {
// try converting string to number
return std::stod(tmp);
} catch (...) {
if (tmp.empty()) {
return 0.0;
}
// conversion failed
}
break;
}
case VPackValueType::Array:
{
VPackValueLength const n = slice.length();
if (n == 0) {
return 0.0;
} else if (n == 1) {
return VelocyPackHelper::toDouble(slice.at(0), failed);
}
break;
}
case VPackValueType::Object:
case VPackValueType::UTCDate:
case VPackValueType::External:
case VPackValueType::MinKey:
case VPackValueType::MaxKey:
case VPackValueType::Binary:
case VPackValueType::BCD:
case VPackValueType::Custom:
break;
}
failed = true;
return 0.0;
}
arangodb::LoggerStream& operator<< (arangodb::LoggerStream& logger,
VPackSlice const& slice) {

View File

@ -38,6 +38,36 @@ class VelocyPackHelper {
~VelocyPackHelper() = delete;
public:
struct VPackHash {
size_t operator()(arangodb::velocypack::Slice const&) const;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief equality comparator for VelocyPack values
////////////////////////////////////////////////////////////////////////////////
struct VPackEqual {
bool operator()(arangodb::velocypack::Slice const&,
arangodb::velocypack::Slice const&) const;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief less comparator for VelocyPack values
////////////////////////////////////////////////////////////////////////////////
template <bool useUtf8>
struct VPackLess {
inline bool operator()(arangodb::velocypack::Slice const& lhs,
arangodb::velocypack::Slice const& rhs) const {
return VelocyPackHelper::compare(lhs, rhs, useUtf8) < 0;
}
};
struct AttributeSorter {
bool operator()(std::string const& l, std::string const& r) const;
};
//////////////////////////////////////////////////////////////////////////////
/// @brief returns a numeric value
//////////////////////////////////////////////////////////////////////////////
@ -125,6 +155,22 @@ class VelocyPackHelper {
//////////////////////////////////////////////////////////////////////////////
static int compare(VPackSlice const&, VPackSlice const&, bool);
//////////////////////////////////////////////////////////////////////////////
/// @brief Merges two VelocyPack Slices
//////////////////////////////////////////////////////////////////////////////
static arangodb::velocypack::Builder merge(arangodb::velocypack::Slice const&,
arangodb::velocypack::Slice const&,
bool, bool);
//////////////////////////////////////////////////////////////////////////////
/// @brief Transforms any VelocyPack to a double value. The second parameter
/// indicates if the transformation was successful.
//////////////////////////////////////////////////////////////////////////////
static double toDouble(VPackSlice const&, bool&);
};
}
}

View File

@ -253,31 +253,14 @@ void TRI_InitializeErrorMessages () {
REG_ERROR(SIMPLE_CLIENT_COULD_NOT_READ, "could not read from server");
REG_ERROR(ERROR_MALFORMED_MANIFEST_FILE, "malformed manifest file");
REG_ERROR(ERROR_INVALID_APPLICATION_MANIFEST, "manifest file is invalid");
REG_ERROR(ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING, "missing manifest attribute");
REG_ERROR(ERROR_CANNOT_EXTRACT_APPLICATION_ROOT, "unable to extract app root path");
REG_ERROR(ERROR_INVALID_FOXX_OPTIONS, "invalid foxx options");
REG_ERROR(ERROR_FAILED_TO_EXECUTE_SCRIPT, "failed to execute script");
REG_ERROR(ERROR_SYNTAX_ERROR_IN_SCRIPT, "syntax error in script");
REG_ERROR(ERROR_INVALID_MOUNTPOINT, "mountpoint is invalid");
REG_ERROR(ERROR_NO_FOXX_FOUND, "No foxx found at this location");
REG_ERROR(ERROR_APP_NOT_FOUND, "App not found");
REG_ERROR(ERROR_APP_NEEDS_CONFIGURATION, "App not configured");
REG_ERROR(ERROR_MODULE_NOT_FOUND, "cannot locate module");
REG_ERROR(ERROR_MODULE_SYNTAX_ERROR, "syntax error in module");
REG_ERROR(ERROR_MODULE_BAD_WRAPPER, "failed to wrap module");
REG_ERROR(ERROR_MODULE_FAILURE, "failed to invoke module");
REG_ERROR(ERROR_MODULE_UNKNOWN_FILE_TYPE, "unknown file type");
REG_ERROR(ERROR_MODULE_PATH_MUST_BE_ABSOLUTE, "path must be absolute");
REG_ERROR(ERROR_MODULE_CAN_NOT_ESCAPE, "cannot use '..' to escape top-level-directory");
REG_ERROR(ERROR_MODULE_DRIVE_LETTER, "drive local path is not supported");
REG_ERROR(ERROR_MODULE_BAD_MODULE_ORIGIN, "corrupted module origin");
REG_ERROR(ERROR_MODULE_BAD_PACKAGE_ORIGIN, "corrupted package origin");
REG_ERROR(ERROR_MODULE_DOCUMENT_IS_EMPTY, "no content");
REG_ERROR(ERROR_MODULE_MAIN_NOT_READABLE, "cannot read main file");
REG_ERROR(ERROR_MODULE_MAIN_NOT_JS, "main file is not of type 'js'");
REG_ERROR(RESULT_ELEMENT_EXISTS, "element not inserted into structure, because it already exists");
REG_ERROR(RESULT_ELEMENT_NOT_FOUND, "element not found in structure");
REG_ERROR(ERROR_APP_ALREADY_EXISTS, "newest version of app already installed");
REG_ERROR(ERROR_QUEUE_ALREADY_EXISTS, "named queue already exists");
REG_ERROR(ERROR_DISPATCHER_IS_STOPPING, "dispatcher stopped");
REG_ERROR(ERROR_QUEUE_UNKNOWN, "named queue does not exist");

View File

@ -606,57 +606,22 @@
/// The manifest file is malformed. It is not in a valid JSON format.
/// - 3001: @LIT{manifest file is invalid}
/// The manifest file of this application is invalid.
/// - 3002: @LIT{missing manifest attribute}
/// The manifest file is incomplete. A required attribute is missing.
/// - 3003: @LIT{unable to extract app root path}
/// The root path of the application could not be found.
/// - 3004: @LIT{invalid foxx options}
/// The options used to configure the foxx are invalid.
/// - 3005: @LIT{failed to execute script}
/// The script provided contains errors.
/// - 3006: @LIT{syntax error in script}
/// contains a syntax error:
/// - 3007: @LIT{mountpoint is invalid}
/// mountpoint is invalid
/// - 3008: @LIT{No foxx found at this location}
/// No foxx found at this location
/// - 3009: @LIT{App not found}
/// No app found at this mountpoint
/// - 3010: @LIT{App not configured}
/// The app has to be configured before it can be used
/// - 3100: @LIT{cannot locate module}
/// The module path could not be resolved.
/// - 3101: @LIT{syntax error in module}
/// The module could not be parsed because of a syntax error.
/// - 3102: @LIT{failed to wrap module}
/// The module wrapper could not be generated. This may indicate a problem
/// with some of the names of the module's context variables.
/// - 3103: @LIT{failed to invoke module}
/// Failed to invoke the module in its context.
/// - 3110: @LIT{unknown file type}
/// The module path resolves to a file of an unknown type.
/// - 3111: @LIT{path must be absolute}
/// The module path must be absolute.
/// - 3112: @LIT{cannot use '..' to escape top-level-directory}
/// The relative module path can not escape the module's top-level directory.
/// - 3113: @LIT{drive local path is not supported}
/// The module path contains a Windows drive letter, which is not supported.
/// - 3120: @LIT{corrupted module origin}
/// The module origin is invalid.
/// - 3121: @LIT{corrupted package origin}
/// The package origin is invalid.
/// - 3125: @LIT{no content}
/// The module resolves to a document which is empty or malformed.
/// - 3130: @LIT{cannot read main file}
/// The module's main file is not readable.
/// - 3131: @LIT{main file is not of type 'js'}
/// The module's main file is not a JavaScript file.
/// - 10000: @LIT{element not inserted into structure, because it already exists}
/// Will be returned if the element was not insert because it already exists.
/// - 10001: @LIT{element not found in structure}
/// Will be returned if the element was not found in the structure.
/// - 20000: @LIT{newest version of app already installed}
/// newest version of app already installed
/// - 21000: @LIT{named queue already exists}
/// "Will be returned if a queue with this name already exists."
/// - 21001: @LIT{dispatcher stopped}
@ -3244,26 +3209,6 @@ void TRI_InitializeErrorMessages ();
#define TRI_ERROR_INVALID_APPLICATION_MANIFEST (3001)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3002: ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING
///
/// missing manifest attribute
///
/// The manifest file is incomplete. A required attribute is missing.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MANIFEST_FILE_ATTRIBUTE_MISSING (3002)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3003: ERROR_CANNOT_EXTRACT_APPLICATION_ROOT
///
/// unable to extract app root path
///
/// The root path of the application could not be found.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_CANNOT_EXTRACT_APPLICATION_ROOT (3003)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3004: ERROR_INVALID_FOXX_OPTIONS
///
@ -3274,26 +3219,6 @@ void TRI_InitializeErrorMessages ();
#define TRI_ERROR_INVALID_FOXX_OPTIONS (3004)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3005: ERROR_FAILED_TO_EXECUTE_SCRIPT
///
/// failed to execute script
///
/// The script provided contains errors.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_FAILED_TO_EXECUTE_SCRIPT (3005)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3006: ERROR_SYNTAX_ERROR_IN_SCRIPT
///
/// syntax error in script
///
/// contains a syntax error:
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_SYNTAX_ERROR_IN_SCRIPT (3006)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3007: ERROR_INVALID_MOUNTPOINT
///
@ -3304,16 +3229,6 @@ void TRI_InitializeErrorMessages ();
#define TRI_ERROR_INVALID_MOUNTPOINT (3007)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3008: ERROR_NO_FOXX_FOUND
///
/// No foxx found at this location
///
/// No foxx found at this location
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_NO_FOXX_FOUND (3008)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3009: ERROR_APP_NOT_FOUND
///
@ -3344,27 +3259,6 @@ void TRI_InitializeErrorMessages ();
#define TRI_ERROR_MODULE_NOT_FOUND (3100)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3101: ERROR_MODULE_SYNTAX_ERROR
///
/// syntax error in module
///
/// The module could not be parsed because of a syntax error.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_SYNTAX_ERROR (3101)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3102: ERROR_MODULE_BAD_WRAPPER
///
/// failed to wrap module
///
/// The module wrapper could not be generated. This may indicate a problem with
/// some of the names of the module's context variables.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_BAD_WRAPPER (3102)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3103: ERROR_MODULE_FAILURE
///
@ -3375,96 +3269,6 @@ void TRI_InitializeErrorMessages ();
#define TRI_ERROR_MODULE_FAILURE (3103)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3110: ERROR_MODULE_UNKNOWN_FILE_TYPE
///
/// unknown file type
///
/// The module path resolves to a file of an unknown type.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_UNKNOWN_FILE_TYPE (3110)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3111: ERROR_MODULE_PATH_MUST_BE_ABSOLUTE
///
/// path must be absolute
///
/// The module path must be absolute.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_PATH_MUST_BE_ABSOLUTE (3111)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3112: ERROR_MODULE_CAN_NOT_ESCAPE
///
/// cannot use '..' to escape top-level-directory
///
/// The relative module path can not escape the module's top-level directory.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_CAN_NOT_ESCAPE (3112)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3113: ERROR_MODULE_DRIVE_LETTER
///
/// drive local path is not supported
///
/// The module path contains a Windows drive letter, which is not supported.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_DRIVE_LETTER (3113)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3120: ERROR_MODULE_BAD_MODULE_ORIGIN
///
/// corrupted module origin
///
/// The module origin is invalid.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_BAD_MODULE_ORIGIN (3120)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3121: ERROR_MODULE_BAD_PACKAGE_ORIGIN
///
/// corrupted package origin
///
/// The package origin is invalid.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_BAD_PACKAGE_ORIGIN (3121)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3125: ERROR_MODULE_DOCUMENT_IS_EMPTY
///
/// no content
///
/// The module resolves to a document which is empty or malformed.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_DOCUMENT_IS_EMPTY (3125)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3130: ERROR_MODULE_MAIN_NOT_READABLE
///
/// cannot read main file
///
/// The module's main file is not readable.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_MAIN_NOT_READABLE (3130)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3131: ERROR_MODULE_MAIN_NOT_JS
///
/// main file is not of type 'js'
///
/// The module's main file is not a JavaScript file.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MODULE_MAIN_NOT_JS (3131)
////////////////////////////////////////////////////////////////////////////////
/// @brief 10000: RESULT_ELEMENT_EXISTS
///
@ -3485,16 +3289,6 @@ void TRI_InitializeErrorMessages ();
#define TRI_RESULT_ELEMENT_NOT_FOUND (10001)
////////////////////////////////////////////////////////////////////////////////
/// @brief 20000: ERROR_APP_ALREADY_EXISTS
///
/// newest version of app already installed
///
/// newest version of app already installed
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_APP_ALREADY_EXISTS (20000)
////////////////////////////////////////////////////////////////////////////////
/// @brief 21000: ERROR_QUEUE_ALREADY_EXISTS
///