From 9ea8e3ea0c6cc8a1ffad50deed0e756e54743481 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 1 Feb 2016 09:48:52 +0100 Subject: [PATCH 01/50] Started to write merge of two slices. This is not yet working for null means delete, works for all other merges. --- arangod/Cluster/ClusterMethods.cpp | 16 +++++ arangod/Cluster/ClusterMethods.h | 4 ++ arangod/V8Server/v8-collection.cpp | 107 ++++++++++++++--------------- arangod/VocBase/shaped-json.cpp | 11 +++ arangod/VocBase/shaped-json.h | 9 +++ lib/Basics/VelocyPackHelper.cpp | 13 ++++ lib/Basics/VelocyPackHelper.h | 9 +++ 7 files changed, 114 insertions(+), 55 deletions(-) diff --git a/arangod/Cluster/ClusterMethods.cpp b/arangod/Cluster/ClusterMethods.cpp index c53b10683f..499137d433 100644 --- a/arangod/Cluster/ClusterMethods.cpp +++ b/arangod/Cluster/ClusterMethods.cpp @@ -176,6 +176,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 tmpOld( + arangodb::basics::VelocyPackHelper::velocyPackToJson(oldSlice)); + if (tmpOld == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + std::unique_ptr 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 //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Cluster/ClusterMethods.h b/arangod/Cluster/ClusterMethods.h index 12e64f8ab2..75d28e8060 100644 --- a/arangod/Cluster/ClusterMethods.h +++ b/arangod/Cluster/ClusterMethods.h @@ -76,6 +76,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 //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/V8Server/v8-collection.cpp b/arangod/V8Server/v8-collection.cpp index 4ad635de92..3cb8b5f805 100644 --- a/arangod/V8Server/v8-collection.cpp +++ b/arangod/V8Server/v8-collection.cpp @@ -689,8 +689,9 @@ static void ModifyVocbaseColCoordinator( TRI_V8_THROW_EXCEPTION(error); } - std::unique_ptr 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 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(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( + 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 ret = TRI_ObjectJson(isolate, json.get()); + v8::Handle 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 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( @@ -1340,9 +1337,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(), " is no valid JSON"); } @@ -1351,7 +1356,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); } @@ -1363,27 +1367,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 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(); } @@ -1391,32 +1395,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); } diff --git a/arangod/VocBase/shaped-json.cpp b/arangod/VocBase/shaped-json.cpp index 69075dae94..2dc6ac3c68 100644 --- a/arangod/VocBase/shaped-json.cpp +++ b/arangod/VocBase/shaped-json.cpp @@ -2107,6 +2107,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 TRI_VelocyPackShapedJson( + VocShaper* shaper, TRI_shaped_json_t const* shaped) { + std::unique_ptr 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 diff --git a/arangod/VocBase/shaped-json.h b/arangod/VocBase/shaped-json.h index 4b7c677bfe..d241d22ad7 100644 --- a/arangod/VocBase/shaped-json.h +++ b/arangod/VocBase/shaped-json.h @@ -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 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 diff --git a/lib/Basics/VelocyPackHelper.cpp b/lib/Basics/VelocyPackHelper.cpp index 98166136c2..629d978766 100644 --- a/lib/Basics/VelocyPackHelper.cpp +++ b/lib/Basics/VelocyPackHelper.cpp @@ -430,3 +430,16 @@ int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs, return 0; } } + +static VPackBuilder mergeNonNull(lhs, rhs, mergeObjects) { +}; +VPackBuilder VelocyPackHelper::merge(VPackSlice const& lhs, + VPackSlice const& rhs, + bool nullMeansRemove, bool mergeObjects) { + // TODO if nullMeans remove exclude values of NULL on rhs from both lhs and rhs. Including nested sub values + if (nullMeansRemove) { + return mergeNonNull(lhs, rhs, mergeObjects); + } + VPackBuilder res = VPackCollection::merge(lhs, rhs, mergeObjects); + return res; +} diff --git a/lib/Basics/VelocyPackHelper.h b/lib/Basics/VelocyPackHelper.h index 2f42dbefcd..f7bcefa24a 100644 --- a/lib/Basics/VelocyPackHelper.h +++ b/lib/Basics/VelocyPackHelper.h @@ -125,6 +125,15 @@ 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); }; } } From 93d0508259914e2f3b5bc28c3504107f1e2a0985 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 1 Feb 2016 17:09:54 +0100 Subject: [PATCH 02/50] Created a temporary type for VPack-based AqlValues. Also started implementing new AQL Functions with this new AqlValue. --- arangod/Aql/AqlValue.cpp | 130 ++++++++++++++++++++++++++++++++++---- arangod/Aql/AqlValue.h | 64 ++++++++++++++++--- arangod/Aql/Functions.cpp | 61 ++++++++++++------ arangod/Aql/Functions.h | 6 +- 4 files changed, 221 insertions(+), 40 deletions(-) diff --git a/arangod/Aql/AqlValue.cpp b/arangod/Aql/AqlValue.cpp index 4a23ff3cdf..2f0feb785c 100644 --- a/arangod/Aql/AqlValue.cpp +++ b/arangod/Aql/AqlValue.cpp @@ -723,20 +723,122 @@ 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> AqlValue::toVelocyPack( - arangodb::AqlTransaction* trx, TRI_document_collection_t const* document, - bool copy) const { +//////////////////////////////////////////////////////////////////////////////// +/// @brief Copy Constructor. +//////////////////////////////////////////////////////////////////////////////// + +AqlValue$::AqlValue$(AqlValue$ const& other) { + VPackSlice s = other.slice(); + VPackValueLength length = s.length(); + if (other.type()) { + // Isse external + _data.external = new VPackBuffer(length); + memcpy(_data.external->data(), other._data.external->data(), length); + } else { + memcpy(_data.internal, other._data.internal, length); + } +} + +// 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 + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + /* + TRI_ASSERT(_range != nullptr); + try { + VPackArrayBuilder b(&builder); + size_t const n = _range->size(); + for (size_t i = 0; i < n; ++i) { + builder.add(VPackValue(_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] = 1; + } else { + // We need a large external buffer + // TODO: Replace by SlimBuffer + _data.external = new VPackBuffer(length); + memcpy(_data.external->data(), builder.data(), length); + _data.internal[15] = 0; + } +} + +bool AqlValue$::type() const { + return _data.internal[15] == 0; +} + +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 +847,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 +870,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 +890,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); diff --git a/arangod/Aql/AqlValue.h b/arangod/Aql/AqlValue.h index 641c22be0e..4253b764cb 100644 --- a/arangod/Aql/AqlValue.h +++ b/arangod/Aql/AqlValue.h @@ -284,15 +284,8 @@ struct AqlValue { arangodb::basics::Json toJson(arangodb::AqlTransaction*, TRI_document_collection_t const*, bool) const; - ////////////////////////////////////////////////////////////////////////////// - /// @brief toVelocyPack method - ////////////////////////////////////////////////////////////////////////////// - - std::shared_ptr> 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 +357,61 @@ struct AqlValue { AqlValueType _type; }; +struct AqlValue$ { + ////////////////////////////////////////////////////////////////////////////// + /// @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* external; + } _data; + + public: + AqlValue$(VPackBuilder const& data); + AqlValue$(VPackBuilder const* data); + + 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 + bool 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 diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 6c1964f120..c601c5916e 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -45,6 +45,8 @@ #include #include +#define TMPUSEVPACK = 1 + using namespace arangodb::aql; using Json = arangodb::basics::Json; using CollectionNameResolver = arangodb::CollectionNameResolver; @@ -57,6 +59,21 @@ using VertexId = arangodb::traverser::VertexId; thread_local std::unordered_map* RegexCache = nullptr; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transform old AQLValues to new AqlValues +/// Only temporary function +//////////////////////////////////////////////////////////////////////////////// + +static VPackFunctionParameters transformParameters( + FunctionParameters const& oldParams, arangodb::AqlTransaction* trx) { + VPackFunctionParameters newParams; + for (auto const& it : oldParams) { + newParams.emplace_back(it.first, trx, it.second); + } + return newParams; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clear the regex cache in a thread //////////////////////////////////////////////////////////////////////////////// @@ -160,17 +177,16 @@ static Json ExtractFunctionParameter(arangodb::AqlTransaction* trx, /// Iff the AQLValue is repsonsible for the data //////////////////////////////////////////////////////////////////////////////// -static std::shared_ptr> ExtractFunctionParameterVPack( - arangodb::AqlTransaction* trx, FunctionParameters const& parameters, - size_t position, bool copy) { +static VPackSlice ExtractFunctionParameter( + arangodb::AqlTransaction* trx, VPackFunctionParameters const& parameters, + size_t position) { if (position >= parameters.size()) { // parameter out of range - VPackBuilder b; - b.add(VPackValue(VPackValueType::Null)); - return b.steal(); + VPackSlice tmp; + return tmp; } auto const& parameter = parameters[position]; - return parameter.first.toVelocyPack(trx, parameter.second, copy); + return parameter.slice(); } //////////////////////////////////////////////////////////////////////////////// @@ -840,36 +856,43 @@ void Functions::DestroyThreadContext() { ClearRegexCache(); } /// @brief function IS_NULL //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsNull(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::IsNull(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return IsNullVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isNull())); +#endif } -AqlValue Functions::IsNullVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { - auto const buffer = ExtractFunctionParameterVPack(trx, parameters, 0, false); - VPackSlice s(buffer->data()); - return AqlValue(new Json(s.isNull())); +AqlValue Functions::IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue(new Json(slice.isNull())); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_BOOL //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsBool(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::IsBool(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return IsBoolVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isBoolean())); +#endif } AqlValue Functions::IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { - auto const buffer = ExtractFunctionParameterVPack(trx, parameters, 0, false); - VPackSlice s(buffer->data()); - return AqlValue(new Json(s.isBoolean())); + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue(new Json(slice.isBoolean())); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 980f4f1a62..5f17bd5acf 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -40,6 +40,8 @@ typedef std::function ExecutionCondition; typedef std::vector> FunctionParameters; +typedef std::vector VPackFunctionParameters; + typedef std::function FunctionImplementation; @@ -62,11 +64,11 @@ struct Functions { static AqlValue IsNull(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - FunctionParameters const&); + VPackFunctionParameters const&); static AqlValue IsBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - FunctionParameters const&); + VPackFunctionParameters const&); static AqlValue IsNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue IsString(arangodb::aql::Query*, arangodb::AqlTransaction*, From c782fe59172b25295f884c141187970a115160d5 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 1 Feb 2016 17:10:25 +0100 Subject: [PATCH 03/50] Use VPackCollection::merge to merge to VPackSlices. --- lib/Basics/VelocyPackHelper.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/Basics/VelocyPackHelper.cpp b/lib/Basics/VelocyPackHelper.cpp index 60bb33dbfe..125aa002df 100644 --- a/lib/Basics/VelocyPackHelper.cpp +++ b/lib/Basics/VelocyPackHelper.cpp @@ -431,15 +431,8 @@ int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs, } } -static VPackBuilder mergeNonNull(lhs, rhs, mergeObjects) { -}; VPackBuilder VelocyPackHelper::merge(VPackSlice const& lhs, VPackSlice const& rhs, bool nullMeansRemove, bool mergeObjects) { - // TODO if nullMeans remove exclude values of NULL on rhs from both lhs and rhs. Including nested sub values - if (nullMeansRemove) { - return mergeNonNull(lhs, rhs, mergeObjects); - } - VPackBuilder res = VPackCollection::merge(lhs, rhs, mergeObjects); - return res; + return VPackCollection::merge(lhs, rhs, mergeObjects, nullMeansRemove); } From 964fbdaabd195940678dd343e5acc4971e996609 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 2 Feb 2016 13:28:21 +0100 Subject: [PATCH 04/50] Started moving tests in aql-operators to use AQL instead of directly using the JS-AQL module. Now they also cover Cxx implementation and AQL parser --- js/server/tests/aql/aql-operators.js | 1102 ++++++++++++++------------ 1 file changed, 598 insertions(+), 504 deletions(-) diff --git a/js/server/tests/aql/aql-operators.js b/js/server/tests/aql/aql-operators.js index 9dae488928..0557cabea5 100644 --- a/js/server/tests/aql/aql-operators.js +++ b/js/server/tests/aql/aql-operators.js @@ -30,34 +30,32 @@ var jsunity = require("jsunity"); var aql = require("@arangodb/aql"); +var db = require("internal").db; //////////////////////////////////////////////////////////////////////////////// /// @brief test suite //////////////////////////////////////////////////////////////////////////////// function ahuacatlOperatorsTestSuite () { - return { -//////////////////////////////////////////////////////////////////////////////// -/// @brief set up -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief set up + //////////////////////////////////////////////////////////////////////////////// - setUp : function () { - }, + setUp: function() {}, -//////////////////////////////////////////////////////////////////////////////// -/// @brief tear down -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief tear down + //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { - }, + tearDown: function() {}, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.KEYS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.KEYS function + //////////////////////////////////////////////////////////////////////////////// - testKeys : function () { + testKeys: function() { assertEqual([ ], aql.KEYS([ ], true)); assertEqual([ 0, 1, 2 ], aql.KEYS([ 0, 1, 2 ], true)); assertEqual([ 0, 1, 2 ], aql.KEYS([ 1, 2, 3 ], true)); @@ -88,414 +86,510 @@ function ahuacatlOperatorsTestSuite () { assertEqual([ 'a1', 'a10', 'a20', 'a200', 'a21' ], aql.KEYS({ 'a200' : true, 'a21' : true, 'a20' : true, 'a10' : false, 'a1' : null }, true)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NULL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NULL function + //////////////////////////////////////////////////////////////////////////////// - testIsNullTrue : function () { - assertTrue(aql.AQL_IS_NULL(null)); + testIsNullTrue: function() { assertTrue(aql.AQL_IS_NULL(undefined)); assertTrue(aql.AQL_IS_NULL(NaN)); assertTrue(aql.AQL_IS_NULL(1.3e308 * 1.3e308)); + var values = [ null ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_NULL(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_NULL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NULL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NULL function + //////////////////////////////////////////////////////////////////////////////// - testIsNullFalse : function () { - assertFalse(aql.AQL_IS_NULL(0)); - assertFalse(aql.AQL_IS_NULL(1)); - assertFalse(aql.AQL_IS_NULL(-1)); - assertFalse(aql.AQL_IS_NULL(0.1)); - assertFalse(aql.AQL_IS_NULL(-0.1)); - assertFalse(aql.AQL_IS_NULL(false)); - assertFalse(aql.AQL_IS_NULL(true)); - assertFalse(aql.AQL_IS_NULL('abc')); - assertFalse(aql.AQL_IS_NULL('null')); - assertFalse(aql.AQL_IS_NULL('false')); - assertFalse(aql.AQL_IS_NULL('undefined')); - assertFalse(aql.AQL_IS_NULL('')); - assertFalse(aql.AQL_IS_NULL(' ')); - assertFalse(aql.AQL_IS_NULL([ ])); - assertFalse(aql.AQL_IS_NULL([ 0 ])); - assertFalse(aql.AQL_IS_NULL([ 0, 1 ])); - assertFalse(aql.AQL_IS_NULL([ 1, 2 ])); - assertFalse(aql.AQL_IS_NULL({ })); - assertFalse(aql.AQL_IS_NULL({ 'a' : 0 })); - assertFalse(aql.AQL_IS_NULL({ 'a' : 1 })); - assertFalse(aql.AQL_IS_NULL({ 'a' : 0, 'b' : 1 })); + testIsNullFalse: function() { + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_NULL(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_NULL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testIsBoolTrue : function () { - assertTrue(aql.AQL_IS_BOOL(false)); - assertTrue(aql.AQL_IS_BOOL(true)); + testIsBoolTrue: function() { + var values = [ false, true ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_BOOL(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testIsBoolFalse : function () { + testIsBoolFalse: function() { assertFalse(aql.AQL_IS_BOOL(undefined)); assertFalse(aql.AQL_IS_BOOL(NaN)); assertFalse(aql.AQL_IS_BOOL(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_BOOL(0)); - assertFalse(aql.AQL_IS_BOOL(1)); - assertFalse(aql.AQL_IS_BOOL(-1)); - assertFalse(aql.AQL_IS_BOOL(0.1)); - assertFalse(aql.AQL_IS_BOOL(-0.1)); - assertFalse(aql.AQL_IS_BOOL(null)); - assertFalse(aql.AQL_IS_BOOL('abc')); - assertFalse(aql.AQL_IS_BOOL('null')); - assertFalse(aql.AQL_IS_BOOL('false')); - assertFalse(aql.AQL_IS_BOOL('undefined')); - assertFalse(aql.AQL_IS_BOOL('')); - assertFalse(aql.AQL_IS_BOOL(' ')); - assertFalse(aql.AQL_IS_BOOL([ ])); - assertFalse(aql.AQL_IS_BOOL([ 0 ])); - assertFalse(aql.AQL_IS_BOOL([ 0, 1 ])); - assertFalse(aql.AQL_IS_BOOL([ 1, 2 ])); - assertFalse(aql.AQL_IS_BOOL([ '' ])); - assertFalse(aql.AQL_IS_BOOL([ '0' ])); - assertFalse(aql.AQL_IS_BOOL([ '1' ])); - assertFalse(aql.AQL_IS_BOOL([ true ])); - assertFalse(aql.AQL_IS_BOOL([ false ])); - assertFalse(aql.AQL_IS_BOOL({ })); - assertFalse(aql.AQL_IS_BOOL({ 'a' : 0 })); - assertFalse(aql.AQL_IS_BOOL({ 'a' : 1 })); - assertFalse(aql.AQL_IS_BOOL({ 'a' : 0, 'b' : 1 })); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_BOOL(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NUMBER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NUMBER function + //////////////////////////////////////////////////////////////////////////////// - testIsNumberTrue : function () { - assertTrue(aql.AQL_IS_NUMBER(0)); - assertTrue(aql.AQL_IS_NUMBER(1)); - assertTrue(aql.AQL_IS_NUMBER(-1)); - assertTrue(aql.AQL_IS_NUMBER(0.1)); - assertTrue(aql.AQL_IS_NUMBER(-0.1)); - assertTrue(aql.AQL_IS_NUMBER(12.5356)); - assertTrue(aql.AQL_IS_NUMBER(-235.26436)); - assertTrue(aql.AQL_IS_NUMBER(-23.3e17)); - assertTrue(aql.AQL_IS_NUMBER(563.44576e19)); + testIsNumberTrue: function() { + var values = [0, 1, -1, 0.1, 12.5356, -235.26436, -23.3e17, 563.44576e19]; + + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_NUMBER(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_NUMBER(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_NUMBER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_NUMBER function + //////////////////////////////////////////////////////////////////////////////// - testIsNumberFalse : function () { - assertFalse(aql.AQL_IS_NUMBER(false)); - assertFalse(aql.AQL_IS_NUMBER(true)); + testIsNumberFalse: function() { assertFalse(aql.AQL_IS_NUMBER(undefined)); assertFalse(aql.AQL_IS_NUMBER(NaN)); assertFalse(aql.AQL_IS_NUMBER(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_NUMBER(null)); - assertFalse(aql.AQL_IS_NUMBER('abc')); - assertFalse(aql.AQL_IS_NUMBER('null')); - assertFalse(aql.AQL_IS_NUMBER('false')); - assertFalse(aql.AQL_IS_NUMBER('undefined')); - assertFalse(aql.AQL_IS_NUMBER('')); - assertFalse(aql.AQL_IS_NUMBER(' ')); - assertFalse(aql.AQL_IS_NUMBER([ ])); - assertFalse(aql.AQL_IS_NUMBER([ 0 ])); - assertFalse(aql.AQL_IS_NUMBER([ 0, 1 ])); - assertFalse(aql.AQL_IS_NUMBER([ 1, 2 ])); - assertFalse(aql.AQL_IS_NUMBER([ '' ])); - assertFalse(aql.AQL_IS_NUMBER([ '0' ])); - assertFalse(aql.AQL_IS_NUMBER([ '1' ])); - assertFalse(aql.AQL_IS_NUMBER([ true ])); - assertFalse(aql.AQL_IS_NUMBER([ false ])); - assertFalse(aql.AQL_IS_NUMBER({ })); - assertFalse(aql.AQL_IS_NUMBER({ 'a' : 0 })); - assertFalse(aql.AQL_IS_NUMBER({ 'a' : 1 })); - assertFalse(aql.AQL_IS_NUMBER({ 'a' : 0, 'b' : 1 })); + + var values = [ + false, + true, + null, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_NUMBER(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_NUMBER(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_STRING function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_STRING function + //////////////////////////////////////////////////////////////////////////////// - testIsStringTrue : function () { - assertTrue(aql.AQL_IS_STRING('abc')); - assertTrue(aql.AQL_IS_STRING('null')); - assertTrue(aql.AQL_IS_STRING('false')); - assertTrue(aql.AQL_IS_STRING('undefined')); - assertTrue(aql.AQL_IS_STRING('')); - assertTrue(aql.AQL_IS_STRING(' ')); + testIsStringTrue: function() { + var values = ["'abc'", "'null'", "'false'", "'undefined'", "''", "' '"]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_STRING(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_STRING(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_STRING function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_STRING function + //////////////////////////////////////////////////////////////////////////////// - testIsStringFalse : function () { - assertFalse(aql.AQL_IS_STRING(false)); - assertFalse(aql.AQL_IS_STRING(true)); + testIsStringFalse: function() { assertFalse(aql.AQL_IS_STRING(undefined)); assertFalse(aql.AQL_IS_STRING(NaN)); assertFalse(aql.AQL_IS_STRING(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_STRING(0)); - assertFalse(aql.AQL_IS_STRING(1)); - assertFalse(aql.AQL_IS_STRING(-1)); - assertFalse(aql.AQL_IS_STRING(0.1)); - assertFalse(aql.AQL_IS_STRING(-0.1)); - assertFalse(aql.AQL_IS_STRING(null)); - assertFalse(aql.AQL_IS_STRING([ ])); - assertFalse(aql.AQL_IS_STRING([ 0 ])); - assertFalse(aql.AQL_IS_STRING([ 0, 1 ])); - assertFalse(aql.AQL_IS_STRING([ 1, 2 ])); - assertFalse(aql.AQL_IS_STRING([ '' ])); - assertFalse(aql.AQL_IS_STRING([ '0' ])); - assertFalse(aql.AQL_IS_STRING([ '1' ])); - assertFalse(aql.AQL_IS_STRING([ true ])); - assertFalse(aql.AQL_IS_STRING([ false ])); - assertFalse(aql.AQL_IS_STRING({ })); - assertFalse(aql.AQL_IS_STRING({ 'a' : 0 })); - assertFalse(aql.AQL_IS_STRING({ 'a' : 1 })); - assertFalse(aql.AQL_IS_STRING({ 'a' : 0, 'b' : 1 })); + + var values = [ + false, + true, + 0, + 1, + -1, + 0.1, + -0.1, + null, + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_STRING(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_STRING(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_LIST function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_LIST function + //////////////////////////////////////////////////////////////////////////////// - testIsListTrue : function () { - assertTrue(aql.AQL_IS_LIST([ ])); - assertTrue(aql.AQL_IS_LIST([ 0 ])); - assertTrue(aql.AQL_IS_LIST([ 0, 1 ])); - assertTrue(aql.AQL_IS_LIST([ 1, 2 ])); - assertTrue(aql.AQL_IS_LIST([ '' ])); - assertTrue(aql.AQL_IS_LIST([ '0' ])); - assertTrue(aql.AQL_IS_LIST([ '1' ])); - assertTrue(aql.AQL_IS_LIST([ true ])); - assertTrue(aql.AQL_IS_LIST([ false ])); + testIsListTrue: function() { + var values = [ + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_LIST(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_LIST(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_LIST function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_LIST function + //////////////////////////////////////////////////////////////////////////////// - testIsListFalse : function () { - assertFalse(aql.AQL_IS_LIST('abc')); - assertFalse(aql.AQL_IS_LIST('null')); - assertFalse(aql.AQL_IS_LIST('false')); - assertFalse(aql.AQL_IS_LIST('undefined')); - assertFalse(aql.AQL_IS_LIST('')); - assertFalse(aql.AQL_IS_LIST(' ')); - assertFalse(aql.AQL_IS_LIST(false)); - assertFalse(aql.AQL_IS_LIST(true)); + testIsListFalse: function() { assertFalse(aql.AQL_IS_LIST(undefined)); assertFalse(aql.AQL_IS_LIST(NaN)); assertFalse(aql.AQL_IS_LIST(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_LIST(0)); - assertFalse(aql.AQL_IS_LIST(1)); - assertFalse(aql.AQL_IS_LIST(-1)); - assertFalse(aql.AQL_IS_LIST(0.1)); - assertFalse(aql.AQL_IS_LIST(-0.1)); - assertFalse(aql.AQL_IS_LIST(null)); - assertFalse(aql.AQL_IS_LIST({ })); - assertFalse(aql.AQL_IS_LIST({ 'a' : 0 })); - assertFalse(aql.AQL_IS_LIST({ 'a' : 1 })); - assertFalse(aql.AQL_IS_LIST({ 'a' : 0, 'b' : 1 })); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_LIST(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_LIST(${v}))`).next()); + }); }, + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_ARRAY function + //////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_ARRAY function -//////////////////////////////////////////////////////////////////////////////// - - testIsArrayTrue : function () { - assertTrue(aql.AQL_IS_ARRAY([ ])); - assertTrue(aql.AQL_IS_ARRAY([ 0 ])); - assertTrue(aql.AQL_IS_ARRAY([ 0, 1 ])); - assertTrue(aql.AQL_IS_ARRAY([ 1, 2 ])); - assertTrue(aql.AQL_IS_ARRAY([ '' ])); - assertTrue(aql.AQL_IS_ARRAY([ '0' ])); - assertTrue(aql.AQL_IS_ARRAY([ '1' ])); - assertTrue(aql.AQL_IS_ARRAY([ true ])); - assertTrue(aql.AQL_IS_ARRAY([ false ])); + testIsArrayTrue: function() { + var values = [ + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function (v) { + assertTrue(db._query(`RETURN IS_ARRAY(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_ARRAY(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_ARRAY function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_ARRAY function + //////////////////////////////////////////////////////////////////////////////// - testIsArrayFalse : function () { - assertFalse(aql.AQL_IS_ARRAY('abc')); - assertFalse(aql.AQL_IS_ARRAY('null')); - assertFalse(aql.AQL_IS_ARRAY('false')); - assertFalse(aql.AQL_IS_ARRAY('undefined')); - assertFalse(aql.AQL_IS_ARRAY('')); - assertFalse(aql.AQL_IS_ARRAY(' ')); - assertFalse(aql.AQL_IS_ARRAY(false)); - assertFalse(aql.AQL_IS_ARRAY(true)); + testIsArrayFalse: function() { assertFalse(aql.AQL_IS_ARRAY(undefined)); assertFalse(aql.AQL_IS_ARRAY(NaN)); assertFalse(aql.AQL_IS_ARRAY(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_ARRAY(0)); - assertFalse(aql.AQL_IS_ARRAY(1)); - assertFalse(aql.AQL_IS_ARRAY(-1)); - assertFalse(aql.AQL_IS_ARRAY(0.1)); - assertFalse(aql.AQL_IS_ARRAY(-0.1)); - assertFalse(aql.AQL_IS_ARRAY(null)); - assertFalse(aql.AQL_IS_ARRAY({ })); - assertFalse(aql.AQL_IS_ARRAY({ 'a' : 0 })); - assertFalse(aql.AQL_IS_ARRAY({ 'a' : 1 })); - assertFalse(aql.AQL_IS_ARRAY({ 'a' : 0, 'b' : 1 })); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' :1 }" + ]; + values.forEach(function (v) { + assertFalse(db._query(`RETURN IS_ARRAY(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_ARRAY(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_DOCUMENT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_DOCUMENT function + //////////////////////////////////////////////////////////////////////////////// - testIsDocumentTrue : function () { - assertTrue(aql.AQL_IS_DOCUMENT({ })); - assertTrue(aql.AQL_IS_DOCUMENT({ 'a' : 0 })); - assertTrue(aql.AQL_IS_DOCUMENT({ 'a' : 1 })); - assertTrue(aql.AQL_IS_DOCUMENT({ 'a' : 0, 'b' : 1 })); - assertTrue(aql.AQL_IS_DOCUMENT({ '1' : false, 'b' : false })); - assertTrue(aql.AQL_IS_DOCUMENT({ '0' : false })); + testIsDocumentTrue: function() { + var values = [ + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' : 1 }", + "{ '1' : false, 'b' : false }", + "{ '0' : false }", + ]; + values.forEach(function(v) { + assertTrue(db._query(`RETURN IS_DOCUMENT(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_DOCUMENT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_DOCUMENT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_DOCUMENT function + //////////////////////////////////////////////////////////////////////////////// - testIsDocumentFalse : function () { - assertFalse(aql.AQL_IS_DOCUMENT('abc')); - assertFalse(aql.AQL_IS_DOCUMENT('null')); - assertFalse(aql.AQL_IS_DOCUMENT('false')); - assertFalse(aql.AQL_IS_DOCUMENT('undefined')); - assertFalse(aql.AQL_IS_DOCUMENT('')); - assertFalse(aql.AQL_IS_DOCUMENT(' ')); - assertFalse(aql.AQL_IS_DOCUMENT(false)); - assertFalse(aql.AQL_IS_DOCUMENT(true)); + testIsDocumentFalse: function() { assertFalse(aql.AQL_IS_DOCUMENT(undefined)); assertFalse(aql.AQL_IS_DOCUMENT(NaN)); assertFalse(aql.AQL_IS_DOCUMENT(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_DOCUMENT(0)); - assertFalse(aql.AQL_IS_DOCUMENT(1)); - assertFalse(aql.AQL_IS_DOCUMENT(-1)); - assertFalse(aql.AQL_IS_DOCUMENT(0.1)); - assertFalse(aql.AQL_IS_DOCUMENT(-0.1)); - assertFalse(aql.AQL_IS_DOCUMENT(null)); - assertFalse(aql.AQL_IS_DOCUMENT([ ])); - assertFalse(aql.AQL_IS_DOCUMENT([ 0 ])); - assertFalse(aql.AQL_IS_DOCUMENT([ 0, 1 ])); - assertFalse(aql.AQL_IS_DOCUMENT([ 1, 2 ])); - assertFalse(aql.AQL_IS_DOCUMENT([ '' ])); - assertFalse(aql.AQL_IS_DOCUMENT([ '0' ])); - assertFalse(aql.AQL_IS_DOCUMENT([ '1' ])); - assertFalse(aql.AQL_IS_DOCUMENT([ true ])); - assertFalse(aql.AQL_IS_DOCUMENT([ false ])); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function(v) { + assertFalse(db._query(`RETURN IS_DOCUMENT(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_DOCUMENT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_OBJECT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_OBJECT function + //////////////////////////////////////////////////////////////////////////////// - testIsObjectTrue : function () { - assertTrue(aql.AQL_IS_OBJECT({ })); - assertTrue(aql.AQL_IS_OBJECT({ 'a' : 0 })); - assertTrue(aql.AQL_IS_OBJECT({ 'a' : 1 })); - assertTrue(aql.AQL_IS_OBJECT({ 'a' : 0, 'b' : 1 })); - assertTrue(aql.AQL_IS_OBJECT({ '1' : false, 'b' : false })); - assertTrue(aql.AQL_IS_OBJECT({ '0' : false })); + testIsObjectTrue: function() { + var values = [ + "{ }", + "{ 'a' : 0 }", + "{ 'a' : 1 }", + "{ 'a' : 0, 'b' : 1 }", + "{ '1' : false, 'b' : false }", + "{ '0' : false }", + ]; + values.forEach(function(v) { + assertTrue(db._query(`RETURN IS_OBJECT(${v})`).next()); + assertTrue(db._query(`RETURN NOOPT(IS_OBJECT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.IS_OBJECT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.IS_OBJECT function + //////////////////////////////////////////////////////////////////////////////// - testIsObjectFalse : function () { - assertFalse(aql.AQL_IS_OBJECT('abc')); - assertFalse(aql.AQL_IS_OBJECT('null')); - assertFalse(aql.AQL_IS_OBJECT('false')); - assertFalse(aql.AQL_IS_OBJECT('undefined')); - assertFalse(aql.AQL_IS_OBJECT('')); - assertFalse(aql.AQL_IS_OBJECT(' ')); - assertFalse(aql.AQL_IS_OBJECT(false)); - assertFalse(aql.AQL_IS_OBJECT(true)); + testIsObjecttFalse: function() { assertFalse(aql.AQL_IS_OBJECT(undefined)); assertFalse(aql.AQL_IS_OBJECT(NaN)); assertFalse(aql.AQL_IS_OBJECT(1.3e308 * 1.3e308)); - assertFalse(aql.AQL_IS_OBJECT(0)); - assertFalse(aql.AQL_IS_OBJECT(1)); - assertFalse(aql.AQL_IS_OBJECT(-1)); - assertFalse(aql.AQL_IS_OBJECT(0.1)); - assertFalse(aql.AQL_IS_OBJECT(-0.1)); - assertFalse(aql.AQL_IS_OBJECT(null)); - assertFalse(aql.AQL_IS_OBJECT([ ])); - assertFalse(aql.AQL_IS_OBJECT([ 0 ])); - assertFalse(aql.AQL_IS_OBJECT([ 0, 1 ])); - assertFalse(aql.AQL_IS_OBJECT([ 1, 2 ])); - assertFalse(aql.AQL_IS_OBJECT([ '' ])); - assertFalse(aql.AQL_IS_OBJECT([ '0' ])); - assertFalse(aql.AQL_IS_OBJECT([ '1' ])); - assertFalse(aql.AQL_IS_OBJECT([ true ])); - assertFalse(aql.AQL_IS_OBJECT([ false ])); + + var values = [ + 0, + 1, + -1, + 0.1, + -0.1, + null, + false, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '""', + '" "', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ '' ]", + "[ '0' ]", + "[ '1' ]", + "[ true ]", + "[ false ]", + ]; + values.forEach(function(v) { + assertFalse(db._query(`RETURN IS_OBJECT(${v})`).next()); + assertFalse(db._query(`RETURN NOOPT(IS_OBJECT(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testCastBoolTrue : function () { - assertEqual(true, aql.AQL_TO_BOOL(true)); - assertEqual(true, aql.AQL_TO_BOOL(1)); - assertEqual(true, aql.AQL_TO_BOOL(2)); - assertEqual(true, aql.AQL_TO_BOOL(-1)); - assertEqual(true, aql.AQL_TO_BOOL(100)); - assertEqual(true, aql.AQL_TO_BOOL(100.01)); - assertEqual(true, aql.AQL_TO_BOOL(0.001)); - assertEqual(true, aql.AQL_TO_BOOL(-0.001)); - assertEqual(true, aql.AQL_TO_BOOL(' ')); - assertEqual(true, aql.AQL_TO_BOOL(' ')); - assertEqual(true, aql.AQL_TO_BOOL('1')); - assertEqual(true, aql.AQL_TO_BOOL('1 ')); - assertEqual(true, aql.AQL_TO_BOOL('0')); - assertEqual(true, aql.AQL_TO_BOOL('-1')); - assertEqual(true, aql.AQL_TO_BOOL([ 0 ])); - assertEqual(true, aql.AQL_TO_BOOL([ 0, 1 ])); - assertEqual(true, aql.AQL_TO_BOOL([ 1, 2 ])); - assertEqual(true, aql.AQL_TO_BOOL([ -1, 0 ])); - assertEqual(true, aql.AQL_TO_BOOL([ '' ])); - assertEqual(true, aql.AQL_TO_BOOL([ false ])); - assertEqual(true, aql.AQL_TO_BOOL([ true ])); - assertEqual(true, aql.AQL_TO_BOOL({ 'a' : true })); - assertEqual(true, aql.AQL_TO_BOOL({ 'a' : false })); - assertEqual(true, aql.AQL_TO_BOOL({ 'a' : false, 'b' : 0 })); - assertEqual(true, aql.AQL_TO_BOOL({ '0' : false })); - assertEqual(true, aql.AQL_TO_BOOL([ ])); - assertEqual(true, aql.AQL_TO_BOOL({ })); + testCastBoolTrue: function() { + var values = [ + 1, + 2, + -1, + 100, + 100.01, + 0.001, + -0.001, + true, + '"abc"', + '"null"', + '"false"', + '"undefined"', + '" "', + '" "', + '"1"', + '"1 "', + '"0"', + '"-1"', + "[ ]", + "[ 0 ]", + "[ 0, 1 ]", + "[ 1, 2 ]", + "[ -1, 0 ]", + "[ '' ]", + "[ true ]", + "[ false ]", + "{ }", + "{ 'a' : true }", + "{ 'a' : false }", + "{ 'a' : false, 'b' : 0 }", + "{ '0' : false }" + ]; + values.forEach(function(v) { + assertEqual(true, db._query(`RETURN TO_BOOL(${v})`).next()); + assertEqual(true, db._query(`RETURN NOOPT(TO_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_BOOL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_BOOL function + //////////////////////////////////////////////////////////////////////////////// - testCastBoolFalse : function () { - assertEqual(false, aql.AQL_TO_BOOL(0)); + testCastBoolFalse: function() { assertEqual(false, aql.AQL_TO_BOOL(NaN)); - assertEqual(false, aql.AQL_TO_BOOL('')); assertEqual(false, aql.AQL_TO_BOOL(undefined)); - assertEqual(false, aql.AQL_TO_BOOL(null)); - assertEqual(false, aql.AQL_TO_BOOL(false)); + + var values = [0, "''", null, false]; + values.forEach(function(v) { + assertEqual(false, db._query(`RETURN TO_BOOL(${v})`).next()); + assertEqual(false, db._query(`RETURN NOOPT(TO_BOOL(${v}))`).next()); + }); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_NUMBER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_NUMBER function + //////////////////////////////////////////////////////////////////////////////// - testCastNumber : function () { + testCastNumber: function() { assertEqual(null, aql.AQL_TO_NUMBER(undefined)); assertEqual(0, aql.AQL_TO_NUMBER(null)); assertEqual(0, aql.AQL_TO_NUMBER(false)); @@ -548,11 +642,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : [ ], 'b' : [ ] })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TO_STRING function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TO_STRING function + //////////////////////////////////////////////////////////////////////////////// - testCastString : function () { + testCastString: function() { assertEqual('null', aql.AQL_TO_STRING(undefined)); assertEqual('null', aql.AQL_TO_STRING(null)); assertEqual('false', aql.AQL_TO_STRING(false)); @@ -588,11 +682,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : [ ], 'b' : [ ] })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_AND function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_AND function + //////////////////////////////////////////////////////////////////////////////// - testLogicalAndUndefined : function () { + testLogicalAndUndefined: function() { var LOGICAL_AND = function (a, b) { return aql.LOGICAL_AND(function () { return a; }, function () { return b; }); }; @@ -727,22 +821,22 @@ function ahuacatlOperatorsTestSuite () { assertEqual(NaN, LOGICAL_AND('0', NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_AND function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_AND function + //////////////////////////////////////////////////////////////////////////////// - testLogicalAndBool : function () { + testLogicalAndBool: function() { assertTrue(aql.LOGICAL_AND(function () { return true; }, function () { return true; })); assertFalse(aql.LOGICAL_AND(function () { return true; }, function () { return false; })); assertFalse(aql.LOGICAL_AND(function () { return false; }, function () { return true; })); assertFalse(aql.LOGICAL_AND(function () { return false; }, function () { return false; })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_OR function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_OR function + //////////////////////////////////////////////////////////////////////////////// - testLogicalOrUndefined : function () { + testLogicalOrUndefined: function() { var LOGICAL_OR = function (a, b) { return aql.LOGICAL_OR(function () { return a; }, function () { return b; }); }; @@ -877,22 +971,22 @@ function ahuacatlOperatorsTestSuite () { assertEqual('0', LOGICAL_OR('0', NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_OR function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_OR function + //////////////////////////////////////////////////////////////////////////////// - testLogicalOrBool : function () { + testLogicalOrBool: function() { assertTrue(aql.LOGICAL_OR(function () { return true; }, function () { return true; })); assertTrue(aql.LOGICAL_OR(function () { return true; }, function () { return false; })); assertTrue(aql.LOGICAL_OR(function () { return false; }, function () { return true; })); assertFalse(aql.LOGICAL_OR(function () { return false; }, function () { return false; })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_NOT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_NOT function + //////////////////////////////////////////////////////////////////////////////// - testLogicalNotUndefined : function () { + testLogicalNotUndefined: function() { assertEqual(true, aql.LOGICAL_NOT(undefined)); assertEqual(true, aql.LOGICAL_NOT(null)); assertEqual(true, aql.LOGICAL_NOT(false)); @@ -914,11 +1008,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(true, aql.LOGICAL_NOT(NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.LOGICAL_NOT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.LOGICAL_NOT function + //////////////////////////////////////////////////////////////////////////////// - testLogicalNotBool : function () { + testLogicalNotBool: function() { assertTrue(aql.LOGICAL_NOT(false)); assertFalse(aql.LOGICAL_NOT(true)); @@ -926,11 +1020,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.LOGICAL_NOT(aql.LOGICAL_NOT(false))); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_EQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_EQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalEqualTrue : function () { + testRelationalEqualTrue: function() { assertTrue(aql.RELATIONAL_EQUAL(undefined, undefined)); assertTrue(aql.RELATIONAL_EQUAL(undefined, null)); assertTrue(aql.RELATIONAL_EQUAL(null, undefined)); @@ -985,11 +1079,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_EQUAL({ 'f' : { 'c' : { 'd' : [ 0, 1 ], 'a' : [ 1, 9 ] }, 'a' : false }, 'a' : true }, { 'a' : true, 'f' : { 'a' : false, 'c' : { 'a' : [ 1, 9 ], 'd' : [ 0, 1 ] } } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_EQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_EQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalEqualFalse : function () { + testRelationalEqualFalse: function() { assertFalse(aql.RELATIONAL_EQUAL(undefined, true)); assertFalse(aql.RELATIONAL_EQUAL(undefined, false)); assertFalse(aql.RELATIONAL_EQUAL(undefined, 0.0)); @@ -1128,11 +1222,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_EQUAL({ 'a' : true, 'b' : { 'a' : false, 'b' : true } }, { 'a' : true, 'b' : { 'a' : true, 'b': true } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_UNEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_UNEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalUnequalTrue : function () { + testRelationalUnequalTrue: function() { assertTrue(aql.RELATIONAL_UNEQUAL(undefined, true)); assertTrue(aql.RELATIONAL_UNEQUAL(undefined, false)); assertTrue(aql.RELATIONAL_UNEQUAL(undefined, 0.0)); @@ -1279,11 +1373,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_UNEQUAL({ 'a' : true, 'b' : { 'a' : false, 'b' : true } }, { 'a' : true, 'b' : { 'a' : true, 'b': true } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_UNEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_UNEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalUnequalFalse : function () { + testRelationalUnequalFalse: function() { assertFalse(aql.RELATIONAL_UNEQUAL(1, 1)); assertFalse(aql.RELATIONAL_UNEQUAL(0, 0)); assertFalse(aql.RELATIONAL_UNEQUAL(-1, -1)); @@ -1336,11 +1430,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_UNEQUAL({ 'f' : { 'c' : { 'd' : [ 0, 1 ], 'a' : [ 1, 9 ] }, 'a' : false }, 'a' : true }, { 'a' : true, 'f' : { 'a' : false, 'c' : { 'a' : [ 1, 9 ], 'd' : [ 0, 1 ] } } })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESS function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessTrue : function () { + testRelationalLessTrue: function() { assertTrue(aql.RELATIONAL_LESS(NaN, false)); assertTrue(aql.RELATIONAL_LESS(NaN, true)); assertTrue(aql.RELATIONAL_LESS(NaN, '')); @@ -1564,11 +1658,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_LESS({ 'a' : [ 10 ], 'b' : true }, { 'a' : [ 10, 1 ] })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESS function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessFalse : function () { + testRelationalLessFalse: function() { assertFalse(aql.RELATIONAL_LESS(undefined, undefined)); assertFalse(aql.RELATIONAL_LESS(undefined, null)); assertFalse(aql.RELATIONAL_LESS(undefined, NaN)); @@ -1805,12 +1899,12 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_LESS([ 5, 6, { } ], [ 5, 6, true ])); assertFalse(aql.RELATIONAL_LESS([ 5, 6, { } ], [ 5, 6, 9, 9 ])); }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATER function -//////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterTrue : function () { + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATER function + //////////////////////////////////////////////////////////////////////////////// + + testRelationalGreaterTrue: function() { assertTrue(aql.RELATIONAL_GREATER(true, undefined)); assertTrue(aql.RELATIONAL_GREATER(false, undefined)); assertTrue(aql.RELATIONAL_GREATER(0.0, undefined)); @@ -2001,11 +2095,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_GREATER({ 'a' : [ 10, 1 ] }, { 'a' : [ 10 ], 'b' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATER function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATER function + //////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterFalse : function () { + testRelationalGreaterFalse: function() { assertFalse(aql.RELATIONAL_GREATER(undefined, undefined)); assertFalse(aql.RELATIONAL_GREATER(undefined, null)); assertFalse(aql.RELATIONAL_GREATER(null, undefined)); @@ -2217,11 +2311,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_GREATER({ 'a' : 1, 'b' : 2, 'c' : null }, { 'a' : 1, 'b' : 2 })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESSEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESSEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessEqualTrue : function () { + testRelationalLessEqualTrue: function() { assertTrue(aql.RELATIONAL_LESSEQUAL(undefined, undefined)); assertTrue(aql.RELATIONAL_LESSEQUAL(undefined, null)); assertTrue(aql.RELATIONAL_LESSEQUAL(null, undefined)); @@ -2473,11 +2567,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_LESSEQUAL({ 'a' : true, 'b' : { 'c' : 1, 'f' : 2 }, 'x' : 9 }, { 'x' : 9, 'b' : { 'f' : 2, 'c' : 1 }, 'a' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_LESSEQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_LESSEQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalLessEqualFalse : function () { + testRelationalLessEqualFalse: function() { assertFalse(aql.RELATIONAL_LESSEQUAL(true, undefined)); assertFalse(aql.RELATIONAL_LESSEQUAL(false, undefined)); assertFalse(aql.RELATIONAL_LESSEQUAL(0.0, undefined)); @@ -2658,11 +2752,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_LESSEQUAL([ null, false ], [ null, null ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATEREQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATEREQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterEqualTrue : function () { + testRelationalGreaterEqualTrue: function() { assertTrue(aql.RELATIONAL_GREATEREQUAL(undefined, undefined)); assertTrue(aql.RELATIONAL_GREATEREQUAL(undefined, null)); assertTrue(aql.RELATIONAL_GREATEREQUAL(null, undefined)); @@ -2930,11 +3024,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_GREATEREQUAL({ 'a' : true, 'b' : { 'c' : 1, 'f' : 2 }, 'x' : 9 }, { 'x' : 9, 'b' : { 'f' : 2, 'c' : 1 }, 'a' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_GREATEREQUAL function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_GREATEREQUAL function + //////////////////////////////////////////////////////////////////////////////// - testRelationalGreaterEqualFalse : function () { + testRelationalGreaterEqualFalse: function() { assertFalse(aql.RELATIONAL_GREATEREQUAL(undefined, true)); assertFalse(aql.RELATIONAL_GREATEREQUAL(undefined, false)); assertFalse(aql.RELATIONAL_GREATEREQUAL(undefined, 0.0)); @@ -3115,11 +3209,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_GREATEREQUAL([ null, null ], [ null, false ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_IN function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_IN function + //////////////////////////////////////////////////////////////////////////////// - testRelationalInUndefined : function () { + testRelationalInUndefined: function() { assertFalse(aql.RELATIONAL_IN(undefined, undefined)); assertFalse(aql.RELATIONAL_IN(undefined, null)); assertFalse(aql.RELATIONAL_IN(undefined, true)); @@ -3276,11 +3370,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_IN({ }, { 'A' : true })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_IN function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_IN function + //////////////////////////////////////////////////////////////////////////////// - testRelationalInTrue : function () { + testRelationalInTrue: function() { assertTrue(aql.RELATIONAL_IN(null, [ null ])); assertTrue(aql.RELATIONAL_IN(null, [ null, false ])); assertTrue(aql.RELATIONAL_IN(null, [ false, null ])); @@ -3317,11 +3411,11 @@ function ahuacatlOperatorsTestSuite () { assertTrue(aql.RELATIONAL_IN({ 'a' : { 'b' : null, 'c': 1 } }, [ 'a', 'b', { 'a' : { 'c' : 1, 'b' : null } } ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.RELATIONAL_IN function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.RELATIONAL_IN function + //////////////////////////////////////////////////////////////////////////////// - testRelationalInFalse : function () { + testRelationalInFalse: function() { assertFalse(aql.RELATIONAL_IN(undefined, [ ])); assertFalse(aql.RELATIONAL_IN(undefined, [ 0 ])); assertFalse(aql.RELATIONAL_IN(undefined, [ 0, 1 ])); @@ -3380,11 +3474,11 @@ function ahuacatlOperatorsTestSuite () { assertFalse(aql.RELATIONAL_IN({ 'a' : true }, [ 1, 2, { 'a' : { 'a' : true } } ])); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testUnaryPlusUndefined : function () { + testUnaryPlusUndefined: function() { assertEqual(null, aql.UNARY_PLUS(undefined)); assertEqual(0, aql.UNARY_PLUS(null)); assertEqual(null, aql.UNARY_PLUS(NaN)); @@ -3405,11 +3499,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.UNARY_PLUS({ 'a' : 1 })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testUnaryPlusValue : function () { + testUnaryPlusValue: function() { assertEqual(0, aql.UNARY_PLUS(0)); assertEqual(1, aql.UNARY_PLUS(1)); assertEqual(-1, aql.UNARY_PLUS(-1)); @@ -3420,11 +3514,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-1054.342, aql.UNARY_PLUS(-1054.342)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_MINUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_MINUS function + //////////////////////////////////////////////////////////////////////////////// - testUnaryMinusUndefined : function () { + testUnaryMinusUndefined: function() { assertEqual(null, aql.UNARY_MINUS(undefined)); assertEqual(0, aql.UNARY_MINUS(null)); assertEqual(0, aql.UNARY_MINUS(false)); @@ -3447,11 +3541,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.UNARY_MINUS(NaN)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.UNARY_MINUS function -//////////////////////////////////////////////////////////////////////////////// - - testUnaryMinusValue : function () { + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.UNARY_MINUS function + //////////////////////////////////////////////////////////////////////////////// + + testUnaryMinusValue: function() { assertEqual(0, aql.UNARY_MINUS(0)); assertEqual(1, aql.UNARY_MINUS(-1)); assertEqual(-1, aql.UNARY_MINUS(1)); @@ -3463,11 +3557,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-1054.342, aql.UNARY_MINUS(1054.342)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticPlusUndefined : function () { + testArithmeticPlusUndefined: function() { assertEqual(null, aql.ARITHMETIC_PLUS(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_PLUS(undefined, null)); assertEqual(null, aql.ARITHMETIC_PLUS(undefined, false)); @@ -3534,11 +3628,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_PLUS(1.3e308 * 10, 1.3e308 * 10)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_PLUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_PLUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticPlusValue : function () { + testArithmeticPlusValue: function() { assertEqual(0, aql.ARITHMETIC_PLUS(0, 0)); assertEqual(0, aql.ARITHMETIC_PLUS(1, -1)); assertEqual(0, aql.ARITHMETIC_PLUS(-1, 1)); @@ -3555,11 +3649,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(2.6e307, aql.ARITHMETIC_PLUS(1.3e307, 1.3e307)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MINUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MINUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticMinusUndefined : function () { + testArithmeticMinusUndefined: function() { assertEqual(null, aql.ARITHMETIC_MINUS(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_MINUS(undefined, null)); assertEqual(null, aql.ARITHMETIC_MINUS(undefined, false)); @@ -3623,11 +3717,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_MINUS(-1.3e308 * 10, 1.3e308 * 10)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MINUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MINUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticMinusValue : function () { + testArithmeticMinusValue: function() { assertEqual(0, aql.ARITHMETIC_MINUS(0, 0)); assertEqual(-1, aql.ARITHMETIC_MINUS(0, 1)); assertEqual(0, aql.ARITHMETIC_MINUS(-1, -1)); @@ -3648,11 +3742,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-2.6e307, aql.ARITHMETIC_MINUS(-1.3e307, 1.3e307)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_TIMES function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_TIMES function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticTimesUndefined : function () { + testArithmeticTimesUndefined: function() { assertEqual(null, aql.ARITHMETIC_TIMES(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_TIMES(undefined, null)); assertEqual(null, aql.ARITHMETIC_TIMES(undefined, false)); @@ -3721,11 +3815,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(0, aql.ARITHMETIC_TIMES('0', '0')); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_TIMES function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_TIMES function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticTimesValue : function () { + testArithmeticTimesValue: function() { assertEqual(0, aql.ARITHMETIC_TIMES(0, 0)); assertEqual(0, aql.ARITHMETIC_TIMES(1, 0)); assertEqual(0, aql.ARITHMETIC_TIMES(0, 1)); @@ -3750,11 +3844,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(1000000, aql.ARITHMETIC_TIMES(1000, 1000)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_DIVIDE function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_DIVIDE function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticDivideUndefined : function () { + testArithmeticDivideUndefined: function() { assertEqual(null, aql.ARITHMETIC_DIVIDE(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_DIVIDE(undefined, null)); assertEqual(null, aql.ARITHMETIC_DIVIDE(undefined, false)); @@ -3825,11 +3919,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_DIVIDE('0', '0')); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_DIVIDE function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_DIVIDE function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticDivideValue : function () { + testArithmeticDivideValue: function() { assertEqual(0, aql.ARITHMETIC_DIVIDE(0, 1)); assertEqual(0, aql.ARITHMETIC_DIVIDE(0, 2)); assertEqual(0, aql.ARITHMETIC_DIVIDE(0, 10)); @@ -3869,11 +3963,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(2, aql.ARITHMETIC_DIVIDE(0.22, 0.11)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MODULUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MODULUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticModulusUndefined : function () { + testArithmeticModulusUndefined: function() { assertEqual(null, aql.ARITHMETIC_MODULUS(undefined, undefined)); assertEqual(null, aql.ARITHMETIC_MODULUS(undefined, null)); assertEqual(null, aql.ARITHMETIC_MODULUS(undefined, false)); @@ -3942,11 +4036,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(null, aql.ARITHMETIC_MODULUS(0, 0)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.ARITHMETIC_MODULUS function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.ARITHMETIC_MODULUS function + //////////////////////////////////////////////////////////////////////////////// - testArithmeticModulusValue : function () { + testArithmeticModulusValue: function() { assertEqual(0, aql.ARITHMETIC_MODULUS(0, 1)); assertEqual(0, aql.ARITHMETIC_MODULUS(1, 1)); assertEqual(1, aql.ARITHMETIC_MODULUS(1, 2)); @@ -3996,11 +4090,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual(-1, aql.ARITHMETIC_MODULUS(-10, 3)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.CONCAT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.CONCAT function + //////////////////////////////////////////////////////////////////////////////// - testStringConcatUndefined : function () { + testStringConcatUndefined: function() { assertEqual("false", aql.AQL_CONCAT(undefined, false)); assertEqual("true", aql.AQL_CONCAT(undefined, true)); assertEqual("0", aql.AQL_CONCAT(undefined, 0)); @@ -4064,11 +4158,11 @@ function ahuacatlOperatorsTestSuite () { assertEqual("a[object Object]", aql.AQL_CONCAT('a', { })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.CONCAT function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.CONCAT function + //////////////////////////////////////////////////////////////////////////////// - testStringConcatValue : function () { + testStringConcatValue: function() { assertEqual('', aql.AQL_CONCAT()); assertEqual('', aql.AQL_CONCAT('')); assertEqual('a', aql.AQL_CONCAT('a')); @@ -4110,21 +4204,21 @@ function ahuacatlOperatorsTestSuite () { assertEqual('fux', aql.AQL_CONCAT(null, 'f', null, 'u', null, 'x', null)); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aql.TERNARY_OPERATOR function -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test aql.TERNARY_OPERATOR function + //////////////////////////////////////////////////////////////////////////////// - testTernaryOperator : function () { + testTernaryOperator: function() { assertEqual(2, aql.TERNARY_OPERATOR(true, function () { return 2; }, function () { return -1; })); assertEqual(-1, aql.TERNARY_OPERATOR(false, function () { return 1; }, function () { return -1; })); assertEqual(2, aql.TERNARY_OPERATOR(0, function () { return 1; }, function () { return 2; })); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test ranges -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// + /// @brief test ranges + //////////////////////////////////////////////////////////////////////////////// - testRanges : function () { + testRanges: function() { assertEqual([ [ 1, 2, 3 ] ], AQL_EXECUTE("RETURN 1..3").json); assertEqual([ [ 0, 1, 2, 3 ] ], AQL_EXECUTE("RETURN null..3").json); assertEqual([ [ 1, 2, 3, 4, 5, 6, 7 ] ], AQL_EXECUTE("RETURN 1..3 + 4").json); From f4eae755d627d019fe9570e54b1c71566f53ec66 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 2 Feb 2016 13:52:10 +0100 Subject: [PATCH 05/50] Moved more tests in aql-operators. --- js/server/tests/aql/aql-operators.js | 176 +++++++++++++++------------ 1 file changed, 97 insertions(+), 79 deletions(-) diff --git a/js/server/tests/aql/aql-operators.js b/js/server/tests/aql/aql-operators.js index 0557cabea5..57e14ad678 100644 --- a/js/server/tests/aql/aql-operators.js +++ b/js/server/tests/aql/aql-operators.js @@ -591,55 +591,65 @@ function ahuacatlOperatorsTestSuite () { testCastNumber: function() { assertEqual(null, aql.AQL_TO_NUMBER(undefined)); - assertEqual(0, aql.AQL_TO_NUMBER(null)); - assertEqual(0, aql.AQL_TO_NUMBER(false)); - assertEqual(1, aql.AQL_TO_NUMBER(true)); - assertEqual(1, aql.AQL_TO_NUMBER(1)); - assertEqual(2, aql.AQL_TO_NUMBER(2)); - assertEqual(-1, aql.AQL_TO_NUMBER(-1)); - assertEqual(0, aql.AQL_TO_NUMBER(0)); assertEqual(null, aql.AQL_TO_NUMBER(NaN)); - assertEqual(0, aql.AQL_TO_NUMBER('')); - assertEqual(0, aql.AQL_TO_NUMBER(' ')); - assertEqual(0, aql.AQL_TO_NUMBER(' ')); - assertEqual(1, aql.AQL_TO_NUMBER('1')); - assertEqual(1, aql.AQL_TO_NUMBER('1 ')); - assertEqual(0, aql.AQL_TO_NUMBER('0')); - assertEqual(-1, aql.AQL_TO_NUMBER('-1')); - assertEqual(-1, aql.AQL_TO_NUMBER('-1 ')); - assertEqual(-1, aql.AQL_TO_NUMBER(' -1 ')); - assertEqual(null, aql.AQL_TO_NUMBER(' -1a')); - assertEqual(null, aql.AQL_TO_NUMBER(' 1a')); - assertEqual(null, aql.AQL_TO_NUMBER(' 12335.3 a')); - assertEqual(null, aql.AQL_TO_NUMBER('a1bc')); - assertEqual(null, aql.AQL_TO_NUMBER('aaaa1')); - assertEqual(null, aql.AQL_TO_NUMBER('-a1')); - assertEqual(-1.255, aql.AQL_TO_NUMBER('-1.255')); - assertEqual(-1.23456, aql.AQL_TO_NUMBER('-1.23456')); - assertEqual(-1.23456, aql.AQL_TO_NUMBER('-1.23456 ')); - assertEqual(1.23456, aql.AQL_TO_NUMBER(' 1.23456 ')); - assertEqual(null, aql.AQL_TO_NUMBER(' 1.23456a')); - assertEqual(null, aql.AQL_TO_NUMBER('--1')); - assertEqual(1, aql.AQL_TO_NUMBER('+1')); - assertEqual(12.42e32, aql.AQL_TO_NUMBER('12.42e32')); - assertEqual(0, aql.AQL_TO_NUMBER([ ])); - assertEqual(0, aql.AQL_TO_NUMBER([ 0 ])); - assertEqual(-17, aql.AQL_TO_NUMBER([ -17 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 0, 1 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 1, 2 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ -1, 0 ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 0, 1, [ 1, 2 ], [ [ 9, 4 ] ] ])); - assertEqual(null, aql.AQL_TO_NUMBER([ { } ])); - assertEqual(null, aql.AQL_TO_NUMBER([ 0, 1, { } ])); - assertEqual(null, aql.AQL_TO_NUMBER([ { }, { } ])); - assertEqual(0, aql.AQL_TO_NUMBER([ '' ])); - assertEqual(0, aql.AQL_TO_NUMBER([ false ])); - assertEqual(1, aql.AQL_TO_NUMBER([ true ])); - assertEqual(null, aql.AQL_TO_NUMBER({ })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : true })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : true, 'b' : 0 })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : { }, 'b' : { } })); - assertEqual(null, aql.AQL_TO_NUMBER({ 'a' : [ ], 'b' : [ ] })); + + var values = [ + {ex: 0, val: null}, + {ex: 0, val: false}, + {ex: 1, val: true}, + {ex: 1, val: 1}, + {ex: 2, val: 2}, + {ex: -1, val: -1}, + {ex: 0, val: 0}, + {ex: 0, val: "''"}, + {ex: 0, val: "' '"}, + {ex: 0, val: "' '"}, + {ex: 1, val: "'1'"}, + {ex: 1, val: "'1 '"}, + {ex: 1, val: "' 1 '"}, + {ex: 0, val: "'0'"}, + {ex: -1, val: "'-1'"}, + {ex: -1, val: "'-1 '"}, + {ex: -1, val: "' -1 '"}, + {ex: null, val: "' -1a '"}, + {ex: null, val: "' 1a '"}, + {ex: null, val: "' 12335.3 a '"}, + {ex: null, val: "'a1bc'"}, + {ex: null, val: "'aaa1'"}, + {ex: null, val: "'-a1'"}, + {ex: -1.255, val: "'-1.255'"}, + {ex: -1.23456, val: "'-1.23456'"}, + {ex: -1.23456, val: "'-1.23456 '"}, + {ex: 1.23456, val: "' 1.23456 '"}, + {ex: null, val: "' 1.23456a'"}, + {ex: null, val: "'--1'"}, + {ex: 1, val: "'+1'"}, + {ex: 12.42e32, val: "'12.42e32'"}, + {ex: 0, val: "[]"}, + {ex: 0, val: "[ 0 ]"}, + {ex: -17, val: "[ -17 ]"}, + {ex: null, val: "[ 0, 1 ]"}, + {ex: null, val: "[ 1, 2 ]"}, + {ex: null, val: "[ -1, 0 ]"}, + {ex: null, val: "[ 0, 1, [ 1, 2 ], [ [ 9, 4 ] ] ]"}, + {ex: null, val: "[ { } ]"}, + {ex: null, val: "[ 0, 1, { } ]"}, + {ex: null, val: "[ { }, { } ]"}, + {ex: 0, val: "[ '' ]"}, + {ex: 0, val: "[ false ]"}, + {ex: 1, val: "[ true ]"}, + {ex: null, val: "{ }"}, + {ex: null, val: "{ 'a' : true }"}, + {ex: null, val: "{ 'a' : true, 'b' : 0 }"}, + {ex: null, val: "{ 'a' : { }, 'b' : { } }"}, + {ex: null, val: "{ 'a' : [ ], 'b' : [ ] }"} + ] + values.forEach(function(v) { + var q = `RETURN TO_BOOL(${v.val})`; + assertEqual(v.ex, db._query(q).next(), q); + var q = `RETURN NOOPT(TO_BOOL(${v.val}))`; + assertEqual(v.ex, db._query(q).next(), q); + }); }, //////////////////////////////////////////////////////////////////////////////// @@ -648,38 +658,46 @@ function ahuacatlOperatorsTestSuite () { testCastString: function() { assertEqual('null', aql.AQL_TO_STRING(undefined)); - assertEqual('null', aql.AQL_TO_STRING(null)); - assertEqual('false', aql.AQL_TO_STRING(false)); - assertEqual('true', aql.AQL_TO_STRING(true)); - assertEqual('1', aql.AQL_TO_STRING(1)); - assertEqual('2', aql.AQL_TO_STRING(2)); - assertEqual('-1', aql.AQL_TO_STRING(-1)); - assertEqual('0', aql.AQL_TO_STRING(0)); assertEqual('null', aql.AQL_TO_STRING(NaN)); - assertEqual('', aql.AQL_TO_STRING('')); - assertEqual(' ', aql.AQL_TO_STRING(' ')); - assertEqual(' ', aql.AQL_TO_STRING(' ')); - assertEqual('1', aql.AQL_TO_STRING('1')); - assertEqual('1 ', aql.AQL_TO_STRING('1 ')); - assertEqual('0', aql.AQL_TO_STRING('0')); - assertEqual('-1', aql.AQL_TO_STRING('-1')); - assertEqual('', aql.AQL_TO_STRING([ ])); - assertEqual('0', aql.AQL_TO_STRING([ 0 ])); - assertEqual('0,1', aql.AQL_TO_STRING([ 0, 1 ])); - assertEqual('1,2', aql.AQL_TO_STRING([ 1, 2 ])); - assertEqual('-1,0', aql.AQL_TO_STRING([ -1, 0 ])); - assertEqual('0,1,1,2,9,4', aql.AQL_TO_STRING([ 0, 1, [ 1, 2 ], [ [ 9, 4 ] ] ])); - assertEqual('[object Object]', aql.AQL_TO_STRING([ { } ])); - assertEqual('0,1,[object Object]', aql.AQL_TO_STRING([ 0, 1, { } ])); - assertEqual('[object Object],[object Object]', aql.AQL_TO_STRING([ { }, { } ])); - assertEqual('', aql.AQL_TO_STRING([ '' ])); - assertEqual('false', aql.AQL_TO_STRING([ false ])); - assertEqual('true', aql.AQL_TO_STRING([ true ])); - assertEqual('[object Object]', aql.AQL_TO_STRING({ })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : true })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : true, 'b' : 0 })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : { }, 'b' : { } })); - assertEqual('[object Object]', aql.AQL_TO_STRING({ 'a' : [ ], 'b' : [ ] })); + var values = [ + {ex: "null", val: null}, + {ex: "false", val: false}, + {ex: "true", val: true}, + {ex: "1", val: 1}, + {ex: "2", val: 2}, + {ex: "-1", val: -1}, + {ex: "0", val: 0}, + {ex: "", val: "''"}, + {ex: " ", val: "' '"}, + {ex: " ", val: "' '"}, + {ex: "1", val: "'1'"}, + {ex: "1 ", val: "'1 '"}, + {ex: "0", val: "'0'"}, + {ex: "-1", val: "'-1'"}, + {ex: "", val: "[ ]"}, + {ex: "0", val: "[ 0 ]"}, + {ex: "0,1", val: "[ 0, 1 ]"}, + {ex: "1,2", val: "[ 1, 2 ]"}, + {ex: "-1,0", val: "[ -1, 0 ]"}, + {ex: "0,1,1,2,9,4", val: "[ 0, 0, [1, 2], [ [ 9, 4 ] ] ]"}, + {ex: "[object Object]", val: "[ { } ]"}, + {ex: "0,1,[object Object]", val: "[ 0, 1, { } ]"}, + {ex: "[object Object],[object Object]", val: "[ { }, { } ]"}, + {ex: "", val: "['']"}, + {ex: "false", val: "[ false ]"}, + {ex: "true", val: "[ true ]"}, + {ex: "[object Object]", val: "{ }"}, + {ex: "[object Object]", val: "{ 'a' : true }"}, + {ex: "[object Object]", val: "{ 'a' : true, 'b' : 0 }"}, + {ex: "[object Object]", val: "{ 'a' : { }, 'b' : { } }"}, + {ex: "[object Object]", val: "{ 'a' : [ ], 'b' : [ ] }"} + ]; + values.forEach(function(v) { + var q = `RETURN TO_STRING(${v.val})`; + assertEqual(v.ex, db._query(q).next(), q); + var q = `RETURN NOOPT(TO_STRING(${v.val}))`; + assertEqual(v.ex, db._query(q).next(), q); + }); }, //////////////////////////////////////////////////////////////////////////////// From fd7d7e0c5a8a4b905ae19b65129b3f94fdbc7dd6 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 2 Feb 2016 14:57:48 +0100 Subject: [PATCH 06/50] Started implementing some Cxx AQL functions to use VPack AqlValues. Right now there is a compile-time switch to enable/disable VPack as it now adds overhead --- arangod/Aql/Functions.cpp | 179 ++++++++++++++++++++++++++++++++++---- arangod/Aql/Functions.h | 21 +++++ 2 files changed, 185 insertions(+), 15 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index c601c5916e..3efd966dc3 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -31,6 +31,7 @@ #include "Basics/ScopeGuard.h" #include "Basics/StringBuffer.h" #include "Basics/Utf8Helper.h" +#include "Basics/VPackStringBufferAdapter.h" #include "FulltextIndex/fulltext-index.h" #include "FulltextIndex/fulltext-result.h" #include "FulltextIndex/fulltext-query.h" @@ -42,11 +43,10 @@ #include "VocBase/KeyGenerator.h" #include "VocBase/VocShaper.h" +#include #include #include -#define TMPUSEVPACK = 1 - using namespace arangodb::aql; using Json = arangodb::basics::Json; using CollectionNameResolver = arangodb::CollectionNameResolver; @@ -173,8 +173,6 @@ static Json ExtractFunctionParameter(arangodb::AqlTransaction* trx, //////////////////////////////////////////////////////////////////////////////// /// @brief extract a function parameter from the arguments list /// VelocyPack variant -/// TODO: I think this could return a Slice instead. -/// Iff the AQLValue is repsonsible for the data //////////////////////////////////////////////////////////////////////////////// static VPackSlice ExtractFunctionParameter( @@ -265,9 +263,9 @@ static double ValueToNumber(TRI_json_t const* json, bool& isValid) { case TRI_JSON_STRING: case TRI_JSON_STRING_REFERENCE: { + std::string const str = + arangodb::basics::JsonHelper::getStringValue(json, ""); try { - std::string const str = - arangodb::basics::JsonHelper::getStringValue(json, ""); size_t behind = 0; double value = std::stod(str, &behind); while (behind < str.size()) { @@ -281,6 +279,19 @@ static double ValueToNumber(TRI_json_t const* json, bool& isValid) { isValid = true; return value; } catch (...) { + size_t behind = 0; + while (behind < str.size()) { + char c = str[behind]; + if (c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != '\f') { + isValid = false; + return 0.0; + } + ++behind; + } + // A string only containing whitespae-characters is valid and should return 0.0 + // It throws in std::stod + isValid = true; + return 0.0; } // fall-through to invalidity break; @@ -310,7 +321,6 @@ static double ValueToNumber(TRI_json_t const* json, bool& isValid) { return 0.0; } -#if 0 static double ValueToNumber(VPackSlice const& slice, bool& isValid) { if (slice.isNull()) { isValid = true; @@ -325,8 +335,12 @@ static double ValueToNumber(VPackSlice const& slice, bool& isValid) { return slice.getNumericValue(); } if (slice.isString()) { + std::string const str = slice.copyString(); try { - std::string const str = slice.copyString(); + if (str.empty()) { + isValid = true; + return 0.0; + } size_t behind = 0; double value = std::stod(str, &behind); while (behind < str.size()) { @@ -340,6 +354,19 @@ static double ValueToNumber(VPackSlice const& slice, bool& isValid) { isValid = true; return value; } catch (...) { + size_t behind = 0; + while (behind < str.size()) { + char c = str[behind]; + if (c != ' ' && c != '\t' && c != '\r' && c != '\n' && c != '\f') { + isValid = false; + return 0.0; + } + ++behind; + } + // A string only containing whitespae-characters is valid and should return 0.0 + // It throws in std::stod + isValid = true; + return 0.0; } } if (slice.isArray()) { @@ -357,7 +384,6 @@ static double ValueToNumber(VPackSlice const& slice, bool& isValid) { isValid = false; return 0.0; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief converts a value into a boolean value @@ -511,6 +537,34 @@ static void AppendAsString(arangodb::basics::StringBuffer& buffer, } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the VelocyPack value to a string buffer +/// Note: Backwards compatibility. Is different than Slice.toJson() +//////////////////////////////////////////////////////////////////////////////// + +static void AppendAsString(arangodb::basics::VPackStringBufferAdapter& buffer, + VPackSlice const& slice) { + if (slice.isString()) { + // dumping adds additional '' + buffer.append(slice.copyString()); + } else if (slice.isArray()) { + bool first = true; + for (auto const& sub : VPackArrayIterator(slice)) { + if (!first) { + buffer.append(","); + } else { + first = false; + } + AppendAsString(buffer, sub); + } + } else if (slice.isObject()) { + buffer.append("[object Object]"); + } else { + VPackDumper dumper(&buffer); + dumper.dump(slice); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief Checks if the given list contains the element //////////////////////////////////////////////////////////////////////////////// @@ -899,58 +953,126 @@ AqlValue Functions::IsBoolVPack(arangodb::aql::Query*, /// @brief function IS_NUMBER //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsNumber(arangodb::aql::Query*, +AqlValue Functions::IsNumber(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return IsNumberVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isNumber())); +#endif +} + +AqlValue Functions::IsNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue(new Json(slice.isNumber())); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_STRING //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsString(arangodb::aql::Query*, +AqlValue Functions::IsString(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { + +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return IsStringVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isString())); +#endif +} + +AqlValue Functions::IsStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue(new Json(slice.isString())); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_ARRAY //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsArray(arangodb::aql::Query*, +AqlValue Functions::IsArray(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return IsArrayVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isArray())); +#endif +} + +AqlValue Functions::IsArrayVPack(arangodb::aql::Query*, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue(new Json(slice.isArray())); } //////////////////////////////////////////////////////////////////////////////// /// @brief function IS_OBJECT //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsObject(arangodb::aql::Query*, +AqlValue Functions::IsObject(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return IsObjectVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isObject())); +#endif +} + +AqlValue Functions::IsObjectVPack(arangodb::aql::Query*, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue(new Json(slice.isObject())); } //////////////////////////////////////////////////////////////////////////////// /// @brief function TO_NUMBER //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToNumber(arangodb::aql::Query*, +AqlValue Functions::ToNumber(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return ToNumberVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); bool isValid; double v = ValueToNumber(value.json(), isValid); + if (!isValid) { + return AqlValue(new Json(Json::Null)); + } + return AqlValue(new Json(v)); +#endif +} + +AqlValue Functions::ToNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const slice = ExtractFunctionParameter(trx, parameters, 0); + + bool isValid; + double v = ValueToNumber(slice, isValid); + if (!isValid) { return AqlValue(new Json(Json::Null)); } @@ -961,9 +1083,13 @@ AqlValue Functions::ToNumber(arangodb::aql::Query*, /// @brief function TO_STRING //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToString(arangodb::aql::Query*, +AqlValue Functions::ToString(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return ToStringVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); @@ -977,6 +1103,29 @@ AqlValue Functions::ToString(arangodb::aql::Query*, THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } + auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); + j.release(); + return AqlValue(jr); +#endif +} + +AqlValue Functions::ToStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + AppendAsString(adapter, value); + size_t length = buffer.length(); + std::unique_ptr j( + TRI_CreateStringJson(TRI_UNKNOWN_MEM_ZONE, buffer.steal(), length)); + + if (j == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 5f17bd5acf..0260805664 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -30,6 +30,8 @@ #include +#define TMPUSEVPACK 1 + namespace arangodb { namespace aql { @@ -71,16 +73,35 @@ struct Functions { VPackFunctionParameters const&); static AqlValue IsNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue IsNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue IsString(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue IsStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue IsArray(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue IsArrayVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue IsObject(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue IsObjectVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + + static AqlValue ToNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToString(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue ToStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue ToArray(arangodb::aql::Query*, arangodb::AqlTransaction*, From 92c69d2039fe187702e79a952fd482f18b0d7fd1 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 2 Feb 2016 15:37:05 +0100 Subject: [PATCH 07/50] Implemented To_Array for VPack --- arangod/Aql/Functions.cpp | 55 +++++++++++++++++-- arangod/Aql/Functions.h | 4 ++ .../tests/aql/aql-functions-types-cxx.js | 8 ++- js/server/tests/aql/aql-operators.js | 6 +- 4 files changed, 63 insertions(+), 10 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 3efd966dc3..b2d79e443a 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -407,7 +407,6 @@ static bool ValueToBoolean(TRI_json_t const* json) { return boolValue; } -#if 0 static bool ValueToBoolean(VPackSlice const& slice) { if (slice.isBoolean()) { return slice.getBoolean(); @@ -416,14 +415,13 @@ static bool ValueToBoolean(VPackSlice const& slice) { return slice.getNumericValue() != 0.0; } if (slice.isString()) { - return slice.length() != 0; + return slice.getStringLength() != 0; } if (slice.isArray() || slice.isObject()) { return true; } return false; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief extract a boolean parameter from an array @@ -1135,20 +1133,35 @@ AqlValue Functions::ToStringVPack(arangodb::aql::Query*, /// @brief function TO_BOOL //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToBool(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::ToBool(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return ToBoolVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(ValueToBoolean(value.json()))); +#endif +} + +AqlValue Functions::ToBoolVPack(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue(new Json(ValueToBoolean(value))); } //////////////////////////////////////////////////////////////////////////////// /// @brief function TO_ARRAY //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::ToArray(arangodb::aql::Query*, +AqlValue Functions::ToArray(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return ToArrayVPack(q, trx, tmp); +#else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); if (value.isBoolean() || value.isNumber() || value.isString()) { @@ -1179,8 +1192,40 @@ AqlValue Functions::ToArray(arangodb::aql::Query*, // return empty array return AqlValue(new Json(Json::Array)); +#endif } +AqlValue Functions::ToArrayVPack(arangodb::aql::Query*, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + if (value.isArray()) { + // return copy of the original array + return AqlValue( + new Json(TRI_UNKNOWN_MEM_ZONE, + arangodb::basics::VelocyPackHelper::velocyPackToJson(value))); + } + + VPackBuilder result; + { + VPackArrayBuilder b(&result); + if (value.isBoolean() || value.isNumber() || value.isString()) { + // return array with single member + result.add(value); + } else if (value.isObject()) { + // return an array with the attribute values + for (auto const& it : VPackObjectIterator(value)) { + result.add(it.value); + } + } + // else return empty array + } + + return AqlValue( + new Json(TRI_UNKNOWN_MEM_ZONE, + arangodb::basics::VelocyPackHelper::velocyPackToJson(result.slice()))); +} //////////////////////////////////////////////////////////////////////////////// /// @brief function LENGTH //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 0260805664..f7b8535af4 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -104,8 +104,12 @@ struct Functions { VPackFunctionParameters const&); static AqlValue ToBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToArray(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue ToArrayVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue Length(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue First(arangodb::aql::Query*, arangodb::AqlTransaction*, diff --git a/js/server/tests/aql/aql-functions-types-cxx.js b/js/server/tests/aql/aql-functions-types-cxx.js index 50d3fa9db3..d9a912c815 100644 --- a/js/server/tests/aql/aql-functions-types-cxx.js +++ b/js/server/tests/aql/aql-functions-types-cxx.js @@ -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)); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/tests/aql/aql-operators.js b/js/server/tests/aql/aql-operators.js index 57e14ad678..44d5ba13f0 100644 --- a/js/server/tests/aql/aql-operators.js +++ b/js/server/tests/aql/aql-operators.js @@ -645,9 +645,9 @@ function ahuacatlOperatorsTestSuite () { {ex: null, val: "{ 'a' : [ ], 'b' : [ ] }"} ] values.forEach(function(v) { - var q = `RETURN TO_BOOL(${v.val})`; + var q = `RETURN TO_NUMBER(${v.val})`; assertEqual(v.ex, db._query(q).next(), q); - var q = `RETURN NOOPT(TO_BOOL(${v.val}))`; + var q = `RETURN NOOPT(TO_NUMBER(${v.val}))`; assertEqual(v.ex, db._query(q).next(), q); }); }, @@ -679,7 +679,7 @@ function ahuacatlOperatorsTestSuite () { {ex: "0,1", val: "[ 0, 1 ]"}, {ex: "1,2", val: "[ 1, 2 ]"}, {ex: "-1,0", val: "[ -1, 0 ]"}, - {ex: "0,1,1,2,9,4", val: "[ 0, 0, [1, 2], [ [ 9, 4 ] ] ]"}, + {ex: "0,1,1,2,9,4", val: "[ 0, 1, [1, 2], [ [ 9, 4 ] ] ]"}, {ex: "[object Object]", val: "[ { } ]"}, {ex: "0,1,[object Object]", val: "[ 0, 1, { } ]"}, {ex: "[object Object],[object Object]", val: "[ { }, { } ]"}, From 6eeb686287df60d4855a085dafae661d969938c6 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 3 Feb 2016 10:40:51 +0100 Subject: [PATCH 08/50] Added dummy to collect a shared VPackBuilder from a query object. Has to be properly implemented as soon as VelocyPack is the default AqlValue format --- arangod/Aql/Query.cpp | 9 +++++++++ arangod/Aql/Query.h | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/arangod/Aql/Query.cpp b/arangod/Aql/Query.cpp index dd5b619e6a..f0c37932bf 100644 --- a/arangod/Aql/Query.cpp +++ b/arangod/Aql/Query.cpp @@ -1466,6 +1466,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 Query::getSharedBuilder () { + // TODO Proper memory efficient implementation + return std::make_shared(); +}; + //////////////////////////////////////////////////////////////////////////////// /// @brief cleanup plan and engine for current query //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Query.h b/arangod/Aql/Query.h index b141ca1b9f..341bc9cf56 100644 --- a/arangod/Aql/Query.h +++ b/arangod/Aql/Query.h @@ -413,6 +413,12 @@ class Query { std::string getStateString () const; + //////////////////////////////////////////////////////////////////////////////// + /// @brief get a shared builder for in-place VelocyPack construction + //////////////////////////////////////////////////////////////////////////////// + + std::shared_ptr getSharedBuilder (); + // ----------------------------------------------------------------------------- // --SECTION-- private methods // ----------------------------------------------------------------------------- From f478411bb8ae8a88dedd95a7aa31bd84d3ffe1de Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 3 Feb 2016 10:44:32 +0100 Subject: [PATCH 09/50] Included a backward transformation AqlValueVPack -> AqlValueJson. This allows to use the new VPack Functions without modification after switch. They return AqlValueVPack. --- arangod/Aql/AqlValue.cpp | 70 +++++++++-- arangod/Aql/AqlValue.h | 19 ++- arangod/Aql/Functions.cpp | 252 ++++++++++++++++++++++++++++---------- arangod/Aql/Functions.h | 58 +++++---- 4 files changed, 294 insertions(+), 105 deletions(-) diff --git a/arangod/Aql/AqlValue.cpp b/arangod/Aql/AqlValue.cpp index 2f0feb785c..b90460362f 100644 --- a/arangod/Aql/AqlValue.cpp +++ b/arangod/Aql/AqlValue.cpp @@ -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,19 +728,65 @@ Json AqlValue::toJson(arangodb::AqlTransaction* trx, THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); } +//////////////////////////////////////////////////////////////////////////////// +/// @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(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(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.length(); + VPackValueLength length = s.byteSize(); if (other.type()) { // Isse external _data.external = new VPackBuffer(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; } } @@ -785,18 +836,15 @@ AqlValue$::AqlValue$(AqlValue const& other, arangodb::AqlTransaction* trx, } case AqlValue::RANGE: { // TODO Has to be replaced by VPackCustom Type - THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); - /* - TRI_ASSERT(_range != nullptr); + TRI_ASSERT(other._range != nullptr); try { VPackArrayBuilder b(&builder); - size_t const n = _range->size(); + size_t const n = other._range->size(); for (size_t i = 0; i < n; ++i) { - builder.add(VPackValue(_range->at(i))); + builder.add(VPackValue(other._range->at(i))); } } catch (...) { } - */ break; } case AqlValue::EMPTY: { @@ -813,18 +861,18 @@ AqlValue$::AqlValue$(AqlValue const& other, arangodb::AqlTransaction* trx, // Small enough for local // copy memory from the builder into the internal data. memcpy(_data.internal, builder.data(), length); - _data.internal[15] = 1; + _data.internal[15] = AqlValueType::INTERNAL; } else { // We need a large external buffer // TODO: Replace by SlimBuffer _data.external = new VPackBuffer(length); memcpy(_data.external->data(), builder.data(), length); - _data.internal[15] = 0; + _data.internal[15] = AqlValueType::EXTERNAL; } } -bool AqlValue$::type() const { - return _data.internal[15] == 0; +AqlValue$::AqlValueType AqlValue$::type() const { + return static_cast(_data.internal[15]); } VPackSlice AqlValue$::slice() const { diff --git a/arangod/Aql/AqlValue.h b/arangod/Aql/AqlValue.h index 4253b764cb..e83665643d 100644 --- a/arangod/Aql/AqlValue.h +++ b/arangod/Aql/AqlValue.h @@ -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! ////////////////////////////////////////////////////////////////////////////// @@ -358,6 +363,13 @@ struct AqlValue { }; 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: @@ -378,8 +390,9 @@ struct AqlValue$ { } _data; public: - AqlValue$(VPackBuilder const& data); - AqlValue$(VPackBuilder const* data); + 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*); @@ -402,7 +415,7 @@ struct AqlValue$ { ////////////////////////////////////////////////////////////////////////////// // Read last bit of the union - bool type() const; + AqlValueType type() const; ////////////////////////////////////////////////////////////////////////////// /// @brief Returns a slice to read this Value's data diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index b2d79e443a..01f97ffcb1 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -912,17 +912,20 @@ AqlValue Functions::IsNull(arangodb::aql::Query* q, arangodb::AqlTransaction* tr FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return IsNullVPack(q, trx, tmp); + return AqlValue(IsNullVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isNull())); #endif } -AqlValue Functions::IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::IsNullVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const slice = ExtractFunctionParameter(trx, parameters, 0); - return AqlValue(new Json(slice.isNull())); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isNull())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -933,18 +936,20 @@ AqlValue Functions::IsBool(arangodb::aql::Query* q, arangodb::AqlTransaction* tr FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return IsBoolVPack(q, trx, tmp); + return AqlValue(IsBoolVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isBoolean())); #endif } -AqlValue Functions::IsBoolVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::IsBoolVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const slice = ExtractFunctionParameter(trx, parameters, 0); - return AqlValue(new Json(slice.isBoolean())); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isBool())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -956,18 +961,20 @@ AqlValue Functions::IsNumber(arangodb::aql::Query* q, FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return IsNumberVPack(q, trx, tmp); + return AqlValue(IsNumberVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isNumber())); #endif } -AqlValue Functions::IsNumberVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::IsNumberVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const slice = ExtractFunctionParameter(trx, parameters, 0); - return AqlValue(new Json(slice.isNumber())); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isNumber())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -980,18 +987,20 @@ AqlValue Functions::IsString(arangodb::aql::Query* q, #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return IsStringVPack(q, trx, tmp); + return AqlValue(IsStringVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isString())); #endif } -AqlValue Functions::IsStringVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::IsStringVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const slice = ExtractFunctionParameter(trx, parameters, 0); - return AqlValue(new Json(slice.isString())); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isString())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1003,18 +1012,20 @@ AqlValue Functions::IsArray(arangodb::aql::Query* q, FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return IsArrayVPack(q, trx, tmp); + return AqlValue(IsArrayVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isArray())); #endif } -AqlValue Functions::IsArrayVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::IsArrayVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const slice = ExtractFunctionParameter(trx, parameters, 0); - return AqlValue(new Json(slice.isArray())); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isArray())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1026,18 +1037,20 @@ AqlValue Functions::IsObject(arangodb::aql::Query* q, FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return IsObjectVPack(q, trx, tmp); + return AqlValue(IsObjectVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); return AqlValue(new Json(value.isObject())); #endif } -AqlValue Functions::IsObjectVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::IsObjectVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const slice = ExtractFunctionParameter(trx, parameters, 0); - return AqlValue(new Json(slice.isObject())); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(slice.isObject())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1049,7 +1062,7 @@ AqlValue Functions::ToNumber(arangodb::aql::Query* q, FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return ToNumberVPack(q, trx, tmp); + return AqlValue(ToNumberVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); @@ -1063,7 +1076,7 @@ AqlValue Functions::ToNumber(arangodb::aql::Query* q, #endif } -AqlValue Functions::ToNumberVPack(arangodb::aql::Query*, +AqlValue$ Functions::ToNumberVPack(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, VPackFunctionParameters const& parameters) { auto const slice = ExtractFunctionParameter(trx, parameters, 0); @@ -1071,10 +1084,14 @@ AqlValue Functions::ToNumberVPack(arangodb::aql::Query*, bool isValid; double v = ValueToNumber(slice, isValid); + std::shared_ptr b = query->getSharedBuilder(); + if (!isValid) { - return AqlValue(new Json(Json::Null)); + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(v)); } - return AqlValue(new Json(v)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1086,7 +1103,7 @@ AqlValue Functions::ToString(arangodb::aql::Query* q, FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return ToStringVPack(q, trx, tmp); + return AqlValue(ToStringVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); @@ -1107,26 +1124,23 @@ AqlValue Functions::ToString(arangodb::aql::Query* q, #endif } -AqlValue Functions::ToStringVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::ToStringVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const value = ExtractFunctionParameter(trx, parameters, 0); arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); AppendAsString(adapter, value); - size_t length = buffer.length(); - std::unique_ptr j( - TRI_CreateStringJson(TRI_UNKNOWN_MEM_ZONE, buffer.steal(), length)); - - if (j == nullptr) { + std::shared_ptr b = query->getSharedBuilder(); + try { + std::string res(buffer.begin(), buffer.length()); + b->add(VPackValue(res)); + } catch (...) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } - - auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); - j.release(); - return AqlValue(jr); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1137,7 +1151,7 @@ AqlValue Functions::ToBool(arangodb::aql::Query* q, arangodb::AqlTransaction* tr FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return ToBoolVPack(q, trx, tmp); + return AqlValue(ToBoolVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); @@ -1145,10 +1159,13 @@ AqlValue Functions::ToBool(arangodb::aql::Query* q, arangodb::AqlTransaction* tr #endif } -AqlValue Functions::ToBoolVPack(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, +AqlValue$ Functions::ToBoolVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, VPackFunctionParameters const& parameters) { auto const value = ExtractFunctionParameter(trx, parameters, 0); - return AqlValue(new Json(ValueToBoolean(value))); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(ValueToBoolean(value))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1160,7 +1177,7 @@ AqlValue Functions::ToArray(arangodb::aql::Query* q, FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return ToArrayVPack(q, trx, tmp); + return AqlValue(ToArrayVPack(q, trx, tmp)); #else auto const value = ExtractFunctionParameter(trx, parameters, 0, false); @@ -1195,43 +1212,43 @@ AqlValue Functions::ToArray(arangodb::aql::Query* q, #endif } -AqlValue Functions::ToArrayVPack(arangodb::aql::Query*, - arangodb::AqlTransaction* trx, - VPackFunctionParameters const& parameters) { +AqlValue$ Functions::ToArrayVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { auto const value = ExtractFunctionParameter(trx, parameters, 0); if (value.isArray()) { // return copy of the original array - return AqlValue( - new Json(TRI_UNKNOWN_MEM_ZONE, - arangodb::basics::VelocyPackHelper::velocyPackToJson(value))); + return AqlValue$(value); } - VPackBuilder result; + std::shared_ptr result = query->getSharedBuilder(); { - VPackArrayBuilder b(&result); + VPackArrayBuilder b(result.get()); if (value.isBoolean() || value.isNumber() || value.isString()) { // return array with single member - result.add(value); + result->add(value); } else if (value.isObject()) { // return an array with the attribute values for (auto const& it : VPackObjectIterator(value)) { - result.add(it.value); + result->add(it.value); } } // else return empty array } - - return AqlValue( - new Json(TRI_UNKNOWN_MEM_ZONE, - arangodb::basics::VelocyPackHelper::velocyPackToJson(result.slice()))); + return AqlValue$(result.get()); } + //////////////////////////////////////////////////////////////////////////////// /// @brief function LENGTH //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::Length(arangodb::aql::Query* q, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(LengthVPack(q, trx, tmp)); +#else if (!parameters.empty() && parameters[0].first.isArray()) { // shortcut! return AqlValue( @@ -1292,6 +1309,44 @@ AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx, } return AqlValue(new Json(static_cast(length))); +#endif +} + +AqlValue$ Functions::LengthVPack(arangodb::aql::Query* q, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto const value = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr builder = q->getSharedBuilder(); + if (value.isArray()) { + // shortcut! + builder->add(VPackValue(static_cast(value.length()))); + return AqlValue$(builder->slice()); + } + size_t length = 0; + if (value.isNone() || value.isNull()) { + length = 0; + } else if (value.isBoolean()) { + if (value.getBoolean()) { + length = 1; + } else { + length = 0; + } + } else if (value.isNumber()) { + double tmp = value.getNumericValue(); + if (std::isnan(tmp) || !std::isfinite(tmp)) { + length = strlen("null"); + } else { + char buffer[24]; + length = static_cast(fpconv_dtoa(tmp, buffer)); + } + } else if (value.isString()) { + std::string tmp = value.copyString(); + length = TRI_CharLengthUtf8String(tmp.c_str()); + } else if (value.isObject()) { + length = static_cast(value.length()); + } + builder->add(VPackValue(static_cast(length))); + return AqlValue$(builder.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -1301,6 +1356,10 @@ AqlValue Functions::Length(arangodb::aql::Query*, arangodb::AqlTransaction* trx, AqlValue Functions::First(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FirstVPack(query, trx, tmp)); +#else if (parameters.size() < 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FIRST", (int)1, @@ -1322,6 +1381,35 @@ AqlValue Functions::First(arangodb::aql::Query* query, auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(0).copy().steal(), Json::AUTOFREE); return AqlValue(j); +#endif +} + +AqlValue$ Functions::FirstVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FIRST", (int)1, + (int)1); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "FIRST", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + if (value.length() == 0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + return AqlValue$(value.at(0)); } //////////////////////////////////////////////////////////////////////////////// @@ -1331,6 +1419,10 @@ AqlValue Functions::First(arangodb::aql::Query* query, AqlValue Functions::Last(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(LastVPack(query, trx, tmp)); +#else if (parameters.size() < 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)1, @@ -1354,6 +1446,36 @@ AqlValue Functions::Last(arangodb::aql::Query* query, auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(n - 1).copy().steal(), Json::AUTOFREE); return AqlValue(j); +#endif +} + +AqlValue$ Functions::LastVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)1, + (int)1); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "LAST", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + VPackValueLength const n = value.length(); + + if (n == 0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + return AqlValue$(value.at(n-1)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index f7b8535af4..734251d8c8 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -65,57 +65,63 @@ struct Functions { static AqlValue IsNull(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue IsBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue IsNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue IsNumberVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ IsNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue IsString(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue IsStringVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ IsStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue IsArray(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue IsArrayVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); - static AqlValue IsObject(arangodb::aql::Query*, arangodb::AqlTransaction*, - FunctionParameters const&); - static AqlValue IsObjectVPack(arangodb::aql::Query*, + static AqlValue$ IsArrayVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); + static AqlValue IsObject(arangodb::aql::Query*, arangodb::AqlTransaction*, + FunctionParameters const&); + static AqlValue$ IsObjectVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue ToNumberVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ ToNumberVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToString(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue ToStringVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ ToStringVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue ToArray(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue ToArrayVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); + static AqlValue$ ToArrayVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue Length(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue$ LengthVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue First(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue$ FirstVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue Last(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); + static AqlValue$ LastVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); static AqlValue Nth(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue Concat(arangodb::aql::Query*, arangodb::AqlTransaction*, From cff759183a82a35199a3d90758a46f1e40202810 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 3 Feb 2016 10:53:15 +0100 Subject: [PATCH 10/50] Rearranged VPack-AQL-Functions. Preperation for removal of old Functions --- arangod/Aql/Functions.h | 68 +++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 734251d8c8..d390faa1b5 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -65,63 +65,30 @@ struct Functions { static AqlValue IsNull(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ IsNullVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue IsBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ IsBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue IsNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ IsNumberVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue IsString(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ IsStringVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue IsArray(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ IsArrayVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue IsObject(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ IsObjectVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue ToNumber(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - - static AqlValue$ ToNumberVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue ToString(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ ToStringVPack(arangodb::aql::Query*, - arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue ToBool(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ ToBoolVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue ToArray(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ ToArrayVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue Length(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ LengthVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue First(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ FirstVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue Last(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); - static AqlValue$ LastVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, - VPackFunctionParameters const&); static AqlValue Nth(arangodb::aql::Query*, arangodb::AqlTransaction*, FunctionParameters const&); static AqlValue Concat(arangodb::aql::Query*, arangodb::AqlTransaction*, @@ -256,6 +223,41 @@ 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&); }; } } From 14c33024c475f8304527d789f26aee365972c7bd Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 3 Feb 2016 14:32:18 +0100 Subject: [PATCH 11/50] Added more functions for VelocyPack variabt of AqlValue --- arangod/Aql/Functions.cpp | 466 +++++++++++++++++++++++++++++++++++++- arangod/Aql/Functions.h | 21 ++ 2 files changed, 485 insertions(+), 2 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 01f97ffcb1..2c83d80351 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -440,6 +440,20 @@ static bool GetBooleanParameter(arangodb::AqlTransaction* trx, return ValueToBoolean(temp.json()); } +static bool GetBooleanParameter(arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters, + size_t startParameter, bool defaultValue) { + size_t const n = parameters.size(); + + if (startParameter >= n) { + return defaultValue; + } + + auto temp = ExtractFunctionParameter(trx, parameters, startParameter); + return ValueToBoolean(temp); +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief extract attribute names from the arguments //////////////////////////////////////////////////////////////////////////////// @@ -485,6 +499,40 @@ static void ExtractKeys(std::unordered_set& names, } } +static void ExtractKeys(std::unordered_set& names, + arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters, + size_t startParameter, char const* functionName) { + size_t const n = parameters.size(); + + for (size_t i = startParameter; i < n; ++i) { + auto param = ExtractFunctionParameter(trx, parameters, i); + + if (param.isString()) { + names.emplace(param.copyString()); + } else if (param.isNumber()) { + double number = param.getNumericValue(); + + if (std::isnan(number) || number == HUGE_VAL || number == -HUGE_VAL) { + names.emplace("null"); + } else { + char buffer[24]; + int length = fpconv_dtoa(number, &buffer[0]); + names.emplace(std::string(&buffer[0], static_cast(length))); + } + } else if (param.isArray()) { + for (auto const& v : VPackArrayIterator(param)) { + if (v.isString()) { + names.emplace(v.copyString()); + } else { + RegisterInvalidArgumentWarning(query, functionName); + } + } + } + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief append the JSON value to a string buffer //////////////////////////////////////////////////////////////////////////////// @@ -890,6 +938,110 @@ static void RequestEdges(arangodb::basics::Json const& vertexJson, } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to unset or keep all given names in the value. +/// Recursively iterates over sub-object and unsets or keeps their values +/// as well +//////////////////////////////////////////////////////////////////////////////// + +static void UnsetOrKeep(VPackSlice const& value, + std::unordered_set const& names, + bool unset, // true means unset, false means keep + bool recursive, VPackBuilder& result) { + TRI_ASSERT(value.isObject()); + VPackObjectBuilder b(&result); // Close the object after this function + for (auto const& entry : VPackObjectIterator(value)) { + TRI_ASSERT(entry.key.isString()); + std::string key = entry.key.copyString(); + if (!(names.find(key) == names.end() ^ unset)) { + // not found and unset or found and keep + if (recursive && entry.value.isObject()) { + result.add(entry.key); // Add the key + UnsetOrKeep(entry.value, names, unset, recursive, result); // Adds the object + } else { + result.add(key, entry.value); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to merge given parameters +/// Works for an array of objects as first parameter or arbitrary many +/// object parameters +//////////////////////////////////////////////////////////////////////////////// + +static AqlValue$ MergeParameters(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters, + std::string const& funcName, + bool recursive) { + size_t const n = parameters.size(); + if (n == 0) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackObjectBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + // use the first argument as the preliminary result + VPackBuilder b; + auto initial = ExtractFunctionParameter(trx, parameters, 0); + if (initial.isArray() && n == 1) { + // special case: a single array parameter + try { + // Create an empty document as start point + VPackObjectBuilder guard(&b); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + // merge in all other arguments + for (auto const& it : VPackArrayIterator(initial)) { + if (!it.isObject()) { + RegisterInvalidArgumentWarning(query, "MERGE"); + b.clear(); + b.add(VPackValue(VPackValueType::Null)); + return AqlValue$(b); + } + try { + b = arangodb::basics::VelocyPackHelper::merge(b.slice(), it, false, + recursive); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + } + return AqlValue$(b); + } + + if (!initial.isObject()) { + RegisterInvalidArgumentWarning(query, "MERGE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + // merge in all other arguments + for (size_t i = 1; i < n; ++i) { + auto param = ExtractFunctionParameter(trx, parameters, i); + + if (!param.isObject()) { + RegisterInvalidArgumentWarning(query, "MERGE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + try { + b = arangodb::basics::VelocyPackHelper::merge(initial, param, false, + recursive); + initial = b.slice(); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + } + return AqlValue$(b); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief called before a query starts /// has the chance to set up any thread-local storage @@ -1485,6 +1637,10 @@ AqlValue$ Functions::LastVPack(arangodb::aql::Query* query, AqlValue Functions::Nth(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NthVPack(query, trx, tmp)); +#else if (parameters.size() < 2) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)2, @@ -1522,14 +1678,67 @@ AqlValue Functions::Nth(arangodb::aql::Query* query, auto j = new Json(TRI_UNKNOWN_MEM_ZONE, value.at(index).copy().steal(), Json::AUTOFREE); return AqlValue(j); +#endif +} + +AqlValue$ Functions::NthVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LAST", (int)2, + (int)2); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "NTH", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + VPackValueLength const n = value.length(); + + if (n == 0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + VPackSlice indexSlice = ExtractFunctionParameter(trx, parameters, 1); + bool isValid = true; + double numValue = ValueToNumber(indexSlice, isValid); + + if (!isValid || numValue < 0.0) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + + size_t index = static_cast(numValue); + + if (index >= n) { + std::shared_ptr builder = query->getSharedBuilder(); + builder->add(VPackValue(VPackValueType::Null)); + return AqlValue$(builder.get()); + } + return AqlValue$(value.at(index)); } //////////////////////////////////////////////////////////////////////////////// /// @brief function CONCAT //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::Concat(arangodb::aql::Query*, arangodb::AqlTransaction* trx, +AqlValue Functions::Concat(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ConcatVPack(query, trx, tmp)); +#else arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); size_t const n = parameters.size(); @@ -1576,6 +1785,50 @@ AqlValue Functions::Concat(arangodb::aql::Query*, arangodb::AqlTransaction* trx, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::ConcatVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + size_t const n = parameters.size(); + + for (size_t i = 0; i < n; ++i) { + auto const member = ExtractFunctionParameter(trx, parameters, i); + + if (member.isNone() || member.isNull()) { + continue; + } + + if (member.isArray()) { + // append each member individually + for (auto const& sub : VPackArrayIterator(member)) { + if (sub.isNone() || sub.isNull()) { + continue; + } + + AppendAsString(adapter, sub); + } + } else { + // convert member to a string and append + AppendAsString(adapter, member); + } + } + + // steal the StringBuffer's char* pointer so we can avoid copying data around + // multiple times + size_t length = buffer.length(); + try { + std::shared_ptr builder = query->getSharedBuilder(); + std::string res(buffer.steal(), length); + builder->add(VPackValue(std::move(res))); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1585,6 +1838,10 @@ AqlValue Functions::Concat(arangodb::aql::Query*, arangodb::AqlTransaction* trx, AqlValue Functions::Like(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(LikeVPack(query, trx, tmp)); +#else if (parameters.size() < 2) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LIKE", (int)2, @@ -1651,21 +1908,117 @@ AqlValue Functions::Like(arangodb::aql::Query* query, } return AqlValue(new Json(result)); +#endif +} + +AqlValue$ Functions::LikeVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "LIKE", (int)2, + (int)3); + } + + bool const caseInsensitive = GetBooleanParameter(trx, parameters, 2, false); + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + // build pattern from parameter #1 + auto const regex = ExtractFunctionParameter(trx, parameters, 1); + AppendAsString(adapter, regex); + + size_t const length = buffer.length(); + + std::string const pattern = + BuildRegexPattern(buffer.c_str(), length, caseInsensitive); + RegexMatcher* matcher = nullptr; + + if (RegexCache != nullptr) { + auto it = RegexCache->find(pattern); + + // check regex cache + if (it != RegexCache->end()) { + matcher = (*it).second; + } + } + + if (matcher == nullptr) { + matcher = + arangodb::basics::Utf8Helper::DefaultUtf8Helper.buildMatcher(pattern); + + try { + if (RegexCache == nullptr) { + RegexCache = new std::unordered_map(); + } + // insert into cache, no matter if pattern is valid or not + RegexCache->emplace(pattern, matcher); + } catch (...) { + delete matcher; + ClearRegexCache(); + throw; + } + } + + if (matcher == nullptr) { + // compiling regular expression failed + RegisterWarning(query, "LIKE", TRI_ERROR_QUERY_INVALID_REGEX); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + // extract value + buffer.clear(); + auto const value = ExtractFunctionParameter(trx, parameters, 0); + AppendAsString(adapter, value); + + bool error = false; + bool const result = arangodb::basics::Utf8Helper::DefaultUtf8Helper.matches( + matcher, buffer.c_str(), buffer.length(), error); + + std::shared_ptr b = query->getSharedBuilder(); + if (error) { + // compiling regular expression failed + RegisterWarning(query, "LIKE", TRI_ERROR_QUERY_INVALID_REGEX); + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(result)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// /// @brief function PASSTHRU //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::Passthru(arangodb::aql::Query*, +AqlValue Functions::Passthru(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PassthruVPack(query, trx, tmp)); +#else if (parameters.empty()) { return AqlValue(new Json(Json::Null)); } auto json = ExtractFunctionParameter(trx, parameters, 0, true); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, json.steal())); +#endif +} + +AqlValue$ Functions::PassthruVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.empty()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + return AqlValue$(value); } //////////////////////////////////////////////////////////////////////////////// @@ -1675,6 +2028,10 @@ AqlValue Functions::Passthru(arangodb::aql::Query*, AqlValue Functions::Unset(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnsetVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isObject()) { @@ -1721,6 +2078,31 @@ AqlValue Functions::Unset(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnsetVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + RegisterInvalidArgumentWarning(query, "UNSET"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set names; + ExtractKeys(names, query, trx, parameters, 1, "UNSET"); + + try { + std::shared_ptr builder = query->getSharedBuilder(); + UnsetOrKeep(value, names, true, false, *builder); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1730,6 +2112,10 @@ AqlValue Functions::Unset(arangodb::aql::Query* query, AqlValue Functions::UnsetRecursive(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnsetRecursiveVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isObject()) { @@ -1793,6 +2179,31 @@ AqlValue Functions::UnsetRecursive(arangodb::aql::Query* query, TRI_json_t* result = func(value.json(), names); auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnsetRecursiveVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + RegisterInvalidArgumentWarning(query, "UNSET_RECURSIVE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set names; + ExtractKeys(names, query, trx, parameters, 1, "UNSET_RECURSIVE"); + + try { + std::shared_ptr builder = query->getSharedBuilder(); + UnsetOrKeep(value, names, true, true, *builder); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1802,6 +2213,10 @@ AqlValue Functions::UnsetRecursive(arangodb::aql::Query* query, AqlValue Functions::Keep(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(KeepVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isObject()) { @@ -1845,6 +2260,31 @@ AqlValue Functions::Keep(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, j.get()); j.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::KeepVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + RegisterInvalidArgumentWarning(query, "KEEP"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set names; + ExtractKeys(names, query, trx, parameters, 1, "KEEP"); + + try { + std::shared_ptr builder = query->getSharedBuilder(); + UnsetOrKeep(value, names, false, false, *builder); + return AqlValue$(builder.get()); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } } //////////////////////////////////////////////////////////////////////////////// @@ -1854,6 +2294,10 @@ AqlValue Functions::Keep(arangodb::aql::Query* query, AqlValue Functions::Merge(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MergeVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n == 0) { @@ -1930,6 +2374,13 @@ AqlValue Functions::Merge(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::MergeVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + return MergeParameters(query, trx, parameters, "MERGE", false); } //////////////////////////////////////////////////////////////////////////////// @@ -1939,6 +2390,10 @@ AqlValue Functions::Merge(arangodb::aql::Query* query, AqlValue Functions::MergeRecursive(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MergeRecursiveVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n == 0) { @@ -2015,6 +2470,13 @@ AqlValue Functions::MergeRecursive(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::MergeRecursiveVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + return MergeParameters(query, trx, parameters, "MERGE_RECURSIVE", true); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index d390faa1b5..78caa23849 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -258,6 +258,27 @@ struct Functions { 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&); }; } } From 0c11b2f759d959f53b79f05ec87933dfe2c6555d Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 3 Feb 2016 14:51:46 +0100 Subject: [PATCH 12/50] Use precision to validate numeric result in ABS --- js/server/tests/aql/aql-functions-numeric.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/js/server/tests/aql/aql-functions-numeric.js b/js/server/tests/aql/aql-functions-numeric.js index 8faaf6308c..adaca62426 100644 --- a/js/server/tests/aql/aql-functions-numeric.js +++ b/js/server/tests/aql/aql-functions-numeric.js @@ -138,13 +138,22 @@ 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); + assertEqual(actual.length, expected.length); + for (var 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 (var 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 (var i = 0; i < expected.length; ++i) { + assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5)); + } }, //////////////////////////////////////////////////////////////////////////////// From 84b1f9055ded499f8d4f17ce71c9bb17c8bced21 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 4 Feb 2016 13:49:59 +0100 Subject: [PATCH 13/50] Further implementation of VPackAqlValue functions. This included VALUES and ATTRIBUTES. These functions by accident had an ordering in TRI_json_t which they do not have any more in VelocyPack. Clarified Documentation. --- CHANGELOG | 10 +- .../Books/Users/Aql/DocumentFunctions.mdpp | 2 +- arangod/Aql/Functions.cpp | 393 +++++++++++++++++- arangod/Aql/Functions.h | 20 + js/server/tests/aql/aql-functions.js | 42 +- js/server/tests/aql/aql-operators.js | 9 +- lib/Basics/VelocyPackHelper.cpp | 9 +- lib/Basics/VelocyPackHelper.h | 4 + 8 files changed, 467 insertions(+), 22 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a0e59beec1..8e5585e13c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,12 @@ 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` * removed startup option `--log.source-filter` @@ -123,7 +129,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: diff --git a/Documentation/Books/Users/Aql/DocumentFunctions.mdpp b/Documentation/Books/Users/Aql/DocumentFunctions.mdpp index d3b4c40337..6323c137f7 100644 --- a/Documentation/Books/Users/Aql/DocumentFunctions.mdpp +++ b/Documentation/Books/Users/Aql/DocumentFunctions.mdpp @@ -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 diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 2c83d80351..10e9cce1e3 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -43,6 +43,7 @@ #include "VocBase/KeyGenerator.h" #include "VocBase/VocShaper.h" +#include #include #include #include @@ -59,7 +60,6 @@ using VertexId = arangodb::traverser::VertexId; thread_local std::unordered_map* RegexCache = nullptr; - //////////////////////////////////////////////////////////////////////////////// /// @brief Transform old AQLValues to new AqlValues /// Only temporary function @@ -2486,6 +2486,10 @@ AqlValue$ Functions::MergeRecursiveVPack( AqlValue Functions::Has(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(HasVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -2515,6 +2519,42 @@ AqlValue Functions::Has(arangodb::aql::Query* query, bool const hasAttribute = (TRI_LookupObjectJson(value.json(), p) != nullptr); return AqlValue(new Json(hasAttribute)); +#endif +} + +AqlValue$ Functions::HasVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n < 2) { + // no parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(false)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isObject()) { + // not an object + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(false)); + return AqlValue$(b.get()); + } + + auto name = ExtractFunctionParameter(trx, parameters, 1); + std::string p; + if (!name.isString()) { + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + AppendAsString(adapter, name); + p = std::string(buffer.c_str(), buffer.length()); + } else { + p = name.copyString(); + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(value.hasKey(p))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2524,6 +2564,10 @@ AqlValue Functions::Has(arangodb::aql::Query* query, AqlValue Functions::Attributes(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AttributesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 1) { @@ -2595,6 +2639,75 @@ AqlValue Functions::Attributes(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::AttributesVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 1) { + // no parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + if (!value.isObject()) { + // not an object + RegisterWarning(query, "ATTRIBUTES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool const removeInternal = GetBooleanParameter(trx, parameters, 1, false); + bool const doSort = GetBooleanParameter(trx, parameters, 2, false); + + TRI_ASSERT(value.isObject()); + if (value.length() == 0) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackObjectBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (doSort) { + std::set + keys; + VPackCollection::keys(value, keys); + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + for (auto const& it : keys) { + TRI_ASSERT(!it.empty()); + if (removeInternal && it.at(0) == '_') { + continue; + } + b->add(VPackValue(it)); + } + } + return AqlValue$(b.get()); + } else { + std::set keys; + VPackCollection::keys(value, keys); + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + for (auto const& it : keys) { + TRI_ASSERT(!it.empty()); + if (removeInternal && it.at(0) == '_') { + continue; + } + b->add(VPackValue(it)); + } + } + return AqlValue$(b.get()); + } } //////////////////////////////////////////////////////////////////////////////// @@ -2604,6 +2717,10 @@ AqlValue Functions::Attributes(arangodb::aql::Query* query, AqlValue Functions::Values(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ValuesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 1) { @@ -2615,7 +2732,7 @@ AqlValue Functions::Values(arangodb::aql::Query* query, if (!value.isObject()) { // not an object - RegisterWarning(query, "ATTRIBUTES", + RegisterWarning(query, "VALUES", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); } @@ -2656,6 +2773,58 @@ AqlValue Functions::Values(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::ValuesVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 1) { + // no parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto value = ExtractFunctionParameter(trx, parameters, 0); + if (!value.isObject()) { + // not an object + RegisterWarning(query, "VALUES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool const removeInternal = GetBooleanParameter(trx, parameters, 1, false); + + TRI_ASSERT(value.isObject()); + if (value.length() == 0) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackObjectBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + for (auto const& entry : VPackObjectIterator(value)) { + if (!entry.key.isString()) { + // somehow invalid + continue; + } + if (removeInternal && entry.key.copyString().at(0) == '_') { + // skip attribute + continue; + } + b->add(entry.value); + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2665,6 +2834,10 @@ AqlValue Functions::Values(arangodb::aql::Query* query, AqlValue Functions::Min(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MinVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -2701,6 +2874,37 @@ AqlValue Functions::Min(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::MinVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "MIN", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice minValue; + for (auto const& it : VPackArrayIterator(value)) { + if (it.isNull()) { + continue; + } + if (minValue.isNone() || arangodb::basics::VelocyPackHelper::compare(it, minValue, true) < 0) { + minValue = it; + } + } + if (minValue.isNone()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + return AqlValue$(minValue); } //////////////////////////////////////////////////////////////////////////////// @@ -2710,6 +2914,10 @@ AqlValue Functions::Min(arangodb::aql::Query* query, AqlValue Functions::Max(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MaxVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -2747,6 +2955,33 @@ AqlValue Functions::Max(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::MaxVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "MAX", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + VPackSlice maxValue; + for (auto const& it : VPackArrayIterator(value)) { + if (maxValue.isNone() || arangodb::basics::VelocyPackHelper::compare(it, maxValue, true) > 0) { + maxValue = it; + } + } + if (maxValue.isNone()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + return AqlValue$(maxValue); } //////////////////////////////////////////////////////////////////////////////// @@ -2756,6 +2991,10 @@ AqlValue Functions::Max(arangodb::aql::Query* query, AqlValue Functions::Sum(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(SumVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -2795,6 +3034,45 @@ AqlValue Functions::Sum(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::SumVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "SUM", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double sum = 0.0; + for (auto const& it : VPackArrayIterator(value)) { + if (it.isNull()) { + continue; + } + if (!it.isNumber()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + double const number = it.getNumericValue(); + + if (!std::isnan(number) && number != HUGE_VAL && number != -HUGE_VAL) { + sum += number; + } + } + std::shared_ptr b = query->getSharedBuilder(); + if (!std::isnan(sum) && sum != HUGE_VAL && sum != -HUGE_VAL) { + b->add(VPackValue(sum)); + } else { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2804,6 +3082,10 @@ AqlValue Functions::Sum(arangodb::aql::Query* query, AqlValue Functions::Average(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AverageVPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); if (!value.isArray()) { @@ -2844,6 +3126,51 @@ AqlValue Functions::Average(arangodb::aql::Query* query, } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::AverageVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "AVERAGE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double sum = 0.0; + size_t count = 0; + for (auto const& v : VPackArrayIterator(value)) { + if (v.isNull()) { + continue; + } + if (!v.isNumber()) { + RegisterWarning(query, "AVERAGE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + // got a numeric value + double const number = v.getNumericValue(); + + if (!std::isnan(number) && number != HUGE_VAL && number != -HUGE_VAL) { + sum += number; + ++count; + } + } + + std::shared_ptr b = query->getSharedBuilder(); + if (count > 0 && !std::isnan(sum) && sum != HUGE_VAL && sum != -HUGE_VAL) { + b->add(VPackValue(sum / static_cast(count))); + } else { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -2875,6 +3202,34 @@ AqlValue Functions::Md5(arangodb::aql::Query* query, return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, hex, 32)); } +AqlValue$ Functions::Md5VPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + AppendAsString(adapter, value); + + // create md5 + char hash[17]; + char* p = &hash[0]; + size_t length; + + arangodb::rest::SslInterface::sslMD5(buffer.c_str(), buffer.length(), p, + length); + + // as hex + char hex[33]; + p = &hex[0]; + + arangodb::rest::SslInterface::sslHEX(hash, 16, p, length); + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(std::string(hex, 32))); + return AqlValue$(b.get()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief function SHA1 //////////////////////////////////////////////////////////////////////////////// @@ -2882,6 +3237,10 @@ AqlValue Functions::Md5(arangodb::aql::Query* query, AqlValue Functions::Sha1(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(Sha1VPack(query, trx, tmp)); +#else auto value = ExtractFunctionParameter(trx, parameters, 0, false); arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); @@ -2902,6 +3261,36 @@ AqlValue Functions::Sha1(arangodb::aql::Query* query, arangodb::rest::SslInterface::sslHEX(hash, 20, p, length); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, hex, 40)); +#endif +} + +AqlValue$ Functions::Sha1VPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + auto value = ExtractFunctionParameter(trx, parameters, 0); + + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + + AppendAsString(adapter, value); + + // create sha1 + char hash[21]; + char* p = &hash[0]; + size_t length; + + arangodb::rest::SslInterface::sslSHA1(buffer.c_str(), buffer.length(), p, + length); + + // as hex + char hex[41]; + p = &hex[0]; + + arangodb::rest::SslInterface::sslHEX(hash, 20, p, length); + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(std::string(hex, 40))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 78caa23849..29ee61593d 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -279,6 +279,26 @@ struct Functions { 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&); }; } } diff --git a/js/server/tests/aql/aql-functions.js b/js/server/tests/aql/aql-functions.js index 79b613deb8..97b1ff87ca 100644 --- a/js/server/tests/aql/aql-functions.js +++ b/js/server/tests/aql/aql-functions.js @@ -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()); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/js/server/tests/aql/aql-operators.js b/js/server/tests/aql/aql-operators.js index 44d5ba13f0..826f812f82 100644 --- a/js/server/tests/aql/aql-operators.js +++ b/js/server/tests/aql/aql-operators.js @@ -645,10 +645,13 @@ function ahuacatlOperatorsTestSuite () { {ex: null, val: "{ 'a' : [ ], 'b' : [ ] }"} ] values.forEach(function(v) { + // double precission check for e=0.0001 var q = `RETURN TO_NUMBER(${v.val})`; - assertEqual(v.ex, db._query(q).next(), q); - var q = `RETURN NOOPT(TO_NUMBER(${v.val}))`; - assertEqual(v.ex, db._query(q).next(), q); + var diff = db._query(q).next() - v.ex; + assertTrue(diff < 0.0001, q); + q = `RETURN NOOPT(TO_NUMBER(${v.val}))`; + diff = db._query(q).next() - v.ex; + assertTrue(diff < 0.0001, q); }); }, diff --git a/lib/Basics/VelocyPackHelper.cpp b/lib/Basics/VelocyPackHelper.cpp index 125aa002df..ca506e7e53 100644 --- a/lib/Basics/VelocyPackHelper.cpp +++ b/lib/Basics/VelocyPackHelper.cpp @@ -37,11 +37,10 @@ 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; +} static int TypeWeight(VPackSlice const& slice) { switch (slice.type()) { diff --git a/lib/Basics/VelocyPackHelper.h b/lib/Basics/VelocyPackHelper.h index f7bcefa24a..b4ad7dfcbe 100644 --- a/lib/Basics/VelocyPackHelper.h +++ b/lib/Basics/VelocyPackHelper.h @@ -38,6 +38,10 @@ class VelocyPackHelper { ~VelocyPackHelper() = delete; public: + struct AttributeSorter { + bool operator()(std::string const& l, std::string const& r) const; + }; + ////////////////////////////////////////////////////////////////////////////// /// @brief returns a numeric value ////////////////////////////////////////////////////////////////////////////// From edf7f6b9d90b781e492e553997b73d3e57584f12 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 4 Feb 2016 15:23:26 +0100 Subject: [PATCH 14/50] Further implementation of AQL functions for VPack. UNIQUE UNIQUE_SORTED UNION UNION_DISTINCT --- arangod/Aql/Functions.cpp | 212 +++++++++++++++++++++++ arangod/Aql/Functions.h | 10 ++ js/common/tests/shell/shell-statement.js | 9 +- lib/Basics/VelocyPackHelper.cpp | 8 + lib/Basics/VelocyPackHelper.h | 27 +++ 5 files changed, 265 insertions(+), 1 deletion(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 10e9cce1e3..30392c899c 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -3300,6 +3300,10 @@ AqlValue$ Functions::Sha1VPack(arangodb::aql::Query* query, AqlValue Functions::Unique(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UniqueVPack(query, trx, tmp)); +#else if (parameters.size() != 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNIQUE", (int)1, @@ -3347,6 +3351,50 @@ AqlValue Functions::Unique(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UniqueVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNIQUE", (int)1, + (int)1); + } + + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "UNIQUE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_set + values(512, arangodb::basics::VelocyPackHelper::VPackHash(), + arangodb::basics::VelocyPackHelper::VPackEqual()); + + for (auto const& s : VPackArrayIterator(value)) { + if (!s.isNone()) { + values.emplace(s); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : values) { + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3356,6 +3404,10 @@ AqlValue Functions::Unique(arangodb::aql::Query* query, AqlValue Functions::SortedUnique(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(SortedUniqueVPack(query, trx, tmp)); +#else if (parameters.size() != 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SORTED_UNIQUE", @@ -3406,6 +3458,45 @@ AqlValue Functions::SortedUnique(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::SortedUniqueVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SORTED_UNIQUE", + (int)1, (int)1); + } + + auto const value = ExtractFunctionParameter(trx, parameters, 0); + + if (!value.isArray()) { + // not an array + // this is an internal function - do NOT issue a warning here + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::set> values; + for (auto const& it : VPackArrayIterator(value)) { + if (!it.isNone()) { + values.insert(it); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : values) { + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3415,6 +3506,10 @@ AqlValue Functions::SortedUnique(arangodb::aql::Query* query, AqlValue Functions::Union(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnionVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -3470,6 +3565,57 @@ AqlValue Functions::Union(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnionVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNION", (int)2, + (int)Function::MaxArguments); + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (size_t i = 0; i < n; ++i) { + auto value = ExtractFunctionParameter(trx, parameters, i); + + if (!value.isArray()) { + // not an array + RegisterInvalidArgumentWarning(query, "UNION"); + b->clear(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + // this passes ownership for the JSON contens into result + for (auto const& it : VPackArrayIterator(value)) { + b->add(it); + TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + } + } + } catch (arangodb::basics::Exception const& e) { + // Rethrow arangodb Errors + throw e; + } catch (std::exception const& e) { + // All other exceptions are OUT_OF_MEMORY + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + TRI_IF_FAILURE("AqlFunctions::OutOfMemory3") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3479,6 +3625,10 @@ AqlValue Functions::Union(arangodb::aql::Query* query, AqlValue Functions::UnionDistinct(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnionDistinctVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -3560,6 +3710,68 @@ AqlValue Functions::UnionDistinct(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif +} + +AqlValue$ Functions::UnionDistinctVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNION_DISTINCT", + (int)2, (int)Function::MaxArguments); + } + + std::unordered_set + values(512, arangodb::basics::VelocyPackHelper::VPackHash(), + arangodb::basics::VelocyPackHelper::VPackEqual()); + + + for (size_t i = 0; i < n; ++i) { + auto value = ExtractFunctionParameter(trx, parameters, i); + + if (!value.isArray()) { + // not an array + RegisterInvalidArgumentWarning(query, "UNION_DISTINCT"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + for (auto const& v : VPackArrayIterator(value)) { + if (values.find(v) == values.end()) { + TRI_IF_FAILURE("AqlFunctions::OutOfMemory1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + values.emplace(v); + } + } + } + + std::shared_ptr b = query->getSharedBuilder(); + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : values) { + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory3") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 29ee61593d..4ae6916ad0 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -299,6 +299,16 @@ struct Functions { 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&); }; } } diff --git a/js/common/tests/shell/shell-statement.js b/js/common/tests/shell/shell-statement.js index 13a6f39882..4734e73391 100644 --- a/js/common/tests/shell/shell-statement.js +++ b/js/common/tests/shell/shell-statement.js @@ -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); } }, diff --git a/lib/Basics/VelocyPackHelper.cpp b/lib/Basics/VelocyPackHelper.cpp index ca506e7e53..d167b09714 100644 --- a/lib/Basics/VelocyPackHelper.cpp +++ b/lib/Basics/VelocyPackHelper.cpp @@ -42,6 +42,14 @@ bool VelocyPackHelper::AttributeSorter::operator()(std::string const& l, 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) { switch (slice.type()) { case VPackValueType::Bool: diff --git a/lib/Basics/VelocyPackHelper.h b/lib/Basics/VelocyPackHelper.h index b4ad7dfcbe..4b79b34dfd 100644 --- a/lib/Basics/VelocyPackHelper.h +++ b/lib/Basics/VelocyPackHelper.h @@ -38,6 +38,33 @@ 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 + 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; }; From 96b75d373331168a03393aecc846f377339329d3 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Fri, 5 Feb 2016 08:45:20 +0100 Subject: [PATCH 15/50] Added a VPack Implementation for AQL Neighbors. This involved modification of Traverser and ExampleMather to understand VPack as well --- arangod/Aql/Functions.cpp | 500 +++++++++++++++++++++++++---- arangod/Aql/Functions.h | 10 + arangod/V8Server/V8Traverser.cpp | 16 + arangod/V8Server/V8Traverser.h | 8 + arangod/VocBase/ExampleMatcher.cpp | 124 +++++++ arangod/VocBase/ExampleMatcher.h | 11 + 6 files changed, 605 insertions(+), 64 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 30392c899c..78a76242dc 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -795,6 +795,49 @@ static inline Json ExpandShapedJson(VocShaper* shaper, return json; } + +static inline void ExpandShapedJson(VocShaper* shaper, + CollectionNameResolver const* resolver, + TRI_voc_cid_t const& cid, + TRI_doc_mptr_t const* mptr, + VPackBuilder& b) { + VPackObjectBuilder guard(&b); + TRI_df_marker_t const* marker = + static_cast(mptr->getDataPtr()); + + TRI_shaped_json_t shaped; + TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, marker); + std::shared_ptr tmp = TRI_VelocyPackShapedJson(shaper, &shaped); + // Copy the shaped into our local builder + for (auto const& it : VPackObjectIterator(tmp->slice())) { + b.add(it.key.copyString(), it.value); + } + + char const* key = TRI_EXTRACT_MARKER_KEY(marker); + std::string id(resolver->getCollectionName(cid)); + id.push_back('/'); + id.append(key); + b.add(TRI_VOC_ATTRIBUTE_ID, VPackValue(id)); + b.add(TRI_VOC_ATTRIBUTE_REV, + VPackValue(std::to_string(TRI_EXTRACT_MARKER_RID(marker)))); + b.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(key)); + + if (TRI_IS_EDGE_MARKER(marker)) { + std::string from(resolver->getCollectionNameCluster( + TRI_EXTRACT_MARKER_FROM_CID(marker))); + from.push_back('/'); + from.append(TRI_EXTRACT_MARKER_FROM_KEY(marker)); + b.add(TRI_VOC_ATTRIBUTE_FROM, VPackValue(from)); + + std::string to( + resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(marker))); + + to.push_back('/'); + to.append(TRI_EXTRACT_MARKER_TO_KEY(marker)); + b.add(TRI_VOC_ATTRIBUTE_TO, VPackValue(to)); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief Reads a document by cid and key /// Also lazy locks the collection. @@ -1042,6 +1085,146 @@ static AqlValue$ MergeParameters(arangodb::aql::Query* query, return AqlValue$(b); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms VertexId to Json +//////////////////////////////////////////////////////////////////////////////// + +static Json VertexIdToJson(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + VertexId const& id) { + auto collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), id.cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, id.key); + + if (res != TRI_ERROR_NO_ERROR) { + if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { + return Json(Json::Null); + } + THROW_ARANGO_EXCEPTION(res); + } + + return ExpandShapedJson(collection->_collection->_collection->getShaper(), + resolver, id.cid, &mptr); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms VertexId to VelocyPack +//////////////////////////////////////////////////////////////////////////////// + +static void VertexIdToVPack(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + VertexId const& id, + VPackBuilder& b) { + auto collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), id.cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(id.cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, id.key); + + if (res != TRI_ERROR_NO_ERROR) { + if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { + b.add(VPackValue(VPackValueType::Null)); + return; + } + THROW_ARANGO_EXCEPTION(res); + } + + ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, + id.cid, &mptr, b); +} + + + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms VertexId to std::string +//////////////////////////////////////////////////////////////////////////////// + +static std::string VertexIdToString(CollectionNameResolver const* resolver, + VertexId const& id) { + return resolver->getCollectionName(id.cid) + "/" + std::string(id.key); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Transforms an unordered_map to AQL json values +//////////////////////////////////////////////////////////////////////////////// + +static AqlValue VertexIdsToAqlValue(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + std::unordered_set& ids, + bool includeData = false) { + auto result = std::make_unique(Json::Array, ids.size()); + + if (includeData) { + for (auto& it : ids) { + result->add(Json(VertexIdToJson(trx, resolver, it))); + } + } else { + for (auto& it : ids) { + result->add(Json(VertexIdToString(resolver, it))); + } + } + + AqlValue v(result.get()); + result.release(); + + return v; +} + +static AqlValue$ VertexIdsToAqlValueVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, std::unordered_set& ids, + bool includeData = false) { + std::shared_ptr result = query->getSharedBuilder(); + { + VPackArrayBuilder b(result.get()); + if (includeData) { + for (auto& it : ids) { + VertexIdToVPack(trx, resolver, it, *result); + } + } else { + for (auto& it : ids) { + result->add(VPackValue(VertexIdToString(resolver, it))); + } + } + } + + return AqlValue$(result.get()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief called before a query starts /// has the chance to set up any thread-local storage @@ -3781,6 +3964,10 @@ AqlValue$ Functions::UnionDistinctVPack(arangodb::aql::Query* query, AqlValue Functions::Intersection(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IntersectionVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -3887,81 +4074,77 @@ AqlValue Functions::Intersection(arangodb::aql::Query* query, auto jr = new Json(TRI_UNKNOWN_MEM_ZONE, result.get()); result.release(); return AqlValue(jr); +#endif } -//////////////////////////////////////////////////////////////////////////////// -/// @brief Transforms VertexId to Json -//////////////////////////////////////////////////////////////////////////////// -static Json VertexIdToJson(arangodb::AqlTransaction* trx, - CollectionNameResolver const* resolver, - VertexId const& id) { - auto collection = trx->trxCollection(id.cid); +AqlValue$ Functions::IntersectionVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); - if (collection == nullptr) { - int res = TRI_AddCollectionTransaction(trx->getInternals(), id.cid, - TRI_TRANSACTION_READ, - trx->nestingLevel(), true, true); - if (res != TRI_ERROR_NO_ERROR) { - THROW_ARANGO_EXCEPTION(res); - } - - TRI_EnsureCollectionsTransaction(trx->getInternals()); - collection = trx->trxCollection(id.cid); - - if (collection == nullptr) { - THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, - "collection is a nullptr"); - } + if (n < 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "INTERSECTION", + (int)2, (int)Function::MaxArguments); } - TRI_doc_mptr_copy_t mptr; - int res = trx->readSingle(collection, &mptr, id.key); + std::unordered_map + values(512, arangodb::basics::VelocyPackHelper::VPackHash(), + arangodb::basics::VelocyPackHelper::VPackEqual()); - if (res != TRI_ERROR_NO_ERROR) { - if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { - return Json(Json::Null); + std::shared_ptr b = query->getSharedBuilder(); + + for (size_t i = 0; i < n; ++i) { + auto value = ExtractFunctionParameter(trx, parameters, i); + + if (!value.isArray()) { + // not an array + RegisterWarning(query, "INTERSECTION", TRI_ERROR_QUERY_ARRAY_EXPECTED); + b->clear(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } - THROW_ARANGO_EXCEPTION(res); + + for (auto const& it : VPackArrayIterator(value)) { + if (i == 0) { + // round one + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + values.emplace(it, 1); + } else { + // check if we have seen the same element before + auto found = values.find(it); + if (found != values.end()) { + // already seen + TRI_ASSERT((*found).second > 0); + ++((*found).second); + } + } + } + + TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + VPackArrayBuilder guard(b.get()); + for (auto& it : values) { + if (it.second == n) { + b->add(it.first); + } + } + values.clear(); } - return ExpandShapedJson(collection->_collection->_collection->getShaper(), - resolver, id.cid, &mptr); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Transforms VertexId to std::string -//////////////////////////////////////////////////////////////////////////////// - -static std::string VertexIdToString(CollectionNameResolver const* resolver, - VertexId const& id) { - return resolver->getCollectionName(id.cid) + "/" + std::string(id.key); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief Transforms an unordered_map to AQL json values -//////////////////////////////////////////////////////////////////////////////// - -static AqlValue VertexIdsToAqlValue(arangodb::AqlTransaction* trx, - CollectionNameResolver const* resolver, - std::unordered_set& ids, - bool includeData = false) { - auto result = std::make_unique(Json::Array, ids.size()); - - if (includeData) { - for (auto& it : ids) { - result->add(Json(VertexIdToJson(trx, resolver, it))); - } - } else { - for (auto& it : ids) { - result->add(Json(VertexIdToString(resolver, it))); - } + TRI_IF_FAILURE("AqlFunctions::OutOfMemory3") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } - - AqlValue v(result.get()); - result.release(); - - return v; + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -3971,6 +4154,10 @@ static AqlValue VertexIdsToAqlValue(arangodb::AqlTransaction* trx, AqlValue Functions::Neighbors(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NeighborsVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); arangodb::traverser::NeighborsOptions opts; @@ -4163,8 +4350,193 @@ AqlValue Functions::Neighbors(arangodb::aql::Query* query, TRI_RunNeighborsSearch(edgeCollectionInfos, opts, neighbors); return VertexIdsToAqlValue(trx, resolver, neighbors, includeData); +#endif } +AqlValue$ Functions::NeighborsVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + arangodb::traverser::NeighborsOptions opts; + + if (n < 4 || n > 6) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEIGHBORS", (int)4, + (int)6); + } + + auto resolver = trx->resolver(); + + VPackSlice vertexCol = ExtractFunctionParameter(trx, parameters, 0); + + if (!vertexCol.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + std::string vColName = vertexCol.copyString(); + + VPackSlice edgeCol = ExtractFunctionParameter(trx, parameters, 1); + if (!edgeCol.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + std::string eColName = edgeCol.copyString(); + + VPackSlice vertexInfo = ExtractFunctionParameter(trx, parameters, 2); + std::string vertexId; + bool splitCollection = false; + if (vertexInfo.isString()) { + vertexId = vertexInfo.copyString(); + if (vertexId.find("/") != std::string::npos) { + splitCollection = true; + } + } else if (vertexInfo.isObject()) { + if (!vertexInfo.hasKey("_id")) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + VPackSlice idSlice = vertexInfo.get("_id"); + if (!idSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + vertexId = idSlice.copyString(); + splitCollection = true; + } else { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + + if (splitCollection) { + size_t split; + char const* str = vertexId.c_str(); + + if (!TRI_ValidateDocumentIdKeyGenerator(str, &split)) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD); + } + + std::string const collectionName = vertexId.substr(0, split); + if (collectionName.compare(vColName) != 0) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_GRAPH_INVALID_PARAMETER, + "specified vertex collection '%s' does " + "not match start vertex collection '%s'", + vColName.c_str(), collectionName.c_str()); + } + auto coli = resolver->getCollectionStruct(collectionName); + + if (coli == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", collectionName.c_str()); + } + + VertexId v(coli->_cid, const_cast(str + split + 1)); + opts.start = v; + } else { + VertexId v(resolver->getCollectionId(vColName), vertexId.c_str()); + opts.start = v; + } + + VPackSlice direction = ExtractFunctionParameter(trx, parameters, 3); + if (!direction.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + { + std::string const dir = direction.copyString(); + if (dir.compare("outbound") == 0) { + opts.direction = TRI_EDGE_OUT; + } else if (dir.compare("inbound") == 0) { + opts.direction = TRI_EDGE_IN; + } else if (dir.compare("any") == 0) { + opts.direction = TRI_EDGE_ANY; + } else { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + } + + bool includeData = false; + + if (n > 5) { + auto options = ExtractFunctionParameter(trx, parameters, 5); + if (!options.isObject()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEIGHBORS"); + } + includeData = arangodb::basics::VelocyPackHelper::getBooleanValue( + options, "includeData", false); + opts.minDepth = + arangodb::basics::VelocyPackHelper::getNumericValue( + options, "minDepth", 1); + if (opts.minDepth == 0) { + opts.maxDepth = + arangodb::basics::VelocyPackHelper::getNumericValue( + options, "maxDepth", 1); + } else { + opts.maxDepth = + arangodb::basics::VelocyPackHelper::getNumericValue( + options, "maxDepth", opts.minDepth); + } + } + + TRI_voc_cid_t eCid = resolver->getCollectionId(eColName); + + { + // ensure the collection is loaded + auto collection = trx->trxCollection(eCid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), eCid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(eCid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + } + + // Function to return constant distance + auto wc = [](TRI_doc_mptr_copy_t&) -> double { return 1; }; + + auto eci = std::make_unique( + trx, eCid, trx->documentCollection(eCid), wc); + TRI_IF_FAILURE("EdgeCollectionInfoOOM1") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + if (n > 4) { + auto edgeExamples = ExtractFunctionParameter(trx, parameters, 4); + if (!(edgeExamples.isArray() && edgeExamples.length() == 0)) { + opts.addEdgeFilter(edgeExamples, eci->getShaper(), eCid, resolver); + } + } + + std::vector edgeCollectionInfos; + arangodb::basics::ScopeGuard guard{[]() -> void {}, + [&edgeCollectionInfos]() -> void { + for (auto& p : edgeCollectionInfos) { + delete p; + } + }}; + edgeCollectionInfos.emplace_back(eci.get()); + eci.release(); + TRI_IF_FAILURE("EdgeCollectionInfoOOM2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + + std::unordered_set neighbors; + TRI_RunNeighborsSearch(edgeCollectionInfos, opts, neighbors); + + return VertexIdsToAqlValueVPack(query, trx, resolver, neighbors, includeData); +} //////////////////////////////////////////////////////////////////////////////// /// @brief function NEAR //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 4ae6916ad0..e99c733a03 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -309,6 +309,16 @@ struct Functions { 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&); }; } } diff --git a/arangod/V8Server/V8Traverser.cpp b/arangod/V8Server/V8Traverser.cpp index d39358373f..7826ef95b9 100644 --- a/arangod/V8Server/V8Traverser.cpp +++ b/arangod/V8Server/V8Traverser.cpp @@ -296,6 +296,22 @@ 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)); + } +} + + + //////////////////////////////////////////////////////////////////////////////// /// @brief Checks if an edge matches to given examples //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/V8Server/V8Traverser.h b/arangod/V8Server/V8Traverser.h index f26beda37c..0873ef8a8b 100644 --- a/arangod/V8Server/V8Traverser.h +++ b/arangod/V8Server/V8Traverser.h @@ -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 const& example, arangodb::ExplicitTransaction* trx, diff --git a/arangod/VocBase/ExampleMatcher.cpp b/arangod/VocBase/ExampleMatcher.cpp index 9bfec55842..fe0642df89 100644 --- a/arangod/VocBase/ExampleMatcher.cpp +++ b/arangod/VocBase/ExampleMatcher.cpp @@ -31,6 +31,9 @@ #include "V8Server/v8-vocbaseprivate.h" #include "VocBase/VocShaper.h" +#include +#include + 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(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,48 @@ ExampleMatcher::ExampleMatcher(TRI_json_t const* example, VocShaper* shaper, } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Constructor using a VelocyPack object +//////////////////////////////////////////////////////////////////////////////// + +ExampleMatcher::ExampleMatcher(VPackSlice const& example, VocShaper* shaper, + CollectionNameResolver const* resolver) + : _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; + 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 //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/VocBase/ExampleMatcher.h b/arangod/VocBase/ExampleMatcher.h index 388af5fb2d..c123be3afa 100644 --- a/arangod/VocBase/ExampleMatcher.h +++ b/arangod/VocBase/ExampleMatcher.h @@ -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 const& example, v8::Handle const& names, size_t& n, @@ -75,6 +83,9 @@ 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); + ~ExampleMatcher() { cleanup(); } bool matches(TRI_voc_cid_t cid, TRI_doc_mptr_t const* mptr) const; From ba9d3566e9de038f06c610aabdeb593662cecb75 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Fri, 5 Feb 2016 10:22:15 +0100 Subject: [PATCH 16/50] Implemented Geo Functions in VPack variant. Also simplified the code. --- arangod/Aql/Functions.cpp | 337 +++++++++++++++++++++++++++++++++++--- 1 file changed, 316 insertions(+), 21 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 78a76242dc..31c6157e2d 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -795,13 +795,13 @@ static inline Json ExpandShapedJson(VocShaper* shaper, return json; } +static inline void ExpandShapedJson( + VocShaper* shaper, CollectionNameResolver const* resolver, + TRI_voc_cid_t const& cid, TRI_doc_mptr_t const* mptr, VPackBuilder& b, + bool keepTopLevelOpen = false, + std::unordered_set const& forbidden = {}) { + b.add(VPackValue(VPackValueType::Object)); -static inline void ExpandShapedJson(VocShaper* shaper, - CollectionNameResolver const* resolver, - TRI_voc_cid_t const& cid, - TRI_doc_mptr_t const* mptr, - VPackBuilder& b) { - VPackObjectBuilder guard(&b); TRI_df_marker_t const* marker = static_cast(mptr->getDataPtr()); @@ -810,31 +810,47 @@ static inline void ExpandShapedJson(VocShaper* shaper, std::shared_ptr tmp = TRI_VelocyPackShapedJson(shaper, &shaped); // Copy the shaped into our local builder for (auto const& it : VPackObjectIterator(tmp->slice())) { - b.add(it.key.copyString(), it.value); + std::string key = it.key.copyString(); + if (forbidden.count(key) == 0) { + b.add(it.key.copyString(), it.value); + } } char const* key = TRI_EXTRACT_MARKER_KEY(marker); std::string id(resolver->getCollectionName(cid)); id.push_back('/'); id.append(key); - b.add(TRI_VOC_ATTRIBUTE_ID, VPackValue(id)); - b.add(TRI_VOC_ATTRIBUTE_REV, - VPackValue(std::to_string(TRI_EXTRACT_MARKER_RID(marker)))); - b.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(key)); + if (forbidden.count(TRI_VOC_ATTRIBUTE_ID) == 0) { + b.add(TRI_VOC_ATTRIBUTE_ID, VPackValue(id)); + } + if (forbidden.count(TRI_VOC_ATTRIBUTE_REV) == 0) { + b.add(TRI_VOC_ATTRIBUTE_REV, + VPackValue(std::to_string(TRI_EXTRACT_MARKER_RID(marker)))); + } + if (forbidden.count(TRI_VOC_ATTRIBUTE_KEY) == 0) { + b.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(key)); + } if (TRI_IS_EDGE_MARKER(marker)) { - std::string from(resolver->getCollectionNameCluster( - TRI_EXTRACT_MARKER_FROM_CID(marker))); - from.push_back('/'); - from.append(TRI_EXTRACT_MARKER_FROM_KEY(marker)); - b.add(TRI_VOC_ATTRIBUTE_FROM, VPackValue(from)); + if (forbidden.count(TRI_VOC_ATTRIBUTE_FROM) == 0) { + std::string from(resolver->getCollectionNameCluster( + TRI_EXTRACT_MARKER_FROM_CID(marker))); + from.push_back('/'); + from.append(TRI_EXTRACT_MARKER_FROM_KEY(marker)); + b.add(TRI_VOC_ATTRIBUTE_FROM, VPackValue(from)); + } - std::string to( - resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(marker))); + if (forbidden.count(TRI_VOC_ATTRIBUTE_TO) == 0) { + std::string to( + resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(marker))); - to.push_back('/'); - to.append(TRI_EXTRACT_MARKER_TO_KEY(marker)); - b.add(TRI_VOC_ATTRIBUTE_TO, VPackValue(to)); + to.push_back('/'); + to.append(TRI_EXTRACT_MARKER_TO_KEY(marker)); + b.add(TRI_VOC_ATTRIBUTE_TO, VPackValue(to)); + } + } + if (!keepTopLevelOpen) { + b.close(); } } @@ -1225,6 +1241,142 @@ static AqlValue$ VertexIdsToAqlValueVPack( return AqlValue$(result.get()); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Load geoindex for collection name +//////////////////////////////////////////////////////////////////////////////// + +static arangodb::Index* getGeoIndex(arangodb::AqlTransaction* trx, + TRI_voc_cid_t const& cid, + std::string const& colName, + VocShaper*& shaper) { + auto collection = trx->trxCollection(cid); + + // ensure the collection is loaded + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION_FORMAT(res, "'%s'", colName.c_str()); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", colName.c_str()); + } + } + + auto document = trx->documentCollection(cid); + + if (document == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + + arangodb::Index* index = nullptr; + + for (auto const& idx : document->allIndexes()) { + if (idx->type() == arangodb::Index::TRI_IDX_TYPE_GEO1_INDEX || + idx->type() == arangodb::Index::TRI_IDX_TYPE_GEO2_INDEX) { + index = idx; + break; + } + } + + if (index == nullptr) { + THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_GEO_INDEX_MISSING, + colName.c_str()); + } + + if (trx->orderDitch(collection) == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + shaper = collection->_collection->_collection->getShaper(); + return index; +} + +static AqlValue$ buildGeoResult(arangodb::aql::Query* query, + GeoCoordinates* cors, VocShaper* shaper, + CollectionNameResolver const* resolver, + TRI_voc_cid_t const& cid, + std::string const& attributeName) { + if (cors == nullptr) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + size_t const nCoords = cors->length; + if (nCoords == 0) { + GeoIndex_CoordinatesFree(cors); + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + struct geo_coordinate_distance_t { + geo_coordinate_distance_t(double distance, TRI_doc_mptr_t const* mptr) + : _distance(distance), _mptr(mptr) {} + + double _distance; + TRI_doc_mptr_t const* _mptr; + }; + + std::vector distances; + + try { + distances.reserve(nCoords); + + for (size_t i = 0; i < nCoords; ++i) { + distances.emplace_back(geo_coordinate_distance_t( + cors->distances[i], + static_cast(cors->coordinates[i].data))); + } + } catch (...) { + GeoIndex_CoordinatesFree(cors); + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + GeoIndex_CoordinatesFree(cors); + + // sort result by distance + std::sort(distances.begin(), distances.end(), + [](geo_coordinate_distance_t const& left, + geo_coordinate_distance_t const& right) { + return left._distance < right._distance; + }); + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + std::unordered_set forbidden; + bool saveAttr = !attributeName.empty(); + if (saveAttr) { + forbidden.emplace(attributeName); + } + + for (auto& it : distances) { + ExpandShapedJson(shaper, resolver, cid, it._mptr, *b, + saveAttr, forbidden); + if (saveAttr) { + // The Object is Open and attributeName is not set + b->add(attributeName, VPackValue(it._distance)); + b->close(); + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief called before a query starts /// has the chance to set up any thread-local storage @@ -4537,6 +4689,7 @@ AqlValue$ Functions::NeighborsVPack(arangodb::aql::Query* query, return VertexIdsToAqlValueVPack(query, trx, resolver, neighbors, includeData); } + //////////////////////////////////////////////////////////////////////////////// /// @brief function NEAR //////////////////////////////////////////////////////////////////////////////// @@ -4544,6 +4697,10 @@ AqlValue$ Functions::NeighborsVPack(arangodb::aql::Query* query, AqlValue Functions::Near(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NearVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 3 || n > 5) { @@ -4714,6 +4871,79 @@ AqlValue Functions::Near(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, array.steal())); +#endif +} + +AqlValue$ Functions::NearVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 3 || n > 5) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "NEAR", (int)3, + (int)5); + } + + auto resolver = trx->resolver(); + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice latitude = ExtractFunctionParameter(trx, parameters, 1); + VPackSlice longitude = ExtractFunctionParameter(trx, parameters, 2); + + if (!latitude.isNumber() || !longitude.isNumber()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + + // extract limit + int64_t limitValue = 100; + + if (n > 3) { + VPackSlice limit = ExtractFunctionParameter(trx, parameters, 3); + + if (limit.isNumber()) { + limitValue = limit.getNumericValue(); + } else if (!limit.isNull()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + } + + std::string attributeName; + if (n > 4) { + // have a distance attribute + VPackSlice distanceAttribute = ExtractFunctionParameter(trx, parameters, 4); + + if (!distanceAttribute.isNull() && !distanceAttribute.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "NEAR"); + } + + if (distanceAttribute.isString()) { + attributeName = distanceAttribute.copyString(); + } + } + + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + VocShaper* shaper = nullptr; + arangodb::Index* index = getGeoIndex(trx, cid, colName, shaper); + + TRI_ASSERT(index != nullptr); + TRI_ASSERT(shaper != nullptr); + + GeoCoordinates* cors = static_cast(index)->nearQuery( + trx, latitude.getNumericValue(), + longitude.getNumericValue(), limitValue); + + return buildGeoResult(query, cors, shaper, resolver, cid, attributeName); } //////////////////////////////////////////////////////////////////////////////// @@ -4723,6 +4953,10 @@ AqlValue Functions::Near(arangodb::aql::Query* query, AqlValue Functions::Within(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(WithinVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 4 || n > 5) { @@ -4879,6 +5113,67 @@ AqlValue Functions::Within(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, array.steal())); +#endif +} + +AqlValue$ Functions::WithinVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 4 || n > 5) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "WITHIN", (int)4, + (int)5); + } + + auto resolver = trx->resolver(); + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "WITHIN"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice latitude = ExtractFunctionParameter(trx, parameters, 1); + VPackSlice longitude = ExtractFunctionParameter(trx, parameters, 2); + VPackSlice radius = ExtractFunctionParameter(trx, parameters, 3); + + if (!latitude.isNumber() || !longitude.isNumber() || !radius.isNumber()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "WITHIN"); + } + + std::string attributeName; + if (n > 4) { + // have a distance attribute + VPackSlice distanceAttribute = ExtractFunctionParameter(trx, parameters, 4); + + if (!distanceAttribute.isNull() && !distanceAttribute.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "WITHIN"); + } + + if (distanceAttribute.isString()) { + attributeName = distanceAttribute.copyString(); + } + } + + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + VocShaper* shaper = nullptr; + arangodb::Index* index = getGeoIndex(trx, cid, colName, shaper); + + TRI_ASSERT(index != nullptr); + TRI_ASSERT(shaper != nullptr); + + GeoCoordinates* cors = static_cast(index)->withinQuery( + trx, latitude.getNumericValue(), + longitude.getNumericValue(), radius.getNumericValue()); + + return buildGeoResult(query, cors, shaper, resolver, cid, attributeName); } //////////////////////////////////////////////////////////////////////////////// From 17abd440aaeb9afaca5c814c4303b621ac02396e Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Fri, 5 Feb 2016 13:55:18 +0100 Subject: [PATCH 17/50] Further implementation of AQL Functions VPack variants. --- arangod/Aql/Functions.cpp | 269 ++++++++++++++++++++++++++++++++++---- arangod/Aql/Functions.h | 13 ++ 2 files changed, 258 insertions(+), 24 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 31c6157e2d..4a8cf23121 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -1377,6 +1377,37 @@ static AqlValue$ buildGeoResult(arangodb::aql::Query* query, return AqlValue$(b.get()); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief internal recursive flatten helper +//////////////////////////////////////////////////////////////////////////////// + +static void FlattenList(Json array, size_t maxDepth, size_t curDepth, + Json& result) { + size_t elementCount = array.size(); + for (size_t i = 0; i < elementCount; ++i) { + Json tmp = array.at(i); + if (tmp.isArray() && curDepth < maxDepth) { + FlattenList(tmp, maxDepth, curDepth + 1, result); + } else { + // Transfer the content of tmp into the result + result.transfer(tmp.json()); + } + } +} + +static void FlattenList(VPackSlice const& array, size_t maxDepth, + size_t curDepth, VPackBuilder& result) { + TRI_ASSERT(result.isOpenArray()); + for (auto const& tmp : VPackArrayIterator(array)) { + if (tmp.isArray() && curDepth < maxDepth) { + FlattenList(tmp, maxDepth, curDepth + 1, result); + } else { + // Copy the content of tmp into the result + result.add(tmp); + } + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief called before a query starts /// has the chance to set up any thread-local storage @@ -4275,23 +4306,25 @@ AqlValue$ Functions::IntersectionVPack(arangodb::aql::Query* query, if (found != values.end()) { // already seen TRI_ASSERT((*found).second > 0); - ++((*found).second); + ++(found->second); } } } + } - TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { - THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); - } + TRI_IF_FAILURE("AqlFunctions::OutOfMemory2") { + THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); + } + { VPackArrayBuilder guard(b.get()); - for (auto& it : values) { + for (auto const& it : values) { if (it.second == n) { b->add(it.first); } } - values.clear(); } + values.clear(); TRI_IF_FAILURE("AqlFunctions::OutOfMemory3") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); @@ -5176,24 +5209,6 @@ AqlValue$ Functions::WithinVPack(arangodb::aql::Query* query, return buildGeoResult(query, cors, shaper, resolver, cid, attributeName); } -//////////////////////////////////////////////////////////////////////////////// -/// @brief internal recursive flatten helper -//////////////////////////////////////////////////////////////////////////////// - -static void FlattenList(Json array, size_t maxDepth, size_t curDepth, - Json& result) { - size_t elementCount = array.size(); - for (size_t i = 0; i < elementCount; ++i) { - Json tmp = array.at(i); - if (tmp.isArray() && curDepth < maxDepth) { - FlattenList(tmp, maxDepth, curDepth + 1, result); - } else { - // Transfer the content of tmp into the result - result.transfer(tmp.json()); - } - } -} - //////////////////////////////////////////////////////////////////////////////// /// @brief function FLATTEN //////////////////////////////////////////////////////////////////////////////// @@ -5201,6 +5216,10 @@ static void FlattenList(Json array, size_t maxDepth, size_t curDepth, AqlValue Functions::Flatten(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FlattenVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n == 0 || n > 2) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -5230,6 +5249,48 @@ AqlValue Functions::Flatten(arangodb::aql::Query* query, FlattenList(listJson.copy(), maxDepth, 0, result); return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::FlattenVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n == 0 || n > 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FLATTEN", (int)1, + (int)2); + } + + VPackSlice listSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!listSlice.isArray()) { + RegisterWarning(query, "FLATTEN", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + size_t maxDepth = 1; + if (n == 2) { + VPackSlice maxDepthSlice = ExtractFunctionParameter(trx, parameters, 1); + bool isValid = true; + double tmpMaxDepth = ValueToNumber(maxDepthSlice, isValid); + if (!isValid || tmpMaxDepth < 1) { + maxDepth = 1; + } else { + maxDepth = static_cast(tmpMaxDepth); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + FlattenList(listSlice, maxDepth, 0, *b); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -5239,6 +5300,10 @@ AqlValue Functions::Flatten(arangodb::aql::Query* query, AqlValue Functions::Zip(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ZipVPack(query, trx, tmp)); +#else if (parameters.size() != 2) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ZIP", (int)2, @@ -5265,6 +5330,48 @@ AqlValue Functions::Zip(arangodb::aql::Query* query, result.set(buffer.c_str(), valuesJson.at(i).copy().steal()); } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::ZipVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ZIP", (int)2, + (int)2); + } + + VPackSlice keysSlice = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice valuesSlice = ExtractFunctionParameter(trx, parameters, 1); + + if (!keysSlice.isArray() || !valuesSlice.isArray() || + keysSlice.length() != valuesSlice.length()) { + RegisterWarning(query, "ZIP", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackValueLength n = keysSlice.length(); + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackObjectBuilder guard(b.get()); + + // Buffer will temporarily hold the keys + arangodb::basics::StringBuffer buffer(TRI_UNKNOWN_MEM_ZONE, 24); + arangodb::basics::VPackStringBufferAdapter adapter(buffer.stringBuffer()); + for (VPackValueLength i = 0; i < n; ++i) { + buffer.reset(); + AppendAsString(adapter, keysSlice.at(i)); + b->add(std::string(buffer.c_str(), buffer.length()), valuesSlice.at(i)); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -5274,6 +5381,10 @@ AqlValue Functions::Zip(arangodb::aql::Query* query, AqlValue Functions::ParseIdentifier(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ParseIdentifierVPack(query, trx, tmp)); +#else if (parameters.size() != 1) { THROW_ARANGO_EXCEPTION_PARAMS( TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PARSE_IDENTIFIER", @@ -5304,6 +5415,48 @@ AqlValue Functions::ParseIdentifier(arangodb::aql::Query* query, RegisterWarning(query, "PARSE_IDENTIFIER", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::ParseIdentifierVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PARSE_IDENTIFIER", + (int)1, (int)1); + } + + VPackSlice value = ExtractFunctionParameter(trx, parameters, 0); + std::string identifier; + if (value.isObject() && value.hasKey(TRI_VOC_ATTRIBUTE_ID)) { + identifier = arangodb::basics::VelocyPackHelper::getStringValue( + value, TRI_VOC_ATTRIBUTE_ID, ""); + } else if (value.isString()) { + identifier = value.copyString(); + } + + if (!identifier.empty()) { + std::vector parts = + arangodb::basics::StringUtils::split(identifier, "/"); + if (parts.size() == 2) { + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackObjectBuilder guard(b.get()); + b->add("collection", VPackValue(parts[0])); + b->add("key", VPackValue(parts[1])); + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); + } + } + + RegisterWarning(query, "PARSE_IDENTIFIER", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -5313,6 +5466,10 @@ AqlValue Functions::ParseIdentifier(arangodb::aql::Query* query, AqlValue Functions::Minus(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MinusVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 2) { @@ -5363,6 +5520,70 @@ AqlValue Functions::Minus(arangodb::aql::Query* query, } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::MinusVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 2) { + // The max number is arbitrary + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "MINUS", (int)2, + (int)99999); + } + VPackSlice baseArray = ExtractFunctionParameter(trx, parameters, 0); + + if (!baseArray.isArray()) { + RegisterWarning(query, "MINUS", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::unordered_map contains; + contains.reserve(n); + + // Fill the original map + for (size_t i = 0; i < baseArray.length(); ++i) { + contains.emplace(baseArray.at(i).toJson(), i); + } + + // Iterate through all following parameters and delete found elements from the + // map + for (size_t k = 1; k < n; ++k) { + VPackSlice nextArray = ExtractFunctionParameter(trx, parameters, k); + if (!nextArray.isArray()) { + RegisterWarning(query, "MINUS", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + for (auto const& searchSlice : VPackArrayIterator(nextArray)) { + std::string search = searchSlice.toJson(); + auto find = contains.find(search); + if (find != contains.end()) { + contains.erase(find); + } + } + } + + // We ommit the normalize part from js, cannot occur here + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : contains) { + b->add(baseArray.at(it.second)); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } static void RegisterCollectionInTransaction( diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index e99c733a03..b280513946 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -319,6 +319,19 @@ struct Functions { 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&); }; } } From dcd275181f0787cd2b6273da1575fea46e3882aa Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Fri, 5 Feb 2016 14:37:33 +0100 Subject: [PATCH 18/50] Added VPack Variant of DOCUMENT() --- arangod/Aql/Functions.cpp | 186 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 4a8cf23121..aa974df0e4 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -5694,6 +5694,88 @@ static Json getDocumentByIdentifier(arangodb::AqlTransaction* trx, resolver, cid, &mptr); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to get a document by it's identifier +/// The collection has to be locked by the transaction before +//////////////////////////////////////////////////////////////////////////////// + +static void getDocumentByIdentifier(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + TRI_transaction_collection_t* collection, + TRI_voc_cid_t const& cid, + std::string const& collectionName, + std::string const& identifier, + VPackBuilder& result) { + std::vector parts = + arangodb::basics::StringUtils::split(identifier, "/"); + + TRI_doc_mptr_copy_t mptr; + if (parts.size() == 1) { + int res = trx->readSingle(collection, &mptr, parts[0]); + if (res != TRI_ERROR_NO_ERROR) { + return; + } + } else if (parts.size() == 2) { + if (parts[0] != collectionName) { + // Reqesting an _id that cannot be stored in this collection + return; + } + int res = trx->readSingle(collection, &mptr, parts[1]); + if (res != TRI_ERROR_NO_ERROR) { + return; + } + } else { + return; + } + + ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, + cid, &mptr, result); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief Helper function to get a document by its _id +/// This function will lazy read-lock the collection. +/// this function will not throw if the document or the collection cannot be +/// found +//////////////////////////////////////////////////////////////////////////////// + +static void getDocumentByIdentifier(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + std::string const& identifier, + VPackBuilder& result) { + std::vector parts = + arangodb::basics::StringUtils::split(identifier, "/"); + + if (parts.size() != 2) { + return; + } + std::string collectionName = parts[0]; + TRI_transaction_collection_t* collection = nullptr; + TRI_voc_cid_t cid = 0; + try { + RegisterCollectionInTransaction(trx, collectionName, cid, collection); + } catch (arangodb::basics::Exception const& ex) { + // don't throw if collection is not found + if (ex.code() == TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) { + return; + } + throw; + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, parts[1]); + + if (res != TRI_ERROR_NO_ERROR) { + return; + } + + ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, + cid, &mptr, result); +} + + + + //////////////////////////////////////////////////////////////////////////////// /// @brief function Document //////////////////////////////////////////////////////////////////////////////// @@ -5701,6 +5783,10 @@ static Json getDocumentByIdentifier(arangodb::AqlTransaction* trx, AqlValue Functions::Document(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(DocumentVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 1 || 2 < n) { @@ -5799,6 +5885,106 @@ AqlValue Functions::Document(arangodb::aql::Query* query, } // Id has invalid format return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::DocumentVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 1 || 2 < n) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "DOCUMENT", (int)1, + (int)2); + } + + auto resolver = trx->resolver(); + if (n == 1) { + VPackSlice id = ExtractFunctionParameter(trx, parameters, 0); + std::shared_ptr b = query->getSharedBuilder(); + if (id.isString()) { + std::string identifier = id.copyString(); + getDocumentByIdentifier(trx, resolver, identifier, *b); + if (b->isEmpty()) { + // not found + b->add(VPackValue(VPackValueType::Null)); + } + } else if (id.isArray()) { + VPackArrayBuilder guard(b.get()); + for (auto const& next : VPackArrayIterator(id)) { + try { + if (next.isString()) { + std::string identifier = next.copyString(); + getDocumentByIdentifier(trx, resolver, identifier, *b); + } + } catch (arangodb::basics::Exception const&) { + // Ignore all ArangoDB exceptions here + } + } + } else { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); + } + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + std::string collectionName = collectionSlice.copyString(); + + TRI_transaction_collection_t* collection = nullptr; + TRI_voc_cid_t cid; + bool notFound = false; + + try { + RegisterCollectionInTransaction(trx, collectionName, cid, collection); + } catch (arangodb::basics::Exception const& ex) { + // don't throw if collection is not found + if (ex.code() != TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) { + throw; + } + notFound = true; + } + + VPackSlice id = ExtractFunctionParameter(trx, parameters, 1); + if (id.isString()) { + if (notFound) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::shared_ptr b = query->getSharedBuilder(); + std::string identifier = id.copyString(); + getDocumentByIdentifier(trx, resolver, collection, cid, collectionName, identifier, *b); + if (b->isEmpty()) { + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); + } else if (id.isArray()) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + if (!notFound) { + for (auto const& next : VPackArrayIterator(id)) { + try { + if (next.isString()) { + std::string identifier = next.copyString(); + getDocumentByIdentifier(trx, resolver, collection, cid, collectionName, identifier, *b); + } + } catch (arangodb::basics::Exception const&) { + // Ignore all ArangoDB exceptions here + } + } + } + } + return AqlValue$(b.get()); + } + // Id has invalid format + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// From f5d93fb872e5390916a66e4a164620e85c88550c Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Fri, 5 Feb 2016 16:18:21 +0100 Subject: [PATCH 19/50] Implemented AQL EDGES as a VPack Variant. --- arangod/Aql/Functions.cpp | 269 ++++++++++++++++++++++++++++- arangod/Aql/Functions.h | 2 + arangod/V8Server/V8Traverser.cpp | 3 +- arangod/VocBase/ExampleMatcher.cpp | 9 +- arangod/VocBase/ExampleMatcher.h | 3 +- 5 files changed, 274 insertions(+), 12 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index aa974df0e4..267ad4a3fd 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -892,6 +892,45 @@ static Json ReadDocument(arangodb::AqlTransaction* trx, resolver, cid, &mptr); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief Reads a document by cid and key +/// Also lazy locks the collection. +/// Returns null if the document does not exist +//////////////////////////////////////////////////////////////////////////////// + +static void ReadDocument(arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + TRI_voc_cid_t cid, char const* key, + VPackBuilder& result) { + auto collection = trx->trxCollection(cid); + + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION(res); + } + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, + "collection is a nullptr"); + } + } + + TRI_doc_mptr_copy_t mptr; + int res = trx->readSingle(collection, &mptr, key); + + if (res != TRI_ERROR_NO_ERROR) { + result.add(VPackValue(VPackValueType::Null)); + } else { + ExpandShapedJson(collection->_collection->_collection->getShaper(), + resolver, cid, &mptr, result); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief function to filter the given list of mptr //////////////////////////////////////////////////////////////////////////////// @@ -997,6 +1036,88 @@ static void RequestEdges(arangodb::basics::Json const& vertexJson, } } +static void RequestEdges(VPackSlice const& vertexSlice, + arangodb::AqlTransaction* trx, + CollectionNameResolver const* resolver, + VocShaper* shaper, TRI_voc_cid_t cid, + TRI_document_collection_t* collection, + TRI_edge_direction_e direction, + arangodb::ExampleMatcher const* matcher, + bool includeVertices, VPackBuilder& result) { + std::string vertexId; + if (vertexSlice.isString()) { + vertexId = vertexSlice.copyString(); + } else if (vertexSlice.isObject()) { + vertexId = arangodb::basics::VelocyPackHelper::getStringValue(vertexSlice, + "_id", ""); + } else { + // Nothing to do. + // Return (error for illegal input is thrown outside + return; + } + + std::vector parts = + arangodb::basics::StringUtils::split(vertexId, "/"); + if (parts.size() != 2) { + THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD, + vertexId); + } + + TRI_voc_cid_t startCid = resolver->getCollectionId(parts[0]); + if (startCid == 0) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, "'%s'", + parts[0].c_str()); + } + + char* key = const_cast(parts[1].c_str()); + std::vector edges = TRI_LookupEdgesDocumentCollection( + trx, collection, direction, startCid, key); + FilterDocuments(matcher, cid, edges); + size_t resultCount = edges.size(); + + if (includeVertices) { + for (size_t i = 0; i < resultCount; ++i) { + VPackObjectBuilder guard(&result); + result.add(VPackValue("edge")); + ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result); + char const* targetKey = nullptr; + TRI_voc_cid_t targetCid = 0; + + switch (direction) { + case TRI_EDGE_OUT: + targetKey = TRI_EXTRACT_MARKER_TO_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_TO_CID(&edges[i]); + break; + case TRI_EDGE_IN: + targetKey = TRI_EXTRACT_MARKER_FROM_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_FROM_CID(&edges[i]); + break; + case TRI_EDGE_ANY: + targetKey = TRI_EXTRACT_MARKER_TO_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_TO_CID(&edges[i]); + if (targetCid == startCid && strcmp(targetKey, key) == 0) { + targetKey = TRI_EXTRACT_MARKER_FROM_KEY(&edges[i]); + targetCid = TRI_EXTRACT_MARKER_FROM_CID(&edges[i]); + } + break; + } + + if (targetKey == nullptr || targetCid == 0) { + // somehow invalid + continue; + } + + result.add(VPackValue("vertex")); + ReadDocument(trx, resolver, targetCid, targetKey, result); + } + } else { + for (size_t i = 0; i < resultCount; ++i) { + ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result); + } + } +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief Helper function to unset or keep all given names in the value. /// Recursively iterates over sub-object and unsets or keeps their values @@ -5994,6 +6115,10 @@ AqlValue$ Functions::DocumentVPack(arangodb::aql::Query* query, AqlValue Functions::Edges(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(EdgesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 3 || 5 < n) { @@ -6138,6 +6263,132 @@ AqlValue Functions::Edges(arangodb::aql::Query* query, includeVertices, result); } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::EdgesVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 3 || 5 < n) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "EDGES", (int)3, + (int)5); + } + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + std::string collectionName = collectionSlice.copyString(); + + TRI_transaction_collection_t* collection = nullptr; + TRI_voc_cid_t cid; + RegisterCollectionInTransaction(trx, collectionName, cid, collection); + if (collection->_collection->_type != TRI_COL_TYPE_EDGE) { + RegisterWarning(query, "EDGES", TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice vertexSlice = ExtractFunctionParameter(trx, parameters, 1); + if (!vertexSlice.isArray() && !vertexSlice.isString() && !vertexSlice.isObject()) { + // Invalid Start vertex + // Early Abort before parsing other parameters + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice directionSlice = ExtractFunctionParameter(trx, parameters, 2); + if (!directionSlice.isString()) { + RegisterWarning(query, "EDGES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::string dirString = directionSlice.copyString(); + // transform String to lower case + std::transform(dirString.begin(), dirString.end(), dirString.begin(), + ::tolower); + + TRI_edge_direction_e direction; + + if (dirString == "inbound") { + direction = TRI_EDGE_IN; + } else if (dirString == "outbound") { + direction = TRI_EDGE_OUT; + } else if (dirString == "any") { + direction = TRI_EDGE_ANY; + } else { + RegisterWarning(query, "EDGES", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + auto resolver = trx->resolver(); + + auto shaper = collection->_collection->_collection->getShaper(); + std::unique_ptr matcher; + + if (n > 3) { + // We might have examples + VPackSlice exampleSlice = ExtractFunctionParameter(trx, parameters, 3); + if ((exampleSlice.isArray() && exampleSlice.length() != 0)|| exampleSlice.isObject()) { + try { + matcher.reset( + new arangodb::ExampleMatcher(exampleSlice, shaper, resolver, false)); + } catch (arangodb::basics::Exception const& e) { + if (e.code() != TRI_RESULT_ELEMENT_NOT_FOUND) { + throw; + } + // We can never fulfill this filter! + // RETURN empty Array + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + } + } + + bool includeVertices = false; + + if (n == 5) { + // We have options + VPackSlice options = ExtractFunctionParameter(trx, parameters, 4); + if (options.isObject()) { + includeVertices = arangodb::basics::VelocyPackHelper::getBooleanValue( + options, "includeVertices", false); + } + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + if (vertexSlice.isArray()) { + for (auto const& v : VPackArrayIterator(vertexSlice)) { + try { + RequestEdges(v, trx, resolver, shaper, cid, + collection->_collection->_collection, direction, + matcher.get(), includeVertices, *b); + } catch (...) { + // Errors in Array are simply ignored + } + } + } else { + RequestEdges(vertexSlice, trx, resolver, shaper, cid, + collection->_collection->_collection, direction, + matcher.get(), includeVertices, *b); + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6145,17 +6396,17 @@ AqlValue Functions::Edges(arangodb::aql::Query* query, //////////////////////////////////////////////////////////////////////////////// AqlValue Functions::Round(arangodb::aql::Query* query, - arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { - size_t const n = parameters.size(); + arangodb::AqlTransaction* trx, + FunctionParameters const& parameters) { +size_t const n = parameters.size(); - if (n != 1) { - THROW_ARANGO_EXCEPTION_PARAMS( - TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ROUND", (int)1, - (int)1); - } +if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ROUND", (int)1, + (int)1); +} - Json inputJson = ExtractFunctionParameter(trx, parameters, 0, false); +Json inputJson = ExtractFunctionParameter(trx, parameters, 0, false); bool unused = false; double input = TRI_ToDoubleJson(inputJson.json(), unused); diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index b280513946..6ab6116146 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -332,6 +332,8 @@ struct Functions { static AqlValue$ DocumentVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); + static AqlValue$ EdgesVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, + VPackFunctionParameters const&); }; } } diff --git a/arangod/V8Server/V8Traverser.cpp b/arangod/V8Server/V8Traverser.cpp index 7826ef95b9..52f700ed8b 100644 --- a/arangod/V8Server/V8Traverser.cpp +++ b/arangod/V8Server/V8Traverser.cpp @@ -306,7 +306,8 @@ void BasicOptions::addEdgeFilter(VPackSlice const& example, VocShaper* shaper, useEdgeFilter = true; auto it = _edgeFilter.find(cid); if (it == _edgeFilter.end()) { - _edgeFilter.emplace(cid, new ExampleMatcher(example, shaper, resolver)); + _edgeFilter.emplace(cid, + new ExampleMatcher(example, shaper, resolver, true)); } } diff --git a/arangod/VocBase/ExampleMatcher.cpp b/arangod/VocBase/ExampleMatcher.cpp index fe0642df89..8de11a4806 100644 --- a/arangod/VocBase/ExampleMatcher.cpp +++ b/arangod/VocBase/ExampleMatcher.cpp @@ -415,10 +415,13 @@ 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) + CollectionNameResolver const* resolver, + bool allowStrings) : _shaper(shaper) { if (example.isObject() || example.isString()) { ExampleDefinition def; @@ -433,6 +436,10 @@ ExampleMatcher::ExampleMatcher(VPackSlice const& example, VocShaper* shaper, } 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)); diff --git a/arangod/VocBase/ExampleMatcher.h b/arangod/VocBase/ExampleMatcher.h index c123be3afa..39aef54b72 100644 --- a/arangod/VocBase/ExampleMatcher.h +++ b/arangod/VocBase/ExampleMatcher.h @@ -84,7 +84,8 @@ class ExampleMatcher { arangodb::CollectionNameResolver const* resolver); ExampleMatcher(arangodb::velocypack::Slice const& example, VocShaper* shaper, - arangodb::CollectionNameResolver const* resolver); + arangodb::CollectionNameResolver const* resolver, + bool allowStrings); ~ExampleMatcher() { cleanup(); } From 335abd5640de88f7dfa2440a62a8f7ff91e2382d Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 9 Feb 2016 16:50:39 +0100 Subject: [PATCH 20/50] Added a helper function to transform any VPack value to a double. This is conistent with V8 Json to double --- lib/Basics/VelocyPackHelper.cpp | 56 +++++++++++++++++++++++++++++++++ lib/Basics/VelocyPackHelper.h | 7 +++++ 2 files changed, 63 insertions(+) diff --git a/lib/Basics/VelocyPackHelper.cpp b/lib/Basics/VelocyPackHelper.cpp index d167b09714..07bdafa301 100644 --- a/lib/Basics/VelocyPackHelper.cpp +++ b/lib/Basics/VelocyPackHelper.cpp @@ -443,3 +443,59 @@ VPackBuilder VelocyPackHelper::merge(VPackSlice const& lhs, 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(); + 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; +} + diff --git a/lib/Basics/VelocyPackHelper.h b/lib/Basics/VelocyPackHelper.h index 4b79b34dfd..1f8be8120a 100644 --- a/lib/Basics/VelocyPackHelper.h +++ b/lib/Basics/VelocyPackHelper.h @@ -165,6 +165,13 @@ class VelocyPackHelper { 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&); }; } } From 7976903c4372e9947e3ebe5d56daeedeae8f9a15 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 9 Feb 2016 16:51:04 +0100 Subject: [PATCH 21/50] Added VPack implementations for Math functions. --- arangod/Aql/Functions.cpp | 207 ++++++++++++++++++++++++++++++++++++-- arangod/Aql/Functions.h | 14 +++ 2 files changed, 214 insertions(+), 7 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 267ad4a3fd..5841ebe0e2 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -6398,20 +6398,47 @@ AqlValue$ Functions::EdgesVPack(arangodb::aql::Query* query, AqlValue Functions::Round(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { -size_t const n = parameters.size(); +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RoundVPack(query, trx, tmp)); +#else + size_t const n = parameters.size(); -if (n != 1) { - THROW_ARANGO_EXCEPTION_PARAMS( - TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ROUND", (int)1, - (int)1); -} + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ROUND", (int)1, + (int)1); + } -Json inputJson = ExtractFunctionParameter(trx, parameters, 0, false); + Json inputJson = ExtractFunctionParameter(trx, parameters, 0, false); bool unused = false; double input = TRI_ToDoubleJson(inputJson.json(), unused); input = floor(input + 0.5); // Rounds down for < x.4999 and up for > x.50000 return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::RoundVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ROUND", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = floor(input + 0.5); // Rounds down for < x.4999 and up for > x.50000 + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6421,6 +6448,10 @@ Json inputJson = ExtractFunctionParameter(trx, parameters, 0, false); AqlValue Functions::Abs(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AbsVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -6435,6 +6466,29 @@ AqlValue Functions::Abs(arangodb::aql::Query* query, double input = TRI_ToDoubleJson(inputJson.json(), unused); input = std::abs(input); return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::AbsVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "ABS", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = std::abs(input); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6444,6 +6498,10 @@ AqlValue Functions::Abs(arangodb::aql::Query* query, AqlValue Functions::Ceil(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(CeilVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -6458,6 +6516,29 @@ AqlValue Functions::Ceil(arangodb::aql::Query* query, double input = TRI_ToDoubleJson(inputJson.json(), unused); input = ceil(input); return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::CeilVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "CEIL", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = ceil(input); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6467,6 +6548,10 @@ AqlValue Functions::Ceil(arangodb::aql::Query* query, AqlValue Functions::Floor(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FloorVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -6481,6 +6566,29 @@ AqlValue Functions::Floor(arangodb::aql::Query* query, double input = TRI_ToDoubleJson(inputJson.json(), unused); input = floor(input); return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::FloorVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FLOOR", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + + input = floor(input); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(input)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6490,6 +6598,10 @@ AqlValue Functions::Floor(arangodb::aql::Query* query, AqlValue Functions::Sqrt(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(SqrtVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -6507,6 +6619,32 @@ AqlValue Functions::Sqrt(arangodb::aql::Query* query, return AqlValue(new Json(Json::Null)); } return AqlValue(new Json(input)); +#endif +} + +AqlValue$ Functions::SqrtVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SQRT", (int)1, + (int)1); + } + + VPackSlice inputSlice = ExtractFunctionParameter(trx, parameters, 0); + + bool unused = false; + double input = arangodb::basics::VelocyPackHelper::toDouble(inputSlice, unused); + input = sqrt(input); + std::shared_ptr b = query->getSharedBuilder(); + if (std::isnan(input)) { + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(input)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6516,6 +6654,10 @@ AqlValue Functions::Sqrt(arangodb::aql::Query* query, AqlValue Functions::Pow(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PowVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2) { @@ -6535,6 +6677,34 @@ AqlValue Functions::Pow(arangodb::aql::Query* query, return AqlValue(new Json(Json::Null)); } return AqlValue(new Json(base)); +#endif +} + +AqlValue$ Functions::PowVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "POW", (int)2, + (int)2); + } + + VPackSlice baseSlice = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice expSlice = ExtractFunctionParameter(trx, parameters, 1); + + bool unused = false; + double base = arangodb::basics::VelocyPackHelper::toDouble(baseSlice, unused); + double exp = arangodb::basics::VelocyPackHelper::toDouble(expSlice, unused); + base = pow(base, exp); + std::shared_ptr b = query->getSharedBuilder(); + if (std::isnan(base) || !std::isfinite(base)) { + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(base)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6544,6 +6714,10 @@ AqlValue Functions::Pow(arangodb::aql::Query* query, AqlValue Functions::Rand(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RandVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 0) { @@ -6555,6 +6729,25 @@ AqlValue Functions::Rand(arangodb::aql::Query* query, // This Random functionality is not too good yet... double output = static_cast(std::rand()) / RAND_MAX; return AqlValue(new Json(output)); +#endif +} + +AqlValue$ Functions::RandVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 0) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "RAND", (int)0, + (int)0); + } + + // This Random functionality is not too good yet... + double output = static_cast(std::rand()) / RAND_MAX; + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(output)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 6ab6116146..59ef12a492 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -334,6 +334,20 @@ struct Functions { 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&); }; } } From acbc7cdad2cf8dcd301e097d651cb0080d2ddeec Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 10 Feb 2016 18:12:17 +0100 Subject: [PATCH 22/50] Added more VPackStyle functions: firstDocument firstArray push. --- arangod/Aql/Functions.cpp | 86 +++++++++++++++++++++++++++++++++++++-- arangod/Aql/Functions.h | 12 ++++++ 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 5841ebe0e2..5fd6ab58f5 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -632,7 +632,6 @@ static bool ListContainsElement(Json const& list, Json const& testee) { return ListContainsElement(list, testee, unused); } -#if 0 static bool ListContainsElement(VPackSlice const& list, VPackSlice const& testee, size_t& index) { TRI_ASSERT(list.isArray()); @@ -645,14 +644,11 @@ static bool ListContainsElement(VPackSlice const& list, } return false; } -#endif -#if 0 static bool ListContainsElement(VPackSlice const& list, VPackSlice const& testee) { size_t unused; return ListContainsElement(list, testee, unused); } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief Computes the Variance of the given list. @@ -6757,6 +6753,10 @@ AqlValue$ Functions::RandVPack(arangodb::aql::Query* query, AqlValue Functions::FirstDocument(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FirstDocumentVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); for (size_t i = 0; i < n; ++i) { Json element = ExtractFunctionParameter(trx, parameters, i, false); @@ -6766,6 +6766,22 @@ AqlValue Functions::FirstDocument(arangodb::aql::Query* query, } } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::FirstDocumentVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + for (size_t i = 0; i < n; ++i) { + VPackSlice element = ExtractFunctionParameter(trx, parameters, i); + if (element.isObject()) { + return AqlValue$(element); + } + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6775,6 +6791,10 @@ AqlValue Functions::FirstDocument(arangodb::aql::Query* query, AqlValue Functions::FirstList(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RandVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); for (size_t i = 0; i < n; ++i) { Json element = ExtractFunctionParameter(trx, parameters, i, false); @@ -6784,6 +6804,22 @@ AqlValue Functions::FirstList(arangodb::aql::Query* query, } } return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::FirstListVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + for (size_t i = 0; i < n; ++i) { + VPackSlice element = ExtractFunctionParameter(trx, parameters, i); + if (element.isArray()) { + return AqlValue$(element); + } + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6793,6 +6829,10 @@ AqlValue Functions::FirstList(arangodb::aql::Query* query, AqlValue Functions::Push(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PushVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -6821,6 +6861,44 @@ AqlValue Functions::Push(arangodb::aql::Query* query, RegisterWarning(query, "PUSH", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::PushVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PUSH", (int)2, + (int)3); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice toPush = ExtractFunctionParameter(trx, parameters, 1); + + std::shared_ptr b = query->getSharedBuilder(); + if (list.isNull()) { + VPackArrayBuilder guard(b.get()); + b->add(toPush); + } else if (list.isArray()) { + VPackArrayBuilder guard(b.get()); + for (auto const& it : VPackArrayIterator(list)) { + b->add(it); + } + if (n == 3) { + VPackSlice unique = ExtractFunctionParameter(trx, parameters, 2); + if (!ValueToBoolean(unique) || !ListContainsElement(list, toPush)) { + b->add(toPush); + } + } else { + b->add(toPush); + } + } else { + RegisterWarning(query, "PUSH", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 59ef12a492..726c558f91 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -348,6 +348,18 @@ struct Functions { 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&); }; } } From a3cccc14cf71ab12f23f615ca642ad1c52a59600 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 10 Feb 2016 18:55:28 +0100 Subject: [PATCH 23/50] Added implementation for VPack variant of POP and APPEND --- arangod/Aql/Functions.cpp | 93 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 5fd6ab58f5..c56156a98b 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -6908,6 +6908,10 @@ AqlValue$ Functions::PushVPack(arangodb::aql::Query* query, AqlValue Functions::Pop(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PopVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -6932,6 +6936,43 @@ AqlValue Functions::Pop(arangodb::aql::Query* query, RegisterWarning(query, "POP", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::PopVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "POP", (int)1, + (int)1); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::shared_ptr b = query->getSharedBuilder(); + if (list.isArray()) { + try { + VPackArrayBuilder guard(b.get()); + auto iterator = VPackArrayIterator(list); + while (!iterator.isLast()) { + b->add(iterator.value()); + iterator.next(); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + } else { + RegisterWarning(query, "POP", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + b->add(VPackValue(VPackValueType::Null)); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -6941,6 +6982,10 @@ AqlValue Functions::Pop(arangodb::aql::Query* query, AqlValue Functions::Append(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(AppendVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -6984,6 +7029,54 @@ AqlValue Functions::Append(arangodb::aql::Query* query, list.add(toPush.copy()); } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, list.copy().steal())); +#endif +} + +AqlValue$ Functions::AppendVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "APPEND", (int)2, + (int)3); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice toAppend = ExtractFunctionParameter(trx, parameters, 1); + + if (toAppend.isNull()) { + return AqlValue$(list); + } + + bool unique = false; + if (n == 3) { + VPackSlice uniqueSlice = ExtractFunctionParameter(trx, parameters, 2); + unique = ValueToBoolean(uniqueSlice); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + bool isNull = list.isNull(); + if (!isNull) { + TRI_ASSERT(list.isArray()); + for (auto const& it : VPackArrayIterator(list)) { + b->add(it); + } + } + if (!toAppend.isArray()) { + if (!unique || !ListContainsElement(list, toAppend)) { + b->add(toAppend); + } + } else { + for (auto const& it : VPackArrayIterator(toAppend)) { + if (!unique || !ListContainsElement(list, it)) { + b->add(it); + } + } + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// From 30547cb696e5ae38f62f09539590da69b03e5292 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 10 Feb 2016 21:56:09 +0100 Subject: [PATCH 24/50] Further implementation if list functions in VPack variant. Also fixed a bug in FIRST --- arangod/Aql/Functions.cpp | 268 +++++++++++++++++++++++++++++++++++++- arangod/Aql/Functions.h | 14 ++ 2 files changed, 279 insertions(+), 3 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index c56156a98b..925918af2a 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -6793,7 +6793,7 @@ AqlValue Functions::FirstList(arangodb::aql::Query* query, FunctionParameters const& parameters) { #ifdef TMPUSEVPACK auto tmp = transformParameters(parameters, trx); - return AqlValue(RandVPack(query, trx, tmp)); + return AqlValue(FirstListVPack(query, trx, tmp)); #else size_t const n = parameters.size(); for (size_t i = 0; i < n; ++i) { @@ -7057,8 +7057,7 @@ AqlValue$ Functions::AppendVPack(arangodb::aql::Query* query, std::shared_ptr b = query->getSharedBuilder(); { VPackArrayBuilder guard(b.get()); - bool isNull = list.isNull(); - if (!isNull) { + if (!list.isNull()) { TRI_ASSERT(list.isArray()); for (auto const& it : VPackArrayIterator(list)) { b->add(it); @@ -7086,6 +7085,10 @@ AqlValue$ Functions::AppendVPack(arangodb::aql::Query* query, AqlValue Functions::Unshift(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(UnshiftVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7127,6 +7130,50 @@ AqlValue Functions::Unshift(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "UNSHIFT"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::UnshiftVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "UNSHIFT", (int)2, + (int)3); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isNull() && !list.isArray()) { + RegisterInvalidArgumentWarning(query, "UNSHIFT"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice toAppend = ExtractFunctionParameter(trx, parameters, 1); + bool unique = false; + if (n == 3) { + VPackSlice uniqueSlice = ExtractFunctionParameter(trx, parameters, 2); + unique = ValueToBoolean(uniqueSlice); + } + + if (unique && list.isArray() && ListContainsElement(list, toAppend)) { + // Short circuit, nothing to do return list + return AqlValue$(list); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + b->add(toAppend); + if (list.isArray()) { + for (auto const& it : VPackArrayIterator(list)) { + b->add(it); + } + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -7136,6 +7183,10 @@ AqlValue Functions::Unshift(arangodb::aql::Query* query, AqlValue Functions::Shift(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(ShiftVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { @@ -7160,6 +7211,45 @@ AqlValue Functions::Shift(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "SHIFT"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::ShiftVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "SHIFT", (int)1, + (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + if (!list.isArray()) { + RegisterInvalidArgumentWarning(query, "SHIFT"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + if (list.length() > 0) { + auto iterator = VPackArrayIterator(list); + // This jumps over the first element + while(iterator.next()) { + b->add(iterator.value()); + } + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -7169,6 +7259,10 @@ AqlValue Functions::Shift(arangodb::aql::Query* query, AqlValue Functions::RemoveValue(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RemoveValueVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7212,6 +7306,67 @@ AqlValue Functions::RemoveValue(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "REMOVE_VALUE"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::RemoveValueVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "REMOVE_VALUE", + (int)2, (int)3); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (!list.isArray()) { + RegisterInvalidArgumentWarning(query, "REMOVE_VALUE"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + bool useLimit = false; + size_t limit = static_cast(list.length()); + + VPackSlice toRemove = ExtractFunctionParameter(trx, parameters, 1); + if (n == 3) { + VPackSlice limitSlice = ExtractFunctionParameter(trx, parameters, 2); + bool unused = false; + if (!limitSlice.isNull()) { + limit = static_cast(ValueToNumber(limitSlice, unused)); + useLimit = true; + } + } + for (auto const& it : VPackArrayIterator(list)) { + if (useLimit && limit == 0) { + // Just copy + b->add(it); + continue; + } + if (arangodb::basics::VelocyPackHelper::compare(toRemove, it, false) == + 0) { + --limit; + continue; + } + b->add(it); + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -7221,6 +7376,10 @@ AqlValue Functions::RemoveValue(arangodb::aql::Query* query, AqlValue Functions::RemoveValues(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RemoveValuesVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7254,6 +7413,50 @@ AqlValue Functions::RemoveValues(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "REMOVE_VALUES"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::RemoveValuesVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "REMOVE_VALUES", + (int)2, (int)2); + } + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice values = ExtractFunctionParameter(trx, parameters, 1); + + if (values.isNull()) { + return AqlValue$(list); + } + + std::shared_ptr b = query->getSharedBuilder(); + if (list.isNull()) { + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (list.isArray() && values.isArray()) { + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : VPackArrayIterator(list)) { + if (!ListContainsElement(values, it)) { + b->add(it); + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); + } + + RegisterInvalidArgumentWarning(query, "REMOVE_VALUES"); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -7263,6 +7466,10 @@ AqlValue Functions::RemoveValues(arangodb::aql::Query* query, AqlValue Functions::RemoveNth(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RemoveNthVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7297,6 +7504,61 @@ AqlValue Functions::RemoveNth(arangodb::aql::Query* query, RegisterInvalidArgumentWarning(query, "REMOVE_NTH"); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::RemoveNthVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "REMOVE_NTH", (int)2, + (int)2); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (list.isNull()) { + std::shared_ptr b = query->getSharedBuilder(); + { + VPackArrayBuilder guard(b.get()); + } + return AqlValue$(b.get()); + } + + if (list.isArray()) { + double const count = static_cast(list.length()); + VPackSlice position = ExtractFunctionParameter(trx, parameters, 1); + bool unused = false; + double p = arangodb::basics::VelocyPackHelper::toDouble(position, unused); + if (p >= count || p < -count) { + return AqlValue$(list); + } + if (p < 0) { + p += count; + } + size_t cur = 0; + size_t target = static_cast(p); + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + for (auto const& it : VPackArrayIterator(list)) { + if (cur != target) { + b->add(it); + } + cur++; + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); + } + + RegisterInvalidArgumentWarning(query, "REMOVE_NTH"); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 726c558f91..71119b2abe 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -360,6 +360,20 @@ struct Functions { 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&); }; } } From 8cbac0258a002c371367de2548efef1f288c2eb1 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Sat, 13 Feb 2016 13:48:34 +0100 Subject: [PATCH 25/50] Added VPack implementation for NotNull, CurrentDatabase and CollectionCount --- arangod/Aql/Functions.cpp | 100 ++++++++++++++++++++++++++++++++++++++ arangod/Aql/Functions.h | 9 ++++ 2 files changed, 109 insertions(+) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 925918af2a..85f86ab72f 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -7568,6 +7568,10 @@ AqlValue$ Functions::RemoveNthVPack(arangodb::aql::Query* query, AqlValue Functions::NotNull(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(NotNullVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); for (size_t i = 0; i < n; ++i) { Json element = ExtractFunctionParameter(trx, parameters, i, false); @@ -7576,8 +7580,25 @@ AqlValue Functions::NotNull(arangodb::aql::Query* query, } } return AqlValue(new Json(Json::Null)); +#endif } +AqlValue$ Functions::NotNullVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + for (size_t i = 0; i < n; ++i) { + VPackSlice element = ExtractFunctionParameter(trx, parameters, i); + if (!element.isNull()) { + return AqlValue$(element); + } + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief function CURRENT_DATABASE //////////////////////////////////////////////////////////////////////////////// @@ -7585,6 +7606,10 @@ AqlValue Functions::NotNull(arangodb::aql::Query* query, AqlValue Functions::CurrentDatabase(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(CurrentDatabaseVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 0) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7592,6 +7617,21 @@ AqlValue Functions::CurrentDatabase(arangodb::aql::Query* query, (int)0, (int)0); } return AqlValue(new Json(query->vocbase()->_name)); +#endif +} + +AqlValue$ Functions::CurrentDatabaseVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 0) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "CURRENT_DATABASE", + (int)0, (int)0); + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(query->vocbase()->_name)); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -7601,6 +7641,10 @@ AqlValue Functions::CurrentDatabase(arangodb::aql::Query* query, AqlValue Functions::CollectionCount(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(CollectionCountVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7650,6 +7694,62 @@ AqlValue Functions::CollectionCount(arangodb::aql::Query* query, } return AqlValue(new Json(static_cast(document->size()))); +#endif +} + +AqlValue$ Functions::CollectionCountVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "COLLECTION_COUNT", + (int)1, (int)1); + } + + VPackSlice element = ExtractFunctionParameter(trx, parameters, 0); + if (!element.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "COLLECTION_COUNT"); + } + + std::string const colName = + basics::VelocyPackHelper::getStringValue(element, ""); + + auto resolver = trx->resolver(); + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + if (cid == 0) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + + auto collection = trx->trxCollection(cid); + + // ensure the collection is loaded + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION_FORMAT(res, "'%s'", colName.c_str()); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", colName.c_str()); + } + } + + auto document = trx->documentCollection(cid); + + if (document == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(document->size())); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 71119b2abe..6edae6b5d8 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -374,6 +374,15 @@ struct Functions { 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&); }; } } From 0688392364b157658ca6802fade777de5b2ed8f9 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Sat, 13 Feb 2016 14:00:40 +0100 Subject: [PATCH 26/50] Added a velocypack variant of stdDev and variance to AQL --- arangod/Aql/Functions.cpp | 190 +++++++++++++++++++++++++++++++++++++- arangod/Aql/Functions.h | 12 +++ 2 files changed, 198 insertions(+), 4 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 85f86ab72f..4c6691df14 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -680,7 +680,6 @@ static bool Variance(Json const& values, double& value, size_t& count) { return true; } -#if 0 static bool Variance(VPackSlice const& values, double& value, size_t& count) { TRI_ASSERT(values.isArray()); value = 0.0; @@ -701,7 +700,6 @@ static bool Variance(VPackSlice const& values, double& value, size_t& count) { } return true; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief Sorts the given list of Numbers in ASC order. @@ -732,7 +730,6 @@ static bool SortNumberList(Json const& values, std::vector& result) { /// Returns false if the list contains non-number values. //////////////////////////////////////////////////////////////////////////////// -#if 0 static bool SortNumberList(VPackSlice const& values, std::vector& result) { TRI_ASSERT(values.isArray()); @@ -749,7 +746,6 @@ static bool SortNumberList(VPackSlice const& values, std::sort(result.begin(), result.end()); return true; } -#endif //////////////////////////////////////////////////////////////////////////////// /// @brief Expands a shaped Json @@ -7759,6 +7755,10 @@ AqlValue$ Functions::CollectionCountVPack( AqlValue Functions::VarianceSample(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(VarianceSampleVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7787,6 +7787,48 @@ AqlValue Functions::VarianceSample(arangodb::aql::Query* query, } return AqlValue(new Json(value / (count - 1))); +#endif +} + +AqlValue$ Functions::VarianceSampleVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "VARIANCE_SAMPLE", + (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "VARIANCE_SAMPLE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "VARIANCE_SAMPLE", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 2) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(value / (count - 1))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -7796,6 +7838,10 @@ AqlValue Functions::VarianceSample(arangodb::aql::Query* query, AqlValue Functions::VariancePopulation(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(VariancePopulationVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7825,8 +7871,52 @@ AqlValue Functions::VariancePopulation(arangodb::aql::Query* query, } return AqlValue(new Json(value / count)); +#endif } +AqlValue$ Functions::VariancePopulationVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, + "VARIANCE_POPULATION", (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "VARIANCE_POPULATION", + TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "VARIANCE_POPULATION", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 1) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(value / count)); + return AqlValue$(b.get()); +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief function STDDEV_SAMPLE //////////////////////////////////////////////////////////////////////////////// @@ -7834,6 +7924,10 @@ AqlValue Functions::VariancePopulation(arangodb::aql::Query* query, AqlValue Functions::StdDevSample(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(StdDevSampleVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7862,6 +7956,48 @@ AqlValue Functions::StdDevSample(arangodb::aql::Query* query, } return AqlValue(new Json(sqrt(value / (count - 1)))); +#endif +} + +AqlValue$ Functions::StdDevSampleVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "STDDEV_SAMPLE", + (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "STDDEV_SAMPLE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "STDDEV_SAMPLE", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 2) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(sqrt(value / (count - 1) ))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -7871,6 +8007,10 @@ AqlValue Functions::StdDevSample(arangodb::aql::Query* query, AqlValue Functions::StdDevPopulation(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(StdDevPopulationVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -7899,6 +8039,48 @@ AqlValue Functions::StdDevPopulation(arangodb::aql::Query* query, } return AqlValue(new Json(sqrt(value / count))); +#endif +} + +AqlValue$ Functions::StdDevPopulationVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "STDDEV_POPULATION", + (int)1, (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "STDDEV_POPULATION", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + double value = 0.0; + size_t count = 0; + + if (!Variance(list, value, count)) { + RegisterWarning(query, "STDDEV_POPULATION", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (count < 1) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(sqrt(value / count))); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 6edae6b5d8..e4263e5db1 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -383,6 +383,18 @@ struct Functions { 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&); }; } } From 521be3c08efbcf314a586c62253429b0bc3dd496 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Sat, 13 Feb 2016 14:15:09 +0100 Subject: [PATCH 27/50] Added VPack variant of PERCENTILE and MEDIAN --- arangod/Aql/Functions.cpp | 171 ++++++++++++++++++++++++++++++++++++++ arangod/Aql/Functions.h | 5 ++ 2 files changed, 176 insertions(+) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 4c6691df14..4506f21d9a 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -8090,6 +8090,10 @@ AqlValue$ Functions::StdDevPopulationVPack( AqlValue Functions::Median(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(MedianVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 1) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -8120,6 +8124,51 @@ AqlValue Functions::Median(arangodb::aql::Query* query, return AqlValue(new Json((values[midpoint - 1] + values[midpoint]) / 2)); } return AqlValue(new Json(values[midpoint])); +#endif +} + +AqlValue$ Functions::MedianVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 1) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "MEDIAN", (int)1, + (int)1); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "MEDIAN", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::vector values; + if (!SortNumberList(list, values)) { + RegisterWarning(query, "MEDIAN", TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (values.empty()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + size_t const l = values.size(); + size_t midpoint = l / 2; + + std::shared_ptr b = query->getSharedBuilder(); + if (l % 2 == 0) { + b->add(VPackValue((values[midpoint - 1] + values[midpoint]) / 2)); + } else { + b->add(VPackValue(values[midpoint])); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -8129,6 +8178,10 @@ AqlValue Functions::Median(arangodb::aql::Query* query, AqlValue Functions::Percentile(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PercentileVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -8224,6 +8277,124 @@ AqlValue Functions::Percentile(arangodb::aql::Query* query, return AqlValue(new Json(Json::Null)); } return AqlValue(new Json(values[static_cast(pos) - 1])); +#endif +} + +AqlValue$ Functions::PercentileVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "PERCENTILE", (int)2, + (int)3); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "PERCENTILE", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + VPackSlice border = ExtractFunctionParameter(trx, parameters, 1); + + if (!border.isNumber()) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool unused = false; + double p = ValueToNumber(border, unused); + if (p <= 0 || p > 100) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool useInterpolation = false; + + if (n == 3) { + VPackSlice methodSlice = ExtractFunctionParameter(trx, parameters, 2); + if (!methodSlice.isString()) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + std::string method = methodSlice.copyString(); + if (method == "interpolation") { + useInterpolation = true; + } else if (method == "rank") { + useInterpolation = false; + } else { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + } + + std::vector values; + if (!SortNumberList(list, values)) { + RegisterWarning(query, "PERCENTILE", + TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + if (values.empty()) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + size_t l = values.size(); + if (l == 1) { + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(values[0])); + return AqlValue$(b.get()); + } + + TRI_ASSERT(l > 1); + + if (useInterpolation) { + double idx = p * (l + 1) / 100; + double pos = floor(idx); + + std::shared_ptr b = query->getSharedBuilder(); + if (pos >= l) { + b->add(VPackValue(values[l - 1])); + } else if (pos <= 0) { + b->add(VPackValue(VPackValueType::Null)); + } else { + double delta = idx - pos; + b->add(VPackValue(delta * (values[static_cast(pos)] - + values[static_cast(pos) - 1]) + + values[static_cast(pos) - 1])); + } + return AqlValue$(b.get()); + } + double idx = p * l / 100; + double pos = ceil(idx); + std::shared_ptr b = query->getSharedBuilder(); + if (pos >= l) { + b->add(VPackValue(values[l - 1])); + } else if (pos <= 0) { + b->add(VPackValue(VPackValueType::Null)); + } else { + b->add(VPackValue(values[static_cast(pos) - 1])); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index e4263e5db1..214383a447 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -395,6 +395,11 @@ struct Functions { 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&); }; } } From bfddd69a03d3129fefb63f9af845025ba35bf08c Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Sat, 13 Feb 2016 14:30:43 +0100 Subject: [PATCH 28/50] Added a velocypack variant of POSITION and RANGE. --- arangod/Aql/Functions.cpp | 129 ++++++++++++++++++++++++++++++++++++++ arangod/Aql/Functions.h | 5 ++ 2 files changed, 134 insertions(+) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 4506f21d9a..a9f7ef5648 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -8404,6 +8404,10 @@ AqlValue$ Functions::PercentileVPack( AqlValue Functions::Range(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(RangeVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { @@ -8458,6 +8462,73 @@ AqlValue Functions::Range(arangodb::aql::Query* query, } } return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, result.steal())); +#endif +} + +AqlValue$ Functions::RangeVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "RANGE", (int)2, + (int)3); + } + + VPackSlice const leftSlice = ExtractFunctionParameter(trx, parameters, 0); + VPackSlice const rightSlice = ExtractFunctionParameter(trx, parameters, 1); + + bool unused = true; + double from = ValueToNumber(leftSlice, unused); + double to = ValueToNumber(rightSlice, unused); + + double step = 0.0; + if (n == 3) { + VPackSlice const stepSlice = ExtractFunctionParameter(trx, parameters, 2); + if (!stepSlice.isNull()) { + step = ValueToNumber(stepSlice, unused); + } else { + // no step specified + if (from <= to) { + step = 1.0; + } else { + step = -1.0; + } + } + } else { + // no step specified + if (from <= to) { + step = 1.0; + } else { + step = -1.0; + } + } + + if (step == 0.0 || (from < to && step < 0.0) || (from > to && step > 0.0)) { + RegisterWarning(query, "RANGE", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + if (step < 0.0 && to <= from) { + for (; from >= to; from += step) { + b->add(VPackValue(from)); + } + } else { + for (; from <= to; from += step) { + b->add(VPackValue(from)); + } + } + } catch (...) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// @@ -8467,6 +8538,10 @@ AqlValue Functions::Range(arangodb::aql::Query* query, AqlValue Functions::Position(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(PositionVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n != 2 && n != 3) { THROW_ARANGO_EXCEPTION_PARAMS( @@ -8503,6 +8578,60 @@ AqlValue Functions::Position(arangodb::aql::Query* query, return AqlValue(new Json(-1)); } return AqlValue(new Json(false)); +#endif +} + +AqlValue$ Functions::PositionVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + if (n != 2 && n != 3) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "POSITION", (int)2, + (int)3); + } + + VPackSlice list = ExtractFunctionParameter(trx, parameters, 0); + + if (!list.isArray()) { + RegisterWarning(query, "POSITION", TRI_ERROR_QUERY_ARRAY_EXPECTED); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); + } + + bool returnIndex = false; + if (n == 3) { + VPackSlice returnIndexSlice = ExtractFunctionParameter(trx, parameters, 2); + returnIndex = ValueToBoolean(returnIndexSlice); + } + + std::shared_ptr b = query->getSharedBuilder(); + if (list.length() > 0) { + VPackSlice searchValue = ExtractFunctionParameter(trx, parameters, 1); + + size_t index; + if (ListContainsElement(list, searchValue, index)) { + if (returnIndex) { + b->add(VPackValue(index)); + } else { + b->add(VPackValue(true)); + } + } else { + if (returnIndex) { + b->add(VPackValue(-1)); + } else { + b->add(VPackValue(false)); + } + } + } else { + if (returnIndex) { + b->add(VPackValue(-1)); + } else { + b->add(VPackValue(false)); + } + } + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 214383a447..427b2601e3 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -400,6 +400,11 @@ struct Functions { 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&); }; } } From a52e70c3f51f277d63fd1da831cdc29314250978 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Sat, 13 Feb 2016 14:40:10 +0100 Subject: [PATCH 29/50] Added a VPack Variant for AQL FULLTEXT function --- arangod/Aql/Functions.cpp | 156 ++++++++++++++++++++++++++++++++++++++ arangod/Aql/Functions.h | 3 + 2 files changed, 159 insertions(+) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index a9f7ef5648..f01bb8b84f 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -8641,6 +8641,10 @@ AqlValue$ Functions::PositionVPack(arangodb::aql::Query* query, AqlValue Functions::Fulltext(arangodb::aql::Query* query, arangodb::AqlTransaction* trx, FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(FulltextVPack(query, trx, tmp)); +#else size_t const n = parameters.size(); if (n < 3 || n > 4) { @@ -8793,6 +8797,158 @@ AqlValue Functions::Fulltext(arangodb::aql::Query* query, TRI_FreeResultFulltextIndex(queryResult); THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } +#endif +} + +AqlValue$ Functions::FulltextVPack(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + size_t const n = parameters.size(); + + if (n < 3 || n > 4) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "FULLTEXT", (int)3, + (int)4); + } + + auto resolver = trx->resolver(); + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice attribute = ExtractFunctionParameter(trx, parameters, 1); + + if (!attribute.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } + + std::string attributeName = attribute.copyString(); + + VPackSlice queryString = ExtractFunctionParameter(trx, parameters, 2); + + if (!queryString.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } + + std::string queryValue = queryString.copyString(); + + size_t maxResults = 0; // 0 means "all results" + if (n >= 4) { + VPackSlice limit = ExtractFunctionParameter(trx, parameters, 3); + if (!limit.isNull() && !limit.isNumber()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "FULLTEXT"); + } else if (limit.isNumber()) { + int64_t value = limit.getNumericValue(); + if (value > 0) { + maxResults = static_cast(value); + } + } + } + + TRI_voc_cid_t cid = resolver->getCollectionId(colName); + auto collection = trx->trxCollection(cid); + + // ensure the collection is loaded + if (collection == nullptr) { + int res = TRI_AddCollectionTransaction(trx->getInternals(), cid, + TRI_TRANSACTION_READ, + trx->nestingLevel(), true, true); + if (res != TRI_ERROR_NO_ERROR) { + THROW_ARANGO_EXCEPTION_FORMAT(res, "'%s'", colName.c_str()); + } + + TRI_EnsureCollectionsTransaction(trx->getInternals()); + collection = trx->trxCollection(cid); + + if (collection == nullptr) { + THROW_ARANGO_EXCEPTION_FORMAT(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, + "'%s'", colName.c_str()); + } + } + + auto document = trx->documentCollection(cid); + + if (document == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND); + } + + arangodb::Index* index = nullptr; + + std::vector> const search( + {{arangodb::basics::AttributeName(attributeName, false)}}); + + for (auto const& idx : document->allIndexes()) { + if (idx->type() == arangodb::Index::TRI_IDX_TYPE_FULLTEXT_INDEX) { + // test if index is on the correct field + if (arangodb::basics::AttributeName::isIdentical(idx->fields(), search, + false)) { + // match! + index = idx; + break; + } + } + } + + if (index == nullptr) { + THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FULLTEXT_INDEX_MISSING, + colName.c_str()); + } + + if (trx->orderDitch(collection) == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + TRI_fulltext_query_t* ft = + TRI_CreateQueryFulltextIndex(TRI_FULLTEXT_SEARCH_MAX_WORDS, maxResults); + + if (ft == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + + bool isSubstringQuery = false; + int res = + TRI_ParseQueryFulltextIndex(ft, queryValue.c_str(), &isSubstringQuery); + + if (res != TRI_ERROR_NO_ERROR) { + TRI_FreeQueryFulltextIndex(ft); + THROW_ARANGO_EXCEPTION(res); + } + + auto fulltextIndex = static_cast(index); + // note: the following call will free "ft"! + TRI_fulltext_result_t* queryResult = + TRI_QueryFulltextIndex(fulltextIndex->internals(), ft); + + if (queryResult == nullptr) { + THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); + } + + auto shaper = collection->_collection->_collection->getShaper(); + size_t const numResults = queryResult->_numDocuments; + + std::shared_ptr b = query->getSharedBuilder(); + try { + VPackArrayBuilder guard(b.get()); + + for (size_t i = 0; i < numResults; ++i) { + ExpandShapedJson(shaper, resolver, cid, + (TRI_doc_mptr_t const*)queryResult->_documents[i], *b); + } + } catch (...) { + TRI_FreeResultFulltextIndex(queryResult); + THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); + } + TRI_FreeResultFulltextIndex(queryResult); + return AqlValue$(b.get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index 427b2601e3..b4e5fdda40 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -405,6 +405,9 @@ struct Functions { static AqlValue$ PositionVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); + static AqlValue$ FulltextVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); }; } } From c8e0d417ba623f1c58d2c478354e304d97399b88 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Sat, 13 Feb 2016 14:46:32 +0100 Subject: [PATCH 30/50] Added VPack Variant for IS_SAME_COLLECTION. This was the function without a VelocyPack variant. AQL Functions are now ready to be switched. --- arangod/Aql/Functions.cpp | 60 +++++++++++++++++++++++++++++++++++++-- arangod/Aql/Functions.h | 3 ++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index f01bb8b84f..bd42ad7dc2 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -8955,9 +8955,13 @@ AqlValue$ Functions::FulltextVPack(arangodb::aql::Query* query, /// @brief function IS_SAME_COLLECTION //////////////////////////////////////////////////////////////////////////////// -AqlValue Functions::IsSameCollection (arangodb::aql::Query* query, - arangodb::AqlTransaction* trx, - FunctionParameters const& parameters) { +AqlValue Functions::IsSameCollection(arangodb::aql::Query* query, + arangodb::AqlTransaction* trx, + FunctionParameters const& parameters) { +#ifdef TMPUSEVPACK + auto tmp = transformParameters(parameters, trx); + return AqlValue(IsSameCollectionVPack(query, trx, tmp)); +#else if (parameters.size() != 2) { THROW_ARANGO_EXCEPTION_PARAMS(TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "IS_SAME_COLLECTION", (int) 2, (int) 2); } @@ -8994,5 +8998,55 @@ AqlValue Functions::IsSameCollection (arangodb::aql::Query* query, RegisterWarning(query, "IS_SAME_COLLECTION", TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); return AqlValue(new Json(Json::Null)); +#endif +} + +AqlValue$ Functions::IsSameCollectionVPack( + arangodb::aql::Query* query, arangodb::AqlTransaction* trx, + VPackFunctionParameters const& parameters) { + if (parameters.size() != 2) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH, "IS_SAME_COLLECTION", + (int)2, (int)2); + } + + VPackSlice collectionSlice = ExtractFunctionParameter(trx, parameters, 0); + + if (!collectionSlice.isString()) { + THROW_ARANGO_EXCEPTION_PARAMS( + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH, "IS_SAME_COLLECTION"); + } + + std::string colName = collectionSlice.copyString(); + + VPackSlice value = ExtractFunctionParameter(trx, parameters, 1); + std::string identifier; + + if (value.isObject() && value.hasKey(TRI_VOC_ATTRIBUTE_ID)) { + identifier = arangodb::basics::VelocyPackHelper::getStringValue( + value, TRI_VOC_ATTRIBUTE_ID, ""); + } else if (value.isString()) { + identifier = value.copyString(); + } + + if (!identifier.empty()) { + size_t pos = identifier.find('/'); + + if (pos != std::string::npos) { + bool const same = (colName == identifier.substr(0, pos)); + + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(same)); + return AqlValue$(b.get()); + } + + // fallthrough intentional + } + + RegisterWarning(query, "IS_SAME_COLLECTION", + TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH); + std::shared_ptr b = query->getSharedBuilder(); + b->add(VPackValue(VPackValueType::Null)); + return AqlValue$(b.get()); } diff --git a/arangod/Aql/Functions.h b/arangod/Aql/Functions.h index b4e5fdda40..83cd20bb72 100644 --- a/arangod/Aql/Functions.h +++ b/arangod/Aql/Functions.h @@ -408,6 +408,9 @@ struct Functions { static AqlValue$ FulltextVPack(arangodb::aql::Query*, arangodb::AqlTransaction*, VPackFunctionParameters const&); + static AqlValue$ IsSameCollectionVPack(arangodb::aql::Query*, + arangodb::AqlTransaction*, + VPackFunctionParameters const&); }; } } From 835e077836c3e823116932754bb31d51e9f75389 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 15 Feb 2016 10:51:12 +0100 Subject: [PATCH 31/50] Fixed a linux compile bug with default parameters. Now they have no defaults any more. --- arangod/Aql/Functions.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 024c90b850..f6251d59e1 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -793,8 +793,8 @@ static inline Json ExpandShapedJson(VocShaper* shaper, static inline void ExpandShapedJson( VocShaper* shaper, CollectionNameResolver const* resolver, TRI_voc_cid_t const& cid, TRI_doc_mptr_t const* mptr, VPackBuilder& b, - bool keepTopLevelOpen = false, - std::unordered_set const& forbidden = {}) { + bool keepTopLevelOpen, + std::unordered_set const& forbidden) { b.add(VPackValue(VPackValueType::Object)); TRI_df_marker_t const* marker = @@ -921,8 +921,9 @@ static void ReadDocument(arangodb::AqlTransaction* trx, if (res != TRI_ERROR_NO_ERROR) { result.add(VPackValue(VPackValueType::Null)); } else { + std::unordered_set unused; ExpandShapedJson(collection->_collection->_collection->getShaper(), - resolver, cid, &mptr, result); + resolver, cid, &mptr, result, false, unused); } } @@ -1074,7 +1075,8 @@ static void RequestEdges(VPackSlice const& vertexSlice, for (size_t i = 0; i < resultCount; ++i) { VPackObjectBuilder guard(&result); result.add(VPackValue("edge")); - ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result); + std::unordered_set unused; + ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result, false, unused); char const* targetKey = nullptr; TRI_voc_cid_t targetCid = 0; @@ -1107,7 +1109,8 @@ static void RequestEdges(VPackSlice const& vertexSlice, } } else { for (size_t i = 0; i < resultCount; ++i) { - ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result); + std::unordered_set unused; + ExpandShapedJson(shaper, resolver, cid, &(edges[i]), result, false, unused); } } } @@ -1295,8 +1298,9 @@ static void VertexIdToVPack(arangodb::AqlTransaction* trx, THROW_ARANGO_EXCEPTION(res); } + std::unordered_set unused; ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, - id.cid, &mptr, b); + id.cid, &mptr, b, false, unused); } @@ -5844,8 +5848,9 @@ static void getDocumentByIdentifier(arangodb::AqlTransaction* trx, return; } + std::unordered_set unused; ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, - cid, &mptr, result); + cid, &mptr, result, false, unused); } //////////////////////////////////////////////////////////////////////////////// @@ -5885,8 +5890,9 @@ static void getDocumentByIdentifier(arangodb::AqlTransaction* trx, return; } + std::unordered_set unused; ExpandShapedJson(collection->_collection->_collection->getShaper(), resolver, - cid, &mptr, result); + cid, &mptr, result, false, unused); } @@ -8943,8 +8949,10 @@ AqlValue$ Functions::FulltextVPack(arangodb::aql::Query* query, VPackArrayBuilder guard(b.get()); for (size_t i = 0; i < numResults; ++i) { + std::unordered_set unused; ExpandShapedJson(shaper, resolver, cid, - (TRI_doc_mptr_t const*)queryResult->_documents[i], *b); + (TRI_doc_mptr_t const*)queryResult->_documents[i], *b, + false, unused); } } catch (...) { TRI_FreeResultFulltextIndex(queryResult); From 2c6c31004c1eff0d1b8504bcc0e72d14c10b0a84 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 15 Feb 2016 10:53:35 +0100 Subject: [PATCH 32/50] Silenced parentheses warning --- arangod/Aql/Functions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index f6251d59e1..00aae36934 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -1131,7 +1131,7 @@ static void UnsetOrKeep(VPackSlice const& value, for (auto const& entry : VPackObjectIterator(value)) { TRI_ASSERT(entry.key.isString()); std::string key = entry.key.copyString(); - if (!(names.find(key) == names.end() ^ unset)) { + if (!((names.find(key) == names.end()) ^ unset)) { // not found and unset or found and keep if (recursive && entry.value.isObject()) { result.add(entry.key); // Add the key From bb264d89f8e7244cde025cceb4280442a9bc54c9 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 15 Feb 2016 11:21:40 +0100 Subject: [PATCH 33/50] Removed VPackSlice const from std::containers. It is against the standard and compiles somehow with clang but not with g++4.9 --- arangod/Aql/Functions.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index 00aae36934..0fe5b11b8e 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -3859,7 +3859,7 @@ AqlValue$ Functions::UniqueVPack(arangodb::aql::Query* query, return AqlValue$(b.get()); } - std::unordered_set values(512, arangodb::basics::VelocyPackHelper::VPackHash(), @@ -3966,7 +3966,7 @@ AqlValue$ Functions::SortedUniqueVPack( return AqlValue$(b.get()); } - std::set> values; + std::set> values; for (auto const& it : VPackArrayIterator(value)) { if (!it.isNone()) { values.insert(it); @@ -4210,7 +4210,7 @@ AqlValue$ Functions::UnionDistinctVPack(arangodb::aql::Query* query, (int)2, (int)Function::MaxArguments); } - std::unordered_set values(512, arangodb::basics::VelocyPackHelper::VPackHash(), @@ -4392,7 +4392,7 @@ AqlValue$ Functions::IntersectionVPack(arangodb::aql::Query* query, (int)2, (int)Function::MaxArguments); } - std::unordered_map values(512, arangodb::basics::VelocyPackHelper::VPackHash(), From 4a7bc9ad952b184385bad2b40d0cabafce10a6b3 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 15 Feb 2016 17:48:20 +0100 Subject: [PATCH 34/50] Removed unnecessary JSON --- arangod/Scheduler/PeriodicTask.cpp | 1 - arangod/VocBase/KeyGenerator.cpp | 2 +- arangod/VocBase/KeyGenerator.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arangod/Scheduler/PeriodicTask.cpp b/arangod/Scheduler/PeriodicTask.cpp index eb45c31b94..b31e23b047 100644 --- a/arangod/Scheduler/PeriodicTask.cpp +++ b/arangod/Scheduler/PeriodicTask.cpp @@ -23,7 +23,6 @@ //////////////////////////////////////////////////////////////////////////////// #include "PeriodicTask.h" -#include "Basics/json.h" #include "Scheduler/Scheduler.h" #include diff --git a/arangod/VocBase/KeyGenerator.cpp b/arangod/VocBase/KeyGenerator.cpp index 8ceb34ec52..3c90878b03 100644 --- a/arangod/VocBase/KeyGenerator.cpp +++ b/arangod/VocBase/KeyGenerator.cpp @@ -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( diff --git a/arangod/VocBase/KeyGenerator.h b/arangod/VocBase/KeyGenerator.h index 731ee95b58..c8ca27043f 100644 --- a/arangod/VocBase/KeyGenerator.h +++ b/arangod/VocBase/KeyGenerator.h @@ -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&); From 86fc1267e79399292cd495cd48d2dbda1595f8b6 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Mon, 15 Feb 2016 23:58:06 +0100 Subject: [PATCH 35/50] Removed obsolete Json imports --- arangod/Wal/LogfileManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/arangod/Wal/LogfileManager.cpp b/arangod/Wal/LogfileManager.cpp index 404933d865..948cb4deef 100644 --- a/arangod/Wal/LogfileManager.cpp +++ b/arangod/Wal/LogfileManager.cpp @@ -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" From f767636f145873400e9b68fbaee3d95c0059f844 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 00:04:32 +0100 Subject: [PATCH 36/50] Added a toVelocyPack serialisation to all Aql Nodes and their dependencies. Right now in parallel to toJson. --- arangod/Aql/AstNode.cpp | 172 +++++++++++++++- arangod/Aql/AstNode.h | 13 ++ arangod/Aql/ClusterNodes.cpp | 83 ++++++++ arangod/Aql/ClusterNodes.h | 28 +++ arangod/Aql/CollectNode.cpp | 69 +++++++ arangod/Aql/CollectNode.h | 7 + arangod/Aql/CollectOptions.cpp | 11 + arangod/Aql/CollectOptions.h | 7 + arangod/Aql/Condition.cpp | 13 ++ arangod/Aql/Condition.h | 6 + arangod/Aql/ExecutionNode.cpp | 307 ++++++++++++++++++++++++++++ arangod/Aql/ExecutionNode.h | 87 ++++++++ arangod/Aql/Expression.h | 8 + arangod/Aql/Index.cpp | 27 +++ arangod/Aql/Index.h | 6 + arangod/Aql/IndexNode.cpp | 29 +++ arangod/Aql/IndexNode.h | 7 + arangod/Aql/ModificationNodes.cpp | 114 +++++++++++ arangod/Aql/ModificationNodes.h | 42 ++++ arangod/Aql/ModificationOptions.cpp | 12 ++ arangod/Aql/ModificationOptions.h | 2 + arangod/Aql/SortNode.cpp | 24 +++ arangod/Aql/SortNode.h | 7 + arangod/Aql/TraversalNode.cpp | 8 + arangod/Aql/TraversalNode.h | 7 + arangod/Aql/Variable.cpp | 12 ++ arangod/Aql/Variable.h | 6 + 27 files changed, 1109 insertions(+), 5 deletions(-) diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index 43c623147a..b822bc456a 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -1285,11 +1285,88 @@ TRI_json_t* AstNode::toJson(TRI_memory_zone_t* zone, bool verbose) const { ////////////////////////////////////////////////////////////////////////////// std::shared_ptr AstNode::toVelocyPackValue() const { - std::unique_ptr tmp(toJsonValue(TRI_UNKNOWN_MEM_ZONE)); - if (tmp == nullptr) { + auto builder = std::make_shared(); + 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(value.value._int))); + break; + case VALUE_TYPE_DOUBLE: + builder.add(VPackValue(value.value._double)); + break; + case VALUE_TYPE_STRING: + builder.add(VPackValue(value.value._string)); + 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 AstNode::toVelocyPackValue() const { ////////////////////////////////////////////////////////////////////////////// std::shared_ptr AstNode::toVelocyPack(bool verbose) const { - std::unique_ptr tmp(toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); - return arangodb::basics::JsonHelper::toVelocyPack(tmp.get()); + auto builder = std::make_shared(); + 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(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(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(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(getData()); + + TRI_ASSERT(variable != nullptr); + builder.add("name", VPackValue(variable->name)); + builder.add("id", VPackValue(static_cast(variable->id))); + } + + if (type == NODE_TYPE_EXPANSION) { + builder.add("levels", VPackValue(static_cast(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); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/AstNode.h b/arangod/Aql/AstNode.h index 1ee4236039..475be26df1 100644 --- a/arangod/Aql/AstNode.h +++ b/arangod/Aql/AstNode.h @@ -361,12 +361,25 @@ struct AstNode { std::shared_ptr 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 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 diff --git a/arangod/Aql/ClusterNodes.cpp b/arangod/Aql/ClusterNodes.cpp index bb3e2b68ea..37f36654c9 100644 --- a/arangod/Aql/ClusterNodes.cpp +++ b/arangod/Aql/ClusterNodes.cpp @@ -68,6 +68,27 @@ void RemoteNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for RemoteNode +//////////////////////////////////////////////////////////////////////////////// + +void RemoteNode::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("server", VPackValue(_server)); + nodes.add("ownName", VPackValue(_ownName)); + nodes.add("queryId", VPackValue(_queryId)); + nodes.add("isResponsibleForInitCursor", + VPackValue(_isResponsibleForInitCursor)); + + // And close it: + nodes.close(); +} + + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// @@ -115,6 +136,20 @@ void ScatterNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for ScatterNode +//////////////////////////////////////////////////////////////////////////////// + +void ScatterNode::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())); + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// @@ -167,6 +202,28 @@ void DistributeNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for DistributedNode +//////////////////////////////////////////////////////////////////////////////// + +void DistributeNode::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("varId", VPackValue(static_cast(_varId))); + nodes.add("alternativeVarId", + VPackValue(static_cast(_alternativeVarId))); + nodes.add("createKeys", VPackValue(_createKeys)); + nodes.add("allowKeyConversionToObject", + VPackValue(_allowKeyConversionToObject)); + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// @@ -217,6 +274,32 @@ void GatherNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for GatherNode +//////////////////////////////////////////////////////////////////////////////// + +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)); + } + } + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ClusterNodes.h b/arangod/Aql/ClusterNodes.h index b435943bbe..20ea890d8d 100644 --- a/arangod/Aql/ClusterNodes.h +++ b/arangod/Aql/ClusterNodes.h @@ -98,6 +98,13 @@ class RemoteNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -246,6 +253,13 @@ class ScatterNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -339,6 +353,13 @@ class DistributeNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -444,6 +465,13 @@ class GatherNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectNode.cpp b/arangod/Aql/CollectNode.cpp index 558559df06..1ae21fd8c3 100644 --- a/arangod/Aql/CollectNode.cpp +++ b/arangod/Aql/CollectNode.cpp @@ -126,6 +126,75 @@ void CollectNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for CollectNode +//////////////////////////////////////////////////////////////////////////////// + +void CollectNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + // group variables + nodes.add(VPackValue("groups")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& groupVariable : _groupVariables) { + VPackObjectBuilder obj(&nodes); + nodes.add(VPackValue("outVariable")); + groupVariable.first->toVelocyPack(nodes); + nodes.add(VPackValue("inVariable")); + groupVariable.second->toVelocyPack(nodes); + } + } + + // aggregate variables + nodes.add(VPackValue("aggregates")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& aggregateVariable : _aggregateVariables) { + 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)); + } + } + + // expression variable might be empty + if (_expressionVariable != nullptr) { + nodes.add(VPackValue("expressionVariable")); + _expressionVariable->toVelocyPack(nodes); + } + + // output variable might be empty + if (_outVariable != nullptr) { + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); + } + + if (!_keepVariables.empty()) { + nodes.add(VPackValue("keepVariables")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& it : _keepVariables) { + VPackObjectBuilder obj(&nodes); + nodes.add(VPackValue("variable")); + it->toVelocyPack(nodes); + } + } + } + + nodes.add("count", VPackValue(_count)); + nodes.add("isDistinctCommand", VPackValue(_isDistinctCommand)); + nodes.add("specialized", VPackValue(_specialized)); + nodes.add(VPackValue("collectOptions")); + _options.toVelocyPack(nodes); + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectNode.h b/arangod/Aql/CollectNode.h index c732aa1872..4140761283 100644 --- a/arangod/Aql/CollectNode.h +++ b/arangod/Aql/CollectNode.h @@ -151,6 +151,13 @@ class CollectNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectOptions.cpp b/arangod/Aql/CollectOptions.cpp index f681e3b515..38345608c1 100644 --- a/arangod/Aql/CollectOptions.cpp +++ b/arangod/Aql/CollectOptions.cpp @@ -24,6 +24,8 @@ #include "Aql/CollectOptions.h" #include "Basics/Exceptions.h" +#include + 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 //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectOptions.h b/arangod/Aql/CollectOptions.h index d4dab3cb38..c0f9ba1d8c 100644 --- a/arangod/Aql/CollectOptions.h +++ b/arangod/Aql/CollectOptions.h @@ -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 ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Condition.cpp b/arangod/Aql/Condition.cpp index d64adc5aea..79f9e39cab 100644 --- a/arangod/Aql/Condition.cpp +++ b/arangod/Aql/Condition.cpp @@ -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 //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Condition.h b/arangod/Aql/Condition.h index 494c4fc610..bc3945bdc6 100644 --- a/arangod/Aql/Condition.h +++ b/arangod/Aql/Condition.h @@ -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 ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index af3d74a374..ae98cc4f3f 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -445,6 +445,23 @@ arangodb::basics::Json ExecutionNode::toJson(TRI_memory_zone_t* zone, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, export an ExecutionNode to VelocyPack +//////////////////////////////////////////////////////////////////////////////// + +void ExecutionNode::toVelocyPack(VPackBuilder& builder, bool verbose) const { + ENTER_BLOCK + 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 //////////////////////////////////////////////////////////////////////////////// @@ -770,6 +787,124 @@ arangodb::basics::Json ExecutionNode::toJsonHelperGeneric( LEAVE_BLOCK } + +//////////////////////////////////////////////////////////////////////////////// +/// @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. +//////////////////////////////////////////////////////////////////////////////// + +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]->toVelocyPackHelper(nodes, verbose); + } + nodes.openObject(); + nodes.add("type", VPackValue(getTypeString())); + if (verbose) { + nodes.add("typeId", VPackValue(static_cast(getType()))); + } + nodes.add(VPackValue("dependencies")); // Open Key + { + VPackArrayBuilder guard(&nodes); + for (auto const& it : _dependencies) { + nodes.add(VPackValue(static_cast(it->id()))); + } + } + if (verbose) { + nodes.add(VPackValue("parents")); // Open Key + VPackArrayBuilder guard(&nodes); + for (auto const& it : _parents) { + nodes.add(VPackValue(static_cast(it->id()))); + } + } + nodes.add("id", VPackValue(static_cast(id()))); + size_t nrItems = 0; + nodes.add("estimateCost", VPackValue(getCost(nrItems))); + nodes.add("estimateNrItems", VPackValue(nrItems)); + + if (verbose) { + nodes.add("depth", VPackValue(static_cast(_depth))); + + if (_registerPlan) { + nodes.add(VPackValue("varInfoList")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneVarInfo : _registerPlan->varInfo) { + VPackObjectBuilder guardInner(&nodes); + nodes.add("VariableId", + VPackValue(static_cast(oneVarInfo.first))); + nodes.add("depth", + VPackValue(static_cast(oneVarInfo.second.depth))); + nodes.add( + "RegisterId", + VPackValue(static_cast(oneVarInfo.second.registerId))); + } + } + nodes.add(VPackValue("nrRegs")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneRegisterID : _registerPlan->nrRegs) { + nodes.add(VPackValue(static_cast(oneRegisterID))); + } + } + nodes.add(VPackValue("nrRegsHere")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneRegisterID : _registerPlan->nrRegsHere) { + nodes.add(VPackValue(static_cast(oneRegisterID))); + } + } + nodes.add("totalNrRegs", VPackValue(_registerPlan->totalNrRegs)); + } else { + 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)); + } + + nodes.add(VPackValue("regsToClear")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneRegisterID : _regsToClear) { + nodes.add(VPackValue(static_cast(oneRegisterID))); + } + } + + nodes.add(VPackValue("varsUsedLater")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneVar : _varsUsedLater) { + oneVar->toVelocyPack(nodes); + } + } + + nodes.add(VPackValue("varsValid")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& oneVar : _varsValid) { + oneVar->toVelocyPack(nodes); + } + } + } + TRI_ASSERT(nodes.isOpenObject()); + LEAVE_BLOCK +} + //////////////////////////////////////////////////////////////////////////////// /// @brief static analysis debugger //////////////////////////////////////////////////////////////////////////////// @@ -1231,6 +1366,22 @@ void SingletonNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for SingletonNode +//////////////////////////////////////////////////////////////////////////////// + +void SingletonNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ENTER_BLOCK + 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 //////////////////////////////////////////////////////////////////////////////// @@ -1275,6 +1426,28 @@ void EnumerateCollectionNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for EnumerateCollectionNode +//////////////////////////////////////////////////////////////////////////////// + +void EnumerateCollectionNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ENTER_BLOCK + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + // Now put info about vocbase and cid in there + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); + nodes.add("collection", VPackValue(_random)); + + // And close it: + nodes.close(); + LEAVE_BLOCK +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// @@ -1340,6 +1513,26 @@ void EnumerateListNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for EnumerateListNode +//////////////////////////////////////////////////////////////////////////////// + +void EnumerateListNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ENTER_BLOCK + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); + + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); + + // And close it: + nodes.close(); + LEAVE_BLOCK +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// @@ -1450,6 +1643,23 @@ void LimitNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +// @brief toVelocyPack, for LimitNode +//////////////////////////////////////////////////////////////////////////////// + +void LimitNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ENTER_BLOCK + + ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose); // call base class method + nodes.add("offset", VPackValue(static_cast(_offset))); + nodes.add("limit", VPackValue(static_cast(_limit))); + nodes.add("fullCount", VPackValue(_fullCount)); + + // And close it: + nodes.close(); + LEAVE_BLOCK +} + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// @@ -1504,6 +1714,35 @@ void CalculationNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for CalculationNode +//////////////////////////////////////////////////////////////////////////////// + +void CalculationNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ENTER_BLOCK + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + nodes.add(VPackValue("expression")); + _expression->toVelocyPack(nodes, verbose); + + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); + + nodes.add("canThrow", VPackValue(_expression->canThrow())); + + if (_conditionVariable != nullptr) { + nodes.add(VPackValue("conditionVariable")); + _conditionVariable->toVelocyPack(nodes); + } + + nodes.add("expressionType", VPackValue(_expression->typeString())); + + // And close it + nodes.close(); + LEAVE_BLOCK +} + ExecutionNode* CalculationNode::clone(ExecutionPlan* plan, bool withDependencies, bool withProperties) const { @@ -1565,6 +1804,25 @@ void SubqueryNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for SubqueryNode +//////////////////////////////////////////////////////////////////////////////// + +void SubqueryNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ENTER_BLOCK + 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.close(); + LEAVE_BLOCK +} + ExecutionNode* SubqueryNode::clone(ExecutionPlan* plan, bool withDependencies, bool withProperties) const { auto outVariable = _outVariable; @@ -1760,6 +2018,23 @@ void FilterNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for FilterNode +//////////////////////////////////////////////////////////////////////////////// + +void FilterNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ENTER_BLOCK + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); + + // And close it: + nodes.close(); + LEAVE_BLOCK +} + ExecutionNode* FilterNode::clone(ExecutionPlan* plan, bool withDependencies, bool withProperties) const { auto inVariable = _inVariable; @@ -1819,6 +2094,24 @@ void ReturnNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for ReturnNode +//////////////////////////////////////////////////////////////////////////////// + +void ReturnNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ENTER_BLOCK + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); + + // And close it: + nodes.close(); + LEAVE_BLOCK +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// @@ -1868,6 +2161,20 @@ void NoResultsNode::toJsonHelper(arangodb::basics::Json& nodes, LEAVE_BLOCK } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for NoResultsNode +//////////////////////////////////////////////////////////////////////////////// + +void NoResultsNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ENTER_BLOCK + ExecutionNode::toVelocyPackHelperGeneric(nodes, verbose); + + //And close it + nodes.close(); + LEAVE_BLOCK +} + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost, the cost of a NoResults is nearly 0 //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index dd568e6b94..952b330162 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -35,6 +35,10 @@ #include "VocBase/vocbase.h" namespace arangodb { +namespace velocypack { +class Builder; +} + namespace aql { class Ast; struct Collection; @@ -454,6 +458,12 @@ class ExecutionNode { arangodb::basics::Json toJson(TRI_memory_zone_t*, bool) const; + /////////////////////////////////////////////////////////////////////////////// + /// @brief toVelocyPack, export an ExecutionNode to VelocyPack + /////////////////////////////////////////////////////////////////////////////// + + void toVelocyPack(arangodb::velocypack::Builder&, bool) const; + ////////////////////////////////////////////////////////////////////////////// /// @brief toJson ////////////////////////////////////////////////////////////////////////////// @@ -461,6 +471,13 @@ class ExecutionNode { virtual void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const = 0; + ////////////////////////////////////////////////////////////////////////////// + /// @brief toVelocyPack + ////////////////////////////////////////////////////////////////////////////// + + virtual void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const = 0; + ////////////////////////////////////////////////////////////////////////////// /// @brief getVariablesUsedHere, returning a vector ////////////////////////////////////////////////////////////////////////////// @@ -705,6 +722,12 @@ class ExecutionNode { arangodb::basics::Json toJsonHelperGeneric(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const; + ////////////////////////////////////////////////////////////////////////////// + /// @brief toVelocyPackHelper, for a generic node + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelperGeneric(arangodb::velocypack::Builder&, bool) const; + ////////////////////////////////////////////////////////////////////////////// /// @brief set regs to be deleted ////////////////////////////////////////////////////////////////////////////// @@ -835,6 +858,13 @@ class SingletonNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -898,6 +928,13 @@ class EnumerateCollectionNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -1006,6 +1043,13 @@ class EnumerateListNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -1107,6 +1151,13 @@ class LimitNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -1212,6 +1263,13 @@ class CalculationNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -1371,6 +1429,13 @@ class SubqueryNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -1490,6 +1555,13 @@ class FilterNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -1619,6 +1691,13 @@ class ReturnNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -1690,6 +1769,14 @@ class NoResultsNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Expression.h b/arangod/Aql/Expression.h index 143dc65bc3..50a711a476 100644 --- a/arangod/Aql/Expression.h +++ b/arangod/Aql/Expression.h @@ -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 ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Index.cpp b/arangod/Aql/Index.cpp index ff58ae771a..f7c1160612 100644 --- a/arangod/Aql/Index.cpp +++ b/arangod/Aql/Index.cpp @@ -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 //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Index.h b/arangod/Aql/Index.h index f568d5a94b..3b4aae71e5 100644 --- a/arangod/Aql/Index.h +++ b/arangod/Aql/Index.h @@ -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; diff --git a/arangod/Aql/IndexNode.cpp b/arangod/Aql/IndexNode.cpp index 3c196f3cf0..63de18243c 100644 --- a/arangod/Aql/IndexNode.cpp +++ b/arangod/Aql/IndexNode.cpp @@ -65,6 +65,35 @@ void IndexNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for IndexNode +//////////////////////////////////////////////////////////////////////////////// + +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 + nodes.add("database", VPackValue(_vocbase->_name)); + nodes.add("collection", VPackValue(_collection->getName())); + nodes.add(VPackValue("outVariable")); + _outVariable->toVelocyPack(nodes); + + 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)); + + // And close it: + nodes.close(); +} + ExecutionNode* IndexNode::clone(ExecutionPlan* plan, bool withDependencies, bool withProperties) const { auto outVariable = _outVariable; diff --git a/arangod/Aql/IndexNode.h b/arangod/Aql/IndexNode.h index e5497d40b6..80d7c50eb7 100644 --- a/arangod/Aql/IndexNode.h +++ b/arangod/Aql/IndexNode.h @@ -114,6 +114,13 @@ class IndexNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ModificationNodes.cpp b/arangod/Aql/ModificationNodes.cpp index 39f6e96289..ced840ade0 100644 --- a/arangod/Aql/ModificationNodes.cpp +++ b/arangod/Aql/ModificationNodes.cpp @@ -67,6 +67,31 @@ void ModificationNode::toJsonHelper(arangodb::basics::Json& json, _options.toJson(json, zone); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack +//////////////////////////////////////////////////////////////////////////////// + +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 + builder.add("database", VPackValue(_vocbase->_name)); + builder.add("collection", VPackValue(_collection->getName())); + + // add out variables + if (_outVariableOld != nullptr) { + builder.add(VPackValue("outVariableOld")); + _outVariableOld->toVelocyPack(builder); + } + if (_outVariableNew != nullptr) { + builder.add(VPackValue("outVariableNew")); + _outVariableNew->toVelocyPack(builder); + } + builder.add(VPackValue("modificationFlags")); + _options.toVelocyPack(builder); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief estimateCost /// Note that all the modifying nodes use this estimateCost method which is @@ -112,6 +137,19 @@ void RemoveNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toJson +//////////////////////////////////////////////////////////////////////////////// + +void RemoveNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ModificationNode::toVelocyPackHelper(nodes, verbose); + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// @@ -163,6 +201,22 @@ void InsertNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack +//////////////////////////////////////////////////////////////////////////////// + +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 + nodes.add(VPackValue("inVariable")); + _inVariable->toVelocyPack(nodes); + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// @@ -221,6 +275,26 @@ void UpdateNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack +//////////////////////////////////////////////////////////////////////////////// + +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) { + nodes.add(VPackValue("inKeyVariable")); + _inKeyVariable->toVelocyPack(nodes); + } + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// @@ -291,6 +365,26 @@ void ReplaceNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack +//////////////////////////////////////////////////////////////////////////////// + +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) { + nodes.add(VPackValue("inKeyVariable")); + _inKeyVariable->toVelocyPack(nodes); + } + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// @@ -359,6 +453,26 @@ void UpsertNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack +//////////////////////////////////////////////////////////////////////////////// + +void UpsertNode::toVelocyPackHelper(VPackBuilder& nodes, + bool verbose) const { + ModificationNode::toVelocyPackHelper(nodes, verbose); + + 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)); + + // And close it: + nodes.close(); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ModificationNodes.h b/arangod/Aql/ModificationNodes.h index 595ce943d7..f0421de28e 100644 --- a/arangod/Aql/ModificationNodes.h +++ b/arangod/Aql/ModificationNodes.h @@ -76,6 +76,13 @@ class ModificationNode : public ExecutionNode { virtual void toJsonHelper(arangodb::basics::Json& json, TRI_memory_zone_t* zone, bool) const override; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + virtual void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override; + public: ////////////////////////////////////////////////////////////////////////////// /// @brief return the database @@ -220,6 +227,13 @@ class RemoveNode : public ModificationNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -287,6 +301,13 @@ class InsertNode : public ModificationNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -360,6 +381,13 @@ class UpdateNode : public ModificationNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -450,6 +478,13 @@ class ReplaceNode : public ModificationNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// @@ -546,6 +581,13 @@ class UpsertNode : public ModificationNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ModificationOptions.cpp b/arangod/Aql/ModificationOptions.cpp index f524f1c5dc..81bf4c44bc 100644 --- a/arangod/Aql/ModificationOptions.cpp +++ b/arangod/Aql/ModificationOptions.cpp @@ -23,6 +23,8 @@ #include "Aql/ModificationOptions.h" +#include + 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)); +} diff --git a/arangod/Aql/ModificationOptions.h b/arangod/Aql/ModificationOptions.h index d6f8939f21..b119124b89 100644 --- a/arangod/Aql/ModificationOptions.h +++ b/arangod/Aql/ModificationOptions.h @@ -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; diff --git a/arangod/Aql/SortNode.cpp b/arangod/Aql/SortNode.cpp index 6de2b6ec85..041743303c 100644 --- a/arangod/Aql/SortNode.cpp +++ b/arangod/Aql/SortNode.cpp @@ -61,6 +61,30 @@ void SortNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for SortNode +//////////////////////////////////////////////////////////////////////////////// + +void SortNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + 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)); + } + } + nodes.add("stable", VPackValue(_stable)); + + // And close it: + nodes.close(); +} + class SortNodeFindMyExpressions : public WalkerWorker { public: size_t _foundCalcNodes; diff --git a/arangod/Aql/SortNode.h b/arangod/Aql/SortNode.h index 8976f5cb2e..8836a452cd 100644 --- a/arangod/Aql/SortNode.h +++ b/arangod/Aql/SortNode.h @@ -79,6 +79,13 @@ class SortNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/TraversalNode.cpp b/arangod/Aql/TraversalNode.cpp index f03e68efe2..34b4a8e084 100644 --- a/arangod/Aql/TraversalNode.cpp +++ b/arangod/Aql/TraversalNode.cpp @@ -516,6 +516,14 @@ void TraversalNode::toJsonHelper(arangodb::basics::Json& nodes, nodes(json); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief toVelocyPack, for TraversalNode +//////////////////////////////////////////////////////////////////////////////// + +void TraversalNode::toVelocyPackHelper(arangodb::velocypack::Builder& nodes, + bool verbose) const { +} + //////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/TraversalNode.h b/arangod/Aql/TraversalNode.h index 497f916c95..67c783d754 100644 --- a/arangod/Aql/TraversalNode.h +++ b/arangod/Aql/TraversalNode.h @@ -109,6 +109,13 @@ class TraversalNode : public ExecutionNode { void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, bool) const override final; + ////////////////////////////////////////////////////////////////////////////// + /// @brief export to VelocyPack + ////////////////////////////////////////////////////////////////////////////// + + void toVelocyPackHelper(arangodb::velocypack::Builder&, + bool) const override final; + ////////////////////////////////////////////////////////////////////////////// /// @brief clone ExecutionNode recursively ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Variable.cpp b/arangod/Aql/Variable.cpp index 03cdc2a108..7bfa9aef39 100644 --- a/arangod/Aql/Variable.cpp +++ b/arangod/Aql/Variable.cpp @@ -24,6 +24,8 @@ #include "Variable.h" #include "Basics/JsonHelper.h" +#include + 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(id))); + builder.add("name", VPackValue(name)); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief replace a variable by another //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Variable.h b/arangod/Aql/Variable.h index bd06035060..2b612570c4 100644 --- a/arangod/Aql/Variable.h +++ b/arangod/Aql/Variable.h @@ -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 ////////////////////////////////////////////////////////////////////////////// From 948951ebe3ec111ee6565b7de620ace7c0b74923 Mon Sep 17 00:00:00 2001 From: hkernbach Date: Tue, 16 Feb 2016 09:47:28 +0100 Subject: [PATCH 37/50] remove index tab when collection not loaded --- .../aardvark/APP/frontend/js/views/collectionsItemView.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js index 949e7f98a2..2b14394197 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js @@ -357,7 +357,12 @@ this.events, null, tabBar ); - this.getIndex(); + if (this.model.get("status") === 'loaded') { + this.getIndex(); + } + else { + $($('#infoTab').children()[1]).remove(); + } this.bindIndexEvents(); }, From f32750e1ac561e5b178753d78723459cda737e90 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 10:29:38 +0100 Subject: [PATCH 38/50] Removed obsolete toJson from AQL Nodes --- arangod/Aql/ClusterNodes.cpp | 94 --------- arangod/Aql/ClusterNodes.h | 28 --- arangod/Aql/CollectNode.cpp | 73 ------- arangod/Aql/CollectNode.h | 7 - arangod/Aql/ExecutionEngine.cpp | 18 +- arangod/Aql/ExecutionNode.cpp | 328 ------------------------------ arangod/Aql/ExecutionNode.h | 83 -------- arangod/Aql/ExecutionPlan.cpp | 6 +- arangod/Aql/Graphs.cpp | 22 ++ arangod/Aql/Graphs.h | 6 + arangod/Aql/IndexNode.cpp | 33 --- arangod/Aql/IndexNode.h | 7 - arangod/Aql/ModificationNodes.cpp | 143 ------------- arangod/Aql/ModificationNodes.h | 42 ---- arangod/Aql/SortNode.cpp | 27 --- arangod/Aql/SortNode.h | 7 - arangod/Aql/TraversalNode.cpp | 161 ++++++++------- arangod/Aql/TraversalNode.h | 9 +- 18 files changed, 133 insertions(+), 961 deletions(-) diff --git a/arangod/Aql/ClusterNodes.cpp b/arangod/Aql/ClusterNodes.cpp index 37f36654c9..e20fa1c198 100644 --- a/arangod/Aql/ClusterNodes.cpp +++ b/arangod/Aql/ClusterNodes.cpp @@ -44,30 +44,6 @@ RemoteNode::RemoteNode(ExecutionPlan* plan, arangodb::basics::Json const& base) _isResponsibleForInitCursor(JsonHelper::checkAndGetBooleanValue( base.json(), "isResponsibleForInitCursor")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, 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; - } - - 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)); - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for RemoteNode //////////////////////////////////////////////////////////////////////////////// @@ -117,25 +93,6 @@ ScatterNode::ScatterNode(ExecutionPlan* plan, _collection(plan->getAst()->query()->collections()->get( JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, 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; - } - - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName())); - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for ScatterNode //////////////////////////////////////////////////////////////////////////////// @@ -180,28 +137,6 @@ 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 - - if (json.isEmpty()) { - return; - } - - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName()))( - "varId", arangodb::basics::Json(static_cast(_varId)))( - "alternativeVarId", - arangodb::basics::Json(static_cast(_alternativeVarId)))( - "createKeys", arangodb::basics::Json(_createKeys))( - "allowKeyConversionToObject", - arangodb::basics::Json(_allowKeyConversionToObject)); - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for DistributedNode //////////////////////////////////////////////////////////////////////////////// @@ -245,35 +180,6 @@ GatherNode::GatherNode(ExecutionPlan* plan, arangodb::basics::Json const& base, _collection(plan->getAst()->query()->collections()->get( JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, 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; - } - - 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); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for GatherNode //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ClusterNodes.h b/arangod/Aql/ClusterNodes.h index 20ea890d8d..05468257f5 100644 --- a/arangod/Aql/ClusterNodes.h +++ b/arangod/Aql/ClusterNodes.h @@ -91,13 +91,6 @@ class RemoteNode : public ExecutionNode { NodeType getType() const override final { return REMOTE; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -246,13 +239,6 @@ class ScatterNode : public ExecutionNode { NodeType getType() const override final { return SCATTER; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -346,13 +332,6 @@ class DistributeNode : public ExecutionNode { NodeType getType() const override final { return DISTRIBUTE; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -458,13 +437,6 @@ class GatherNode : public ExecutionNode { NodeType getType() const override final { return GATHER; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectNode.cpp b/arangod/Aql/CollectNode.cpp index 1ae21fd8c3..569f262297 100644 --- a/arangod/Aql/CollectNode.cpp +++ b/arangod/Aql/CollectNode.cpp @@ -53,79 +53,6 @@ CollectNode::CollectNode( CollectNode::~CollectNode() {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, 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; - } - - // group variables - { - arangodb::basics::Json values(arangodb::basics::Json::Array, - _groupVariables.size()); - - for (auto const& groupVariable : _groupVariables) { - arangodb::basics::Json variable(arangodb::basics::Json::Object); - variable("outVariable", groupVariable.first->toJson())( - "inVariable", groupVariable.second->toJson()); - values(variable); - } - json("groups", values); - } - - // aggregate variables - { - arangodb::basics::Json values(arangodb::basics::Json::Array, - _aggregateVariables.size()); - - 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); - } - json("aggregates", values); - } - - // expression variable might be empty - if (_expressionVariable != nullptr) { - json("expressionVariable", _expressionVariable->toJson()); - } - - // output variable might be empty - if (_outVariable != nullptr) { - json("outVariable", _outVariable->toJson()); - } - - 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); - } - json("keepVariables", values); - } - - json("count", arangodb::basics::Json(_count)); - json("isDistinctCommand", arangodb::basics::Json(_isDistinctCommand)); - json("specialized", arangodb::basics::Json(_specialized)); - - _options.toJson(json, zone); - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for CollectNode //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/CollectNode.h b/arangod/Aql/CollectNode.h index 4140761283..e829c178c9 100644 --- a/arangod/Aql/CollectNode.h +++ b/arangod/Aql/CollectNode.h @@ -144,13 +144,6 @@ class CollectNode : public ExecutionNode { CollectOptions& getOptions() { return _options; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index 781128b0f5..c9f21c9c52 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -426,11 +426,9 @@ struct CoordinatorInstanciator : public WalkerWorker { /// @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 { } 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 { 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 tmp(arangodb::basics::VelocyPackHelper::velocyPackToJson(b.slice())); distributePlanToShard(coordTransactionID, info, collection, connectedId, - shardId, jsonPlan.steal()); + shardId, tmp.get()); } // fix collection diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index ae98cc4f3f..92587b6dec 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -427,24 +427,6 @@ ExecutionNode::ExecutionNode(ExecutionPlan* plan, } } -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, export an ExecutionNode to JSON -//////////////////////////////////////////////////////////////////////////////// - -arangodb::basics::Json ExecutionNode::toJson(TRI_memory_zone_t* zone, - 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; - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, export an ExecutionNode to VelocyPack //////////////////////////////////////////////////////////////////////////////// @@ -672,122 +654,6 @@ Variable* ExecutionNode::varFromJson(Ast* ast, return ast->variables()->createVariable(variableJson); } -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJsonHelper, for a generic node -//////////////////////////////////////////////////////////////////////////////// - -arangodb::basics::Json ExecutionNode::toJsonHelperGeneric( - arangodb::basics::Json& nodes, TRI_memory_zone_t* zone, - bool verbose) const { - ENTER_BLOCK - size_t const n = _dependencies.size(); - for (size_t i = 0; i < n; i++) { - _dependencies[i]->toJsonHelper(nodes, zone, verbose); - } - - arangodb::basics::Json json(arangodb::basics::Json::Object, 5); - json("type", arangodb::basics::Json(getTypeString())); - - if (verbose) { - json("typeID", arangodb::basics::Json(static_cast(getType()))); - } - - arangodb::basics::Json deps(arangodb::basics::Json::Array, n); - for (size_t i = 0; i < n; i++) { - deps(arangodb::basics::Json(static_cast(_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(_parents[i]->id()))); - } - json("parents", parents); - } - - json("id", arangodb::basics::Json(static_cast(id()))); - size_t nrItems = 0; - json("estimatedCost", arangodb::basics::Json(getCost(nrItems))); - json("estimatedNrItems", - arangodb::basics::Json(static_cast(nrItems))); - - if (verbose) { - json("depth", arangodb::basics::Json(static_cast(_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(oneVarInfo.first)))( - "depth", arangodb::basics::Json( - static_cast(oneVarInfo.second.depth)))( - "RegisterId", arangodb::basics::Json(static_cast( - oneVarInfo.second.registerId))); - jsonVarInfoList(jsonOneVarInfoArray); - } - 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(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(oneRegisterID))); - } - json("nrRegsHere", jsonNRRegsHereList); - json("totalNrRegs", arangodb::basics::Json( - static_cast(_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)); - } - - arangodb::basics::Json jsonRegsToClearList(arangodb::basics::Json::Array, - _regsToClear.size()); - for (auto const& oneRegisterID : _regsToClear) { - jsonRegsToClearList( - arangodb::basics::Json(static_cast(oneRegisterID))); - } - json("regsToClear", jsonRegsToClearList); - - arangodb::basics::Json jsonVarsUsedLaterList(arangodb::basics::Json::Array, - _varsUsedLater.size()); - for (auto const& oneVarUsedLater : _varsUsedLater) { - jsonVarsUsedLaterList.add(oneVarUsedLater->toJson()); - } - - json("varsUsedLater", jsonVarsUsedLaterList); - - arangodb::basics::Json jsonvarsValidList(arangodb::basics::Json::Array, - _varsValid.size()); - for (auto const& oneVarUsedLater : _varsValid) { - jsonvarsValidList.add(oneVarUsedLater->toJson()); - } - - json("varsValid", jsonvarsValidList); - } - - return json; - LEAVE_BLOCK -} - - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPackHelper, for a generic node /// Note: The input nodes has to be an Array Element that is still Open. @@ -1351,21 +1217,6 @@ 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 { - ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for SingletonNode //////////////////////////////////////////////////////////////////////////////// @@ -1400,32 +1251,6 @@ EnumerateCollectionNode::EnumerateCollectionNode( _outVariable(varFromJson(plan->getAst(), base, "outVariable")), _random(JsonHelper::checkAndGetBooleanValue(base.json(), "random")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for EnumerateCollectionNode -//////////////////////////////////////////////////////////////////////////////// - -void EnumerateCollectionNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, - 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 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)); - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for EnumerateCollectionNode //////////////////////////////////////////////////////////////////////////////// @@ -1492,27 +1317,6 @@ EnumerateListNode::EnumerateListNode(ExecutionPlan* plan, _inVariable(varFromJson(plan->getAst(), base, "inVariable")), _outVariable(varFromJson(plan->getAst(), base, "outVariable")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for EnumerateListNode -//////////////////////////////////////////////////////////////////////////////// - -void EnumerateListNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, - 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()); - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for EnumerateListNode //////////////////////////////////////////////////////////////////////////////// @@ -1621,28 +1425,6 @@ LimitNode::LimitNode(ExecutionPlan* plan, arangodb::basics::Json const& base) _fullCount( JsonHelper::checkAndGetBooleanValue(base.json(), "fullCount")) {} -//////////////////////////////////////////////////////////////////////////////// -// @brief toJson, for LimitNode -//////////////////////////////////////////////////////////////////////////////// - -void LimitNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, 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(_offset)))( - "limit", arangodb::basics::Json(static_cast(_limit)))( - "fullCount", arangodb::basics::Json(_fullCount)); - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// // @brief toVelocyPack, for LimitNode //////////////////////////////////////////////////////////////////////////////// @@ -1684,36 +1466,6 @@ CalculationNode::CalculationNode(ExecutionPlan* plan, _expression(new Expression(plan->getAst(), base)), _canRemoveIfThrows(false) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for CalculationNode -//////////////////////////////////////////////////////////////////////////////// - -void CalculationNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, - bool verbose) const { - ENTER_BLOCK - arangodb::basics::Json json(ExecutionNode::toJsonHelperGeneric( - nodes, zone, verbose)); // call base class method - - if (json.isEmpty()) { - return; - } - - json("expression", _expression->toJson(TRI_UNKNOWN_MEM_ZONE, verbose))( - "outVariable", _outVariable->toJson())( - "canThrow", arangodb::basics::Json(_expression->canThrow())); - - if (_conditionVariable != nullptr) { - json("conditionVariable", _conditionVariable->toJson()); - } - - json("expressionType", arangodb::basics::Json(_expression->typeString())); - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for CalculationNode //////////////////////////////////////////////////////////////////////////////// @@ -1784,26 +1536,6 @@ SubqueryNode::SubqueryNode(ExecutionPlan* plan, _subquery(nullptr), _outVariable(varFromJson(plan->getAst(), base, "outVariable")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for SubqueryNode -//////////////////////////////////////////////////////////////////////////////// - -void SubqueryNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, 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()); - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for SubqueryNode //////////////////////////////////////////////////////////////////////////////// @@ -1998,26 +1730,6 @@ FilterNode::FilterNode(ExecutionPlan* plan, arangodb::basics::Json const& base) : ExecutionNode(plan, base), _inVariable(varFromJson(plan->getAst(), base, "inVariable")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for FilterNode -//////////////////////////////////////////////////////////////////////////////// - -void FilterNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, 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()); - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for FilterNode //////////////////////////////////////////////////////////////////////////////// @@ -2073,27 +1785,6 @@ ReturnNode::ReturnNode(ExecutionPlan* plan, arangodb::basics::Json const& base) : ExecutionNode(plan, base), _inVariable(varFromJson(plan->getAst(), base, "inVariable")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for ReturnNode -//////////////////////////////////////////////////////////////////////////////// - -void ReturnNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, 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()); - - // And add it: - nodes(json); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for ReturnNode //////////////////////////////////////////////////////////////////////////////// @@ -2142,25 +1833,6 @@ double ReturnNode::estimateCost(size_t& nrItems) const { LEAVE_BLOCK } -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for NoResultsNode -//////////////////////////////////////////////////////////////////////////////// - -void NoResultsNode::toJsonHelper(arangodb::basics::Json& nodes, - TRI_memory_zone_t* zone, 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); - LEAVE_BLOCK -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for NoResultsNode //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index 952b330162..3a99936f4d 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -452,25 +452,12 @@ class ExecutionNode { bool walk(WalkerWorker* worker); - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON, returns an AUTOFREE Json object - ////////////////////////////////////////////////////////////////////////////// - - arangodb::basics::Json toJson(TRI_memory_zone_t*, bool) const; - /////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, export an ExecutionNode to VelocyPack /////////////////////////////////////////////////////////////////////////////// void toVelocyPack(arangodb::velocypack::Builder&, bool) const; - ////////////////////////////////////////////////////////////////////////////// - /// @brief toJson - ////////////////////////////////////////////////////////////////////////////// - - virtual void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const = 0; - ////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -715,13 +702,6 @@ class ExecutionNode { arangodb::basics::Json const& oneNode, char const* which); - ////////////////////////////////////////////////////////////////////////////// - /// @brief toJsonHelper, for a generic node - ////////////////////////////////////////////////////////////////////////////// - - arangodb::basics::Json toJsonHelperGeneric(arangodb::basics::Json&, - TRI_memory_zone_t*, bool) const; - ////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPackHelper, for a generic node ////////////////////////////////////////////////////////////////////////////// @@ -851,13 +831,6 @@ class SingletonNode : public ExecutionNode { NodeType getType() const override final { return SINGLETON; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -921,13 +894,6 @@ class EnumerateCollectionNode : public ExecutionNode { NodeType getType() const override final { return ENUMERATE_COLLECTION; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -1036,13 +1002,6 @@ class EnumerateListNode : public ExecutionNode { NodeType getType() const override final { return ENUMERATE_LIST; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -1144,13 +1103,6 @@ class LimitNode : public ExecutionNode { NodeType getType() const override final { return LIMIT; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -1256,13 +1208,6 @@ class CalculationNode : public ExecutionNode { NodeType getType() const override final { return CALCULATION; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -1422,13 +1367,6 @@ class SubqueryNode : public ExecutionNode { Variable const* outVariable() const { return _outVariable; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -1548,13 +1486,6 @@ class FilterNode : public ExecutionNode { NodeType getType() const override final { return FILTER; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -1684,13 +1615,6 @@ class ReturnNode : public ExecutionNode { NodeType getType() const override final { return RETURN; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -1762,13 +1686,6 @@ class NoResultsNode : public ExecutionNode { NodeType getType() const override final { return NORESULTS; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index fb7c6d4849..30af76e6bc 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -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)); diff --git a/arangod/Aql/Graphs.cpp b/arangod/Aql/Graphs.cpp index ad0c4995ec..679301b5da 100644 --- a/arangod/Aql/Graphs.cpp +++ b/arangod/Aql/Graphs.cpp @@ -24,6 +24,8 @@ #include "Graphs.h" #include "Basics/JsonHelper.h" +#include + 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); diff --git a/arangod/Aql/Graphs.h b/arangod/Aql/Graphs.h index 1cc8b154bb..69efac9373 100644 --- a/arangod/Aql/Graphs.h +++ b/arangod/Aql/Graphs.h @@ -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 diff --git a/arangod/Aql/IndexNode.cpp b/arangod/Aql/IndexNode.cpp index 63de18243c..ebf7f8578f 100644 --- a/arangod/Aql/IndexNode.cpp +++ b/arangod/Aql/IndexNode.cpp @@ -32,39 +32,6 @@ using namespace arangodb::aql; using JsonHelper = arangodb::basics::JsonHelper; -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, 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; - } - - // 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()); - - arangodb::basics::Json indexes(arangodb::basics::Json::Array, - _indexes.size()); - for (auto& index : _indexes) { - indexes.add(index->toJson()); - } - - json("indexes", indexes); - json("condition", _condition->toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); - json("reverse", arangodb::basics::Json(_reverse)); - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for IndexNode //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/IndexNode.h b/arangod/Aql/IndexNode.h index 80d7c50eb7..7096e36df3 100644 --- a/arangod/Aql/IndexNode.h +++ b/arangod/Aql/IndexNode.h @@ -107,13 +107,6 @@ class IndexNode : public ExecutionNode { bool reverse() const { return _reverse; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ModificationNodes.cpp b/arangod/Aql/ModificationNodes.cpp index ced840ade0..abb2bf551a 100644 --- a/arangod/Aql/ModificationNodes.cpp +++ b/arangod/Aql/ModificationNodes.cpp @@ -46,27 +46,6 @@ ModificationNode::ModificationNode(ExecutionPlan* plan, TRI_ASSERT(_collection != nullptr); } -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson -//////////////////////////////////////////////////////////////////////////////// - -void ModificationNode::toJsonHelper(arangodb::basics::Json& json, - TRI_memory_zone_t* zone, bool) const { - // Now put info about vocbase and cid in there - json("database", arangodb::basics::Json(_vocbase->_name))( - "collection", arangodb::basics::Json(_collection->getName())); - - // add out variables - if (_outVariableOld != nullptr) { - json("outVariableOld", _outVariableOld->toJson()); - } - if (_outVariableNew != nullptr) { - json("outVariableNew", _outVariableNew->toJson()); - } - - _options.toJson(json, zone); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// @@ -119,28 +98,6 @@ 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 - - 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); -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson -//////////////////////////////////////////////////////////////////////////////// - void RemoveNode::toVelocyPackHelper(VPackBuilder& nodes, bool verbose) const { ModificationNode::toVelocyPackHelper(nodes, verbose); nodes.add(VPackValue("inVariable")); @@ -179,28 +136,6 @@ InsertNode::InsertNode(ExecutionPlan* plan, arangodb::basics::Json const& base) : ModificationNode(plan, base), _inVariable(varFromJson(plan->getAst(), base, "inVariable")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson -//////////////////////////////////////////////////////////////////////////////// - -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; - } - - // Now put info about vocbase and cid in there - json("inVariable", _inVariable->toJson()); - - ModificationNode::toJsonHelper(json, zone, verbose); - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// @@ -248,33 +183,6 @@ UpdateNode::UpdateNode(ExecutionPlan* plan, arangodb::basics::Json const& base) _inKeyVariable( varFromJson(plan->getAst(), base, "inKeyVariable", Optional)) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson -//////////////////////////////////////////////////////////////////////////////// - -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); - - // inKeyVariable might be empty - if (_inKeyVariable != nullptr) { - json("inKeyVariable", _inKeyVariable->toJson()); - } - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// @@ -338,33 +246,6 @@ ReplaceNode::ReplaceNode(ExecutionPlan* plan, _inKeyVariable( varFromJson(plan->getAst(), base, "inKeyVariable", Optional)) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson -//////////////////////////////////////////////////////////////////////////////// - -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); - - // inKeyVariable might be empty - if (_inKeyVariable != nullptr) { - json("inKeyVariable", _inKeyVariable->toJson()); - } - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// @@ -429,30 +310,6 @@ UpsertNode::UpsertNode(ExecutionPlan* plan, arangodb::basics::Json const& base) _isReplace( JsonHelper::checkAndGetBooleanValue(base.json(), "isReplace")) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson -//////////////////////////////////////////////////////////////////////////////// - -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 - - if (json.isEmpty()) { - return; - } - - 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); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ModificationNodes.h b/arangod/Aql/ModificationNodes.h index f0421de28e..fa20e62baa 100644 --- a/arangod/Aql/ModificationNodes.h +++ b/arangod/Aql/ModificationNodes.h @@ -69,13 +69,6 @@ class ModificationNode : public ExecutionNode { ModificationNode(ExecutionPlan*, arangodb::basics::Json const& json); - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - virtual void toJsonHelper(arangodb::basics::Json& json, - TRI_memory_zone_t* zone, bool) const override; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -220,13 +213,6 @@ class RemoveNode : public ModificationNode { NodeType getType() const override final { return REMOVE; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -294,13 +280,6 @@ class InsertNode : public ModificationNode { NodeType getType() const override final { return INSERT; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -374,13 +353,6 @@ class UpdateNode : public ModificationNode { NodeType getType() const override final { return UPDATE; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -471,13 +443,6 @@ class ReplaceNode : public ModificationNode { NodeType getType() const override final { return REPLACE; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// @@ -574,13 +539,6 @@ class UpsertNode : public ModificationNode { NodeType getType() const override final { return UPSERT; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/SortNode.cpp b/arangod/Aql/SortNode.cpp index 041743303c..2d5a25ef50 100644 --- a/arangod/Aql/SortNode.cpp +++ b/arangod/Aql/SortNode.cpp @@ -34,33 +34,6 @@ SortNode::SortNode(ExecutionPlan* plan, arangodb::basics::Json const& base, SortElementVector const& elements, bool stable) : ExecutionNode(plan, base), _elements(elements), _stable(stable) {} -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, 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 - - if (json.isEmpty()) { - return; - } - 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)); - - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for SortNode //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/SortNode.h b/arangod/Aql/SortNode.h index 8836a452cd..e5fb8b7531 100644 --- a/arangod/Aql/SortNode.h +++ b/arangod/Aql/SortNode.h @@ -72,13 +72,6 @@ class SortNode : public ExecutionNode { inline bool isStable() const { return _stable; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/TraversalNode.cpp b/arangod/Aql/TraversalNode.cpp index 34b4a8e084..2db9c8ad47 100644 --- a/arangod/Aql/TraversalNode.cpp +++ b/arangod/Aql/TraversalNode.cpp @@ -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(); @@ -444,84 +463,82 @@ int TraversalNode::checkIsOutVariable(size_t variableId) const { return -1; } -//////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, 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 - - if (json.isEmpty()) { - return; - } - - json("database", arangodb::basics::Json(_vocbase->_name))( - "minDepth", arangodb::basics::Json(static_cast(_minDepth)))( - "maxDepth", arangodb::basics::Json(static_cast(_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(d))); - } - json("directions", dirJson); - - // In variable - if (usesInVariable()) { - json("inVariable", inVariable()->toJson()); - } else { - json("vertexId", arangodb::basics::Json(_vertexId)); - } - - if (_condition != nullptr) { - json("condition", _condition->toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); - } - - if (_graphObj != nullptr) { - json("graphDefinition", _graphObj->toJson(TRI_UNKNOWN_MEM_ZONE, verbose)); - } - - // Out variables - if (usesVertexOutVariable()) { - json("vertexOutVariable", vertexOutVariable()->toJson()); - } - if (usesEdgeOutVariable()) { - json("edgeOutVariable", edgeOutVariable()->toJson()); - } - if (usesPathOutVariable()) { - json("pathOutVariable", pathOutVariable()->toJson()); - } - - if (!_expressions.empty()) { - arangodb::basics::Json expressionObject = arangodb::basics::Json( - arangodb::basics::Json::Object, _expressions.size()); - for (auto const& map : _expressions) { - arangodb::basics::Json expressionArray = arangodb::basics::Json( - arangodb::basics::Json::Array, map.second.size()); - for (auto const& x : map.second) { - arangodb::basics::Json exp(zone, arangodb::basics::Json::Object); - auto tmp = dynamic_cast(x); - if (tmp != nullptr) { - tmp->toJson(exp, zone); - } - expressionArray(exp); - } - expressionObject.set(std::to_string(map.first), expressionArray); - } - json("simpleExpressions", expressionObject); - } - // And add it: - nodes(json); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief toVelocyPack, for TraversalNode //////////////////////////////////////////////////////////////////////////////// void TraversalNode::toVelocyPackHelper(arangodb::velocypack::Builder& nodes, bool verbose) const { + ExecutionNode::toVelocyPackHelperGeneric(nodes, + verbose); // call base class method + + 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()); + } + nodes.add(VPackValue("directions")); + { + VPackArrayBuilder guard(&nodes); + for (auto const& d : _directions) { + nodes.add(VPackValue(d)); + } + } + + // In variable + if (usesInVariable()) { + nodes.add(VPackValue("inVariable")); + inVariable()->toVelocyPack(nodes); + } else { + nodes.add("vertexId", VPackValue(_vertexId)); + } + + if (_condition != nullptr) { + nodes.add(VPackValue("condition")); + _condition->toVelocyPack(nodes, verbose); + } + + if (_graphObj != nullptr) { + nodes.add(VPackValue("graphDefinition")); + _graphObj->toVelocyPack(nodes, verbose); + } + + // Out variables + if (usesVertexOutVariable()) { + nodes.add(VPackValue("vertexOutVariable")); + vertexOutVariable()->toVelocyPack(nodes); + } + if (usesEdgeOutVariable()) { + nodes.add(VPackValue("edgeOutVariable")); + edgeOutVariable()->toVelocyPack(nodes); + } + if (usesPathOutVariable()) { + nodes.add(VPackValue("pathOutVariable")); + pathOutVariable()->toVelocyPack(nodes); + } + + if (!_expressions.empty()) { + nodes.add(VPackValue("simpleExpressions")); + VPackObjectBuilder guard(&nodes); + for (auto const& map : _expressions) { + nodes.add(VPackValue(std::to_string(map.first))); + VPackArrayBuilder guard2(&nodes); + for (auto const& x : map.second) { + VPackObjectBuilder guard3(&nodes); + auto tmp = dynamic_cast(x); + if (tmp != nullptr) { + tmp->toVelocyPack(nodes); + } + } + } + } + + // And close it: + nodes.close(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/TraversalNode.h b/arangod/Aql/TraversalNode.h index 67c783d754..42c3bcbda4 100644 --- a/arangod/Aql/TraversalNode.h +++ b/arangod/Aql/TraversalNode.h @@ -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; }; //////////////////////////////////////////////////////////////////////////////// @@ -102,13 +104,6 @@ class TraversalNode : public ExecutionNode { NodeType getType() const override final { return TRAVERSAL; } - ////////////////////////////////////////////////////////////////////////////// - /// @brief export to JSON - ////////////////////////////////////////////////////////////////////////////// - - void toJsonHelper(arangodb::basics::Json&, TRI_memory_zone_t*, - bool) const override final; - ////////////////////////////////////////////////////////////////////////////// /// @brief export to VelocyPack ////////////////////////////////////////////////////////////////////////////// From 9900b006a908d9a2eebf1fa07b836ee6bd247882 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 10:30:00 +0100 Subject: [PATCH 39/50] Indention fix --- lib/Basics/VelocyPackHelper.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Basics/VelocyPackHelper.h b/lib/Basics/VelocyPackHelper.h index f4b4d367d5..20888264b7 100644 --- a/lib/Basics/VelocyPackHelper.h +++ b/lib/Basics/VelocyPackHelper.h @@ -62,8 +62,7 @@ class VelocyPackHelper { 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; From 116f8a822c29eac14dfe4ce5d367239c9de8c993 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 11:15:53 +0100 Subject: [PATCH 40/50] Fixed typos in Attribute Names for toVelocyPack. --- arangod/Aql/ExecutionNode.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 92587b6dec..70c0fab9b2 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -673,7 +673,7 @@ void ExecutionNode::toVelocyPackHelperGeneric(VPackBuilder& nodes, nodes.openObject(); nodes.add("type", VPackValue(getTypeString())); if (verbose) { - nodes.add("typeId", VPackValue(static_cast(getType()))); + nodes.add("typeID", VPackValue(static_cast(getType()))); } nodes.add(VPackValue("dependencies")); // Open Key { @@ -691,8 +691,8 @@ void ExecutionNode::toVelocyPackHelperGeneric(VPackBuilder& nodes, } nodes.add("id", VPackValue(static_cast(id()))); size_t nrItems = 0; - nodes.add("estimateCost", VPackValue(getCost(nrItems))); - nodes.add("estimateNrItems", VPackValue(nrItems)); + nodes.add("estimatedCost", VPackValue(getCost(nrItems))); + nodes.add("estimatedNrItems", VPackValue(nrItems)); if (verbose) { nodes.add("depth", VPackValue(static_cast(_depth))); @@ -1266,7 +1266,7 @@ void EnumerateCollectionNode::toVelocyPackHelper(VPackBuilder& nodes, nodes.add("collection", VPackValue(_collection->getName())); nodes.add(VPackValue("outVariable")); _outVariable->toVelocyPack(nodes); - nodes.add("collection", VPackValue(_random)); + nodes.add("random", VPackValue(_random)); // And close it: nodes.close(); From 85b38d09b933b9a82bcdbc8a3dabb53eea55d868 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 11:34:26 +0100 Subject: [PATCH 41/50] Fixed double free bug in cluster case --- arangod/Aql/ExecutionEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index c9f21c9c52..851f178f46 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -609,7 +609,7 @@ struct CoordinatorInstanciator : public WalkerWorker { std::unique_ptr tmp(arangodb::basics::VelocyPackHelper::velocyPackToJson(b.slice())); distributePlanToShard(coordTransactionID, info, collection, connectedId, - shardId, tmp.get()); + shardId, tmp.release()); } // fix collection From b93e56031bafea4515f415dbd6a93ca3a415aefc Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 13:54:02 +0100 Subject: [PATCH 42/50] Fixed handling of Null Bytes in AqlValue for VPack. --- arangod/Aql/AstNode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index b822bc456a..437e9d3bcd 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -1315,7 +1315,7 @@ void AstNode::toVelocyPackValue(VPackBuilder& builder) const { builder.add(VPackValue(value.value._double)); break; case VALUE_TYPE_STRING: - builder.add(VPackValue(value.value._string)); + builder.add(VPackValue(std::string(value.value._string, value.length))); break; } return; From 8295bae5b35179ff75f874f757c3e13dcceaef49 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 14:07:10 +0100 Subject: [PATCH 43/50] Added generated files --- .../APP/frontend/js/bootstrap/errors.js | 17 -- .../frontend/js/bootstrap/modules/internal.js | 19 +- .../js/modules/client/@arangodb/arangosh.js | 4 +- js/common/bootstrap/errors.js | 17 -- lib/Basics/voc-errors.cpp | 17 -- lib/Basics/voc-errors.h | 206 ------------------ 6 files changed, 15 insertions(+), 265 deletions(-) diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/errors.js b/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/errors.js index ecc78d3068..61ece84fdb 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/errors.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/errors.js @@ -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" }, diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/modules/internal.js b/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/modules/internal.js index bf77d6db2e..58e15bff00 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/modules/internal.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/bootstrap/modules/internal.js @@ -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}`; }; diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/modules/client/@arangodb/arangosh.js b/js/apps/system/_admin/aardvark/APP/frontend/js/modules/client/@arangodb/arangosh.js index 6578f7eae9..b40a760068 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/modules/client/@arangodb/arangosh.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/modules/client/@arangodb/arangosh.js @@ -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 diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index ecc78d3068..61ece84fdb 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -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" }, diff --git a/lib/Basics/voc-errors.cpp b/lib/Basics/voc-errors.cpp index f5b7c53eeb..37e254c4b5 100644 --- a/lib/Basics/voc-errors.cpp +++ b/lib/Basics/voc-errors.cpp @@ -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"); diff --git a/lib/Basics/voc-errors.h b/lib/Basics/voc-errors.h index 3c94da08f4..d8abba6e5f 100644 --- a/lib/Basics/voc-errors.h +++ b/lib/Basics/voc-errors.h @@ -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 /// From 7388345f875294b2af382b46f41f800e2ba2de98 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 16 Feb 2016 15:18:40 +0100 Subject: [PATCH 44/50] Fixed JSLINT --- js/server/tests/aql/aql-functions-numeric.js | 7 ++++--- js/server/tests/aql/aql-operators.js | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/js/server/tests/aql/aql-functions-numeric.js b/js/server/tests/aql/aql-functions-numeric.js index adaca62426..9fd7b93843 100644 --- a/js/server/tests/aql/aql-functions-numeric.js +++ b/js/server/tests/aql/aql-functions-numeric.js @@ -138,20 +138,21 @@ 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)"); + var i = 0; assertEqual(actual.length, expected.length); - for (var i = 0; i < expected.length; ++i) { + 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(actual.length, expected.length); - for (var i = 0; i < expected.length; ++i) { + 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(actual.length, expected.length); - for (var i = 0; i < expected.length; ++i) { + for (i = 0; i < expected.length; ++i) { assertEqual(expected[i].toPrecision(5), actual[i].toPrecision(5)); } }, diff --git a/js/server/tests/aql/aql-operators.js b/js/server/tests/aql/aql-operators.js index 826f812f82..61a9bb070e 100644 --- a/js/server/tests/aql/aql-operators.js +++ b/js/server/tests/aql/aql-operators.js @@ -643,7 +643,7 @@ function ahuacatlOperatorsTestSuite () { {ex: null, val: "{ 'a' : true, 'b' : 0 }"}, {ex: null, val: "{ 'a' : { }, 'b' : { } }"}, {ex: null, val: "{ 'a' : [ ], 'b' : [ ] }"} - ] + ]; values.forEach(function(v) { // double precission check for e=0.0001 var q = `RETURN TO_NUMBER(${v.val})`; @@ -698,7 +698,7 @@ function ahuacatlOperatorsTestSuite () { values.forEach(function(v) { var q = `RETURN TO_STRING(${v.val})`; assertEqual(v.ex, db._query(q).next(), q); - var q = `RETURN NOOPT(TO_STRING(${v.val}))`; + q = `RETURN NOOPT(TO_STRING(${v.val}))`; assertEqual(v.ex, db._query(q).next(), q); }); }, From b4286a66fc5b25682bde14eb6701626a1d12bd33 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Tue, 16 Feb 2016 16:30:59 +0100 Subject: [PATCH 45/50] added USE_FAILURE_TESTS --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d005d24309..b60c4609f9 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,6 +192,13 @@ if (USE_MAINTAINER_MODE) add_definitions("-DTRI_ENABLE_MAINTAINER_MODE=1") endif() +# Maintainer mode (Failure Tests) ---------------------------------------------- +option(USE_FAILURE_TESTS + "whether we want to have failure tests compiled in" OFF) +if (USE_FAILURE_TESTS) + add_definitions("-DTRI_ENABLE_FAILURE_TESTS=1") +endif() + # Enable relative paths to binaries -------------------------------------------- option(USE_RELATIVE "Do you want to have all path are relative to the binary" OFF) From 6f348eec861a7148aef087fda1859a55b310ac78 Mon Sep 17 00:00:00 2001 From: Kaveh Vahedipour Date: Tue, 16 Feb 2016 15:38:06 +0000 Subject: [PATCH 46/50] Logger handles now operator<< std::vector and std::unordered_list. And etcd builds. --- 3rdParty/CMakeLists.txt | 14 ++++++++++++++ lib/Basics/Logger.h | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index 7a8013ae01..1a963f0d9e 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -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 diff --git a/lib/Basics/Logger.h b/lib/Basics/Logger.h index 0be2a1a7b3..fefdaf302d 100644 --- a/lib/Basics/Logger.h +++ b/lib/Basics/Logger.h @@ -512,6 +512,20 @@ class LoggerStream { return *this; } + template + LoggerStream& operator<<(std::vector const& v) { + for (auto const& i : v) + _out << i << " "; + return *this; + } + + template + LoggerStream& operator<<(std::unordered_set const& us) { + for (auto const& i : us) + _out << i; + return *this; + } + private: std::stringstream _out; size_t _topicId; From 6278621804732127e42a7fa7053b89cb5fada0cf Mon Sep 17 00:00:00 2001 From: hkernbach Date: Tue, 16 Feb 2016 20:12:20 +0100 Subject: [PATCH 47/50] improved webui when using big collections --- .../aardvark/APP/frontend/js/arango/arango.js | 6 +- .../js/models/arangoCollectionModel.js | 7 ++- .../js/templates/collectionsItemView.ejs | 8 ++- .../frontend/js/templates/collectionsView.ejs | 15 ----- .../frontend/js/views/collectionsItemView.js | 63 +++++++++++++++---- .../APP/frontend/js/views/collectionsView.js | 45 ++++++++++++- .../APP/frontend/scss/_collection.scss | 7 +++ .../aardvark/APP/frontend/scss/_colors.scss | 1 + .../APP/frontend/scss/_documentsView.scss | 12 +++- .../aardvark/APP/frontend/scss/_modals.scss | 2 +- .../aardvark/APP/frontend/scss/_tiles.scss | 47 ++++++++++++++ 11 files changed, 173 insertions(+), 40 deletions(-) diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/arango/arango.js b/js/apps/system/_admin/aardvark/APP/frontend/js/arango/arango.js index 9f88e52a70..aeb4115e88 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/arango/arango.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/arango/arango.js @@ -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); + } } }); } diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/models/arangoCollectionModel.js b/js/apps/system/_admin/aardvark/APP/frontend/js/models/arangoCollectionModel.js index 87861d4c0e..62c200bb96 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/models/arangoCollectionModel.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/models/arangoCollectionModel.js @@ -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(); }, diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsItemView.ejs b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsItemView.ejs index fbccc27138..ecabcb9476 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsItemView.ejs +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsItemView.ejs @@ -18,5 +18,11 @@ -
<%= model.get('name') %>
+ +<% if(model.get('lockType') === "index") { %> + +
<%= model.get('name') %>
+<% } else { %> +
<%= model.get('name') %>
+<% } %> diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs index d0d899121a..3abb90de72 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/templates/collectionsView.ejs @@ -115,19 +115,4 @@ - - - diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js index 2b14394197..598ce69cab 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsItemView.js @@ -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} @@ -394,6 +407,7 @@ }); $('#infoTab a').bind('click', function(e) { + $('#indexDeleteModal').remove(); if ($(e.currentTarget).html() === 'Indices' && !$(e.currentTarget).parent().hasClass('active')) { $('#newIndexView').hide(); @@ -518,7 +532,6 @@ break; } var callback = function(error, msg){ - if (error) { if (msg) { var message = JSON.parse(msg.responseText); @@ -531,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, @@ -550,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( + ''); + $('#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( + '' + ); } - }; + 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( + '' + ); }, selectIndexType: function () { @@ -637,7 +675,6 @@ } else { - console.log("toggle else"); $('#indexEditView').show(); $('#newIndexView').hide(); $('#addIndex').detach().appendTo('#modal-dialog .modal-footer'); diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js index a8a3538ce9..d1b2cee45a 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/views/collectionsView.js @@ -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(); diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss index c601a99b12..4a7e06af97 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_collection.scss @@ -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, diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss index 5c677dbfe3..9fa9ca2c6c 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_colors.scss @@ -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; diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss index 4130a848ba..a83449317a 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_documentsView.scss @@ -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; + } } } diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss index 416d294520..037829924b 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_modals.scss @@ -39,7 +39,7 @@ } .modal-tabbar { - border-bottom: 1px solid $c-black; + border-bottom: 1px solid $c-darker-grey; } .modal-body { diff --git a/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss b/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss index 6cbeb9271f..7d7de761bd 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss +++ b/js/apps/system/_admin/aardvark/APP/frontend/scss/_tiles.scss @@ -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 { From 4f821750a4c20736f7818efa524f6fd49e3931a5 Mon Sep 17 00:00:00 2001 From: hkernbach Date: Tue, 16 Feb 2016 20:12:36 +0100 Subject: [PATCH 48/50] grunt build --- .../APP/clusterFrontend/build/cluster.js | 6 +- .../APP/clusterFrontend/build/cluster.js.gz | Bin 34575 -> 34577 bytes .../clusterFrontend/build/style-minified.css | 2 +- .../build/style-minified.css.gz | Bin 26107 -> 26202 bytes .../APP/clusterFrontend/build/style.css | 56 +++++++- .../APP/clusterFrontend/build/style.css.gz | Bin 40649 -> 41123 bytes .../_admin/aardvark/APP/frontend/build/app.js | 128 ++++++++++++++---- .../aardvark/APP/frontend/build/app.js.gz | Bin 284338 -> 284947 bytes .../APP/frontend/build/standalone-min.html | 23 +--- .../APP/frontend/build/standalone-min.html.gz | Bin 25202 -> 25093 bytes .../APP/frontend/build/standalone.html | 23 +--- .../APP/frontend/build/style-minified.css | 4 +- .../APP/frontend/build/style-minified.css.gz | Bin 41943 -> 42195 bytes .../aardvark/APP/frontend/build/style.css | 43 +++++- .../aardvark/APP/frontend/build/style.css.gz | Bin 48565 -> 48836 bytes 15 files changed, 220 insertions(+), 65 deletions(-) diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js index 004f26f4ca..0b03d2d333 100644 --- a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js +++ b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js @@ -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); + } } }); } diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js.gz b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/cluster.js.gz index e0a932e87119a2e464b760b24a1a26be7863123b..0e7730d1560edc5c1afda0d69c321dffea1c15b6 100644 GIT binary patch delta 31996 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 delta 31994 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 diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css index f26a8f942f..76b33f6f36 100644 --- a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css +++ b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css @@ -1,4 +1,4 @@ @charset "UTF-8";.fa.fa-pull-left,.fa.pull-left{margin-right:.3em}.fa,.fa-stack{display:inline-block}.clusterDownBtn,.clusterDownBtn button,.fa-fw,.fa-li,.fa-stack-1x,.fa-stack-2x,.footer,.modal-body th .valueCell,.modal-body th th.actionCell,.modal-body th th.keyCell,.waitModal,div.toolbox div.gv_action_button{text-align:center}.page-title span,.pingback a.url,body,input,textarea{font-family:'Open Sans',sans-serif!important;font-weight:400}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;src:local("Open Sans Light"),local("OpenSans-Light"),url(../fonts/opensans/OpenSansLight.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;src:local("Open Sans"),local("OpenSans"),url(../fonts/opensans/OpenSans.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:700;src:local("Open Sans Bold"),local("OpenSans-Bold"),url(../fonts/opensans/OpenSansBold.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;src:local("Open Sans Light Italic"),local("OpenSansLight-Italic"),url(../fonts/opensans/OpenSansLightItalic.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;src:local("Open Sans Italic"),local("OpenSans-Italic"),url(../fonts/opensans/OpenSansItalic.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:700;src:local("Open Sans Bold Italic"),local("OpenSans-BoldItalic"),url(../fonts/opensans/OpenSansBoldItalic.woff) format("woff")}/*! * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome/fontawesome-webfont.eot?v=4.4.0);src:url(../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.4.0) format("embedded-opentype"),url(../fonts/fontawesome/fontawesome-webfont.woff2?v=4.4.0) format("woff2"),url(../fonts/fontawesome/fontawesome-webfont.woff?v=4.4.0) format("woff"),url(../fonts/fontawesome/fontawesome-webfont.ttf?v=4.4.0) format("truetype"),url(../fonts/fontawesome/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.modal-body,button{font-family:'Open Sans',sans-serif!important}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa.fa-pull-right,.fa.pull-right{margin-left:.3em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right,.pull-right{float:right}.contentDiv li,.dashboard-bar-chart-container,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage,.dashboard-full-width-chart,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart,.dashboard-half-height-legend,.dashboard-large-chart,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-legend,.dashboard-medium-chart,.dashboard-medium-chart .dashboard-interior-chart,.dashboard-small-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart,.dashboard-sub-bar,.dashboard-sub-bar .dashboard-sub-bar-title,.dashboard-tendency-container,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar,.dashboard-title-bar .dashboard-half-title-bar,.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.machineClass,.modal-chart-detail,.modal-chart-detail .modal-body,.modal-chart-detail .modal-dashboard-legend,.modal-chart-detail .modal-inner-detail,.navlist li,.navlogo,.pull-left,.scenarioMachine,.script-dropdown-menu,.user-dropdown-menu,a.button-gui,a.headerButton,div .bigtile,div .bigtile a span.add-Icon,div .tile,div .tile a span.add-Icon,div.centralContent,div.dropdownInner ul,div.footer-center,div.footer-left,div.footer-left p{float:left}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.dashboard-sub-bar-menu,.headerBar>div.headerButtonBar,.navmenu,.search-field,div .bigtile .iconSet span,div .tile .iconSet span,div.footer-right,div.footer-right p,ul.headerButtonList li{float:right}.dashboard-bar-chart-container .dashboard-bar-chart:after,.dashboard-medium-chart .dashboard-medium-chart-inner:after,.dashboard-medium-chart .dashboard-medium-chart-menu:after,.dashboard-row:after,.dashboard-sub-bar:after,.dashboard-tendency-container .dashboard-tendency-chart:after,.detail-chart:after,.headerBar>div.headerButtonBar:after,.machineClass:after,.resizecontainer:after,.scenarioSingleMachine:after,.tileList:after{clear:both;content:'.';display:block;font-size:0;height:0;visibility:hidden}.addButton,.arangoicon,.clusterDownBtn button,.contentDiv .icon,.deleteButton,.gv-search-submit-icon,.icon-info-sign,.scenarioImage,.script-dropdown-menu .dropdown-item,.search-submit-icon,a.button-gui,a.headerButton,div .bigtile,div .bigtile .iconSet span,div .bigtile a span.icon,div .bigtile a svg,div .tile .iconSet span,div .tile a span.icon,div .tile a svg,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,div.toolbox div.gv_action_button{cursor:pointer}.navbar,footer.footer{background-color:rgba(245,248,240,.95);color:#fff;left:0;position:fixed;right:0;width:100%;z-index:1000}.button-danger{background-color:#da4f49}.button-danger:focus,.button-danger:hover{background-color:#be342e}.deleteButton,a.danger.coordinator,a.danger.dbserver{color:#da4f49}.deleteButton:focus,.deleteButton:hover,a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{color:#be342e}a.danger.coordinator,a.danger.dbserver{fill:#da4f49}a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{fill:#be342e}.button-success{background-color:#8aa051}.button-success:focus,.button-success:hover{background-color:#788f3d}.addButton,a.success.coordinator,a.success.dbserver{color:#8aa051}.addButton:focus,.addButton:hover,a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{color:#788f3d}a.success.coordinator,a.success.dbserver{fill:#8aa051}a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{fill:#788f3d}.button-warning{background-color:#faa732}.button-warning:focus,.button-warning:hover{background-color:#f89406}a.warning.coordinator,a.warning.dbserver{color:#faa732;fill:#faa732}a.warning.coordinator:focus,a.warning.coordinator:hover,a.warning.dbserver:focus,a.warning.dbserver:hover{color:#f89406;fill:#f89406}.button-close,.button-neutral{background-color:#8f8d8c}.button-close:focus,.button-close:hover,.button-neutral:focus,.button-neutral:hover{background-color:#736b68}.dashboard-sub-bar-menu{color:#8f8d8c}.dashboard-sub-bar-menu:focus,.dashboard-sub-bar-menu:hover{color:#736b68}.button-primary{background-color:#564e4a}.button-primary:focus,.button-primary:hover{background-color:#3a322e}.button-header,a.button-gui,a.headerButton{background-color:#fff;border:1px solid #fff;color:#555}.button-header:focus,.button-header:hover,a.button-gui:focus,a.button-gui:hover,a.headerButton:focus,a.headerButton:hover{background-color:#8aa051;border:1px solid #8aa051;color:#fff}.button-notification{background-color:#faa020}.button-notification:focus,.button-notification:hover{background-color:#f87c0f}.button-inactive,.button-inactive:focus,.button-inactive:hover,[class*=' button-']:disabled,[class*=' button-']:focus:disabled,[class*=' button-']:hover:disabled,[class^=button-]:disabled,[class^=button-]:focus:disabled,[class^=button-]:hover:disabled,button.disabled,button.disabled:focus,button.disabled:hover{background-color:#d3d3d3}a.headerButton.disabled,a.headerButton.disabled:focus,a.headerButton.disabled:hover,a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{color:#d3d3d3}a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{fill:#d3d3d3}div.queryline .fa.fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:relative;right:21px;top:-1px}div.queryline .fa.fa-search:hover{cursor:pointer;opacity:1}.modal-body .select2-choices input,.modal-body input,.modal-body select,.modal-body textarea,.navbar .arango-collection-select,div.queryline input,div.queryline select,input.search-input{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#fff!important;border:1px solid rgba(140,138,137,.25);box-shadow:none;outline:transparent 0}.modal-body input:focus,.modal-body select:focus,.modal-body textarea:focus,.navbar .arango-collection-select:focus,div.queryline input:focus,div.queryline select:focus,input.search-input:focus{border-color:#999;box-shadow:none;outline:transparent 0}.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.script-dropdown-menu,.user-dropdown-menu{background-color:#f5f8f0;border-color:#666;border-radius:3px;border-style:solid;border-width:1px;box-shadow:none;display:none;list-style:none;margin:5px 0 0;padding:5px 0;position:absolute;right:0;top:80%;z-index:1000}.script-dropdown-menu .dropdown-item a,.tab{display:block}.dropdown-toolbar li,.gv-dropdown-menu li,.link-dropdown-menu li,.script-dropdown-menu li,.user-dropdown-menu li{line-height:23px;white-space:nowrap;width:100%}.dropdown-toolbar .dropdown-header,.gv-dropdown-menu .dropdown-header,.link-dropdown-menu .dropdown-header,.script-dropdown-menu .dropdown-header,.user-dropdown-menu .dropdown-header{color:#999;font-size:15px;font-weight:600;font-variant:small-caps;padding:0}.dropdown-toolbar .dropdown-header:hover,.gv-dropdown-menu .dropdown-header:hover,.link-dropdown-menu .dropdown-header:hover,.script-dropdown-menu .dropdown-header:hover,.user-dropdown-menu .dropdown-header:hover{cursor:default}.dropdown-toolbar .divider,.gv-dropdown-menu .divider,.link-dropdown-menu .divider,.script-dropdown-menu .divider,.user-dropdown-menu .divider{background-color:#666;height:1px;margin:10px 0 5px}.dropdown-toolbar a,.gv-dropdown-menu a,.link-dropdown-menu a,.script-dropdown-menu a,.user-dropdown-menu a{color:#fff;padding:0 20px}.navbar{-webkit-font-smoothing:subpixel-antialiased;height:44px;margin-bottom:3px;padding-top:6px;top:0}.navbar .no-left-margin{border:0;margin-left:0}.navbar .no-left-margin.hover{background-color:transparent}.navbar .arangodbLogo{height:auto;margin-left:-5px;margin-top:-1px;width:40%}.navbar .arango-collection-select{position:relative;right:-22px;top:4px}.navbar .nav .dropdown .active>.dropdown-toggle,.navbar .nav .dropdown .open.active>.dropdown-toggle,.navbar .nav .dropdown .open>.dropdown-toggle{background:#788f3d}.navbar .nav>.active>a{-webkit-box-shadow:0 0 0 transparent inset;-moz-box-shadow:0 0 0 transparent inset;box-shadow:0 0 0 transparent inset;background-color:#fff;color:#000}.navbar .nav>li>a:focus{background-color:#fff}.navbar .nav>li>a:hover{background-color:#000;color:#686766}.navlist .dropdown-item:hover a,.navlist>.active a,.navlist>.active:hover a,.navlist>li:hover a{color:#000}.navlogo{margin-left:5px;margin-right:-3px;padding-top:3px}.navlist{list-style:none}.navlist>li{height:39px}.navlist li{border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;margin-left:7px}.navlist li.dropdown:hover{background-color:#fff;border-bottom-left-radius:0;border-bottom-right-radius:0;border-left:1px solid rgba(0,0,0,.2);border-right:1px solid rgba(0,0,0,.2);border-top:1px solid rgba(0,0,0,.2)}.navlist li.dropdown:hover a{border-bottom:2px solid #fff}.navlist li.divider,.navlist li.navbar-spacer{border:0}.navlist li.divider{background-color:rgba(0,0,0,.2)}.navlist li.navbar-spacer{background-color:#a0a0a0;height:21px;margin-top:9px;width:1px}.navlist li.navbar-spacer.big{margin-left:15px;margin-right:15px}.navlist li.navbar-spacer.med{margin-left:5px;margin-right:5px}.navlist .dropdown-item,.script-dropdown-menu .dropdown-item{margin-left:0}.navlist li.navbar-spacer:hover{background-color:#a0a0a0}.navlist .active .tab{border-bottom:2px solid #8aa051;padding-bottom:4px}.navlist>.active{background-color:transparent}.navlist>.active:hover{background-color:#fff}.navlist .dropdown-item:hover,.navlist>li:hover{background-color:#fff;border-radius:3px}.navlist .dropdown-item a{border-bottom:0;display:block;font-size:11pt}.navlist .dropdown-item a:hover{background-color:#dee9cf;color:#686766}.tab{color:#686766;font-size:12pt;font-weight:100;padding:9px 5px 10px}.tab.userImg{padding-bottom:5px}.dropdown-item a{border-bottom:0!important;font-weight:300}.dropdown-toolbar,div.headerBar,div.headerDropdown{border:1px solid rgba(140,138,137,.25)}.dropdown-toolbar li a,footer.footer p{font-weight:100}.dropdown-toolbar{background-color:#fff!important}.dropdown-toolbar li a:hover{background:0 0;background-color:#dee9cf!important;color:#000!important}.link-dropdown-menu,.user-dropdown-menu{background-color:#fff;border:1px solid rgba(0,0,0,.2);border-top-right-radius:0;margin-right:-1px;margin-top:7px;z-index:-10}.link-dropdown-menu .dropdown-item,.user-dropdown-menu .dropdown-item{border-left:0;border-right:0}.script-dropdown-menu .dropdown-item a:hover{color:#fff}.script-dropdown-menu .dropdown-item:hover{background-color:#8aa051}.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:rgba(0,0,0,.7);border:1px solid #c2c2c2;margin-right:-20px;margin-top:6px}.gv-dropdown-menu:after{border-bottom-color:#fff}.gv-dropdown-menu li:hover{background-color:#fff;background-image:none}.gv-dropdown-menu li a{padding:0}.gv-dropdown-menu li a label{color:#fff;padding-left:5px}.gv-dropdown-menu li a:focus{background-color:#8aa051!important;background-image:none}#arangoCollectionSelect{display:none;float:right;margin-bottom:0;margin-right:15px;padding-bottom:0}.caret{border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #686766;content:'';display:inline-block;height:0;vertical-align:top;width:0}.applications-menu{display:block}.arango-logo{height:34px;padding:0!important}.arango-logo img{margin-left:22px}.footer{bottom:0;font-size:14px;left:0;position:fixed;right:0;z-index:1000}.modal,.select2-drop-active{z-index:9999999}footer.footer{bottom:0;height:40px}footer.footer p{font-size:10pt;margin-bottom:0;padding-bottom:10px;padding-top:10px}div.footer-left{background:none;color:#686766;width:45%}div.footer-left .social-icons{margin-top:5px}div.footer-left .social-icons a{display:block;float:left;height:25px;width:25px}div.footer-left .social-icons p{background:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;height:25px;margin-right:10px;padding:0;width:25px}div.footer-left .social-icons p:hover{background:#8aa051;cursor:pointer}div.footer-left .social-icons p:hover i{color:#fff}div.footer-left .social-icons i{color:#000;margin-top:6px;position:absolute}.addButton,.deleteButton{position:relative;font-size:22px}div.footer-left .social-icons i.fa-twitter{margin-left:-5px}div.footer-left .social-icons i.fa-envelope{margin-left:-19px}div.footer-left .social-icons i.fa-google{margin-left:-17px;margin-top:7px}div.footer-left .social-icons i.fa-stack-overflow{margin-left:-17px}div.footer-center{background:none;color:#686766;width:10%}div.footer-center i{background-color:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;margin-left:1px;padding:6px 2px;width:20px}div.footer-center i:hover{background-color:#8aa051;color:#fff}div.footer-center p{padding-top:5px}div.footer-center p:hover{cursor:pointer}[class*=' button-']:disabled,[class^=button-]:disabled,a.headerButton.disabled,button.disabled{cursor:not-allowed}div.footer-right{background:none;color:#686766;width:45%}div.footer-right p{color:#fff}div.footer-right i{color:#da4f49;font-size:18px}div.footer-right a{color:#686766;margin-left:5px;position:relative;top:-1px}div.footer-right .isOnline{color:#8aa051!important}.button-close,.button-danger,.button-header,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;font-size:14px;font-weight:300!important}.button-close,.button-danger,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{border:0;color:#fff;margin-left:10px;padding:5px 16px}.button-header{margin-top:5px}.addButton{margin-right:7px;margin-top:2px}.deleteButton{padding-right:3px;top:3px}#closeBtnInfoView{margin-left:0!important}button.btn-server{width:120px}button.gv-zoom-btn{background-size:14px 14px;height:14px;vertical-align:baseline;width:14px}button.gv-zoom-btn.btn-zoom-right{border:0;box-shadow:none;right:0;top:13px}button.gv-zoom-btn.pan-right{background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-right:hover{background:inherit;background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-left{background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-left:hover{background:inherit;background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-top{background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-top:hover{background:inherit;background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-bottom{background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.pan-bottom:hover{background:inherit;background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.btn-zoom{height:14px;margin:0;padding:0;position:absolute;width:16px}button.gv-zoom-btn.btn-zoom-top{border:0;box-shadow:none;left:13px;top:1}button.gv-zoom-btn.btn-zoom-left{border:0;box-shadow:none;left:0;top:13px}button.gv-zoom-btn.btn-zoom-bottom{border:0;box-shadow:none;left:13px;top:25px}button.gv-icon-btn{-moz-border-radius:0!important;-webkit-border-radius:0!important;border-radius:0!important;background-size:36px 36px;height:36px;width:36px}button.gv-icon-btn.active{background-color:#8aa051}button.gv_dropdown_entry{height:30px;margin:4px 4px 4px 30px;width:160px}button.gv_context_button{width:65px}button.large-distance{margin-left:12px}button.short-distance{margin-left:6px}button.shutdown{margin-top:6px;padding:3px 14px}button.graphViewer-icon-button{background-color:transparent;border:0;height:20px;margin-left:5px;margin-top:-2px;padding:0;width:20px}button.graphViewer-icon-button img{height:20px;padding-bottom:10px;width:20px}ul.headerButtonList{display:inline-block;margin-bottom:0;margin-left:0;padding-left:0!important}ul.headerButtonList li{display:inline}a.button-gui,a.headerButton{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;margin-left:5px;margin-right:5px}a.headerButton{margin-top:2px;position:relative}a.headerButton .fa,a.headerButton [class*=" icon_"],a.headerButton [class^=icon_]{display:block;height:23px;line-height:23px;position:static;right:0;text-align:center;top:0;width:27px}a.button-gui.button-gui-disabled,div.headerDropdown,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox{display:none}a.headerButton .icon_arangodb_arrowleft,a.headerButton .icon_arangodb_arrowright{font-weight:700}a.headerButton.activated{background-color:#788f3d;border:1px solid #788f3d;color:#fff}div.toolbox,div.toolbox div.gv_action_button{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#fff}a.headerButton.activated:hover{background-color:#fff;color:#788f3d}div.toolbox{border-radius:3px;border:1px solid rgba(140,138,137,.25);margin-right:5px;margin-top:-3px;padding-bottom:5px;padding-top:5px;position:absolute}div.toolbox div.gv_action_button{border-radius:3px;color:#555;height:30px;margin:5px;position:relative;width:30px}div.toolbox div.gv_action_button.active{background-color:#8aa051;color:#fff}div.toolbox div.gv_action_button:first-child{margin-top:0}div.toolbox div.gv_action_button:last-child{margin-bottom:0}h6.gv_button_title,h6.gv_icon_icon{left:0;margin:0;position:absolute;right:0}h6.gv_icon_icon{font-size:22px;left:1px;top:4px}h6.gv_button_title{bottom:1px;display:none}.btn-icon{background-color:#383434;padding:4px}.gv-icon-small{background-size:16px 16px;height:16px!important;width:16px!important}.gv-icon-small.delete{background-image:url(../img/icon_delete.png)}.gv-icon-small.add{background-image:url(../img/plus_icon.png)}a.pagination-button,ul.arango-pagination a{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.badge,.btn,.label{text-shadow:none!important}.navbar-inner,.thumbnail{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0}.modal-body th.actionCell>button{margin-top:-12px}.btn-old-padding{padding-bottom:4px!important;padding-top:4px!important}button.btn-overview,button.btn-server{margin:5px}a.button-gui{height:auto;margin-bottom:0;margin-top:0;padding-bottom:1px;padding-top:1px;position:absolute;right:2px;text-decoration:none!important;top:2px;width:auto}.clusterDownBtn{padding-bottom:10px;padding-top:10px}.clusterDownBtn button{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#f1f1f1;border:1px solid rgba(0,0,0,.1875);color:#333;font-size:20px;font-weight:300;margin:0;padding:12px 18px;text-decoration:none!important;width:250px}.clusterDownBtn button:hover{background-color:#e8e8e8;color:#4a6c30;-webkit-transition-delay:0;-webkit-transition-duration:.2s;-webkit-transition-property:all;-webkit-transition-timing-function:ease-in}.clusterDownBtn button.green{background-color:#617e2b;color:#fff}.clusterDownBtn button.green:hover{background-color:#8ba142}.bottomButtonBar{background-color:#fff;border-top:1px solid rgba(104,103,102,.1);height:30px;padding:10px}.clusterInfoIcon{float:left;padding-left:5px;padding-top:2px}.waitModal.icon{font-size:100px;height:120px}.waitModal.message{font-size:20px}.icon_arangodb_info{color:#333;font-size:23px}li a [class*=" icon_arangodb"],li a [class^=icon_arangodb]{font-size:18px;position:absolute;right:4px;top:2px}.fa-minus-circle{color:#da4f49;font-size:14pt}.fa-minus-circle:hover{cursor:pointer}div.headerDropdown{background-color:#fff;border-radius:3px;clear:both;padding:10px;position:relative;width:auto}div.headerDropdown.smallDropdown .dropdownInner{min-height:20px}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.dropdown-title{margin-bottom:10px}div.dropdownInner{-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;min-height:125px;position:relative;width:auto}div.dropdownInner .nav-header{font-size:10pt}div.dropdownInner>.nav-header{color:#000;font-size:10pt;font-weight:400}div.dropdownInner>label{color:#000;font-weight:300}div.dropdownInner ul{border-left:1px solid rgba(140,138,137,.25);display:inline;list-style-type:none;margin-top:10px;min-height:105px;width:230px}div.dropdownInner ul:first-of-type,div.queryline input[type=file]{border:0}div.dropdownInner ul label{color:#000;padding-left:20px}div.dropdownInner ul li .fa{color:#999;margin-right:5px}div.dropdownInner ul li .fa.fa-square-o{margin-left:1px;margin-right:6px}div.dropdownInner ul li .fa.fa-check-circle-o,div.dropdownInner ul li .fa.fa-check-square-o,div.dropdownInner ul li .fa.fa-dot-circle-o{color:#8aa051}div.queryline{color:#000;height:35px}div.queryline .textDiv{margin-right:10px;margin-top:4px}div.queryline input,div.queryline select{margin-bottom:5px}div.queryline.querylineAdd span{color:#fff;padding-left:10px;position:relative;top:-21px}div.queryline .removeFilterItem i{margin-left:5px!important;margin-top:0!important}div.queryline div.searchByAttribute{margin-left:6px;margin-right:6px;position:relative}div.queryline div.searchByAttribute>ul.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:#fff;color:#fff;display:none;left:0;position:absolute;top:20px;width:247px}div.dropdownImport{background-color:#fff;border-radius:3px;display:none;position:relative;padding:10px 10px 5px}div.dropdownImport input{line-height:0;margin-bottom:-15px;margin-top:5px}select.filterSelect{color:#00f;margin-left:10px;margin-right:10px;width:100px}#filterHeader button{float:right;margin-left:10px!important;margin-top:1px}div.input-append button.gv_example_toggle{-moz-border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;background-color:#8f8d8c;height:30px;margin-left:-1px;padding-left:10px;padding-right:10px;padding-top:12px;vertical-align:top}div.input-append button.gv_example_toggle:hover{background-color:#8aa051}div.headerBar,div.headerBar .infoField{background-color:#fff;padding-left:5px;padding-right:5px}.searchEqualsLabel{margin-left:6px;margin-right:6px}img.gv-throbber{background-image:url(../img/swagger/throbber.gif)}span.gv_caret{border-top:5px solid #fff;margin-top:2px!important}input.search-input{height:14px;line-height:18px;margin-right:-1px;margin-top:6px;width:120px}.search-field{margin-left:10px}.search-field .fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:absolute;right:9px;top:9px}.search-field .fa-search:hover{cursor:pointer;opacity:1}.gv-search-submit-icon,.search-submit-icon{background-image:url(../img/enter_icon.png);background-size:14px;height:14px;margin-left:-18px;opacity:.2;position:absolute;width:14px}.gv-search-submit-icon:hover,.search-submit-icon:hover{opacity:.8}.search-submit-icon{margin-top:11px}.gv-search-submit-icon{margin-top:6px}div.headerBar{border-radius:3px;color:#fff;font-size:16px;height:36px;margin-bottom:5px;margin-top:15px;position:relative}div.headerBar .infoField{border:1px solid rgba(140,138,137,.25);border-radius:3px!important;color:#000;float:right;font-size:12px;margin-right:7px;margin-top:7px}div.headerBar .infoField .fa{cursor:pointer;margin-left:5px}div.headerBar input[type=checkbox].css-checkbox{display:none}div.headerBar input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;cursor:pointer;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerBar input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.headerBar input[type=radio]{display:none}div.headerBar input[type=radio] label span{background:url(../img/check_radio_sheet.png) -38px top no-repeat;cursor:pointer;display:inline-block;height:19px;margin:-1px 4px 0 0;vertical-align:middle;width:19px}#transparentHeader input[type=checkbox].css-checkbox,.lineGraph .many .dygraph-legend>span,.modal-delete-confirmation{display:none}div.headerBar input[type=radio]:checked+label span{background:url(../img/check_radio_sheet.png) -57px top no-repeat}.headerButtonList a.error{color:#da4f49}.headerButtonList a.error:hover{background-color:#da4f49;border-color:#da4f49;color:#fff}.headerBar a.arangoHeader{color:#000;font-size:13pt;font-weight:100;left:0;position:relative;top:7px}.headerBar>div.headerButtonBar{margin:4px 0;margin-bottom:0!important}.breadcrumb{background:0 0;border:0;border-radius:0;padding:7px 0}.breadcrumb .disabledBread{color:#666;float:left;font-size:13pt;font-weight:100;padding-right:5px;position:relative}.breadcrumb .disabledBread i{font-size:10pt;margin-left:10px}.breadcrumb .activeBread{color:#8aa051;float:left;font-size:13pt;font-weight:100}.arangoHeader{font-weight:400}.checkboxLabel{margin-top:4px;padding-left:0}.css-label{background-image:url(../img/dark-check-green.png)}.css-label-round{background-image:url(../img/dark-check-green-round.png)}.modal-dashboard-header,.modal-header{background-color:#fff;border-bottom:0!important;border-radius:3px;margin-top:5px;padding-left:5px;padding-right:10px;padding-top:4px}.modal-dashboard-header .arangoHeader,.modal-header .arangoHeader{color:#000;font-size:13pt;font-weight:100;left:5px;position:relative;top:2px}.modal-dashboard-header a,.modal-header a{top:2px!important}.modal-dashboard-header .close,.modal-header .close{color:#fff;font-weight:300;margin-top:2px;opacity:.5}.modal-dashboard-header .close:hover,.modal-header .close:hover{opacity:1}.modal-tabbar{border-bottom:1px solid #000}.modal-body{color:#736b68;font-size:14px;font-weight:300;max-height:410px}.modal-body .select2-choices{background-image:none!important;border:1px solid #999;border-radius:3px;-webkit-box-shadow:none;box-shadow:none}.modal-body .select2-choices input:active{-webkit-box-shadow:none;box-shadow:none;outline:0!important}.modal-body .select2-choices .select2-search-choice{margin:5px 0 3px 5px!important}.modal-body .select2-choices li{background-color:#fff!important;background-image:none!important;color:#000}.modal-body tr.first,.modal-body tr.last,.modal-body tr.middle{background-color:#f5f8f0}.modal-body .select2-choices li a{margin-left:1px;margin-top:-1px}.modal-body .select2-choices:active{border:1px solid #999;-webkit-box-shadow:none!important;box-shadow:none!important;outline:transparent!important}.modal-body .nav-tabs{margin-top:15px}.modal-body .nav-tabs>li>a:hover{border-color:#8c8a89}.modal-body input,.modal-body select,.modal-body textarea{margin-top:10px}.modal-body input[type=checkbox]{margin-bottom:10px}.modal-body input[type=text].invalid-input{border-color:rgba(234,23,23,.6)}.modal-body input[type=text].invalid-input:focus{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6)}.modal-body input[type=file]{line-height:17px}.modal-body tr.spacer{height:10px}.modal-body tr.first th:first-child{border-top-left-radius:3px}.modal-body tr.first th:last-child{border-top-right-radius:3px}.modal-body tr.middle{padding-left:10px;padding-right:10px}.modal-body tr.last th:first-child{border-bottom-left-radius:3px}.modal-body tr.last th:last-child{border-bottom-right-radius:3px}.modal-body tr.first th:first-child,.modal-body tr.last th:first-child,.modal-body tr.middle th:first-child{padding-left:10px}.modal-body tr.first th:last-child,.modal-body tr.last th:last-child,.modal-body tr.middle th:last-child{padding-right:10px}.modal-body th.actionCell{width:30px}.modal-body th.keyCell{width:170px}.modal-body th.keyCell input{width:150px}.modal-body th .valueCell{width:300px}.modal-body th .valueCell input{width:290px}.modal-body th .select2-container{margin-bottom:10px;margin-top:10px}.modal-body .icon-info-sign{margin-bottom:10px;margin-left:10px;opacity:.7;padding-bottom:5px}.modal-body .icon-info-sign:hover{opacity:1}.modal-body .icon_arangodb_info{color:#736b68;font-size:18px;margin-top:-10px;position:absolute;right:12px}.modal-body .icon_arangodb_info:hover{color:#000}.modal-body .collapse{margin-right:-14px;position:relative}.modal-body .accordion-inner{border-top:0;margin-left:0;padding-left:0;padding-right:0}.modal-body .accordion-toggle span .caret{border-top-color:#000;float:right;margin-top:5px}.modal-body .accordion-toggle.collapsed span .caret{-ms-transform:rotate(90deg);-webkit-transform:rotate(90deg);transform:rotate(90deg)}.modal-body input{width:384px}.modal-body select{width:398px}.modal-body .collectionTh{height:50px}.modal-body .tab-content{min-height:200px}.modal-body .tab-content .tab-pane{border-top:1px solid #666!important;margin-left:0!important;padding-top:10px}.modal-body .tab-content .tab-pane-modal{border-top:none!important}.modal-body .tab-content #appstore{max-height:290px}.modal-body .errorMessage{background-color:#fff;color:#da4f49;font-size:9pt;font-weight:400;margin-bottom:5px;margin-top:-9px;position:absolute}.modal-body .nav .tab-icon{margin-right:5px;margin-top:-3px;width:20px}.modal-text{font-weight:300;padding-bottom:3px;padding-top:3px}.modal-backdrop,.modal-backdrop.fade.in{opacity:.4}.modal{border:0!important;border-radius:3px!important;box-shadow:0;width:580px}.modal .fade.in{top:12.1%!important}.modal table tr:last-child{border-bottom:0!important}.waitModal{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:0 0;border:0;color:#fff}.waitModalBackdrop{opacity:.7!important}.modalTooltips span{color:#736b68;font-size:20px}.modalTooltips span:hover{color:#000}.gv-object-view{text-align:left;white-space:pre}.capitalize{text-transform:capitalize}.modal-footer{border-top:0!important;padding-right:17px}.modal-header{margin-left:5px;margin-right:5px}.modal-dashboard-header{margin-left:0;margin-right:0;padding-bottom:9px}.modal table tr,.thBorderBottom{border-bottom:1px solid #f7f3f2!important}.modal-delete-confirmation button{margin-right:10px;margin-top:-4px}.modal-delete-confirmation button .modal-confirm-delete{margin-right:-18px}.modal-delete-confirmation fieldset input{float:left}.modal-delete-confirmation fieldset label{float:left;margin-left:10px}.createModalDialog table{width:100%}.createModalDialog .collection-info-figures table{float:left;margin-left:0;margin-right:0;margin-top:0;min-width:200px;padding:3px;text-align:left}.createModalDialog .figures1,.createModalDialog .figures2{margin-bottom:20px;width:255px}.createModalDialog .figures2{margin-left:20px!important}.createModalDialog .figures3{margin-bottom:0;width:100%}.foxx-store-row .foxx-name{font-weight:700}.foxx-store-row .foxx-author{font-size:10pt;font-weight:300;margin-top:-4px}.foxx-store-row .foxx-version{font-weight:400}#new-app-mount{margin-right:24px;width:360px}#control_event_edge_delete_modal,#control_event_edge_edit_modal,#control_event_new_node_modal,#control_event_node_delete_modal,#control_event_node_edit_modal{margin-left:-320px;width:640px}.scenarioImage{height:70%;width:auto}svg.clusterChart{height:auto;margin:auto;width:auto}.lineGraph{position:absolute}.lineGraph .few .dygraph-legend>span.highlight{border:1px solid grey}.lineGraph .many .dygraph-legend>span.highlight{display:inline}a.coordinator,a.dbserver{color:#000;height:50px;position:absolute;top:10px;width:50px}a.coordinator h6.serverName,a.dbserver h6.serverName{bottom:0;font-size:11px;left:0;margin:0;position:absolute;right:0}a.coordinator.single{left:90px}a.coordinator.double{left:60px}a.dbserver.single{right:90px}a.dbserver.double{right:60px}.cluster-connection-check-success{color:#8aa051;margin-left:20px}.cluster-connection-check-fail{color:#da4f49;margin-left:20px}.cluster-unreachable-info{margin:0 auto;max-width:320px;padding-top:17px;text-align:center}.machineClass{background-color:#e1e1e1;margin-left:31px;margin-right:31px;padding:10px}.scenarioBox{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:rgba(0,0,0,.075);border:1px solid rgba(0,0,0,.19);height:65px;left:10px;margin-top:30px;position:absolute;right:10px;width:auto}.scenarioMachine,div .bigtile,div .tile{background-color:#fff;position:relative}.scenarioBox.bottomBox{bottom:30px}.scenarioBoxHeader{border-bottom:1px solid rgba(0,0,0,.19);height:18px;line-height:18px;margin-top:0;padding-bottom:0;text-align:center;width:auto}.scenarioBoxText{font-size:13px;font-weight:400;margin-top:17px;text-align:center;width:auto}.collectionName,div .bigtile .badge-success,div .tile .badge-success{font-weight:300}.scenarioMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;border:1px solid rgba(0,0,0,.19);height:257px;margin-right:17px;width:109px}.scenarioMachine:last-child{margin-right:0}.scenarioSingleMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background-color:#fff;border:1px solid rgba(0,0,0,.19)}.scenarioSingleMachine .scenarioMachine{border:1px solid transparent;height:238px}.bigtile.informationtile{cursor:auto}div .bigtile .collection-type-icon:hover,div .bigtile img:hover,div .bigtile:hover,div .tile .collection-type-icon:hover,div .tile img:hover,div .tile:hover{cursor:pointer}.informationText{background:#fff;font-size:12px;margin:10px;padding:5px;text-align:left}.tileList{margin-left:-6px;margin-right:-6px}.tileList legend{padding-left:5px}.tileList .tile:first-child a{opacity:.8}.tileList .tile:first-child a:hover{opacity:1}div .bigtile,div .tile{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border:1px solid #f5f8f0;border-radius:3px;font-size:14px;list-style:none;margin-bottom:13px;margin-left:6px;margin-right:6px;text-align:center;z-index:1}div .bigtile .warning-icons,div .tile .warning-icons{background-color:#da4f49;border-radius:3px;color:#fff;font-size:11px;height:17px;left:0;line-height:13px;margin-left:5px;margin-top:5px;padding-left:9px;padding-right:9px;position:absolute;top:0}div .bigtile a svg.icon,div .bigtile img.icon,div .tile a svg.icon,div .tile img.icon{height:50px;width:50px}div .bigtile .warning-icons .fa,div .tile .warning-icons .fa{font-size:11pt;margin-left:1px}div .bigtile .collection-type-icon,div .tile .collection-type-icon{color:#666;font-size:30pt;margin-top:12pt}div .bigtile img,div .tile img{position:relative}div .bigtile a span.add-Icon,div .tile a span.add-Icon{font-size:22px;margin-left:22px;margin-right:10px;margin-top:-5px;position:relative;right:4px;top:2px}div .bigtile a span.icon,div .tile a span.icon{font-size:50px}div .bigtile .tile-icon-svg,div .tile .tile-icon-svg{cursor:pointer;fill:#686766;height:50px;margin-left:90px;margin-top:10px;position:absolute;width:50px}div .bigtile .tile-icon,div .tile .tile-icon{color:#686766;font-size:50px;line-height:1.2}div .bigtile .icon_arangodb_edge5-2,div .tile .icon_arangodb_edge5-2{display:inline-block;position:relative;top:15px;-moz-transform:rotate(80deg);-o-transform:rotate(80deg);-webkit-transform:rotate(80deg)}div .bigtile h5,div .tile h5{background:#8c8a89;color:#fff;font-size:12px;margin:0;overflow:hidden!important;padding:4px 8px;text-overflow:ellipsis!important;white-space:nowrap!important}div .bigtile .tileSelects,div .tile .tileSelects{margin-left:40px;position:relative;z-index:9999}div .bigtile .tileSelects select,div .tile .tileSelects select{float:right;height:20px;margin-right:5px;margin-top:16px;width:70px}div .bigtile .fullBorderBox,div .tile .fullBorderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:100%;position:absolute;width:100%}div .bigtile .borderBox,div .tile .borderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:75px;position:absolute;width:224px}.collectionName,.dashboard-sub-bar{border-bottom-left-radius:3px;border-bottom-right-radius:3px}div .bigtile .iconSet,div .tile .iconSet{position:absolute;right:5px;top:5px}div .bigtile .iconSet span,div .tile .iconSet span{border-radius:3px;color:#666;font-size:18px;z-index:2;padding:2px 3px}div .bigtile .iconSet span:hover,div .tile .iconSet span:hover{background-color:#8aa051;color:#fff}div .bigtile .iconSet span.disabled,div .tile .iconSet span.disabled{cursor:default;opacity:.2}div .bigtile .iconSet span.disabled:hover,div .tile .iconSet span.disabled:hover{background-color:#fff;color:#000;cursor:default;opacity:.2}div .bigtile .unloaded div,div .tile .unloaded div{border-bottom:16px solid #ff8f35}div .bigtile .deleted div,div .tile .deleted div{border-bottom:16px solid #700}div .bigtile .tileBadge,div .tile .tileBadge{bottom:29px;font-size:11px;font-weight:300;position:absolute;right:0}div .bigtile .tileBadge button,div .tile .tileBadge button{margin-left:0;margin-right:5px}div .bigtile .tileBadge span,div .tile .tileBadge span{display:inline-block;line-height:15px}div .bigtile .tileBadge span .corneredBadge,div .tile .tileBadge span .corneredBadge{border-bottom-style:solid;border-bottom-width:17px;border-left:5px solid transparent;border-radius:3px;color:#fff;height:0;margin-bottom:4px;margin-right:5px;padding-left:1px;padding-right:6px}div .bigtile .tileBadge span .corneredBadge.loading,div .tile .tileBadge span .corneredBadge.loading{border-bottom-color:#ff8f35}div .bigtile .tileBadge span .corneredBadge.loaded,div .tile .tileBadge span .corneredBadge.loaded{border-bottom-color:#8aa051}div .bigtile .tileBadge span .corneredBadge.development,div .bigtile .tileBadge span .corneredBadge.unloaded,div .tile .tileBadge span .corneredBadge.development,div .tile .tileBadge span .corneredBadge.unloaded{border-bottom-color:#ff8f35}div .tile{height:100px;width:226px}div .tile-graph .tile-icon:hover{cursor:pointer}div .bigtile{height:309px;width:452px}div .bigtile .shardContainer{font-size:30px}div .bigtile .shardContainer span{padding:2px}.collectionName{bottom:0;left:0;position:absolute;right:0;text-align:left}.dashboard-bar-chart-container,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-medium-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-tendency-container{border-top-left-radius:3px;border-top-right-radius:3px}.dashboard-bar-chart-container:first-child,.dashboard-full-width-chart .dashboard-full-width-chart-inner:first-child,.dashboard-large-chart .dashboard-large-chart-inner:first-child,.dashboard-medium-chart:first-child,.dashboard-small-chart .dashboard-small-chart-inner:first-child,.dashboard-tendency-container:first-child{margin-left:0}.dashboard-bar-chart-container,.dashboard-full-width-chart,.dashboard-large-chart,.dashboard-medium-chart,.dashboard-small-chart,.dashboard-tendency-container{margin-bottom:10px;position:relative}.dashboard-sub-bar-menu{cursor:pointer;position:absolute;right:9px;top:6px}.dataNotReadyYet{font-family:'Open Sans',sans-serif;font-size:20px;font-weight:100;text-align:center}.dashboard-sub-bar{background-color:#686766;color:#fff;height:24px;line-height:24px;margin:0;padding:0 6px}.dashboard-full-width-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-subtitle-bar.top{border-bottom:1px solid #e1e1e1;height:48px;line-height:48px;text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{border-left:1px solid #e1e1e1}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner{margin-left:10px;margin-right:10px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table{margin-bottom:10px;margin-top:10px;table-layout:fixed;width:100%}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-medium-chart .dashboard-interior-chart{margin-bottom:0}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table .no-data{font-style:italic;font-weight:100}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table tr{border-bottom:1px solid rgba(0,0,0,.025)}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:first-child{width:100px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:last-child{text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart:first-child{border-left:0}.dashboard-full-width-chart .state{background-color:#fff;border-radius:5px;color:#000;margin-left:5px;padding-left:6px;padding-right:4px}.dashboard-large-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-large-chart .dashboard-large-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-small-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-small-chart .dashboard-small-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:5px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart-outer:first-child{margin-right:10px}.dashboard-medium-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;margin-bottom:0;padding-top:10px}.dashboard-medium-chart:first-child{margin-right:12px}.dashboard-medium-chart .dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart .dashboard-medium-chart-menu{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:0 solid rgba(0,0,0,.3);color:rgba(0,0,0,.3);cursor:pointer;padding:0 4px;position:absolute;z-index:1000}.dashboard-medium-chart .dashboard-medium-chart-menu:hover{color:rgba(0,0,0,.7)}.dashboard-medium-chart .dashboard-medium-chart-inner{padding-bottom:10px}.dashboard-medium-chart .clusterChart .slice path{fill-opacity:.15;stroke-opacity:1;stroke-width:1.5px}.dashboard-tendency-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-tendency-container .dashboard-tendency-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{background-color:#fff;margin-top:5px;padding:0 8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency:first-child{border-right:1px solid #e1e1e1}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar{border-bottom:1px solid #e1e1e1;text-align:right}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure{text-align:center}.dashboard-bar-chart-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-bar-chart-container .dashboard-bar-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{margin-top:5px;padding:0 8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{font-weight:400}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{text-align:right}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-legend .dashboard-legend-inner{padding:0 5px 5px 0}.dashboard-spacer{margin:0 12px}.headerBar.dashboard-headerbar{margin:20px 0}.modal-chart-detail .modal-dashboard-legend .dashboard-legend-inner{padding-left:20px}.dashboard-half-height-legend .dashboard-legend-inner{padding-top:20px}.dashboard-title-bar{background-color:#686766;color:#fff;font-size:14.5px;font-weight:400;height:30px;line-height:30px;padding:0 5px 0 10px}.dashboard-title-bar .dashboard-half-title-bar{border-left:1px solid #000;margin-left:-1px;width:50%}.dashboard-title-bar .dashboard-half-title-bar:first-child{border-left:0;margin-left:0}.dashboard-row{margin-bottom:0;margin-left:0;margin-right:0}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{color:#666}.resizecontainer{margin:0 auto}@media (max-width:738px){#arangoCollectionUl{display:none}#collectionsDropdown ul{width:auto!important}#arangoCollectionSelect{display:inline-block;height:29px;margin-top:1px}}@media (min-width:739px) and (max-width:1041px){#arangoCollectionUl a{font-size:12px;height:12px;padding:8px 5px}}@media (min-width:1042px) and (max-width:1284px){#arangoCollectionUl a{font-size:14px}}@media (min-width:250px) and (max-width:489px){.resizecontainer{width:228px}.dashboard-full-width-chart{width:225px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:215px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:69.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:214px}.dashboard-large-chart{width:146px}.dashboard-large-chart .dashboard-sub-bar{width:134px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:136px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:106px}.dashboard-medium-chart{width:96px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:95px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:96px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:79px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:66px}.dashboard-small-chart .dashboard-sub-bar{width:54px}.dashboard-small-chart .dashboard-small-chart-inner{width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:54px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:56px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:40px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-114px;width:248px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:208px}.modal-body .dashboard-large-chart{width:143px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:131px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:133px}.modal-body .dashboard-medium-chart-outer{float:left;width:91px}.modal-body .dashboard-medium-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:89px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:74px}.modal-body .dashboard-small-chart{width:61px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:49px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:51px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:6.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:51px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:56px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:40px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:228px}.application-detail-view aside.meta{display:none}}@media (min-width:490px) and (max-width:729px){.resizecontainer{width:468px}.dashboard-full-width-chart{width:465px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:455px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:149.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart{width:306px}.dashboard-large-chart .dashboard-sub-bar{width:294px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:296px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:226px}.dashboard-medium-chart{width:216px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:215px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:216px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:199px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:146px}.dashboard-small-chart .dashboard-sub-bar{width:134px}.dashboard-small-chart .dashboard-small-chart-inner{width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:48px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:134px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:136px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:120px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-234px;width:488px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:448px}.modal-body .dashboard-large-chart{width:303px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:291px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:293px}.modal-body .dashboard-medium-chart-outer{float:left;width:211px}.modal-body .dashboard-medium-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:194px}.modal-body .dashboard-small-chart{width:141px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:129px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:131px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:46.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:131px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:136px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:120px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:468px}.application-detail-view aside.meta{display:none}}@media (min-width:730px) and (max-width:969px){.resizecontainer{width:708px}.dashboard-full-width-chart{width:705px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:695px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:229.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:694px}.dashboard-large-chart{width:466px}.dashboard-large-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:456px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:346px}.dashboard-medium-chart{width:336px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:335px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:319px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:226px}.dashboard-small-chart .dashboard-sub-bar{width:214px}.dashboard-small-chart .dashboard-small-chart-inner{width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:88px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:214px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:216px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:200px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-354px;width:728px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:688px}.modal-body .dashboard-large-chart{width:463px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:451px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:453px}.modal-body .dashboard-medium-chart-outer{float:left;width:331px}.modal-body .dashboard-medium-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:329px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:314px}.modal-body .dashboard-small-chart{width:221px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:211px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:86.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:211px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:216px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:200px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:508px}}@media (min-width:970px) and (max-width:1209px){.resizecontainer{width:948px}.dashboard-full-width-chart{width:945px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:935px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:309.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart{width:626px}.dashboard-large-chart .dashboard-sub-bar{width:614px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:220px;width:496px}.dashboard-sub-bar-menu{font-size:13px}.dashboard-medium-chart-outer{float:left;width:466px}.dashboard-medium-chart{width:456px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:455px}.dashboard-medium-chart .dashboard-interior-chart{height:220px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:13px;left:438px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:220px;width:456px}.dashboard-medium-chart #clusterGraphs svg text{font-size:11px}.dashboard-small-chart{width:306px}.dashboard-small-chart .dashboard-sub-bar{width:294px}.dashboard-small-chart .dashboard-small-chart-inner{width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:229px;width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:11px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:96.5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:128px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:31.17px;line-height:31.17px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:52.33px;line-height:25.17px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:294px}.dashboard-bar-chart-container{height:98px}.dashboard-bar-chart-container .dashboard-bar-chart{height:96px;width:296px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:31.33px;line-height:31.33px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:45.67px;line-height:45.67px;padding:5px 8px 10px;width:280px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:50.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-474px;width:968px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:13px;min-height:225px;width:130px}.absolut,.percentage{font-size:15px}.modal-chart-detail .modal-inner-detail{width:808px}.modal-body .dashboard-large-chart{width:623px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:611px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:493px}.modal-body .dashboard-medium-chart-outer{float:left;width:451px}.modal-body .dashboard-medium-chart{width:451px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:433px}.modal-body .dashboard-small-chart{width:301px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:289px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:291px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:126.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:291px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:296px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:280px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:11px;font-weight:400}.dashboard-subtitle-bar{font-size:15px;font-weight:300}.dashboard-figure{font-size:18px;font-weight:400}.dashboard-figurePer{font-size:16px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:11px}.dashboard-legend{height:225px;margin-top:-3px;width:120px}.dashboard-half-height-legend{font-size:11px;height:117.5px;width:60px}.application-detail-view section.info{width:748px}}@media (min-width:1210px) and (max-width:1449px){.resizecontainer{width:1188px}.dashboard-full-width-chart{width:1185px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1175px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:389.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1174px}.dashboard-large-chart{width:786px}.dashboard-large-chart .dashboard-sub-bar{width:774px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:255px;width:646px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:586px}.dashboard-medium-chart{width:576px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:575px}.dashboard-medium-chart .dashboard-interior-chart{height:255px;width:446px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:16px;left:555px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:255px;width:576px}.dashboard-medium-chart #clusterGraphs svg text{font-size:12px}.dashboard-small-chart{width:386px}.dashboard-small-chart .dashboard-sub-bar{width:374px}.dashboard-small-chart .dashboard-small-chart-inner{width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:264px;width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:114px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:168px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:37px;line-height:37px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:64px;line-height:31px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:374px}.dashboard-bar-chart-container{height:115.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:113.5px;width:376px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:37.17px;line-height:37.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:57.33px;line-height:57.33px;padding:5px 8px 10px;width:360px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:62.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-594px;width:1208px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:14px;min-height:260px;width:140px}.absolut,.percentage{font-size:18px}.modal-chart-detail .modal-inner-detail{width:1038px}.modal-body .dashboard-large-chart{width:783px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:771px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:643px}.modal-body .dashboard-medium-chart-outer{float:left;width:571px}.modal-body .dashboard-medium-chart{width:571px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:569px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:441px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:550px}.modal-body .dashboard-small-chart{width:381px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:369px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:371px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:166.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:371px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:376px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:360px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:18px;font-weight:300}.dashboard-figure{font-size:22px;font-weight:400}.dashboard-figurePer{font-size:20px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:13px;font-weight:400}.dashboard-legend{font-size:12px;font-weight:400;height:260px;margin-top:-3px;width:130px}.dashboard-half-height-legend{font-size:12px;height:135px;width:65px}.application-detail-view section.info{width:988px}}@media (min-width:1450px) and (max-width:1689px){.resizecontainer{width:1428px}.dashboard-full-width-chart{width:1425px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1415px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:469.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart{width:946px}.dashboard-large-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:796px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:706px}.dashboard-medium-chart{width:696px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:695px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:556px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:18px;left:673px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:696px}.dashboard-medium-chart #clusterGraphs svg text{font-size:13px}.dashboard-small-chart{width:466px}.dashboard-small-chart .dashboard-sub-bar{width:454px}.dashboard-small-chart .dashboard-small-chart-inner{width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:208px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:454px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:456px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:440px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-714px;width:1448px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:15px;min-height:290px;width:150px}.absolut,.percentage{font-size:20px}.modal-chart-detail .modal-inner-detail{width:1268px}.modal-body .dashboard-large-chart{width:943px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:931px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:793px}.modal-body .dashboard-medium-chart-outer{float:left;width:691px}.modal-body .dashboard-medium-chart{width:691px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:551px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:668px}.modal-body .dashboard-small-chart{width:461px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:451px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:206.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:451px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:456px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:440px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:20px;font-weight:300}.dashboard-figure{font-size:26px;font-weight:400}.dashboard-figurePer{font-size:24px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:13px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:13px;height:150px;width:70px}.application-detail-view section.info{width:1228px}}@media (min-width:1690px) and (max-width:1929px){.resizecontainer{width:1668px}.dashboard-full-width-chart{width:1665px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1655px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:549.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1654px}.dashboard-large-chart{width:1106px}.dashboard-large-chart .dashboard-sub-bar{width:1094px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:325px;width:936px}.dashboard-sub-bar-menu{font-size:16px}.dashboard-medium-chart-outer{float:left;width:826px}.dashboard-medium-chart{width:816px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:815px}.dashboard-medium-chart .dashboard-interior-chart{height:325px;width:656px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:22px;left:789px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:325px;width:816px}.dashboard-medium-chart #clusterGraphs svg text{font-size:14px}.dashboard-small-chart{width:546px}.dashboard-small-chart .dashboard-sub-bar{width:534px}.dashboard-small-chart .dashboard-small-chart-inner{width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:334px;width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:149px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:248px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:48.67px;line-height:48.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:87.33px;line-height:42.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:534px}.dashboard-bar-chart-container{height:150.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:148.5px;width:536px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:48.83px;line-height:48.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:80.67px;line-height:80.67px;padding:5px 8px 10px;width:520px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:85.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-834px;width:1688px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:16px;min-height:330px;width:170px}.absolut,.percentage{font-size:24px}.modal-chart-detail .modal-inner-detail{width:1488px}.modal-body .dashboard-large-chart{width:1103px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1091px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:933px}.modal-body .dashboard-medium-chart-outer{float:left;width:811px}.modal-body .dashboard-medium-chart{width:811px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:809px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:651px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:784px}.modal-body .dashboard-small-chart{width:541px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:529px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:531px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:246.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:531px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:536px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:520px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:14px;font-weight:400}.dashboard-subtitle-bar{font-size:24px;font-weight:300}.dashboard-figure{font-size:30px;font-weight:400}.dashboard-figurePer{font-size:28px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:14px}.dashboard-legend{height:330px;margin-top:-3px;width:160px}.dashboard-half-height-legend{font-size:14px;height:170px;width:80px}.application-detail-view section.info{width:1468px}}@media (min-width:1930px) and (max-width:2169px){.resizecontainer{width:1908px}.dashboard-full-width-chart{width:1905px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1895px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:629.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1894px}.dashboard-large-chart{width:1266px}.dashboard-large-chart .dashboard-sub-bar{width:1254px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:385px;width:1086px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:946px}.dashboard-medium-chart{width:936px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:935px}.dashboard-medium-chart .dashboard-interior-chart{height:385px;width:766px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:26px;left:905px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:385px;width:936px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:626px}.dashboard-small-chart .dashboard-sub-bar{width:614px}.dashboard-small-chart .dashboard-small-chart-inner{width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:394px;width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:179px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:288px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:58.67px;line-height:58.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:107.33px;line-height:52.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:614px}.dashboard-bar-chart-container{height:180.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:178.5px;width:616px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:58.83px;line-height:58.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:100.67px;line-height:100.67px;padding:5px 8px 10px;width:600px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:105.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-954px;width:1928px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:390px;width:180px}.absolut,.percentage{font-size:28px}.modal-chart-detail .modal-inner-detail{width:1718px}.modal-body .dashboard-large-chart{width:1263px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1251px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1083px}.modal-body .dashboard-medium-chart-outer{float:left;width:931px}.modal-body .dashboard-medium-chart{width:931px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:929px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:761px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:900px}.modal-body .dashboard-small-chart{width:621px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:609px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:611px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:286.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:611px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:616px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:600px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:28px;font-weight:300}.dashboard-figure{font-size:34px;font-weight:400}.dashboard-figurePer{font-size:32px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:14px;font-weight:400}.dashboard-legend{font-size:15px;font-weight:400;height:390px;margin-top:-3px;width:170px}.dashboard-half-height-legend{font-size:15px;height:200px;width:85px}.application-detail-view section.info{width:1708px}}@media (min-width:2170px) and (max-width:2409px){.resizecontainer{width:2148px}.dashboard-full-width-chart{width:2145px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2135px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:709.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2134px}.dashboard-large-chart{width:1426px}.dashboard-large-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1276px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1066px}.dashboard-medium-chart{width:1056px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1055px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:916px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1031px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1056px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:706px}.dashboard-small-chart .dashboard-sub-bar{width:694px}.dashboard-small-chart .dashboard-small-chart-inner{width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:328px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:694px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:696px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:680px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1074px;width:2168px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:1988px}.modal-body .dashboard-large-chart{width:1423px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1411px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1273px}.modal-body .dashboard-medium-chart-outer{float:left;width:1051px}.modal-body .dashboard-medium-chart{width:1051px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1049px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:911px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1026px}.modal-body .dashboard-small-chart{width:701px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:691px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:326.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:691px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:696px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:680px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:1948px}}@media (min-width:2410px) and (max-width:2649px){.resizecontainer{width:2388px}.dashboard-full-width-chart{width:2385px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2375px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:789.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2374px}.dashboard-large-chart{width:1586px}.dashboard-large-chart .dashboard-sub-bar{width:1574px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1436px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1186px}.dashboard-medium-chart{width:1176px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1175px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1036px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1151px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1176px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:786px}.dashboard-small-chart .dashboard-sub-bar{width:774px}.dashboard-small-chart .dashboard-small-chart-inner{width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:368px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:774px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:776px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:760px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1194px;width:2408px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2228px}.modal-body .dashboard-large-chart{width:1583px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1571px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1433px}.modal-body .dashboard-medium-chart-outer{float:left;width:1171px}.modal-body .dashboard-medium-chart{width:1171px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1169px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1031px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1146px}.modal-body .dashboard-small-chart{width:781px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:769px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:771px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:366.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:771px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:776px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:760px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2188px}}@media (min-width:2650px) and (max-width:2889px){.resizecontainer{width:2628px}.dashboard-full-width-chart{width:2625px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2615px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:869.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2614px}.dashboard-large-chart{width:1746px}.dashboard-large-chart .dashboard-sub-bar{width:1734px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1596px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1306px}.dashboard-medium-chart{width:1296px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1295px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1156px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1271px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1296px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:866px}.dashboard-small-chart .dashboard-sub-bar{width:854px}.dashboard-small-chart .dashboard-small-chart-inner{width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:408px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:854px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:856px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:840px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1314px;width:2648px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2468px}.modal-body .dashboard-large-chart{width:1743px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1731px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1593px}.modal-body .dashboard-medium-chart-outer{float:left;width:1291px}.modal-body .dashboard-medium-chart{width:1291px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1289px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1151px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1266px}.modal-body .dashboard-small-chart{width:861px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:849px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:851px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:406.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:851px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:856px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:840px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2428px}}div.centralRow{margin-bottom:40px;margin-top:40px}div.centralContent{background-color:transparent;height:100%;margin-left:-5px;margin-right:-5px;min-height:80px;padding:5px;width:100%}.contentDiv{list-style:none;padding:13px 0 0}.contentDiv li{background-color:rgba(0,0,0,.05)}.contentDiv a.add{display:block;font-weight:400;padding:40px 0;text-align:left}.contentDiv .icon{padding-left:5px;padding-right:5px;padding-top:10px}.contentDiv:after{clear:both}.contentDiv:after,.contentDiv:before{content:'';display:table;line-height:0}body{background-color:rgba(245,248,240,.95)}.headerButtonBar select{border:1px solid rgba(140,138,137,.25);height:28px} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome/fontawesome-webfont.eot?v=4.4.0);src:url(../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=4.4.0) format("embedded-opentype"),url(../fonts/fontawesome/fontawesome-webfont.woff2?v=4.4.0) format("woff2"),url(../fonts/fontawesome/fontawesome-webfont.woff?v=4.4.0) format("woff"),url(../fonts/fontawesome/fontawesome-webfont.ttf?v=4.4.0) format("truetype"),url(../fonts/fontawesome/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.modal-body,button{font-family:'Open Sans',sans-serif!important}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa.fa-pull-right,.fa.pull-right{margin-left:.3em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right,.pull-right{float:right}.contentDiv li,.dashboard-bar-chart-container,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut,.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage,.dashboard-full-width-chart,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart,.dashboard-half-height-legend,.dashboard-large-chart,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-legend,.dashboard-medium-chart,.dashboard-medium-chart .dashboard-interior-chart,.dashboard-small-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart,.dashboard-sub-bar,.dashboard-sub-bar .dashboard-sub-bar-title,.dashboard-tendency-container,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar,.dashboard-title-bar .dashboard-half-title-bar,.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.machineClass,.modal-chart-detail,.modal-chart-detail .modal-body,.modal-chart-detail .modal-dashboard-legend,.modal-chart-detail .modal-inner-detail,.navlist li,.navlogo,.pull-left,.scenarioMachine,.script-dropdown-menu,.user-dropdown-menu,a.button-gui,a.headerButton,div .bigtile,div .bigtile a span.add-Icon,div .tile,div .tile a span.add-Icon,div.centralContent,div.dropdownInner ul,div.footer-center,div.footer-left,div.footer-left p{float:left}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before{content:""}.fa-check-circle:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before{content:""}.fa-arrow-circle-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.dashboard-sub-bar-menu,.headerBar>div.headerButtonBar,.navmenu,.search-field,div .bigtile .iconSet span,div .tile .iconSet span,div.footer-right,div.footer-right p,ul.headerButtonList li{float:right}.dashboard-bar-chart-container .dashboard-bar-chart:after,.dashboard-medium-chart .dashboard-medium-chart-inner:after,.dashboard-medium-chart .dashboard-medium-chart-menu:after,.dashboard-row:after,.dashboard-sub-bar:after,.dashboard-tendency-container .dashboard-tendency-chart:after,.detail-chart:after,.headerBar>div.headerButtonBar:after,.machineClass:after,.resizecontainer:after,.scenarioSingleMachine:after,.tileList:after{clear:both;content:'.';display:block;font-size:0;height:0;visibility:hidden}.addButton,.arangoicon,.clusterDownBtn button,.contentDiv .icon,.deleteButton,.gv-search-submit-icon,.icon-info-sign,.scenarioImage,.script-dropdown-menu .dropdown-item,.search-submit-icon,a.button-gui,a.headerButton,div .bigtile,div .bigtile .iconSet span,div .bigtile a span.icon,div .bigtile a svg,div .tile .iconSet span,div .tile a span.icon,div .tile a svg,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,div.toolbox div.gv_action_button{cursor:pointer}.navbar,footer.footer{background-color:rgba(245,248,240,.95);color:#fff;left:0;position:fixed;right:0;width:100%;z-index:1000}.button-danger{background-color:#da4f49}.button-danger:focus,.button-danger:hover{background-color:#be342e}.deleteButton,a.danger.coordinator,a.danger.dbserver{color:#da4f49}.deleteButton:focus,.deleteButton:hover,a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{color:#be342e}a.danger.coordinator,a.danger.dbserver{fill:#da4f49}a.danger.coordinator:focus,a.danger.coordinator:hover,a.danger.dbserver:focus,a.danger.dbserver:hover{fill:#be342e}.button-success{background-color:#8aa051}.button-success:focus,.button-success:hover{background-color:#788f3d}.addButton,a.success.coordinator,a.success.dbserver{color:#8aa051}.addButton:focus,.addButton:hover,a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{color:#788f3d}a.success.coordinator,a.success.dbserver{fill:#8aa051}a.success.coordinator:focus,a.success.coordinator:hover,a.success.dbserver:focus,a.success.dbserver:hover{fill:#788f3d}.button-warning{background-color:#faa732}.button-warning:focus,.button-warning:hover{background-color:#f89406}a.warning.coordinator,a.warning.dbserver{color:#faa732;fill:#faa732}a.warning.coordinator:focus,a.warning.coordinator:hover,a.warning.dbserver:focus,a.warning.dbserver:hover{color:#f89406;fill:#f89406}.button-close,.button-neutral{background-color:#8f8d8c}.button-close:focus,.button-close:hover,.button-neutral:focus,.button-neutral:hover{background-color:#736b68}.dashboard-sub-bar-menu{color:#8f8d8c}.dashboard-sub-bar-menu:focus,.dashboard-sub-bar-menu:hover{color:#736b68}.button-primary{background-color:#564e4a}.button-primary:focus,.button-primary:hover{background-color:#3a322e}.button-header,a.button-gui,a.headerButton{background-color:#fff;border:1px solid #fff;color:#555}.button-header:focus,.button-header:hover,a.button-gui:focus,a.button-gui:hover,a.headerButton:focus,a.headerButton:hover{background-color:#8aa051;border:1px solid #8aa051;color:#fff}.button-notification{background-color:#faa020}.button-notification:focus,.button-notification:hover{background-color:#f87c0f}.button-inactive,.button-inactive:focus,.button-inactive:hover,[class*=' button-']:disabled,[class*=' button-']:focus:disabled,[class*=' button-']:hover:disabled,[class^=button-]:disabled,[class^=button-]:focus:disabled,[class^=button-]:hover:disabled,button.disabled,button.disabled:focus,button.disabled:hover{background-color:#d3d3d3}a.headerButton.disabled,a.headerButton.disabled:focus,a.headerButton.disabled:hover,a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{color:#d3d3d3}a.inactive.coordinator,a.inactive.coordinator:focus,a.inactive.coordinator:hover,a.inactive.dbserver,a.inactive.dbserver:focus,a.inactive.dbserver:hover{fill:#d3d3d3}div.queryline .fa.fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:relative;right:21px;top:-1px}div.queryline .fa.fa-search:hover{cursor:pointer;opacity:1}.modal-body .select2-choices input,.modal-body input,.modal-body select,.modal-body textarea,.navbar .arango-collection-select,div.queryline input,div.queryline select,input.search-input{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#fff!important;border:1px solid rgba(140,138,137,.25);box-shadow:none;outline:transparent 0}.modal-body input:focus,.modal-body select:focus,.modal-body textarea:focus,.navbar .arango-collection-select:focus,div.queryline input:focus,div.queryline select:focus,input.search-input:focus{border-color:#999;box-shadow:none;outline:transparent 0}.dropdown-toolbar,.gv-dropdown-menu,.link-dropdown-menu,.script-dropdown-menu,.user-dropdown-menu{background-color:#f5f8f0;border-color:#666;border-radius:3px;border-style:solid;border-width:1px;box-shadow:none;display:none;list-style:none;margin:5px 0 0;padding:5px 0;position:absolute;right:0;top:80%;z-index:1000}.script-dropdown-menu .dropdown-item a,.tab{display:block}.dropdown-toolbar li,.gv-dropdown-menu li,.link-dropdown-menu li,.script-dropdown-menu li,.user-dropdown-menu li{line-height:23px;white-space:nowrap;width:100%}.dropdown-toolbar .dropdown-header,.gv-dropdown-menu .dropdown-header,.link-dropdown-menu .dropdown-header,.script-dropdown-menu .dropdown-header,.user-dropdown-menu .dropdown-header{color:#999;font-size:15px;font-weight:600;font-variant:small-caps;padding:0}.dropdown-toolbar .dropdown-header:hover,.gv-dropdown-menu .dropdown-header:hover,.link-dropdown-menu .dropdown-header:hover,.script-dropdown-menu .dropdown-header:hover,.user-dropdown-menu .dropdown-header:hover{cursor:default}.dropdown-toolbar .divider,.gv-dropdown-menu .divider,.link-dropdown-menu .divider,.script-dropdown-menu .divider,.user-dropdown-menu .divider{background-color:#666;height:1px;margin:10px 0 5px}.dropdown-toolbar a,.gv-dropdown-menu a,.link-dropdown-menu a,.script-dropdown-menu a,.user-dropdown-menu a{color:#fff;padding:0 20px}.navbar{-webkit-font-smoothing:subpixel-antialiased;height:44px;margin-bottom:3px;padding-top:6px;top:0}.navbar .no-left-margin{border:0;margin-left:0}.navbar .no-left-margin.hover{background-color:transparent}.navbar .arangodbLogo{height:auto;margin-left:-5px;margin-top:-1px;width:40%}.navbar .arango-collection-select{position:relative;right:-22px;top:4px}.navbar .nav .dropdown .active>.dropdown-toggle,.navbar .nav .dropdown .open.active>.dropdown-toggle,.navbar .nav .dropdown .open>.dropdown-toggle{background:#788f3d}.navbar .nav>.active>a{-webkit-box-shadow:0 0 0 transparent inset;-moz-box-shadow:0 0 0 transparent inset;box-shadow:0 0 0 transparent inset;background-color:#fff;color:#000}.navbar .nav>li>a:focus{background-color:#fff}.navbar .nav>li>a:hover{background-color:#000;color:#686766}.navlist .dropdown-item:hover a,.navlist>.active a,.navlist>.active:hover a,.navlist>li:hover a{color:#000}.navlogo{margin-left:5px;margin-right:-3px;padding-top:3px}.navlist{list-style:none}.navlist>li{height:39px}.navlist li{border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;margin-left:7px}.navlist li.dropdown:hover{background-color:#fff;border-bottom-left-radius:0;border-bottom-right-radius:0;border-left:1px solid rgba(0,0,0,.2);border-right:1px solid rgba(0,0,0,.2);border-top:1px solid rgba(0,0,0,.2)}.navlist li.dropdown:hover a{border-bottom:2px solid #fff}.navlist li.divider,.navlist li.navbar-spacer{border:0}.navlist li.divider{background-color:rgba(0,0,0,.2)}.navlist li.navbar-spacer{background-color:#a0a0a0;height:21px;margin-top:9px;width:1px}.navlist li.navbar-spacer.big{margin-left:15px;margin-right:15px}.navlist li.navbar-spacer.med{margin-left:5px;margin-right:5px}.navlist .dropdown-item,.script-dropdown-menu .dropdown-item{margin-left:0}.navlist li.navbar-spacer:hover{background-color:#a0a0a0}.navlist .active .tab{border-bottom:2px solid #8aa051;padding-bottom:4px}.navlist>.active{background-color:transparent}.navlist>.active:hover{background-color:#fff}.navlist .dropdown-item:hover,.navlist>li:hover{background-color:#fff;border-radius:3px}.navlist .dropdown-item a{border-bottom:0;display:block;font-size:11pt}.navlist .dropdown-item a:hover{background-color:#dee9cf;color:#686766}.tab{color:#686766;font-size:12pt;font-weight:100;padding:9px 5px 10px}.tab.userImg{padding-bottom:5px}.dropdown-item a{border-bottom:0!important;font-weight:300}.dropdown-toolbar,div.headerBar,div.headerDropdown{border:1px solid rgba(140,138,137,.25)}.dropdown-toolbar li a,footer.footer p{font-weight:100}.dropdown-toolbar{background-color:#fff!important}.dropdown-toolbar li a:hover{background:0 0;background-color:#dee9cf!important;color:#000!important}.link-dropdown-menu,.user-dropdown-menu{background-color:#fff;border:1px solid rgba(0,0,0,.2);border-top-right-radius:0;margin-right:-1px;margin-top:7px;z-index:-10}.link-dropdown-menu .dropdown-item,.user-dropdown-menu .dropdown-item{border-left:0;border-right:0}.script-dropdown-menu .dropdown-item a:hover{color:#fff}.script-dropdown-menu .dropdown-item:hover{background-color:#8aa051}.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:rgba(0,0,0,.7);border:1px solid #c2c2c2;margin-right:-20px;margin-top:6px}.gv-dropdown-menu:after{border-bottom-color:#fff}.gv-dropdown-menu li:hover{background-color:#fff;background-image:none}.gv-dropdown-menu li a{padding:0}.gv-dropdown-menu li a label{color:#fff;padding-left:5px}.gv-dropdown-menu li a:focus{background-color:#8aa051!important;background-image:none}#arangoCollectionSelect{display:none;float:right;margin-bottom:0;margin-right:15px;padding-bottom:0}.caret{border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #686766;content:'';display:inline-block;height:0;vertical-align:top;width:0}.applications-menu{display:block}.arango-logo{height:34px;padding:0!important}.arango-logo img{margin-left:22px}.footer{bottom:0;font-size:14px;left:0;position:fixed;right:0;z-index:1000}.modal,.select2-drop-active{z-index:9999999}footer.footer{bottom:0;height:40px}footer.footer p{font-size:10pt;margin-bottom:0;padding-bottom:10px;padding-top:10px}div.footer-left{background:none;color:#686766;width:45%}div.footer-left .social-icons{margin-top:5px}div.footer-left .social-icons a{display:block;float:left;height:25px;width:25px}div.footer-left .social-icons p{background:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;height:25px;margin-right:10px;padding:0;width:25px}div.footer-left .social-icons p:hover{background:#8aa051;cursor:pointer}div.footer-left .social-icons p:hover i{color:#fff}div.footer-left .social-icons i{color:#000;margin-top:6px;position:absolute}.addButton,.deleteButton{position:relative;font-size:22px}div.footer-left .social-icons i.fa-twitter{margin-left:-5px}div.footer-left .social-icons i.fa-envelope{margin-left:-19px}div.footer-left .social-icons i.fa-google{margin-left:-17px;margin-top:7px}div.footer-left .social-icons i.fa-stack-overflow{margin-left:-17px}div.footer-center{background:none;color:#686766;width:10%}div.footer-center i{background-color:#fff;border:1px solid rgba(104,103,102,.1);border-radius:20px;margin-left:1px;padding:6px 2px;width:20px}div.footer-center i:hover{background-color:#8aa051;color:#fff}div.footer-center p{padding-top:5px}div.footer-center p:hover{cursor:pointer}[class*=' button-']:disabled,[class^=button-]:disabled,a.headerButton.disabled,button.disabled{cursor:not-allowed}div.footer-right{background:none;color:#686766;width:45%}div.footer-right p{color:#fff}div.footer-right i{color:#da4f49;font-size:18px}div.footer-right a{color:#686766;margin-left:5px;position:relative;top:-1px}div.footer-right .isOnline{color:#8aa051!important}.button-close,.button-danger,.button-header,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;font-size:14px;font-weight:300!important}.button-close,.button-danger,.button-inactive,.button-neutral,.button-notification,.button-primary,.button-success,.button-warning{border:0;color:#fff;margin-left:10px;padding:5px 16px}.button-header{margin-top:5px}.addButton{margin-right:7px;margin-top:2px}.deleteButton{padding-right:3px;top:3px}#closeBtnInfoView{margin-left:0!important}button.btn-server{width:120px}button.gv-zoom-btn{background-size:14px 14px;height:14px;vertical-align:baseline;width:14px}button.gv-zoom-btn.btn-zoom-right{border:0;box-shadow:none;right:0;top:13px}button.gv-zoom-btn.pan-right{background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-right:hover{background:inherit;background-image:url(../img/gv_arrow_right.png)}button.gv-zoom-btn.pan-left{background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-left:hover{background:inherit;background-image:url(../img/gv_arrow_left.png)}button.gv-zoom-btn.pan-top{background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-top:hover{background:inherit;background-image:url(../img/gv_arrow_top.png)}button.gv-zoom-btn.pan-bottom{background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.pan-bottom:hover{background:inherit;background-image:url(../img/gv_arrow_bottom.png)}button.gv-zoom-btn.btn-zoom{height:14px;margin:0;padding:0;position:absolute;width:16px}button.gv-zoom-btn.btn-zoom-top{border:0;box-shadow:none;left:13px;top:1}button.gv-zoom-btn.btn-zoom-left{border:0;box-shadow:none;left:0;top:13px}button.gv-zoom-btn.btn-zoom-bottom{border:0;box-shadow:none;left:13px;top:25px}button.gv-icon-btn{-moz-border-radius:0!important;-webkit-border-radius:0!important;border-radius:0!important;background-size:36px 36px;height:36px;width:36px}button.gv-icon-btn.active{background-color:#8aa051}button.gv_dropdown_entry{height:30px;margin:4px 4px 4px 30px;width:160px}button.gv_context_button{width:65px}button.large-distance{margin-left:12px}button.short-distance{margin-left:6px}button.shutdown{margin-top:6px;padding:3px 14px}button.graphViewer-icon-button{background-color:transparent;border:0;height:20px;margin-left:5px;margin-top:-2px;padding:0;width:20px}button.graphViewer-icon-button img{height:20px;padding-bottom:10px;width:20px}ul.headerButtonList{display:inline-block;margin-bottom:0;margin-left:0;padding-left:0!important}ul.headerButtonList li{display:inline}a.button-gui,a.headerButton{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;margin-left:5px;margin-right:5px}a.headerButton{margin-top:2px;position:relative}a.headerButton .fa,a.headerButton [class*=" icon_"],a.headerButton [class^=icon_]{display:block;height:23px;line-height:23px;position:static;right:0;text-align:center;top:0;width:27px}a.button-gui.button-gui-disabled,div.headerDropdown,div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox{display:none}a.headerButton .icon_arangodb_arrowleft,a.headerButton .icon_arangodb_arrowright{font-weight:700}a.headerButton.activated{background-color:#788f3d;border:1px solid #788f3d;color:#fff}div.toolbox,div.toolbox div.gv_action_button{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#fff}a.headerButton.activated:hover{background-color:#fff;color:#788f3d}div.toolbox{border-radius:3px;border:1px solid rgba(140,138,137,.25);margin-right:5px;margin-top:-3px;padding-bottom:5px;padding-top:5px;position:absolute}div.toolbox div.gv_action_button{border-radius:3px;color:#555;height:30px;margin:5px;position:relative;width:30px}div.toolbox div.gv_action_button.active{background-color:#8aa051;color:#fff}div.toolbox div.gv_action_button:first-child{margin-top:0}div.toolbox div.gv_action_button:last-child{margin-bottom:0}h6.gv_button_title,h6.gv_icon_icon{left:0;margin:0;position:absolute;right:0}h6.gv_icon_icon{font-size:22px;left:1px;top:4px}h6.gv_button_title{bottom:1px;display:none}.btn-icon{background-color:#383434;padding:4px}.gv-icon-small{background-size:16px 16px;height:16px!important;width:16px!important}.gv-icon-small.delete{background-image:url(../img/icon_delete.png)}.gv-icon-small.add{background-image:url(../img/plus_icon.png)}a.pagination-button,ul.arango-pagination a{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.badge,.btn,.label{text-shadow:none!important}.navbar-inner,.thumbnail{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0}.modal-body th.actionCell>button{margin-top:-12px}.btn-old-padding{padding-bottom:4px!important;padding-top:4px!important}button.btn-overview,button.btn-server{margin:5px}a.button-gui{height:auto;margin-bottom:0;margin-top:0;padding-bottom:1px;padding-top:1px;position:absolute;right:2px;text-decoration:none!important;top:2px;width:auto}.clusterDownBtn{padding-bottom:10px;padding-top:10px}.clusterDownBtn button{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#f1f1f1;border:1px solid rgba(0,0,0,.1875);color:#333;font-size:20px;font-weight:300;margin:0;padding:12px 18px;text-decoration:none!important;width:250px}.clusterDownBtn button:hover{background-color:#e8e8e8;color:#4a6c30;-webkit-transition-delay:0;-webkit-transition-duration:.2s;-webkit-transition-property:all;-webkit-transition-timing-function:ease-in}.clusterDownBtn button.green{background-color:#617e2b;color:#fff}.clusterDownBtn button.green:hover{background-color:#8ba142}.bottomButtonBar{background-color:#fff;border-top:1px solid rgba(104,103,102,.1);height:30px;padding:10px}.clusterInfoIcon{float:left;padding-left:5px;padding-top:2px}.waitModal.icon{font-size:100px;height:120px}.waitModal.message{font-size:20px}.icon_arangodb_info{color:#333;font-size:23px}li a [class*=" icon_arangodb"],li a [class^=icon_arangodb]{font-size:18px;position:absolute;right:4px;top:2px}.fa-minus-circle{color:#da4f49;font-size:14pt}.fa-minus-circle:hover{cursor:pointer}div.headerDropdown{background-color:#fff;border-radius:3px;clear:both;padding:10px;position:relative;width:auto}div.headerDropdown.smallDropdown .dropdownInner{min-height:20px}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.dropdown-title{margin-bottom:10px}div.dropdownInner{-webkit-box-shadow:0;-moz-box-shadow:0;box-shadow:0;min-height:125px;position:relative;width:auto}div.dropdownInner .nav-header{font-size:10pt}div.dropdownInner>.nav-header{color:#000;font-size:10pt;font-weight:400}div.dropdownInner>label{color:#000;font-weight:300}div.dropdownInner ul{border-left:1px solid rgba(140,138,137,.25);display:inline;list-style-type:none;margin-top:10px;min-height:105px;width:230px}div.dropdownInner ul:first-of-type,div.queryline input[type=file]{border:0}div.dropdownInner ul label{color:#000;padding-left:20px}div.dropdownInner ul li .fa{color:#999;margin-right:5px}div.dropdownInner ul li .fa.fa-square-o{margin-left:1px;margin-right:6px}div.dropdownInner ul li .fa.fa-check-circle-o,div.dropdownInner ul li .fa.fa-check-square-o,div.dropdownInner ul li .fa.fa-dot-circle-o{color:#8aa051}div.queryline{color:#000;height:35px}div.queryline .textDiv{margin-right:10px;margin-top:4px}div.queryline input,div.queryline select{margin-bottom:5px}div.queryline.querylineAdd span{color:#fff;padding-left:10px;position:relative;top:-21px}div.queryline .removeFilterItem i{margin-left:5px!important;margin-top:0!important}div.queryline div.searchByAttribute{margin-left:6px;margin-right:6px;position:relative}div.queryline div.searchByAttribute>ul.gv-dropdown-menu{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;background-color:#fff;color:#fff;display:none;left:0;position:absolute;top:20px;width:247px}div.dropdownImport{background-color:#fff;border-radius:3px;display:none;position:relative;padding:10px 10px 5px}div.dropdownImport input{line-height:0;margin-bottom:-15px;margin-top:5px}select.filterSelect{color:#00f;margin-left:10px;margin-right:10px;width:100px}#filterHeader button{float:right;margin-left:10px!important;margin-top:1px}div.input-append button.gv_example_toggle{-moz-border-radius:0 4px 4px 0;-webkit-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;background-color:#8f8d8c;height:30px;margin-left:-1px;padding-left:10px;padding-right:10px;padding-top:12px;vertical-align:top}div.input-append button.gv_example_toggle:hover{background-color:#8aa051}div.headerBar,div.headerBar .infoField{background-color:#fff;padding-left:5px;padding-right:5px}.searchEqualsLabel{margin-left:6px;margin-right:6px}img.gv-throbber{background-image:url(../img/swagger/throbber.gif)}span.gv_caret{border-top:5px solid #fff;margin-top:2px!important}input.search-input{height:14px;line-height:18px;margin-right:-1px;margin-top:6px;width:120px}.search-field{margin-left:10px}.search-field .fa-search{color:#c2c2c2;font-size:12pt;opacity:.5;position:absolute;right:9px;top:9px}.search-field .fa-search:hover{cursor:pointer;opacity:1}.gv-search-submit-icon,.search-submit-icon{background-image:url(../img/enter_icon.png);background-size:14px;height:14px;margin-left:-18px;opacity:.2;position:absolute;width:14px}.gv-search-submit-icon:hover,.search-submit-icon:hover{opacity:.8}.search-submit-icon{margin-top:11px}.gv-search-submit-icon{margin-top:6px}div.headerBar{border-radius:3px;color:#fff;font-size:16px;height:36px;margin-bottom:5px;margin-top:15px;position:relative}div.headerBar .infoField{border:1px solid rgba(140,138,137,.25);border-radius:3px!important;color:#000;float:right;font-size:12px;margin-right:7px;margin-top:7px}div.headerBar .infoField .fa{cursor:pointer;margin-left:5px}div.headerBar input[type=checkbox].css-checkbox{display:none}div.headerBar input[type=checkbox].css-checkbox label.css-label{background-position:0 0;background-repeat:no-repeat;cursor:pointer;display:inline-block;font-size:15px;height:15px;margin-top:0;padding-left:20px;vertical-align:middle}div.headerBar input[type=checkbox].css-checkbox:checked+label.css-label{background-position:0 -15px}div.headerBar input[type=radio]{display:none}div.headerBar input[type=radio] label span{background:url(../img/check_radio_sheet.png) -38px top no-repeat;cursor:pointer;display:inline-block;height:19px;margin:-1px 4px 0 0;vertical-align:middle;width:19px}#transparentHeader input[type=checkbox].css-checkbox,.lineGraph .many .dygraph-legend>span,.modal-delete-confirmation{display:none}div.headerBar input[type=radio]:checked+label span{background:url(../img/check_radio_sheet.png) -57px top no-repeat}.headerButtonList a.error{color:#da4f49}.headerButtonList a.error:hover{background-color:#da4f49;border-color:#da4f49;color:#fff}.headerBar a.arangoHeader{color:#000;font-size:13pt;font-weight:100;left:0;position:relative;top:7px}.headerBar>div.headerButtonBar{margin:4px 0;margin-bottom:0!important}.breadcrumb{background:0 0;border:0;border-radius:0;padding:7px 0}.breadcrumb .disabledBread{color:#666;float:left;font-size:13pt;font-weight:100;padding-right:5px;position:relative}.breadcrumb .disabledBread i{font-size:10pt;margin-left:10px}.breadcrumb .activeBread{color:#8aa051;float:left;font-size:13pt;font-weight:100}.arangoHeader{font-weight:400}.checkboxLabel{margin-top:4px;padding-left:0}.css-label{background-image:url(../img/dark-check-green.png)}.css-label-round{background-image:url(../img/dark-check-green-round.png)}.modal-dashboard-header,.modal-header{background-color:#fff;border-bottom:0!important;border-radius:3px;margin-top:5px;padding-left:5px;padding-right:10px;padding-top:4px}.modal-dashboard-header .arangoHeader,.modal-header .arangoHeader{color:#000;font-size:13pt;font-weight:100;left:5px;position:relative;top:2px}.modal-dashboard-header a,.modal-header a{top:2px!important}.modal-dashboard-header .close,.modal-header .close{color:#fff;font-weight:300;margin-top:2px;opacity:.5}.modal-dashboard-header .close:hover,.modal-header .close:hover{opacity:1}.modal-tabbar{border-bottom:1px solid #666}.modal-body{color:#736b68;font-size:14px;font-weight:300;max-height:410px}.modal-body .select2-choices{background-image:none!important;border:1px solid #999;border-radius:3px;-webkit-box-shadow:none;box-shadow:none}.modal-body .select2-choices input:active{-webkit-box-shadow:none;box-shadow:none;outline:0!important}.modal-body .select2-choices .select2-search-choice{margin:5px 0 3px 5px!important}.modal-body .select2-choices li{background-color:#fff!important;background-image:none!important;color:#000}.modal-body tr.first,.modal-body tr.last,.modal-body tr.middle{background-color:#f5f8f0}.modal-body .select2-choices li a{margin-left:1px;margin-top:-1px}.modal-body .select2-choices:active{border:1px solid #999;-webkit-box-shadow:none!important;box-shadow:none!important;outline:transparent!important}.modal-body .nav-tabs{margin-top:15px}.modal-body .nav-tabs>li>a:hover{border-color:#8c8a89}.modal-body input,.modal-body select,.modal-body textarea{margin-top:10px}.modal-body input[type=checkbox]{margin-bottom:10px}.modal-body input[type=text].invalid-input{border-color:rgba(234,23,23,.6)}.modal-body input[type=text].invalid-input:focus{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(234,23,23,.6)}.modal-body input[type=file]{line-height:17px}.modal-body tr.spacer{height:10px}.modal-body tr.first th:first-child{border-top-left-radius:3px}.modal-body tr.first th:last-child{border-top-right-radius:3px}.modal-body tr.middle{padding-left:10px;padding-right:10px}.modal-body tr.last th:first-child{border-bottom-left-radius:3px}.modal-body tr.last th:last-child{border-bottom-right-radius:3px}.modal-body tr.first th:first-child,.modal-body tr.last th:first-child,.modal-body tr.middle th:first-child{padding-left:10px}.modal-body tr.first th:last-child,.modal-body tr.last th:last-child,.modal-body tr.middle th:last-child{padding-right:10px}.modal-body th.actionCell{width:30px}.modal-body th.keyCell{width:170px}.modal-body th.keyCell input{width:150px}.modal-body th .valueCell{width:300px}.modal-body th .valueCell input{width:290px}.modal-body th .select2-container{margin-bottom:10px;margin-top:10px}.modal-body .icon-info-sign{margin-bottom:10px;margin-left:10px;opacity:.7;padding-bottom:5px}.modal-body .icon-info-sign:hover{opacity:1}.modal-body .icon_arangodb_info{color:#736b68;font-size:18px;margin-top:-10px;position:absolute;right:12px}.modal-body .icon_arangodb_info:hover{color:#000}.modal-body .collapse{margin-right:-14px;position:relative}.modal-body .accordion-inner{border-top:0;margin-left:0;padding-left:0;padding-right:0}.modal-body .accordion-toggle span .caret{border-top-color:#000;float:right;margin-top:5px}.modal-body .accordion-toggle.collapsed span .caret{-ms-transform:rotate(90deg);-webkit-transform:rotate(90deg);transform:rotate(90deg)}.modal-body input{width:384px}.modal-body select{width:398px}.modal-body .collectionTh{height:50px}.modal-body .tab-content{min-height:200px}.modal-body .tab-content .tab-pane{border-top:1px solid #666!important;margin-left:0!important;padding-top:10px}.modal-body .tab-content .tab-pane-modal{border-top:none!important}.modal-body .tab-content #appstore{max-height:290px}.modal-body .errorMessage{background-color:#fff;color:#da4f49;font-size:9pt;font-weight:400;margin-bottom:5px;margin-top:-9px;position:absolute}.modal-body .nav .tab-icon{margin-right:5px;margin-top:-3px;width:20px}.modal-text{font-weight:300;padding-bottom:3px;padding-top:3px}.modal-backdrop,.modal-backdrop.fade.in{opacity:.4}.modal{border:0!important;border-radius:3px!important;box-shadow:0;width:580px}.modal .fade.in{top:12.1%!important}.modal table tr:last-child{border-bottom:0!important}.waitModal{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:0 0;border:0;color:#fff}.waitModalBackdrop{opacity:.7!important}.modalTooltips span{color:#736b68;font-size:20px}.modalTooltips span:hover{color:#000}.gv-object-view{text-align:left;white-space:pre}.capitalize{text-transform:capitalize}.modal-footer{border-top:0!important;padding-right:17px}.modal-header{margin-left:5px;margin-right:5px}.modal-dashboard-header{margin-left:0;margin-right:0;padding-bottom:9px}.modal table tr,.thBorderBottom{border-bottom:1px solid #f7f3f2!important}.modal-delete-confirmation button{margin-right:10px;margin-top:-4px}.modal-delete-confirmation button .modal-confirm-delete{margin-right:-18px}.modal-delete-confirmation fieldset input{float:left}.modal-delete-confirmation fieldset label{float:left;margin-left:10px}.createModalDialog table{width:100%}.createModalDialog .collection-info-figures table{float:left;margin-left:0;margin-right:0;margin-top:0;min-width:200px;padding:3px;text-align:left}.createModalDialog .figures1,.createModalDialog .figures2{margin-bottom:20px;width:255px}.createModalDialog .figures2{margin-left:20px!important}.createModalDialog .figures3{margin-bottom:0;width:100%}.foxx-store-row .foxx-name{font-weight:700}.foxx-store-row .foxx-author{font-size:10pt;font-weight:300;margin-top:-4px}.foxx-store-row .foxx-version{font-weight:400}#new-app-mount{margin-right:24px;width:360px}#control_event_edge_delete_modal,#control_event_edge_edit_modal,#control_event_new_node_modal,#control_event_node_delete_modal,#control_event_node_edit_modal{margin-left:-320px;width:640px}.scenarioImage{height:70%;width:auto}svg.clusterChart{height:auto;margin:auto;width:auto}.lineGraph{position:absolute}.lineGraph .few .dygraph-legend>span.highlight{border:1px solid grey}.lineGraph .many .dygraph-legend>span.highlight{display:inline}a.coordinator,a.dbserver{color:#000;height:50px;position:absolute;top:10px;width:50px}a.coordinator h6.serverName,a.dbserver h6.serverName{bottom:0;font-size:11px;left:0;margin:0;position:absolute;right:0}a.coordinator.single{left:90px}a.coordinator.double{left:60px}a.dbserver.single{right:90px}a.dbserver.double{right:60px}.cluster-connection-check-success{color:#8aa051;margin-left:20px}.cluster-connection-check-fail{color:#da4f49;margin-left:20px}.cluster-unreachable-info{margin:0 auto;max-width:320px;padding-top:17px;text-align:center}.machineClass{background-color:#e1e1e1;margin-left:31px;margin-right:31px;padding:10px}.scenarioBox{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:rgba(0,0,0,.075);border:1px solid rgba(0,0,0,.19);height:65px;left:10px;margin-top:30px;position:absolute;right:10px;width:auto}.scenarioMachine,div .bigtile,div .tile{background-color:#fff;position:relative}.scenarioBox.bottomBox{bottom:30px}.scenarioBoxHeader{border-bottom:1px solid rgba(0,0,0,.19);height:18px;line-height:18px;margin-top:0;padding-bottom:0;text-align:center;width:auto}.scenarioBoxText{font-size:13px;font-weight:400;margin-top:17px;text-align:center;width:auto}.collectionName,div .bigtile .badge-success,div .tile .badge-success{font-weight:300}.scenarioMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;border:1px solid rgba(0,0,0,.19);height:257px;margin-right:17px;width:109px}.scenarioMachine:last-child{margin-right:0}.scenarioSingleMachine{-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background-color:#fff;border:1px solid rgba(0,0,0,.19)}.scenarioSingleMachine .scenarioMachine{border:1px solid transparent;height:238px}.bigtile.informationtile{cursor:auto}.informationText{background:#fff;font-size:12px;margin:10px;padding:5px;text-align:left}.tileList{margin-left:-6px;margin-right:-6px}.tileList legend{padding-left:5px}.tileList .tile:first-child a{opacity:.8}.tileList .tile:first-child a:hover{opacity:1}div .bigtile,div .tile{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border:1px solid #f5f8f0;border-radius:3px;font-size:14px;list-style:none;margin-bottom:13px;margin-left:6px;margin-right:6px;text-align:center;z-index:1}div .bigtile progress[value],div .tile progress[value]{color:#5bc0de}div .bigtile progress::-webkit-progress-bar-value,div .tile progress::-webkit-progress-bar-value{background:#5bc0de}div .bigtile progress::-webkit-progress-value,div .tile progress::-webkit-progress-value{background:#5bc0de}div .bigtile progress::-moz-progress-bar,div .tile progress::-moz-progress-bar{background:#5bc0de}div .bigtile progress,div .tile progress{-webkit-appearance:none;border-radius:0;height:2px;margin-top:16px;position:relative;width:100%;z-index:10}div .bigtile:hover,div .tile:hover{cursor:pointer}div .locked.bigtile,div .locked.tile{cursor:not-allowed;opacity:.5}div .locked.bigtile .iconSet span:hover,div .locked.tile .iconSet span:hover{background-color:#fff!important;color:#000;cursor:not-allowed!important}div .locked.bigtile .iconSet:hover,div .locked.tile .iconSet:hover{cursor:not-allowed!important}div .bigtile .collection-type-icon:hover,div .bigtile img:hover,div .tile .collection-type-icon:hover,div .tile img:hover{cursor:pointer}div .bigtile .warning-icons,div .tile .warning-icons{background-color:#da4f49;border-radius:3px;color:#fff;font-size:11px;height:17px;left:0;line-height:13px;margin-left:5px;margin-top:5px;padding-left:9px;padding-right:9px;position:absolute;top:0}div .bigtile a svg.icon,div .bigtile img.icon,div .tile a svg.icon,div .tile img.icon{height:50px;width:50px}div .bigtile .warning-icons .fa,div .tile .warning-icons .fa{font-size:11pt;margin-left:1px}div .bigtile .collection-type-icon,div .tile .collection-type-icon{color:#666;font-size:30pt;margin-top:12pt}div .bigtile img,div .tile img{position:relative}div .bigtile a span.add-Icon,div .tile a span.add-Icon{font-size:22px;margin-left:22px;margin-right:10px;margin-top:-5px;position:relative;right:4px;top:2px}div .bigtile a span.icon,div .tile a span.icon{font-size:50px}div .bigtile .tile-icon-svg,div .tile .tile-icon-svg{cursor:pointer;fill:#686766;height:50px;margin-left:90px;margin-top:10px;position:absolute;width:50px}div .bigtile .tile-icon,div .tile .tile-icon{color:#686766;font-size:50px;line-height:1.2}div .bigtile .icon_arangodb_edge5-2,div .tile .icon_arangodb_edge5-2{display:inline-block;position:relative;top:15px;-moz-transform:rotate(80deg);-o-transform:rotate(80deg);-webkit-transform:rotate(80deg)}div .bigtile h5,div .tile h5{background:#8c8a89;color:#fff;font-size:12px;margin:0;overflow:hidden!important;padding:4px 8px;text-overflow:ellipsis!important;white-space:nowrap!important}div .bigtile h5.inProgress,div .tile h5.inProgress{color:#5bc0de}div .bigtile .tileSelects,div .tile .tileSelects{margin-left:40px;position:relative;z-index:9999}div .bigtile .tileSelects select,div .tile .tileSelects select{float:right;height:20px;margin-right:5px;margin-top:16px;width:70px}div .bigtile .fullBorderBox,div .tile .fullBorderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:100%;position:absolute;width:100%}div .bigtile .borderBox,div .tile .borderBox{border:1px solid rgba(140,138,137,.25);border-radius:3px;height:75px;position:absolute;width:224px}.collectionName,.dashboard-sub-bar{border-bottom-left-radius:3px;border-bottom-right-radius:3px}div .bigtile .iconSet,div .tile .iconSet{position:absolute;right:5px;top:5px}div .bigtile .iconSet span,div .tile .iconSet span{border-radius:3px;color:#666;font-size:18px;z-index:2;padding:2px 3px}div .bigtile .iconSet span:hover,div .tile .iconSet span:hover{background-color:#8aa051;color:#fff}div .bigtile .iconSet span.disabled,div .tile .iconSet span.disabled{cursor:default;opacity:.2}div .bigtile .iconSet span.disabled:hover,div .tile .iconSet span.disabled:hover{background-color:#fff;color:#000;cursor:default;opacity:.2}div .bigtile .unloaded div,div .tile .unloaded div{border-bottom:16px solid #ff8f35}div .bigtile .deleted div,div .tile .deleted div{border-bottom:16px solid #700}div .bigtile .tileBadge,div .tile .tileBadge{bottom:29px;font-size:11px;font-weight:300;position:absolute;right:0}div .bigtile .tileBadge button,div .tile .tileBadge button{margin-left:0;margin-right:5px}div .bigtile .tileBadge span,div .tile .tileBadge span{display:inline-block;line-height:15px}div .bigtile .tileBadge span .corneredBadge,div .tile .tileBadge span .corneredBadge{border-bottom-style:solid;border-bottom-width:17px;border-left:5px solid transparent;border-radius:3px;color:#fff;height:0;margin-bottom:4px;margin-right:5px;padding-left:1px;padding-right:6px}div .bigtile .tileBadge span .corneredBadge.loading,div .tile .tileBadge span .corneredBadge.loading{border-bottom-color:#ff8f35}div .bigtile .tileBadge span .corneredBadge.loaded,div .tile .tileBadge span .corneredBadge.loaded{border-bottom-color:#8aa051}div .bigtile .tileBadge span .corneredBadge.development,div .bigtile .tileBadge span .corneredBadge.unloaded,div .tile .tileBadge span .corneredBadge.development,div .tile .tileBadge span .corneredBadge.unloaded{border-bottom-color:#ff8f35}div .tile{height:100px;width:226px}div .tile-graph .tile-icon:hover{cursor:pointer}div .bigtile{height:309px;width:452px}div .bigtile .shardContainer{font-size:30px}div .bigtile .shardContainer span{padding:2px}.collectionName{bottom:0;left:0;position:absolute;right:0;text-align:left}.dashboard-bar-chart-container,.dashboard-full-width-chart .dashboard-full-width-chart-inner,.dashboard-large-chart .dashboard-large-chart-inner,.dashboard-medium-chart,.dashboard-small-chart .dashboard-small-chart-inner,.dashboard-tendency-container{border-top-left-radius:3px;border-top-right-radius:3px}.dashboard-bar-chart-container:first-child,.dashboard-full-width-chart .dashboard-full-width-chart-inner:first-child,.dashboard-large-chart .dashboard-large-chart-inner:first-child,.dashboard-medium-chart:first-child,.dashboard-small-chart .dashboard-small-chart-inner:first-child,.dashboard-tendency-container:first-child{margin-left:0}.dashboard-bar-chart-container,.dashboard-full-width-chart,.dashboard-large-chart,.dashboard-medium-chart,.dashboard-small-chart,.dashboard-tendency-container{margin-bottom:10px;position:relative}.dashboard-sub-bar-menu{cursor:pointer;position:absolute;right:9px;top:6px}.dataNotReadyYet{font-family:'Open Sans',sans-serif;font-size:20px;font-weight:100;text-align:center}.dashboard-sub-bar{background-color:#686766;color:#fff;height:24px;line-height:24px;margin:0;padding:0 6px}.dashboard-full-width-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-subtitle-bar.top{border-bottom:1px solid #e1e1e1;height:48px;line-height:48px;text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{border-left:1px solid #e1e1e1}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner{margin-left:10px;margin-right:10px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table{margin-bottom:10px;margin-top:10px;table-layout:fixed;width:100%}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart,.dashboard-medium-chart .dashboard-interior-chart{margin-bottom:0}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table .no-data{font-style:italic;font-weight:100}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table tr{border-bottom:1px solid rgba(0,0,0,.025)}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:first-child{width:100px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart .inner table td:last-child{text-align:right}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart:first-child{border-left:0}.dashboard-full-width-chart .state{background-color:#fff;border-radius:5px;color:#000;margin-left:5px;padding-left:6px;padding-right:4px}.dashboard-large-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px;margin-right:12px}.dashboard-large-chart .dashboard-large-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:12px}.dashboard-small-chart{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-small-chart .dashboard-small-chart-inner{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;padding-bottom:10px;padding-top:5px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart-outer:first-child{margin-right:10px}.dashboard-medium-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;margin-bottom:0;padding-top:10px}.dashboard-medium-chart:first-child{margin-right:12px}.dashboard-medium-chart .dashboard-medium-chart-outer{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-medium-chart .dashboard-medium-chart-menu{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;border:0 solid rgba(0,0,0,.3);color:rgba(0,0,0,.3);cursor:pointer;padding:0 4px;position:absolute;z-index:1000}.dashboard-medium-chart .dashboard-medium-chart-menu:hover{color:rgba(0,0,0,.7)}.dashboard-medium-chart .dashboard-medium-chart-inner{padding-bottom:10px}.dashboard-medium-chart .clusterChart .slice path{fill-opacity:.15;stroke-opacity:1;stroke-width:1.5px}.dashboard-tendency-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-tendency-container .dashboard-tendency-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{background-color:#fff;margin-top:5px;padding:0 8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency:first-child{border-right:1px solid #e1e1e1}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar{border-bottom:1px solid #e1e1e1;text-align:right}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure{text-align:center}.dashboard-bar-chart-container{border:1px solid rgba(104,103,102,.1);border-radius:3px}.dashboard-bar-chart-container .dashboard-bar-chart{background-color:#fff;border-left:5px solid #fff;border-right:5px solid #fff;border-top:5px solid #fff;border-top-left-radius:3px;border-top-right-radius:3px;padding-bottom:5px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{margin-top:5px;padding:0 8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{font-weight:400}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{text-align:right}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart .nv-bar rect{fill-opacity:.15;stroke-opacity:.8;stroke-width:.5px}.dashboard-legend .dashboard-legend-inner{padding:0 5px 5px 0}.dashboard-spacer{margin:0 12px}.headerBar.dashboard-headerbar{margin:20px 0}.modal-chart-detail .modal-dashboard-legend .dashboard-legend-inner{padding-left:20px}.dashboard-half-height-legend .dashboard-legend-inner{padding-top:20px}.dashboard-title-bar{background-color:#686766;color:#fff;font-size:14.5px;font-weight:400;height:30px;line-height:30px;padding:0 5px 0 10px}.dashboard-title-bar .dashboard-half-title-bar{border-left:1px solid #000;margin-left:-1px;width:50%}.dashboard-title-bar .dashboard-half-title-bar:first-child{border-left:0;margin-left:0}.dashboard-row{margin-bottom:0;margin-left:0;margin-right:0}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{color:#666}.resizecontainer{margin:0 auto}@media (max-width:738px){#arangoCollectionUl{display:none}#collectionsDropdown ul{width:auto!important}#arangoCollectionSelect{display:inline-block;height:29px;margin-top:1px}}@media (min-width:739px) and (max-width:1041px){#arangoCollectionUl a{font-size:12px;height:12px;padding:8px 5px}}@media (min-width:1042px) and (max-width:1284px){#arangoCollectionUl a{font-size:14px}}@media (min-width:250px) and (max-width:489px){.resizecontainer{width:228px}.dashboard-full-width-chart{width:225px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:215px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:69.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:214px}.dashboard-large-chart{width:146px}.dashboard-large-chart .dashboard-sub-bar{width:134px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:136px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:106px}.dashboard-medium-chart{width:96px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:95px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:96px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:79px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:66px}.dashboard-small-chart .dashboard-sub-bar{width:54px}.dashboard-small-chart .dashboard-small-chart-inner{width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:56px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:8px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:54px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:56px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:40px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-114px;width:248px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:208px}.modal-body .dashboard-large-chart{width:143px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:131px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:133px}.modal-body .dashboard-medium-chart-outer{float:left;width:91px}.modal-body .dashboard-medium-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:89px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:91px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:74px}.modal-body .dashboard-small-chart{width:61px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:49px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:51px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:6.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:51px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:56px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:28px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:10.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:40px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:54px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:228px}.application-detail-view aside.meta{display:none}}@media (min-width:490px) and (max-width:729px){.resizecontainer{width:468px}.dashboard-full-width-chart{width:465px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:455px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:149.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart{width:306px}.dashboard-large-chart .dashboard-sub-bar{width:294px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:296px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:226px}.dashboard-medium-chart{width:216px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:215px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:216px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:199px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:146px}.dashboard-small-chart .dashboard-sub-bar{width:134px}.dashboard-small-chart .dashboard-small-chart-inner{width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:136px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:48px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:134px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:136px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:120px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-234px;width:488px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:448px}.modal-body .dashboard-large-chart{width:303px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:291px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:293px}.modal-body .dashboard-medium-chart-outer{float:left;width:211px}.modal-body .dashboard-medium-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:211px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:194px}.modal-body .dashboard-small-chart{width:141px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:129px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:131px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:46.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:131px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:136px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:84px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:34.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:120px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:134px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:468px}.application-detail-view aside.meta{display:none}}@media (min-width:730px) and (max-width:969px){.resizecontainer{width:708px}.dashboard-full-width-chart{width:705px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:695px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:229.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:694px}.dashboard-large-chart{width:466px}.dashboard-large-chart .dashboard-sub-bar{width:454px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:185px;width:456px}.dashboard-sub-bar-menu{font-size:12px}.dashboard-medium-chart-outer{float:left;width:346px}.dashboard-medium-chart{width:336px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:335px}.dashboard-medium-chart #clusterGraphs svg,.dashboard-medium-chart .dashboard-interior-chart{height:185px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:12px;left:319px;top:0}.dashboard-medium-chart #clusterGraphs svg text{font-size:10px}.dashboard-small-chart{width:226px}.dashboard-small-chart .dashboard-sub-bar{width:214px}.dashboard-small-chart .dashboard-small-chart-inner{width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:197px;width:216px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:10px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:78.25px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:88px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:25.08px;line-height:25.08px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:40.17px;line-height:19.08px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:214px}.dashboard-bar-chart-container{height:79.75px}.dashboard-bar-chart-container .dashboard-bar-chart{height:77.75px;width:216px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:25.25px;line-height:25.25px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:33.5px;line-height:33.5px;padding:5px 8px 10px;width:200px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:38.5px}.dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-354px;width:728px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{display:none;font-size:12px;min-height:190px;width:10px}.absolut,.percentage{font-size:14px}.modal-chart-detail .modal-inner-detail{width:688px}.modal-body .dashboard-large-chart{width:463px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:451px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:453px}.modal-body .dashboard-medium-chart-outer{float:left;width:331px}.modal-body .dashboard-medium-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:329px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:314px}.modal-body .dashboard-small-chart{width:221px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:209px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:211px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:86.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:211px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:216px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:140px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:58.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:200px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:214px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:10px;font-weight:400}.dashboard-subtitle-bar{font-size:14px;font-weight:300}.dashboard-figure{font-size:16px;font-weight:400}.dashboard-figurePer{font-size:14px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:10px}.dashboard-legend{display:none;height:190px;margin-top:-3px;width:0}.dashboard-half-height-legend{display:none;font-size:10px;height:100px;width:0}.application-detail-view section.info{width:508px}}@media (min-width:970px) and (max-width:1209px){.resizecontainer{width:948px}.dashboard-full-width-chart{width:945px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:935px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:309.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart{width:626px}.dashboard-large-chart .dashboard-sub-bar{width:614px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:220px;width:496px}.dashboard-sub-bar-menu{font-size:13px}.dashboard-medium-chart-outer{float:left;width:466px}.dashboard-medium-chart{width:456px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:455px}.dashboard-medium-chart .dashboard-interior-chart{height:220px;width:336px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:13px;left:438px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:220px;width:456px}.dashboard-medium-chart #clusterGraphs svg text{font-size:11px}.dashboard-small-chart{width:306px}.dashboard-small-chart .dashboard-sub-bar{width:294px}.dashboard-small-chart .dashboard-small-chart-inner{width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:229px;width:296px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:11px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:96.5px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:128px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:31.17px;line-height:31.17px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:52.33px;line-height:25.17px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:294px}.dashboard-bar-chart-container{height:98px}.dashboard-bar-chart-container .dashboard-bar-chart{height:96px;width:296px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:31.33px;line-height:31.33px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:45.67px;line-height:45.67px;padding:5px 8px 10px;width:280px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:50.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-474px;width:968px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:13px;min-height:225px;width:130px}.absolut,.percentage{font-size:15px}.modal-chart-detail .modal-inner-detail{width:808px}.modal-body .dashboard-large-chart{width:623px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:611px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:493px}.modal-body .dashboard-medium-chart-outer{float:left;width:451px}.modal-body .dashboard-medium-chart{width:451px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:331px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:433px}.modal-body .dashboard-small-chart{width:301px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:289px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:291px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:126.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:291px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:296px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:196px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:82.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:280px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:294px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:11px;font-weight:400}.dashboard-subtitle-bar{font-size:15px;font-weight:300}.dashboard-figure{font-size:18px;font-weight:400}.dashboard-figurePer{font-size:16px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:11px}.dashboard-legend{height:225px;margin-top:-3px;width:120px}.dashboard-half-height-legend{font-size:11px;height:117.5px;width:60px}.application-detail-view section.info{width:748px}}@media (min-width:1210px) and (max-width:1449px){.resizecontainer{width:1188px}.dashboard-full-width-chart{width:1185px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1175px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:389.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1174px}.dashboard-large-chart{width:786px}.dashboard-large-chart .dashboard-sub-bar{width:774px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:255px;width:646px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:586px}.dashboard-medium-chart{width:576px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:575px}.dashboard-medium-chart .dashboard-interior-chart{height:255px;width:446px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:16px;left:555px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:255px;width:576px}.dashboard-medium-chart #clusterGraphs svg text{font-size:12px}.dashboard-small-chart{width:386px}.dashboard-small-chart .dashboard-sub-bar{width:374px}.dashboard-small-chart .dashboard-small-chart-inner{width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:264px;width:376px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:114px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:168px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:37px;line-height:37px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:64px;line-height:31px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:374px}.dashboard-bar-chart-container{height:115.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:113.5px;width:376px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:37.17px;line-height:37.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:57.33px;line-height:57.33px;padding:5px 8px 10px;width:360px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:62.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-594px;width:1208px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:14px;min-height:260px;width:140px}.absolut,.percentage{font-size:18px}.modal-chart-detail .modal-inner-detail{width:1038px}.modal-body .dashboard-large-chart{width:783px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:771px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:643px}.modal-body .dashboard-medium-chart-outer{float:left;width:571px}.modal-body .dashboard-medium-chart{width:571px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:569px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:441px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:550px}.modal-body .dashboard-small-chart{width:381px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:369px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:371px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:166.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:371px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:376px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:252px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:106.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:360px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:374px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:18px;font-weight:300}.dashboard-figure{font-size:22px;font-weight:400}.dashboard-figurePer{font-size:20px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:13px;font-weight:400}.dashboard-legend{font-size:12px;font-weight:400;height:260px;margin-top:-3px;width:130px}.dashboard-half-height-legend{font-size:12px;height:135px;width:65px}.application-detail-view section.info{width:988px}}@media (min-width:1450px) and (max-width:1689px){.resizecontainer{width:1428px}.dashboard-full-width-chart{width:1425px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1415px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:469.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart{width:946px}.dashboard-large-chart .dashboard-sub-bar{width:934px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:796px}.dashboard-sub-bar-menu{font-size:15px}.dashboard-medium-chart-outer{float:left;width:706px}.dashboard-medium-chart{width:696px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:695px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:556px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:18px;left:673px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:696px}.dashboard-medium-chart #clusterGraphs svg text{font-size:13px}.dashboard-small-chart{width:466px}.dashboard-small-chart .dashboard-sub-bar{width:454px}.dashboard-small-chart .dashboard-small-chart-inner{width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:456px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:13px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:208px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:454px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:456px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:440px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-714px;width:1448px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:15px;min-height:290px;width:150px}.absolut,.percentage{font-size:20px}.modal-chart-detail .modal-inner-detail{width:1268px}.modal-body .dashboard-large-chart{width:943px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:931px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:793px}.modal-body .dashboard-medium-chart-outer{float:left;width:691px}.modal-body .dashboard-medium-chart{width:691px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:551px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:668px}.modal-body .dashboard-small-chart{width:461px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:449px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:451px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:206.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:451px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:456px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:308px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:130.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:440px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:454px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:13px;font-weight:400}.dashboard-subtitle-bar{font-size:20px;font-weight:300}.dashboard-figure{font-size:26px;font-weight:400}.dashboard-figurePer{font-size:24px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:13px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:13px;height:150px;width:70px}.application-detail-view section.info{width:1228px}}@media (min-width:1690px) and (max-width:1929px){.resizecontainer{width:1668px}.dashboard-full-width-chart{width:1665px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1655px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:549.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1654px}.dashboard-large-chart{width:1106px}.dashboard-large-chart .dashboard-sub-bar{width:1094px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:325px;width:936px}.dashboard-sub-bar-menu{font-size:16px}.dashboard-medium-chart-outer{float:left;width:826px}.dashboard-medium-chart{width:816px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:815px}.dashboard-medium-chart .dashboard-interior-chart{height:325px;width:656px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:22px;left:789px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:325px;width:816px}.dashboard-medium-chart #clusterGraphs svg text{font-size:14px}.dashboard-small-chart{width:546px}.dashboard-small-chart .dashboard-sub-bar{width:534px}.dashboard-small-chart .dashboard-small-chart-inner{width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:334px;width:536px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:149px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:248px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:48.67px;line-height:48.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:87.33px;line-height:42.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:534px}.dashboard-bar-chart-container{height:150.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:148.5px;width:536px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:48.83px;line-height:48.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:80.67px;line-height:80.67px;padding:5px 8px 10px;width:520px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:85.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-834px;width:1688px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:16px;min-height:330px;width:170px}.absolut,.percentage{font-size:24px}.modal-chart-detail .modal-inner-detail{width:1488px}.modal-body .dashboard-large-chart{width:1103px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1091px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:933px}.modal-body .dashboard-medium-chart-outer{float:left;width:811px}.modal-body .dashboard-medium-chart{width:811px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:809px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:651px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:784px}.modal-body .dashboard-small-chart{width:541px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:529px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:531px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:246.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:531px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:536px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:364px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:154.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:520px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:534px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:14px;font-weight:400}.dashboard-subtitle-bar{font-size:24px;font-weight:300}.dashboard-figure{font-size:30px;font-weight:400}.dashboard-figurePer{font-size:28px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:14px}.dashboard-legend{height:330px;margin-top:-3px;width:160px}.dashboard-half-height-legend{font-size:14px;height:170px;width:80px}.application-detail-view section.info{width:1468px}}@media (min-width:1930px) and (max-width:2169px){.resizecontainer{width:1908px}.dashboard-full-width-chart{width:1905px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:1895px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:629.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:1894px}.dashboard-large-chart{width:1266px}.dashboard-large-chart .dashboard-sub-bar{width:1254px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:385px;width:1086px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:946px}.dashboard-medium-chart{width:936px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:935px}.dashboard-medium-chart .dashboard-interior-chart{height:385px;width:766px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:26px;left:905px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:385px;width:936px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:626px}.dashboard-small-chart .dashboard-sub-bar{width:614px}.dashboard-small-chart .dashboard-small-chart-inner{width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:394px;width:616px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:14px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:179px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:288px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:58.67px;line-height:58.67px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:107.33px;line-height:52.67px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:614px}.dashboard-bar-chart-container{height:180.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:178.5px;width:616px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:58.83px;line-height:58.83px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:100.67px;line-height:100.67px;padding:5px 8px 10px;width:600px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:105.67px}.dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-954px;width:1928px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:390px;width:180px}.absolut,.percentage{font-size:28px}.modal-chart-detail .modal-inner-detail{width:1718px}.modal-body .dashboard-large-chart{width:1263px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1251px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1083px}.modal-body .dashboard-medium-chart-outer{float:left;width:931px}.modal-body .dashboard-medium-chart{width:931px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:929px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:761px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:900px}.modal-body .dashboard-small-chart{width:621px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:609px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:611px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:286.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:611px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:616px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:420px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:178.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:600px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:614px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:28px;font-weight:300}.dashboard-figure{font-size:34px;font-weight:400}.dashboard-figurePer{font-size:32px;font-weight:300}.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-size:14px;font-weight:400}.dashboard-legend{font-size:15px;font-weight:400;height:390px;margin-top:-3px;width:170px}.dashboard-half-height-legend{font-size:15px;height:200px;width:85px}.application-detail-view section.info{width:1708px}}@media (min-width:2170px) and (max-width:2409px){.resizecontainer{width:2148px}.dashboard-full-width-chart{width:2145px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2135px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:709.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2134px}.dashboard-large-chart{width:1426px}.dashboard-large-chart .dashboard-sub-bar{width:1414px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1276px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1066px}.dashboard-medium-chart{width:1056px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1055px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:916px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1031px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1056px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:706px}.dashboard-small-chart .dashboard-sub-bar{width:694px}.dashboard-small-chart .dashboard-small-chart-inner{width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:696px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:328px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:694px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:696px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:680px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1074px;width:2168px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:1988px}.modal-body .dashboard-large-chart{width:1423px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1411px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1273px}.modal-body .dashboard-medium-chart-outer{float:left;width:1051px}.modal-body .dashboard-medium-chart{width:1051px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1049px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:911px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1026px}.modal-body .dashboard-small-chart{width:701px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:689px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:691px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:326.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:691px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:696px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:476px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:202.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:680px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:694px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:1948px}}@media (min-width:2410px) and (max-width:2649px){.resizecontainer{width:2388px}.dashboard-full-width-chart{width:2385px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2375px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:789.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2374px}.dashboard-large-chart{width:1586px}.dashboard-large-chart .dashboard-sub-bar{width:1574px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1436px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1186px}.dashboard-medium-chart{width:1176px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1175px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1036px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1151px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1176px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:786px}.dashboard-small-chart .dashboard-sub-bar{width:774px}.dashboard-small-chart .dashboard-small-chart-inner{width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:776px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:368px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:774px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:776px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:760px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1194px;width:2408px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2228px}.modal-body .dashboard-large-chart{width:1583px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1571px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1433px}.modal-body .dashboard-medium-chart-outer{float:left;width:1171px}.modal-body .dashboard-medium-chart{width:1171px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1169px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1031px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1146px}.modal-body .dashboard-small-chart{width:781px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:769px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:771px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:366.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:771px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:776px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:532px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:226.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:760px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:774px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2188px}}@media (min-width:2650px) and (max-width:2889px){.resizecontainer{width:2628px}.dashboard-full-width-chart{width:2625px}.dashboard-full-width-chart .dashboard-full-width-chart-inner{width:2615px}.dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart{float:left;width:869.33px}.dashboard-full-width-chart .dashboard-sub-bar{width:2614px}.dashboard-large-chart{width:1746px}.dashboard-large-chart .dashboard-sub-bar{width:1734px}.dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{height:285px;width:1596px}.dashboard-sub-bar-menu{font-size:17px}.dashboard-medium-chart-outer{float:left;width:1306px}.dashboard-medium-chart{width:1296px}.dashboard-medium-chart .dashboard-sub-bar{margin-left:-5px;width:1295px}.dashboard-medium-chart .dashboard-interior-chart{height:285px;width:1156px}.dashboard-medium-chart .dashboard-medium-chart-menu{font-size:20px;left:1271px;top:0}.dashboard-medium-chart #clusterGraphs svg{height:285px;width:1296px}.dashboard-medium-chart #clusterGraphs svg text{font-size:15px}.dashboard-small-chart{width:866px}.dashboard-small-chart .dashboard-sub-bar{width:854px}.dashboard-small-chart .dashboard-small-chart-inner{width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{height:294px;width:856px}.dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart .nv-axis text{fill:#666;font-size:15px;font-weight:400}.dashboard-tendency-container .dashboard-tendency-chart{height:129px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:408px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar{height:42px;line-height:42px}.dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure{height:74px;line-height:36px;padding-top:5px}.dashboard-tendency-container .dashboard-sub-bar{width:854px}.dashboard-bar-chart-container{height:130.5px}.dashboard-bar-chart-container .dashboard-bar-chart{height:128.5px;width:856px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title{height:42.17px;line-height:42.17px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart{height:67.33px;line-height:67.33px;padding:5px 8px 10px;width:840px}.dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart #residentSizeChart{height:72.33px}.dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.modal-chart-detail{bottom:12.1%!important;left:50%;margin-left:-1314px;width:2648px!important}.modal-chart-detail .modal-body{height:95%;max-height:none;padding:5px}.modal-chart-detail .modal-dashboard-legend{font-size:17px;min-height:290px;width:150px}.absolut,.percentage{font-size:22px}.modal-chart-detail .modal-inner-detail{width:2468px}.modal-body .dashboard-large-chart{width:1743px}.modal-body .dashboard-large-chart .dashboard-sub-bar{width:1731px}.modal-body .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart{width:1593px}.modal-body .dashboard-medium-chart-outer{float:left;width:1291px}.modal-body .dashboard-medium-chart{width:1291px}.modal-body .dashboard-medium-chart .dashboard-sub-bar{width:1289px}.modal-body .dashboard-medium-chart .dashboard-interior-chart{width:1151px}.modal-body .dashboard-medium-chart .dashboard-medium-chart-menu{left:1266px}.modal-body .dashboard-small-chart{width:861px}.modal-body .dashboard-small-chart .dashboard-sub-bar{width:849px}.modal-body .dashboard-small-chart .dashboard-small-chart-inner,.modal-body .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart{width:851px}.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-figure,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-subtitle-bar,.modal-body .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency{width:406.5px}.modal-body .dashboard-tendency-container .dashboard-sub-bar{width:851px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart{width:856px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage{width:588px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut{width:250.8px}.modal-body .dashboard-bar-chart-container .dashboard-bar-chart-chart{width:840px}.modal-body .dashboard-bar-chart-container .dashboard-sub-bar{width:854px}.absolut{font-weight:300}.dashboard-sub-bar{font-size:15px;font-weight:400}.dashboard-subtitle-bar{font-size:22px;font-weight:300}.dashboard-figure{font-size:36px;font-weight:400}.dashboard-figurePer{font-size:34px;font-weight:300}.dashboard-legend,.dygraph-axis-label.dygraph-axis-label-x,.dygraph-axis-label.dygraph-axis-label-y{font-weight:400;font-size:15px}.dashboard-legend{height:290px;margin-top:-3px;width:140px}.dashboard-half-height-legend{font-size:15px;height:150px;width:70px}.application-detail-view section.info{width:2428px}}div.centralRow{margin-bottom:40px;margin-top:40px}div.centralContent{background-color:transparent;height:100%;margin-left:-5px;margin-right:-5px;min-height:80px;padding:5px;width:100%}.contentDiv{list-style:none;padding:13px 0 0}.contentDiv li{background-color:rgba(0,0,0,.05)}.contentDiv a.add{display:block;font-weight:400;padding:40px 0;text-align:left}.contentDiv .icon{padding-left:5px;padding-right:5px;padding-top:10px}.contentDiv:after{clear:both}.contentDiv:after,.contentDiv:before{content:'';display:table;line-height:0}body{background-color:rgba(245,248,240,.95)}.headerButtonBar select{border:1px solid rgba(140,138,137,.25);height:28px} \ No newline at end of file diff --git a/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css.gz b/js/apps/system/_admin/aardvark/APP/clusterFrontend/build/style-minified.css.gz index 45acccb95779575e3550eee53dc0a5593e0586e3..b72c83e4c260e21d5174700c2dfa9f9bc575018a 100644 GIT binary patch delta 25853 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%0Awqd51FI<5O~ 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 LP=cnQi`D}Gm;3?O literal 40649 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 Y)})LbsU2?>!+YkYqr;YsA2<*G2j~DNwg3PC diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/app.js b/js/apps/system/_admin/aardvark/APP/frontend/build/app.js index 9d50e4fb10..307622717a 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/build/app.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/build/app.js @@ -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( + ''); + $('#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( + '' + ); } - }; + 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( + '' + ); }, 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(); diff --git a/js/apps/system/_admin/aardvark/APP/frontend/build/app.js.gz b/js/apps/system/_admin/aardvark/APP/frontend/build/app.js.gz index 1118306bc2801d6f55654a9a10654d440276e34f..e40d940da9f5258c7a5b53ed67d002994370f2ec 100644 GIT binary patch delta 224138 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ⅆ_5=I6H2g!{EzL< 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�BT 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 delta 223621 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�$F92Y+~tZ^?b4s%9bP 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%0D2(l17 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 -

    <%= model.get('name') %>