1
0
Fork 0

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

This commit is contained in:
Frank Celler 2016-04-19 19:18:02 -07:00
commit 3bb24146a6
97 changed files with 1838 additions and 855 deletions

View File

@ -214,8 +214,7 @@ class Slice {
// check if a slice is any number type
bool isInteger() const throw() {
return isType(ValueType::Int) || isType(ValueType::UInt) ||
isType(ValueType::SmallInt);
return (isInt() || isUInt() || isSmallInt());
}
// check if slice is any Number-type object
@ -228,10 +227,10 @@ class Slice {
// return the value for a Bool object
bool getBool() const {
if (type() != ValueType::Bool) {
if (!isBool()) {
throw Exception(Exception::InvalidValueType, "Expecting type Bool");
}
return (head() == 0x1a); // 0x19 == false, 0x1a == true
return isTrue();
}
// return the value for a Bool object - this is an alias for getBool()
@ -239,7 +238,7 @@ class Slice {
// return the value for a Double object
double getDouble() const {
if (type() != ValueType::Double) {
if (!isDouble()) {
throw Exception(Exception::InvalidValueType, "Expecting type Double");
}
union {
@ -264,7 +263,7 @@ class Slice {
// - 0x08 : array with 4-byte index table entries
// - 0x09 : array with 8-byte index table entries
Slice at(ValueLength index) const {
if (!isType(ValueType::Array)) {
if (!isArray()) {
throw Exception(Exception::InvalidValueType, "Expecting type Array");
}
@ -275,7 +274,7 @@ class Slice {
// return the number of members for an Array or Object object
ValueLength length() const {
if (type() != ValueType::Array && type() != ValueType::Object) {
if (!isArray() && !isObject()) {
throw Exception(Exception::InvalidValueType,
"Expecting type Array or Object");
}
@ -326,7 +325,7 @@ class Slice {
// - 0x12 : object with 8-byte index table entries, not sorted by
// attribute name
Slice keyAt(ValueLength index) const {
if (!isType(ValueType::Object)) {
if (!isObject()) {
throw Exception(Exception::InvalidValueType, "Expecting type Object");
}
@ -334,7 +333,7 @@ class Slice {
}
Slice valueAt(ValueLength index) const {
if (!isType(ValueType::Object)) {
if (!isObject()) {
throw Exception(Exception::InvalidValueType, "Expecting type Object");
}
@ -414,12 +413,21 @@ class Slice {
// return the pointer to the data for an External object
char const* getExternal() const {
if (type() != ValueType::External) {
if (!isExternal()) {
throw Exception(Exception::InvalidValueType, "Expecting type External");
}
return extractValue<char const*>();
}
// returns the Slice managed by an External or the Slice itself if it's not
// an External
Slice resolveExternal() const {
if (isExternal()) {
return Slice(extractValue<char const*>());
}
return *this;
}
// translates an integer key into a string
Slice translate() const;
@ -494,10 +502,9 @@ class Slice {
// return the value for a UTCDate object
int64_t getUTCDate() const {
if (type() != ValueType::UTCDate) {
if (!isUTCDate()) {
throw Exception(Exception::InvalidValueType, "Expecting type UTCDate");
}
assertType(ValueType::UTCDate);
uint64_t v = readInteger<uint64_t>(_start + 1, sizeof(uint64_t));
return toInt64(v);
}
@ -559,7 +566,7 @@ class Slice {
// return the value for a Binary object
uint8_t const* getBinary(ValueLength& length) const {
if (type() != ValueType::Binary) {
if (!isBinary()) {
throw Exception(Exception::InvalidValueType, "Expecting type Binary");
}
@ -573,7 +580,7 @@ class Slice {
// return the length of the Binary slice
ValueLength getBinaryLength() const {
if (type() != ValueType::Binary) {
if (!isBinary()) {
throw Exception(Exception::InvalidValueType, "Expecting type Binary");
}
@ -585,7 +592,7 @@ class Slice {
// return a copy of the value for a Binary object
std::vector<uint8_t> copyBinary() const {
if (type() != ValueType::Binary) {
if (!isBinary()) {
throw Exception(Exception::InvalidValueType, "Expecting type Binary");
}

View File

@ -319,7 +319,7 @@ uint64_t Slice::normalizedHash(uint64_t seed) const {
// look for the specified attribute inside an Object
// returns a Slice(ValueType::None) if not found
Slice Slice::get(std::string const& attribute) const {
if (!isType(ValueType::Object)) {
if (!isObject()) {
throw Exception(Exception::InvalidValueType, "Expecting Object");
}
@ -512,7 +512,7 @@ Slice Slice::getFromCompactObject(std::string const& attribute) const {
// get the offset for the nth member from an Array or Object type
ValueLength Slice::getNthOffset(ValueLength index) const {
VELOCYPACK_ASSERT(type() == ValueType::Array || type() == ValueType::Object);
VELOCYPACK_ASSERT(isArray() || isObject());
auto const h = head();
@ -565,7 +565,7 @@ ValueLength Slice::getNthOffset(ValueLength index) const {
// extract the nth member from an Array
Slice Slice::getNth(ValueLength index) const {
VELOCYPACK_ASSERT(type() == ValueType::Array);
VELOCYPACK_ASSERT(isArray());
return Slice(_start + getNthOffset(index));
}

View File

@ -611,6 +611,7 @@ void AqlValue::toVelocyPack(AqlTransaction* trx,
case VPACK_POINTER:
case VPACK_INLINE:
case VPACK_EXTERNAL: {
// TODO: optionally resolve externals
builder.add(slice());
break;
}
@ -619,6 +620,7 @@ void AqlValue::toVelocyPack(AqlTransaction* trx,
for (auto const& it : *_data.docvec) {
size_t const n = it->size();
for (size_t i = 0; i < n; ++i) {
// TODO: optionally resolve externals
it->getValueReference(i, 0).toVelocyPack(trx, builder);
}
}
@ -629,6 +631,7 @@ void AqlValue::toVelocyPack(AqlTransaction* trx,
builder.openArray();
size_t const n = _data.range->size();
for (size_t i = 0; i < n; ++i) {
// TODO: optionally resolve externals
builder.add(VPackValue(_data.range->at(i)));
}
builder.close();
@ -647,14 +650,10 @@ AqlValue AqlValue::materialize(AqlTransaction* trx, bool& hasCopied) const {
hasCopied = false;
return *this;
}
case DOCVEC: {
VPackBuilder builder;
toVelocyPack(trx, builder);
hasCopied = true;
return AqlValue(builder);
}
case DOCVEC:
case RANGE: {
VPackBuilder builder;
// TODO: optionally resolve externals
toVelocyPack(trx, builder);
hasCopied = true;
return AqlValue(builder);
@ -740,6 +739,7 @@ void AqlValue::destroy() {
/// @brief return the slice from the value
VPackSlice AqlValue::slice() const {
// TODO: optionally resolve externals
switch (type()) {
case VPACK_DOCUMENT:
case VPACK_POINTER: {

View File

@ -201,6 +201,10 @@ void Expression::replaceVariableReference(Variable const* variable,
// must even set back the expression type so the expression will be analyzed
// again
_type = UNPROCESSED;
} else if (_type == SIMPLE) {
// must rebuild the expression completely, as it may have changed drastically
_built = false;
_type = UNPROCESSED;
}
const_cast<AstNode*>(_node)->clearFlags();

View File

@ -531,6 +531,10 @@ QueryResult Query::execute(QueryRegistry* registry) {
if (cacheEntry != nullptr) {
// got a result from the query cache
QueryResult res(TRI_ERROR_NO_ERROR);
// we don't have yet a transaction when we're here, so let's create
// a mimimal context to build the result
res.context = std::make_shared<StandaloneTransactionContext>(_vocbase);
res.warnings = warningsToVelocyPack();
TRI_ASSERT(cacheEntry->_queryResult != nullptr);
res.result = cacheEntry->_queryResult;
@ -539,10 +543,10 @@ QueryResult Query::execute(QueryRegistry* registry) {
}
}
QueryResult res = prepare(registry);
QueryResult result = prepare(registry);
if (res.code != TRI_ERROR_NO_ERROR) {
return res;
if (result.code != TRI_ERROR_NO_ERROR) {
return result;
}
if (_queryString == nullptr) {
@ -629,11 +633,12 @@ QueryResult Query::execute(QueryRegistry* registry) {
auto stats = std::make_shared<VPackBuilder>();
_engine->_stats.toVelocyPack(*(stats.get()));
result.context = _trx->transactionContext();
cleanupPlanAndEngine(TRI_ERROR_NO_ERROR);
enterState(FINALIZATION);
QueryResult result(TRI_ERROR_NO_ERROR);
result.warnings = warningsToVelocyPack();
result.result = resultBuilder;
result.stats = stats;
@ -684,13 +689,13 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
arangodb::aql::QueryCacheResultEntryGuard guard(cacheEntry);
if (cacheEntry != nullptr) {
// we don't have yet a transaction when we're here, so let's create
// a mimimal context to build the result
auto transactionContext = createTransactionContext();
// got a result from the query cache
QueryResultV8 res(TRI_ERROR_NO_ERROR);
// we don't have yet a transaction when we're here, so let's create
// a mimimal context to build the result
res.context = std::make_shared<StandaloneTransactionContext>(_vocbase);
v8::Handle<v8::Value> values = TRI_VPackToV8(isolate, cacheEntry->_queryResult->slice(), transactionContext->getVPackOptions());
v8::Handle<v8::Value> values = TRI_VPackToV8(isolate, cacheEntry->_queryResult->slice(), res.context->getVPackOptions());
TRI_ASSERT(values->IsArray());
res.result = v8::Handle<v8::Array>::Cast(values);
res.cached = true;
@ -698,10 +703,10 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
}
}
QueryResultV8 res = prepare(registry);
QueryResultV8 result = prepare(registry);
if (res.code != TRI_ERROR_NO_ERROR) {
return res;
if (result.code != TRI_ERROR_NO_ERROR) {
return result;
}
work.reset(new AqlWorkStack(_vocbase, _id, _queryString, _queryLength));
@ -713,7 +718,6 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
useQueryCache = false;
}
QueryResultV8 result(TRI_ERROR_NO_ERROR);
result.result = v8::Array::New(isolate);
// this is the RegisterId our results can be found in
@ -779,6 +783,8 @@ QueryResultV8 Query::executeV8(v8::Isolate* isolate, QueryRegistry* registry) {
auto stats = std::make_shared<VPackBuilder>();
_engine->_stats.toVelocyPack(*(stats.get()));
result.context = _trx->transactionContext();
cleanupPlanAndEngine(TRI_ERROR_NO_ERROR);
enterState(FINALIZATION);

View File

@ -30,23 +30,14 @@ namespace arangodb {
namespace velocypack {
class Builder;
}
class TransactionContext;
namespace aql {
struct QueryResult {
QueryResult& operator=(QueryResult const& other) = delete;
QueryResult(QueryResult&& other) {
code = other.code;
cached = other.cached;
details = other.details;
warnings.swap(other.warnings);
result.swap(other.result);
stats.swap(other.stats);
profile.swap(other.profile);
bindParameters = other.bindParameters;
collectionNames = other.collectionNames;
}
QueryResult(QueryResult&& other) = default;
QueryResult(int code, std::string const& details)
: code(code),
@ -54,7 +45,8 @@ struct QueryResult {
details(details),
warnings(nullptr),
result(nullptr),
profile(nullptr) {}
profile(nullptr),
context(nullptr) {}
explicit QueryResult(int code) : QueryResult(code, "") {}
@ -71,6 +63,7 @@ struct QueryResult {
std::shared_ptr<arangodb::velocypack::Builder> result;
std::shared_ptr<arangodb::velocypack::Builder> stats;
std::shared_ptr<arangodb::velocypack::Builder> profile;
std::shared_ptr<arangodb::TransactionContext> context;
};
}
}

View File

@ -1036,6 +1036,7 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
arangodb::LogTopic const& logTopic) {
if (requests.size() == 0) {
nrDone = 0;
return 0;
}
@ -1056,7 +1057,7 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
std::unordered_map<OperationID, size_t> opIDtoIndex;
try {
while (true) {
while (now <= endTime) {
if (nrDone >= requests.size()) {
// All good, report
return nrGood;
@ -1065,7 +1066,10 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
// First send away what is due:
for (size_t i = 0; i < requests.size(); i++) {
if (!requests[i].done && now >= dueTime[i]) {
auto headers = std::make_unique<std::map<std::string, std::string>>();
if (requests[i].headerFields.get() == nullptr) {
requests[i].headerFields
= std::make_unique<std::map<std::string, std::string>>();
}
LOG_TOPIC(TRACE, logTopic)
<< "ClusterComm::performRequests: sending request to "
<< requests[i].destination << ":" << requests[i].path
@ -1075,7 +1079,8 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
requests[i].requestType,
requests[i].path,
requests[i].body,
headers, nullptr, timeout - (now - startTime),
requests[i].headerFields,
nullptr, timeout - (now - startTime),
false);
if (res.status == CL_COMM_ERROR) {
// We did not find the destination, this is could change in the
@ -1108,6 +1113,16 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
if (res.status == CL_COMM_TIMEOUT && res.operationID == 0) {
break;
}
if (res.status == CL_COMM_DROPPED) {
// Nothing in flight, simply wait:
now = TRI_microtime();
if (now >= actionNeeded) {
break;
}
usleep( (std::min)(500000,
static_cast<int>((actionNeeded-now)*1000000)) );
continue;
}
auto it = opIDtoIndex.find(res.operationID);
TRI_ASSERT(it != opIDtoIndex.end()); // we should really know this!
size_t index = it->second;
@ -1149,6 +1164,9 @@ size_t ClusterComm::performRequests(std::vector<ClusterCommRequest>& requests,
// We only get here if the global timeout was triggered, not all
// requests are marked by done!
LOG_TOPIC(ERR, logTopic) << "ClusterComm::performRequests: "
<< "got timeout, this will be reported...";
// Forget about
drop("", coordinatorTransactionID, 0, "");
return nrGood;

View File

@ -187,6 +187,7 @@ struct ClusterCommRequest {
GeneralRequest::RequestType requestType;
std::string path;
std::shared_ptr<std::string const> body;
std::unique_ptr<std::map<std::string, std::string>> headerFields;
ClusterCommResult result;
bool done;
@ -201,6 +202,9 @@ struct ClusterCommRequest {
{
}
void setHeaders(std::unique_ptr<std::map<std::string, std::string>>& headers) {
headerFields = std::move(headers);
}
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -474,7 +474,7 @@ void ClusterFeature::stop() {
{
// Try only once to unregister because maybe the agencycomm
// is shutting down as well...
AgencyCommLocker locker("Current", "WRITE", 120.0, 0.001);
AgencyCommLocker locker("Current", "WRITE", 120.0, 1.000);
if (locker.successful()) {
// unregister ourselves

View File

@ -85,7 +85,7 @@ Index::Index(VPackSlice const& slice)
std::vector<arangodb::basics::AttributeName> parsedAttributes;
TRI_ParseAttributeString(name.copyString(), parsedAttributes);
_fields.emplace_back(parsedAttributes);
_fields.emplace_back(std::move(parsedAttributes));
}
_selectivityEstimate =

View File

@ -175,10 +175,9 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
auto transactionContext = std::make_shared<StandaloneTransactionContext>(_vocbase);
arangodb::basics::VPackStringBufferAdapter bufferAdapter(
_response->body().stringBuffer());
VPackDumper dumper(&bufferAdapter, transactionContext->getVPackOptions());
VPackDumper dumper(&bufferAdapter, queryResult.context->getVPackOptions());
dumper.dump(result.slice());
return;
}
@ -192,9 +191,11 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
bool count = arangodb::basics::VelocyPackHelper::getBooleanValue(
opts, "count", false);
TRI_ASSERT(queryResult.result.get() != nullptr);
// steal the query result, cursor will take over the ownership
arangodb::JsonCursor* cursor = cursors->createFromVelocyPack(
queryResult.result, batchSize, extra, ttl, count, queryResult.cached);
arangodb::VelocyPackCursor* cursor = cursors->createFromQueryResult(
std::move(queryResult), batchSize, extra, ttl, count);
try {
_response->body().appendChar('{');

View File

@ -185,6 +185,11 @@ void TRI_FillRequestStatistics(StatisticsDistribution& totalTime,
StatisticsDistribution& ioTime,
StatisticsDistribution& bytesSent,
StatisticsDistribution& bytesReceived) {
if (!StatisticsFeature::enabled()) {
// all the below objects may be deleted if we don't have statistics enabled
return;
}
MUTEX_LOCKER(mutexLocker, RequestDataLock);
totalTime = *TRI_TotalTimeDistributionStatistics;
@ -269,6 +274,15 @@ void TRI_FillConnectionStatistics(
StatisticsCounter& httpConnections, StatisticsCounter& totalRequests,
std::vector<StatisticsCounter>& methodRequests,
StatisticsCounter& asyncRequests, StatisticsDistribution& connectionTime) {
if (!StatisticsFeature::enabled()) {
// all the below objects may be deleted if we don't have statistics enabled
for (int i = 0; i < ((int)arangodb::GeneralRequest::RequestType::ILLEGAL) + 1;
++i) {
methodRequests.emplace_back(StatisticsCounter());
}
return;
}
MUTEX_LOCKER(mutexLocker, ConnectionDataLock);
httpConnections = TRI_HttpConnectionsStatistics;
@ -341,12 +355,19 @@ static void StatisticsQueueWorker(void* data) {
}
delete TRI_ConnectionTimeDistributionStatistics;
TRI_ConnectionTimeDistributionStatistics = nullptr;
delete TRI_TotalTimeDistributionStatistics;
TRI_TotalTimeDistributionStatistics = nullptr;
delete TRI_RequestTimeDistributionStatistics;
TRI_RequestTimeDistributionStatistics = nullptr;
delete TRI_QueueTimeDistributionStatistics;
TRI_QueueTimeDistributionStatistics = nullptr;
delete TRI_IoTimeDistributionStatistics;
TRI_IoTimeDistributionStatistics = nullptr;
delete TRI_BytesSentDistributionStatistics;
TRI_BytesSentDistributionStatistics = nullptr;
delete TRI_BytesReceivedDistributionStatistics;
TRI_BytesReceivedDistributionStatistics = nullptr;
{
TRI_request_statistics_t* entry = nullptr;

View File

@ -22,7 +22,6 @@
////////////////////////////////////////////////////////////////////////////////
#include "Cursor.h"
#include "Basics/JsonHelper.h"
#include "Basics/VelocyPackHelper.h"
#include "Basics/VPackStringBufferAdapter.h"
#include "Utils/CollectionExport.h"
@ -63,20 +62,20 @@ VPackSlice Cursor::extra() const {
return _extra->slice();
}
JsonCursor::JsonCursor(TRI_vocbase_t* vocbase, CursorId id,
std::shared_ptr<VPackBuilder> json, size_t batchSize,
std::shared_ptr<VPackBuilder> extra, double ttl,
bool hasCount, bool cached)
VelocyPackCursor::VelocyPackCursor(TRI_vocbase_t* vocbase, CursorId id,
aql::QueryResult&& result, size_t batchSize,
std::shared_ptr<VPackBuilder> extra,
double ttl, bool hasCount)
: Cursor(id, batchSize, extra, ttl, hasCount),
_vocbase(vocbase),
_json(json),
_size(json->slice().length()),
_cached(cached) {
TRI_ASSERT(json->slice().isArray());
_result(std::move(result)),
_size(_result.result->slice().length()),
_cached(_result.cached) {
TRI_ASSERT(_result.result->slice().isArray());
TRI_UseVocBase(vocbase);
}
JsonCursor::~JsonCursor() {
VelocyPackCursor::~VelocyPackCursor() {
freeJson();
TRI_ReleaseVocBase(_vocbase);
@ -86,7 +85,7 @@ JsonCursor::~JsonCursor() {
/// @brief check whether the cursor contains more data
////////////////////////////////////////////////////////////////////////////////
bool JsonCursor::hasNext() {
bool VelocyPackCursor::hasNext() {
if (_position < _size) {
return true;
}
@ -99,10 +98,10 @@ bool JsonCursor::hasNext() {
/// @brief return the next element
////////////////////////////////////////////////////////////////////////////////
VPackSlice JsonCursor::next() {
TRI_ASSERT(_json != nullptr);
VPackSlice VelocyPackCursor::next() {
TRI_ASSERT(_result.result != nullptr);
TRI_ASSERT(_position < _size);
VPackSlice slice = _json->slice();
VPackSlice slice = _result.result->slice();
return slice.at(_position++);
}
@ -110,13 +109,13 @@ VPackSlice JsonCursor::next() {
/// @brief return the cursor size
////////////////////////////////////////////////////////////////////////////////
size_t JsonCursor::count() const { return _size; }
size_t VelocyPackCursor::count() const { return _size; }
////////////////////////////////////////////////////////////////////////////////
/// @brief dump the cursor contents into a string buffer
////////////////////////////////////////////////////////////////////////////////
void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
void VelocyPackCursor::dump(arangodb::basics::StringBuffer& buffer) {
buffer.appendText("\"result\":[");
size_t const n = batchSize();
@ -135,6 +134,9 @@ void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
}
}
arangodb::basics::VPackStringBufferAdapter bufferAdapter(
buffer.stringBuffer());
VPackDumper dumper(&bufferAdapter, transactionContext->getVPackOptions());
for (size_t i = 0; i < n; ++i) {
if (!hasNext()) {
break;
@ -149,9 +151,6 @@ void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
arangodb::basics::VPackStringBufferAdapter bufferAdapter(
buffer.stringBuffer());
VPackDumper dumper(&bufferAdapter, transactionContext->getVPackOptions());
try {
dumper.dump(row);
} catch (...) {
@ -198,9 +197,7 @@ void JsonCursor::dump(arangodb::basics::StringBuffer& buffer) {
/// @brief free the internals
////////////////////////////////////////////////////////////////////////////////
void JsonCursor::freeJson() {
_json = nullptr;
void VelocyPackCursor::freeJson() {
_isDeleted = true;
}

View File

@ -26,6 +26,7 @@
#include "Basics/Common.h"
#include "Basics/StringBuffer.h"
#include "Aql/QueryResult.h"
#include "VocBase/voc-types.h"
struct TRI_vocbase_t;
@ -107,14 +108,13 @@ class Cursor {
bool _isUsed;
};
class JsonCursor : public Cursor {
class VelocyPackCursor : public Cursor {
public:
JsonCursor(TRI_vocbase_t*, CursorId,
std::shared_ptr<arangodb::velocypack::Builder>, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, double, bool,
VelocyPackCursor(TRI_vocbase_t*, CursorId, aql::QueryResult&&, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, double,
bool);
~JsonCursor();
~VelocyPackCursor();
public:
bool hasNext() override final;
@ -130,7 +130,7 @@ class JsonCursor : public Cursor {
private:
TRI_vocbase_t* _vocbase;
std::shared_ptr<arangodb::velocypack::Builder> _json;
aql::QueryResult _result;
size_t const _size;
bool _cached;
};

View File

@ -91,17 +91,15 @@ CursorRepository::~CursorRepository() {
/// the cursor will take ownership of both json and extra
////////////////////////////////////////////////////////////////////////////////
JsonCursor* CursorRepository::createFromVelocyPack(
std::shared_ptr<VPackBuilder> json, size_t batchSize,
std::shared_ptr<VPackBuilder> extra, double ttl, bool count, bool cached) {
TRI_ASSERT(json != nullptr);
VelocyPackCursor* CursorRepository::createFromQueryResult(
aql::QueryResult&& result, size_t batchSize, std::shared_ptr<VPackBuilder> extra,
double ttl, bool count) {
TRI_ASSERT(result.result != nullptr);
CursorId const id = TRI_NewTickServer();
arangodb::JsonCursor* cursor = nullptr;
cursor = new arangodb::JsonCursor(_vocbase, id, json, batchSize, extra, ttl,
count, cached);
arangodb::VelocyPackCursor* cursor = new arangodb::VelocyPackCursor(
_vocbase, id, std::move(result), batchSize, extra, ttl, count);
cursor->use();
try {

View File

@ -36,6 +36,10 @@ namespace velocypack {
class Builder;
}
namespace aql {
struct QueryResult;
}
class CollectionExport;
class CursorRepository {
@ -60,9 +64,9 @@ class CursorRepository {
/// the cursor will retain a shared pointer of both json and extra
//////////////////////////////////////////////////////////////////////////////
JsonCursor* createFromVelocyPack(
std::shared_ptr<arangodb::velocypack::Builder>, size_t,
std::shared_ptr<arangodb::velocypack::Builder>, double, bool, bool);
VelocyPackCursor* createFromQueryResult(
aql::QueryResult&&, size_t, std::shared_ptr<arangodb::velocypack::Builder>,
double, bool);
//////////////////////////////////////////////////////////////////////////////
/// @brief creates a cursor and stores it in the registry

View File

@ -1190,6 +1190,16 @@ OperationResult Transaction::insertLocal(std::string const& collectionName,
TRI_voc_cid_t cid = addCollectionAtRuntime(collectionName);
TRI_document_collection_t* document = documentCollection(trxCollection(cid));
// First see whether or not we have to do synchronous replication:
std::shared_ptr<std::vector<ServerID> const> followers;
bool doingSynchronousReplication = false;
if (ServerState::instance()->isDBServer()) {
// Now replicate the same operation on all followers:
auto const& followerInfo = document->followers();
followers = followerInfo->get();
doingSynchronousReplication = followers->size() > 0;
}
VPackBuilder resultBuilder;
auto workForOneDocument = [&](VPackSlice const value) -> int {
@ -1204,7 +1214,7 @@ OperationResult Transaction::insertLocal(std::string const& collectionName,
return res;
}
if (options.silent) {
if (options.silent && !doingSynchronousReplication) {
// no need to construct the result object
return TRI_ERROR_NO_ERROR;
}
@ -1237,24 +1247,43 @@ OperationResult Transaction::insertLocal(std::string const& collectionName,
res = workForOneDocument(value);
}
if (ServerState::instance()->isDBServer()) {
if (doingSynchronousReplication) {
// Now replicate the same operation on all followers:
auto const& followerInfo = document->followers();
std::shared_ptr<std::vector<ServerID> const> followers = followerInfo->get();
if (followers->size() > 0) {
auto cc = arangodb::ClusterComm::instance();
std::string path
= "/_db/" +
arangodb::basics::StringUtils::urlEncode(_vocbase->_name) +
"/_api/document/" +
arangodb::basics::StringUtils::urlEncode(document->_info.name());
// FIXME: scan options and append the right ones
arangodb::basics::StringUtils::urlEncode(document->_info.name())
+ "?isRestore=true";
// FIXME: We might only want to send the successful tries to the
// replica, for now, we simply send the same body:
VPackBuilder payload;
auto doOneDoc = [&](VPackSlice doc, VPackSlice result) {
VPackObjectBuilder guard(&payload);
TRI_SanitizeObject(doc, payload);
VPackSlice s = result.get(TRI_VOC_ATTRIBUTE_KEY);
payload.add(TRI_VOC_ATTRIBUTE_KEY, s);
s = result.get(TRI_VOC_ATTRIBUTE_REV);
payload.add(TRI_VOC_ATTRIBUTE_REV, s);
};
VPackSlice ourResult = resultBuilder.slice();
if (value.isArray()) {
VPackArrayBuilder guard(&payload);
VPackArrayIterator itValue(value);
VPackArrayIterator itResult(ourResult);
while (itValue.valid() && itResult.valid()) {
doOneDoc(itValue.value(), itResult.value());
itValue.next();
itResult.next();
}
} else {
doOneDoc(value, ourResult);
}
auto body = std::make_shared<std::string>();
*body = value.toJson();
*body = payload.slice().toJson();
// Now prepare the requests:
std::vector<ClusterCommRequest> requests;
@ -1264,7 +1293,7 @@ OperationResult Transaction::insertLocal(std::string const& collectionName,
path, body);
}
size_t nrDone = 0;
size_t nrGood = cc->performRequests(requests, 60.0, nrDone,
size_t nrGood = cc->performRequests(requests, 15.0, nrDone,
Logger::REPLICATION);
if (nrGood < followers->size()) {
// we drop all followers that were not successful:
@ -1275,11 +1304,11 @@ OperationResult Transaction::insertLocal(std::string const& collectionName,
GeneralResponse::ResponseCode::ACCEPTED &&
requests[i].result.answer_code !=
GeneralResponse::ResponseCode::CREATED)) {
followerInfo->remove(requests[i].result.serverID);
auto const& followerInfo = document->followers();
followerInfo->remove((*followers)[i]);
LOG_TOPIC(ERR, Logger::REPLICATION)
<< "insertLocal: dropping follower "
<< requests[i].result.serverID;
}
<< (*followers)[i] << " for shard " << collectionName;
}
}
}

View File

@ -90,7 +90,7 @@ struct BasicExpander {
TRI_ASSERT(edgeCollection != nullptr);
std::shared_ptr<OperationCursor> edgeCursor = edgeCollection->getEdges(_dir, v);
while (edgeCursor->hasMore()) {
edgeCursor->getMore(_opRes);
edgeCursor->getMore(_opRes, UINT64_MAX, false);
if (_opRes->failed()) {
THROW_ARANGO_EXCEPTION(_opRes->code);
}
@ -102,12 +102,12 @@ struct BasicExpander {
if (from == v) {
std::string to = edge.get(TRI_VOC_ATTRIBUTE_TO).copyString();
if (to != v) {
res_edges.emplace_back(edgeId);
neighbors.emplace_back(to);
res_edges.emplace_back(std::move(edgeId));
neighbors.emplace_back(std::move(to));
}
} else {
res_edges.emplace_back(edgeId);
neighbors.emplace_back(from);
res_edges.emplace_back(std::move(edgeId));
neighbors.emplace_back(std::move(from));
}
}
@ -214,8 +214,9 @@ class MultiCollectionEdgeExpander {
auto cand = candidates.find(t);
if (cand == candidates.end()) {
// Add weight
result.emplace_back(new ArangoDBPathFinder::Step(
t, s, currentWeight, edgeCollection->trx()->extractIdString(edge)));
auto step = std::make_unique<ArangoDBPathFinder::Step>(
t, s, currentWeight, edgeCollection->trx()->extractIdString(edge));
result.emplace_back(step.release());
candidates.emplace(t, result.size() - 1);
} else {
// Compare weight
@ -229,7 +230,7 @@ class MultiCollectionEdgeExpander {
auto opRes = std::make_shared<OperationResult>(TRI_ERROR_NO_ERROR);
while (edgeCursor->hasMore()) {
edgeCursor->getMore(opRes);
edgeCursor->getMore(opRes, UINT64_MAX, false);
if (opRes->failed()) {
THROW_ARANGO_EXCEPTION(opRes->code);
}
@ -266,6 +267,8 @@ class SimpleEdgeExpander {
EdgeCollectionInfo* _edgeCollection;
std::unordered_map<std::string, size_t> _candidates;
public:
SimpleEdgeExpander(TRI_edge_direction_e& direction,
EdgeCollectionInfo* edgeCollection)
@ -275,16 +278,16 @@ class SimpleEdgeExpander {
std::vector<ArangoDBPathFinder::Step*>& result) {
TRI_ASSERT(_edgeCollection != nullptr);
std::unordered_map<std::string, size_t> candidates;
_candidates.clear();
auto inserter = [&](std::string const& s, std::string const& t,
double currentWeight, VPackSlice edge) {
auto cand = candidates.find(t);
if (cand == candidates.end()) {
auto cand = _candidates.find(t);
if (cand == _candidates.end()) {
// Add weight
result.emplace_back(new ArangoDBPathFinder::Step(
t, s, currentWeight, _edgeCollection->trx()->extractIdString(edge)));
candidates.emplace(t, result.size() - 1);
auto step = std::make_unique<ArangoDBPathFinder::Step>(
std::move(t), std::move(s), currentWeight, _edgeCollection->trx()->extractIdString(edge));
result.emplace_back(step.release());
} else {
// Compare weight
auto oldWeight = result[cand->second]->weight();
@ -297,7 +300,7 @@ class SimpleEdgeExpander {
auto edgeCursor = _edgeCollection->getEdges(_direction, source);
auto opRes = std::make_shared<OperationResult>(TRI_ERROR_NO_ERROR);
while (edgeCursor->hasMore()) {
edgeCursor->getMore(opRes);
edgeCursor->getMore(opRes, UINT64_MAX, false);
if (opRes->failed()) {
THROW_ARANGO_EXCEPTION(opRes->code);
}
@ -307,9 +310,9 @@ class SimpleEdgeExpander {
std::string const to = edge.get(TRI_VOC_ATTRIBUTE_TO).copyString();
double currentWeight = _edgeCollection->weightEdge(edge);
if (from == source) {
inserter(from, to, currentWeight, edge);
inserter(std::move(from), std::move(to), currentWeight, edge);
} else {
inserter(to, from, currentWeight, edge);
inserter(std::move(to), std::move(from), currentWeight, edge);
}
}
}
@ -329,12 +332,14 @@ void BasicOptions::addVertexFilter(v8::Isolate* isolate,
if (it == _vertexFilter.end()) {
if (example->IsArray()) {
_vertexFilter.emplace(name, new ExampleMatcher(
isolate, v8::Handle<v8::Array>::Cast(example), errorMessage));
auto matcher = std::make_unique<ExampleMatcher>(
isolate, v8::Handle<v8::Array>::Cast(example), errorMessage);
_vertexFilter.emplace(name, matcher.release());
} else {
// Has to be Object
_vertexFilter.emplace(name, new ExampleMatcher(
isolate, v8::Handle<v8::Object>::Cast(example), errorMessage));
auto matcher = std::make_unique<ExampleMatcher>(
isolate, v8::Handle<v8::Object>::Cast(example), errorMessage);
_vertexFilter.emplace(name, matcher.release());
}
}
}
@ -376,14 +381,14 @@ void BasicOptions::addEdgeFilter(v8::Isolate* isolate,
}
if (example->IsArray()) {
_edgeFilter.emplace(
cName, new ExampleMatcher(isolate, v8::Handle<v8::Array>::Cast(example),
errorMessage));
auto matcher = std::make_unique<ExampleMatcher>(
isolate, v8::Handle<v8::Array>::Cast(example), errorMessage);
_edgeFilter.emplace(cName, matcher.release());
} else {
// Has to be Object
_edgeFilter.emplace(
cName, new ExampleMatcher(isolate, v8::Handle<v8::Object>::Cast(example),
errorMessage));
auto matcher = std::make_unique<ExampleMatcher>(
isolate, v8::Handle<v8::Object>::Cast(example), errorMessage);
_edgeFilter.emplace(cName, matcher.release());
}
}
@ -396,7 +401,8 @@ void BasicOptions::addEdgeFilter(VPackSlice const& example,
useEdgeFilter = true;
auto it = _edgeFilter.find(cName);
if (it == _edgeFilter.end()) {
_edgeFilter.emplace(cName, new ExampleMatcher(example, true));
auto matcher = std::make_unique<ExampleMatcher>(example, true);
_edgeFilter.emplace(cName, matcher.release());
}
}
@ -584,8 +590,9 @@ TRI_RunSimpleShortestPathSearch(
auto bwExpander = BasicExpander(collectionInfos, trx, backward);
ArangoDBConstDistancePathFinder pathFinder(fwExpander, bwExpander);
auto path = std::make_unique<ArangoDBConstDistancePathFinder::Path>();
path.reset(pathFinder.search(opts.start, opts.end));
auto path = std::unique_ptr<ArangoDBConstDistancePathFinder::Path>(
pathFinder.search(opts.start, opts.end));
return path;
}
@ -609,7 +616,7 @@ static void InboundNeighbors(std::vector<EdgeCollectionInfo*>& collectionInfos,
for (auto const& start : startVertices) {
auto edgeCursor = col->getEdges(dir, start);
while (edgeCursor->hasMore()) {
edgeCursor->getMore(opRes);
edgeCursor->getMore(opRes, UINT64_MAX, false);
if (opRes->failed()) {
THROW_ARANGO_EXCEPTION(opRes->code);
}
@ -648,7 +655,7 @@ static void InboundNeighbors(std::vector<EdgeCollectionInfo*>& collectionInfos,
static void OutboundNeighbors(std::vector<EdgeCollectionInfo*>& collectionInfos,
NeighborsOptions& opts,
std::unordered_set<std::string>& startVertices,
std::unordered_set<std::string> const& startVertices,
std::unordered_set<std::string>& visited,
std::unordered_set<std::string>& distinct,
uint64_t depth = 1) {
@ -662,27 +669,29 @@ static void OutboundNeighbors(std::vector<EdgeCollectionInfo*>& collectionInfos,
for (auto const& start : startVertices) {
auto edgeCursor = col->getEdges(dir, start);
while (edgeCursor->hasMore()) {
edgeCursor->getMore(opRes);
edgeCursor->getMore(opRes, UINT64_MAX, false);
if (opRes->failed()) {
THROW_ARANGO_EXCEPTION(opRes->code);
}
VPackSlice edges = opRes->slice();
for (auto const& edge : VPackArrayIterator(edges)) {
if (opts.matchesEdge(edge)) {
std::string v = edge.get(TRI_VOC_ATTRIBUTE_TO).copyString();
if (visited.find(v) != visited.end()) {
VPackValueLength l;
char const* v = edge.get(TRI_VOC_ATTRIBUTE_TO).getString(l);
if (visited.find(std::string(v, l)) != visited.end()) {
// We have already visited this vertex
continue;
}
visited.emplace(v);
std::string tmp(v, l);
if (depth >= opts.minDepth) {
if (opts.matchesVertex(v)) {
distinct.emplace(v);
if (opts.matchesVertex(tmp)) {
distinct.emplace(tmp);
}
}
if (depth < opts.maxDepth) {
nextDepth.emplace(v);
nextDepth.emplace(tmp);
}
visited.emplace(std::move(tmp));
}
}
}
@ -716,7 +725,7 @@ static void AnyNeighbors(std::vector<EdgeCollectionInfo*>& collectionInfos,
for (auto const& start : startVertices) {
auto edgeCursor = col->getEdges(dir, start);
while (edgeCursor->hasMore()) {
edgeCursor->getMore(opRes);
edgeCursor->getMore(opRes, UINT64_MAX, false);
if (opRes->failed()) {
THROW_ARANGO_EXCEPTION(opRes->code);
}

View File

@ -27,6 +27,7 @@
#include "Basics/StringUtils.h"
#include "Basics/process-utils.h"
#include "Rest/GeneralRequest.h"
#include "Statistics/StatisticsFeature.h"
#include "Statistics/statistics.h"
#include "V8/v8-conv.h"
#include "V8/v8-globals.h"
@ -108,6 +109,20 @@ static void JS_ServerStatistics(
TRI_V8_TRY_CATCH_END
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not server-side statistics are enabled
////////////////////////////////////////////////////////////////////////////////
static void JS_EnabledStatistics(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate)
v8::HandleScope scope(isolate);
v8::Handle<v8::Value> result = v8::Boolean::New(isolate, StatisticsFeature::enabled());
TRI_V8_RETURN(result);
TRI_V8_TRY_CATCH_END
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the current request and connection statistics
////////////////////////////////////////////////////////////////////////////////
@ -244,6 +259,9 @@ void TRI_InitV8Statistics(v8::Isolate* isolate,
// create the global functions
// .............................................................................
TRI_AddGlobalFunctionVocbase(isolate, context,
TRI_V8_ASCII_STRING("SYS_ENABLED_STATISTICS"),
JS_EnabledStatistics);
TRI_AddGlobalFunctionVocbase(isolate, context,
TRI_V8_ASCII_STRING("SYS_CLIENT_STATISTICS"),
JS_ClientStatistics);

View File

@ -25,6 +25,7 @@
#include "Basics/conversions.h"
#include "Utils/Cursor.h"
#include "Utils/CursorRepository.h"
#include "Utils/StandaloneTransactionContext.h"
#include "V8/v8-conv.h"
#include "V8/v8-vpack.h"
#include "V8Server/v8-voccursor.h"
@ -88,9 +89,16 @@ static void JS_CreateCursor(v8::FunctionCallbackInfo<v8::Value> const& args) {
auto cursors =
static_cast<arangodb::CursorRepository*>(vocbase->_cursorRepository);
arangodb::aql::QueryResult result(TRI_ERROR_NO_ERROR);
result.result = builder;
result.cached = false;
result.context = std::make_shared<arangodb::StandaloneTransactionContext>(vocbase);
TRI_ASSERT(builder.get() != nullptr);
try {
arangodb::Cursor* cursor = cursors->createFromVelocyPack(
builder, static_cast<size_t>(batchSize), nullptr, ttl, true, false);
arangodb::Cursor* cursor = cursors->createFromQueryResult(
std::move(result), static_cast<size_t>(batchSize), nullptr, ttl, true);
TRI_ASSERT(cursor != nullptr);
cursors->release(cursor);

View File

@ -59,12 +59,6 @@ typedef uint64_t TRI_voc_cid_t;
typedef uint64_t TRI_voc_fid_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief document key identifier type
////////////////////////////////////////////////////////////////////////////////
typedef char* TRI_voc_key_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief revision identifier type
////////////////////////////////////////////////////////////////////////////////
@ -146,16 +140,40 @@ enum TRI_edge_direction_e {
////////////////////////////////////////////////////////////////////////////////
/// @brief velocypack sub-object (for indexes, as part of TRI_index_element_t,
/// if offset is non-zero, then it is an offset into the VelocyPack data in
/// the data or WAL file. If offset is 0, then data contains the actual data
/// in place.
/// if the last byte in data[] is 0, then it is an offset into the VelocyPack
/// data in the datafile or WAL file. If the last byte in data[] is 1, then
/// value.data contains the actual VelocyPack data in place.
////////////////////////////////////////////////////////////////////////////////
struct TRI_vpack_sub_t {
union {
uint8_t data[12];
uint32_t offset;
uint8_t data[8];
} value;
VPackSlice const slice(TRI_doc_mptr_t const* mptr) const;
static constexpr size_t maxValueLength() noexcept {
return sizeof(value.data) - 1;
}
void setOffset(uint32_t offset) noexcept {
value.offset = offset;
value.data[maxValueLength()] = 0; // type = offset
}
void setValue(uint8_t const* data, size_t length) noexcept {
memcpy(&value.data[0], data, length);
value.data[maxValueLength()] = 1; // type = value
}
inline bool isOffset() const noexcept {
return value.data[maxValueLength()] == 0;
}
inline bool isValue() const noexcept {
return value.data[maxValueLength()] == 1;
}
VPackSlice slice(TRI_doc_mptr_t const* mptr) const;
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -2296,12 +2296,11 @@ TRI_vocbase_t::getReplicationClients() {
/// in place.
////////////////////////////////////////////////////////////////////////////////
VPackSlice const TRI_vpack_sub_t::slice(TRI_doc_mptr_t const* mptr) const {
if (offset == 0) {
return VPackSlice(data);
} else {
return VPackSlice(mptr->vpack() + offset);
VPackSlice TRI_vpack_sub_t::slice(TRI_doc_mptr_t const* mptr) const {
if (isValue()) {
return VPackSlice(&value.data[0]);
}
return VPackSlice(mptr->vpack() + value.offset);
}
////////////////////////////////////////////////////////////////////////////////
@ -2310,14 +2309,12 @@ VPackSlice const TRI_vpack_sub_t::slice(TRI_doc_mptr_t const* mptr) const {
void TRI_FillVPackSub(TRI_vpack_sub_t* sub,
VPackSlice const base, VPackSlice const value) noexcept {
if (value.byteSize() <= sizeof(sub->data)) {
sub->offset = 0;
memcpy(sub->data, value.start(), value.byteSize());
if (value.byteSize() <= TRI_vpack_sub_t::maxValueLength()) {
sub->setValue(value.start(), value.byteSize());
} else {
size_t off = value.start() - base.start();
TRI_ASSERT(off <= UINT32_MAX);
sub->offset = static_cast<uint32_t>(off);
memset(sub->data, 0, sizeof(sub->data));
sub->setOffset(static_cast<uint32_t>(off));
}
}

View File

@ -515,6 +515,9 @@ void LogfileManager::stop() {
// set WAL to read-only mode
allowWrites(false);
// notify slots that we're shutting down
_slots->shutdown();
// finalize allocator thread
// this prevents creating new (empty) WAL logfile once we flush
// current logfile

View File

@ -52,13 +52,20 @@ Slots::Slots(LogfileManager* logfileManager, size_t numberOfSlots,
_lastCommittedDataTick(0),
_numEvents(0),
_lastDatabaseId(0),
_lastCollectionId(0) {
_lastCollectionId(0),
_shutdown(false) {
_slots = new Slot[numberOfSlots];
}
/// @brief destroy the slots
Slots::~Slots() { delete[] _slots; }
/// @brief sets a shutdown flag, disabling the request for new logfiles
void Slots::shutdown() {
MUTEX_LOCKER(mutexLocker, _lock);
_shutdown = true;
}
/// @brief get the statistics of the slots
void Slots::statistics(Slot::TickType& lastAssignedTick,
Slot::TickType& lastCommittedTick,
@ -78,6 +85,11 @@ int Slots::flush(bool waitForSync) {
int res = closeLogfile(lastTick, worked);
if (res == TRI_ERROR_REQUEST_CANCELED) {
// only happens during shutdown
res = TRI_ERROR_NO_ERROR;
}
if (res == TRI_ERROR_NO_ERROR) {
_logfileManager->signalSync();
@ -661,6 +673,10 @@ bool Slots::waitForTick(Slot::TickType tick) {
int Slots::newLogfile(uint32_t size, Logfile::StatusType& status) {
TRI_ASSERT(size > 0);
if (_shutdown) {
return TRI_ERROR_REQUEST_CANCELED;
}
status = Logfile::StatusType::UNKNOWN;
Logfile* logfile = nullptr;
int res = _logfileManager->getWriteableLogfile(size, status, logfile);

View File

@ -85,6 +85,9 @@ class Slots {
~Slots();
public:
/// @brief sets a shutdown flag, disabling the request for new logfiles
void shutdown();
/// @brief get the statistics of the slots
void statistics(Slot::TickType&, Slot::TickType&, Slot::TickType&, uint64_t&);
@ -186,6 +189,9 @@ class Slots {
/// @brief last written collection id (in prologue marker)
TRI_voc_cid_t _lastCollectionId;
/// @brief shutdown flag, set by LogfileManager on shutdown
bool _shutdown;
};
}
}

View File

@ -144,7 +144,11 @@ void ImportFeature::validateOptions(
size_t n = positionals.size();
if (1 == n) {
// only take positional file name attribute into account if user
// did not specify the --file option as well
if (!options->processingResult().touched("--file")) {
_filename = positionals[0];
}
} else if (1 < n) {
LOG(FATAL) << "expecting at most one filename, got " +
StringUtils::join(positionals, ", ");

View File

@ -118,6 +118,7 @@ actions.defineHttp({
try {
result = {};
result.time = internal.time();
result.enabled = internal.enabledStatistics();
result.system = internal.processStatistics();
result.client = internal.clientStatistics();
result.http = internal.httpStatistics();

View File

@ -1,57 +0,0 @@
/*jshint strict: false */
////////////////////////////////////////////////////////////////////////////////
/// @brief open actions
///
/// @file
/// Actions that are mapped under the "_open" path. Allowing to execute the
/// actions without authorization.
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var actions = require("@arangodb/actions");
////////////////////////////////////////////////////////////////////////////////
/// @brief cerberus password manager
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: "_open/cerberus",
prefix : true,
callback : function (req, res) {
req.user = null;
req.database = "_system";
var suffix = "_system/cerberus";
suffix = suffix.split("/");
suffix = suffix.concat(req.suffix);
req.suffix = suffix;
actions.routeRequest(req, res);
}
});

View File

@ -67,10 +67,8 @@ router.get('/whoAmI', function(req, res) {
router.post('/logout', function (req, res) {
if (req.session) {
sessions.clear(req.session._key);
sessions.clear(req.session);
delete req.session;
}
res.json({success: true});
})
.summary('Log out')
@ -95,6 +93,7 @@ router.post('/login', function (req, res) {
}
sessions.setUser(req.session, doc);
sessions.save(req.session);
const user = doc.user;
res.json({user});
})
@ -110,22 +109,12 @@ router.post('/login', function (req, res) {
`);
router.get('/unauthorized', function(req, res) {
res.throw('unauthorized');
})
.error('unauthorized')
.summary('Unauthorized')
.description(dd`
Responds with a HTTP 401 response.
`);
const authRouter = createRouter();
router.use(authRouter);
authRouter.use((req, res, next) => {
if (!internal.options()['server.disable-authentication'] && !req.session.uid) {
if (!internal.options()['server.disable-authentication'] && (!req.session || !req.session.uid)) {
res.throw('unauthorized');
}
next();

File diff suppressed because one or more lines are too long

View File

@ -35,7 +35,7 @@ module.exports = router;
router.use((req, res, next) => {
if (!internal.options()['server.disable-authentication'] && !req.session.uid) {
if (!internal.options()['server.disable-authentication'] && (!req.session || !req.session.uid)) {
res.throw('unauthorized');
}
next();

View File

@ -796,4 +796,4 @@
</div>
</div>
</div>
</div></script></head><body><nav class="navbar"><div class="primary"><div class="navlogo"><a class="logo" href="#"><img class="arangodbLogo" src="img/DEVLOGO.png"></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="bodyWrapper"><div class="centralRow"><div id="navbar2" class="secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper" style="clear:both"><div id="content" class="centralContent"></div></div><div class="resizecontainer footerWrapper" style="clear:both"><footer class="footer"><div class="" id="footerBar"></div></footer></div></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js"></script><script src="cluster.js"></script></body></html>
</div></script></head><body><nav class="navbar"><div class="primary"><div class="navlogo"><a class="logo big" href="#"><img class="arangodbLogo" src="img/arangodb_logo_big.png"></a> <a class="logo small" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="bodyWrapper"><div class="centralRow"><div id="navbar2" class="navbarWrapper secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper"><div id="content" class="centralContent"></div><footer class="footer"><div id="footerBar"></div></footer></div></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js"></script><script src="cluster.js"></script></body></html>

View File

@ -889,7 +889,8 @@
<nav class="navbar">
<div class="primary">
<div class="navlogo">
<a class="logo" href="#"><img class="arangodbLogo" src="img/DEVLOGO.png"/></a>
<a class="logo big" href="#"><img class="arangodbLogo" src="img/arangodb_logo_big.png"/></a>
<a class="logo small" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"/></a>
</div>
<!-- <div id="progressPlaceholderIcon"></div> -->
<div class="statmenu" id="statisticBar">
@ -902,18 +903,19 @@
<div class="bodyWrapper">
<div class="centralRow">
<div id='navbar2' class="secondary">
<div id='navbar2' class="navbarWrapper secondary">
<div class="subnavmenu" id="subNavigationBar"></div>
</div>
<div class="resizecontainer contentWrapper" style="clear:both;">
<div class="resizecontainer contentWrapper">
<div id="content" class="centralContent"></div>
</div>
<div class="resizecontainer footerWrapper" style="clear:both;">
<footer class="footer">
<div class="" id="footerBar">
</div>
<div id="footerBar"></div>
</footer>
</div>
</div>
</div>

View File

@ -222,6 +222,94 @@
}
},
//object: {"name": "Menu 1", func: function(), active: true/false }
buildSubNavBar: function(menuItems) {
$('#subNavigationBar .bottom').html('');
var cssClass;
_.each(menuItems, function(menu, name) {
cssClass = '';
if (menu.active) {
cssClass += ' active';
}
if (menu.disabled) {
cssClass += ' disabled';
}
$('#subNavigationBar .bottom').append(
'<li class="subMenuEntry ' + cssClass + '"><a>' + name + '</a></li>'
);
if (!menu.disabled) {
$('#subNavigationBar .bottom').children().last().bind('click', function() {
window.App.navigate(menu.route, {trigger: true});
});
}
});
},
buildNodeSubNav: function(node, activeKey, disabled) {
var menus = {
Dashboard: {
route: '#node/' + encodeURIComponent(node)
},
Logs: {
route: '#nLogs/' + encodeURIComponent(node),
disabled: true
}
};
menus[activeKey].active = true;
menus[disabled].disabled = true;
this.buildSubNavBar(menus);
},
//nav for collection view
buildNodesSubNav: function(type) {
var menus = {
Coordinators: {
route: '#cNodes'
},
DBServers: {
route: '#dNodes'
}
};
if (type === 'coordinator') {
menus.Coordinators.active = true;
}
else {
menus.DBServers.active = true;
}
this.buildSubNavBar(menus);
},
//nav for collection view
buildCollectionSubNav: function(collectionName, activeKey) {
var defaultRoute = '#collection/' + encodeURIComponent(collectionName);
var menus = {
Content: {
route: defaultRoute + '/documents/1'
},
Indices: {
route: '#cIndices/' + encodeURIComponent(collectionName)
},
Info: {
route: '#cInfo/' + encodeURIComponent(collectionName)
},
Settings: {
route: '#cSettings/' + encodeURIComponent(collectionName)
}
};
menus[activeKey].active = true;
this.buildSubNavBar(menus);
},
enableKeyboardHotkeys: function (enable) {
var hotkeys = window.arangoHelper.hotkeysFunctions;
if (enable === true) {
@ -1948,7 +2036,7 @@ window.StatisticsCollection = Backbone.Collection.extend({
initialize: function () {
//also server online check
var self = this;
window.setInterval(function(){
window.setInterval(function() {
self.getVersion();
}, 15000);
self.getVersion();
@ -1962,7 +2050,9 @@ window.StatisticsCollection = Backbone.Collection.extend({
template: templateEngine.createTemplate("footerView.ejs"),
showServerStatus: function(isOnline) {
if (!window.App.isCluster) {
var self = this;
if (!window.App.isCluster) {
if (isOnline === true) {
$('#healthStatus').removeClass('negative');
$('#healthStatus').addClass('positive');
@ -1976,6 +2066,55 @@ window.StatisticsCollection = Backbone.Collection.extend({
$('.health-icon').html('<i class="fa fa-exclamation-circle"></i>');
}
}
else {
self.collection.fetch({
success: function() {
self.renderClusterState(true);
},
error: function() {
self.renderClusterState(false);
}
});
}
},
renderClusterState: function(connection) {
var ok = 0, error = 0;
if (connection) {
this.collection.each(function(value) {
if (value.toJSON().status === 'ok') {
ok++;
}
else {
error++;
}
});
if (error > 0) {
$('#healthStatus').removeClass('positive');
$('#healthStatus').addClass('negative');
if (error === 1) {
$('.health-state').html(error + ' NODE ERROR');
}
else {
$('.health-state').html(error + ' NODES ERROR');
}
$('.health-icon').html('<i class="fa fa-exclamation-circle"></i>');
}
else {
$('#healthStatus').removeClass('negative');
$('#healthStatus').addClass('positive');
$('.health-state').html('NODES OK');
$('.health-icon').html('<i class="fa fa-check-circle"></i>');
}
}
else {
$('#healthStatus').removeClass('positive');
$('#healthStatus').addClass('negative');
$('.health-state').html(window.location.host + ' OFFLINE');
$('.health-icon').html('<i class="fa fa-exclamation-circle"></i>');
}
},
showShortcutModal: function() {
@ -3253,7 +3392,8 @@ window.StatisticsCollection = Backbone.Collection.extend({
};
},
show: function(templateName, title, buttons, tableContent, advancedContent, extraInfo, events, noConfirm, tabBar) {
show: function(templateName, title, buttons, tableContent, advancedContent,
extraInfo, events, noConfirm, tabBar, divID) {
var self = this, lastBtn, confirmMsg, closeButtonFound = false;
buttons = buttons || [];
noConfirm = Boolean(noConfirm);
@ -3276,6 +3416,7 @@ window.StatisticsCollection = Backbone.Collection.extend({
} else {
buttons.push(self.createCloseButton('Close'));
}
if (!divID) {
$(this.el).html(this.baseTemplate.render({
title: title,
buttons: buttons,
@ -3283,6 +3424,27 @@ window.StatisticsCollection = Backbone.Collection.extend({
confirm: confirmMsg,
tabBar: tabBar
}));
}
else {
//render into custom div
$('#' + divID).html(this.baseTemplate.render({
title: title,
buttons: buttons,
hideFooter: this.hideFooter,
confirm: confirmMsg,
tabBar: tabBar
}));
//remove not needed modal elements
$('#' + divID + " #modal-dialog").removeClass("fade hide modal");
$('#' + divID + " .modal-header").remove();
$('#' + divID + " .modal-tabbar").remove();
$('#' + divID + " .modal-tabbar").remove();
$('#' + divID + " .button-close").remove();
if ($('#' + divID + " .modal-footer").children().length === 0) {
$('#' + divID + " .modal-footer").remove();
}
}
_.each(buttons, function(b, i) {
if (b.disabled || !b.callback) {
return;
@ -3377,7 +3539,9 @@ window.StatisticsCollection = Backbone.Collection.extend({
}, 100);
}
if (!divID) {
$("#modal-dialog").modal("show");
}
//enable modal hotkeys after rendering is complete
if (this.enabledHotkey === false) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@ input,
textarea,
.page-title span,
.pingback a.url {
font-family: 'Lato', sans-serif !important;
font-family: 'Roboto', sans-serif !important;
font-weight: 400; }
@font-face {
@ -2066,7 +2066,7 @@ textarea,
.user-dropdown-menu, .script-dropdown-menu, .gv-dropdown-menu, .navlogo, .navlist li, div.footer-left, div.footer-left p, div.footer-center, a.headerButton, a.button-gui, div .tile, div .bigtile, div .tile a span.add-Icon, div .bigtile a span.add-Icon, div.centralContent, .contentDiv li, div.dropdownInner ul, .machineClass, .scenarioMachine, .dashboard-full-width-chart .dashboard-full-width-chart-inner, .dashboard-large-chart .dashboard-large-chart-inner, .dashboard-small-chart .dashboard-small-chart-inner, .dashboard-medium-chart, .dashboard-tendency-container, .dashboard-bar-chart-container, .dashboard-full-width-chart, .dashboard-large-chart, .dashboard-small-chart, .dashboard-sub-bar, .dashboard-sub-bar .dashboard-sub-bar-title, .dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart, .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart, .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart, .dashboard-medium-chart .dashboard-interior-chart, .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency, .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar, .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart, .modal-chart-detail, .modal-chart-detail .modal-body, .modal-chart-detail .modal-dashboard-legend, .modal-chart-detail .modal-inner-detail, .dashboard-half-height-legend, .dashboard-title-bar .dashboard-half-title-bar {
float: left; }
div.footer-right, div.footer-right p, ul.headerButtonList li, div .tile .iconSet span, div .bigtile .iconSet span, .search-field, .headerBar > div.headerButtonBar, .dashboard-sub-bar-menu, .dashboard-legend, .dashboard-legend .dashboard-legend-inner span {
div.footer-right, div.footer-right p, ul.headerButtonList li, div .tile .iconSet span, div .bigtile .iconSet span, .search-field, .headerBar > div.headerButtonBar, .dashboard-sub-bar-menu, .dashboard-legend {
float: right; }
.tileList:after, .resizecontainer:after, .headerBar > div.headerButtonBar:after, .machineClass:after, .scenarioSingleMachine:after, .detail-chart:after, .dashboard-sub-bar:after, .dashboard-medium-chart .dashboard-medium-chart-menu:after, .dashboard-medium-chart .dashboard-medium-chart-inner:after, .dashboard-tendency-container .dashboard-tendency-chart:after, .dashboard-bar-chart-container .dashboard-bar-chart:after, .dashboard-row:after {
@ -2077,10 +2077,11 @@ div.footer-right, div.footer-right p, ul.headerButtonList li, div .tile .iconSet
height: 0;
visibility: hidden; }
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton i, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .scenarioImage {
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton i, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .scenarioImage {
cursor: pointer; }
.navbar, footer.footer {
.navbar {
color: #fff;
left: 0;
right: 0;
@ -2316,6 +2317,8 @@ div.queryline input, input.search-input, .modal-body .select2-choices input, .mo
.navlogo {
height: 60px;
width: 100%; }
.navlogo .small {
display: none; }
.navmenu {
clear: both; }
@ -2328,12 +2331,22 @@ div.queryline input, input.search-input, .modal-body .select2-choices input, .mo
line-height: 30px; }
.navlist li {
width: 150px; }
.navlist li a {
outline: none; }
.navlist li .fa {
opacity: .3;
padding-left: 5px;
padding-right: 15px;
text-align: center;
width: 10px; }
.navlist li .fa.fa-heart {
color: #ff7a7a;
opacity: 1; }
.navlist li.disabled:hover {
cursor: default; }
.navlist li.disabled:hover a:hover {
cursor: default;
opacity: .8; }
.navlist li.dropdown:hover {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
@ -2344,8 +2357,8 @@ div.queryline input, input.search-input, .modal-body .select2-choices input, .mo
.navlist li.navbar-spacer {
background-color: #fff;
height: 1px;
margin-bottom: 5px;
margin-top: 5px;
margin-bottom: 0;
margin-top: 0;
opacity: .2; }
.navlist .active {
border-left: 2px solid #77cb99; }
@ -2471,21 +2484,18 @@ div.queryline input, input.search-input, .modal-body .select2-choices input, .mo
.arango-logo img {
margin-left: 22px; }
.footerWrapper {
bottom: 0;
height: 42px;
position: absolute; }
.footer {
background-color: rgba(239, 240, 241, 0.8);
font-size: 14px;
left: 0;
right: 0;
left: 160px;
right: 10px;
text-align: center;
z-index: 1000; }
footer.footer {
bottom: 0;
height: 40px; }
height: 43px;
position: fixed; }
footer.footer p {
font-size: 10pt;
font-weight: 100;
@ -2611,7 +2621,7 @@ button.disabled,
margin-left: 0 !important; }
button {
font-family: 'Lato', sans-serif !important; }
font-family: 'Roboto', sans-serif !important; }
button.btn-server {
width: 120px; }
button.gv-zoom-btn {
@ -3144,8 +3154,8 @@ div .bigtile {
text-align: left; }
.resizecontainer {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding-left: 10px;
padding-right: 10px; }
@ -5201,31 +5211,37 @@ div .bigtile {
.application-detail-view section.info {
width: 2290px; } }
div.contentWrapper {
padding-bottom: 42px; }
div.headerBar {
background-color: none;
border-radius: 2px;
float: right;
font-size: 16px;
height: 36px;
margin-top: -55px;
position: absolute;
right: 150px; }
div.centralRow {
background: rgba(64, 74, 83, 0.04);
float: left;
height: 100%;
left: 150px;
min-height: 100%;
overflow-y: auto;
position: absolute;
position: relative;
right: 0; }
div.centralContent {
background-color: transparent;
margin-left: -5px;
margin-right: -5px;
box-sizing: border-box;
margin-top: 10px;
min-height: 80px;
padding: 5px;
padding-bottom: 43px;
padding-left: 5px;
padding-right: 5px;
padding-top: 5px;
width: 100%; }
.contentDiv {
list-style: none;
padding: 15px 0 0; }
padding: 0; }
.contentDiv li {
background-color: rgba(0, 0, 0, 0.05); }
.contentDiv a.add {
@ -5275,7 +5291,8 @@ li a [class*=" icon_arangodb"] {
.fa-minus-circle:hover {
cursor: pointer; }
div.headerDropdown {
div.headerDropdown,
.dropdownImport {
background-color: #fff;
border: 1px solid rgba(140, 138, 137, 0.25);
border-radius: 2px;
@ -5284,11 +5301,14 @@ div.headerDropdown {
padding: 10px;
position: relative;
width: auto; }
div.headerDropdown.smallDropdown .dropdownInner {
div.headerDropdown.smallDropdown .dropdownInner,
.dropdownImport.smallDropdown .dropdownInner {
min-height: 20px; }
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox {
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox {
display: none; }
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label {
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox label.css-label {
background-position: 0 0;
background-repeat: no-repeat;
display: inline-block;
@ -5297,7 +5317,8 @@ div.headerDropdown {
margin-top: 0;
padding-left: 20px;
vertical-align: middle; }
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked + label.css-label {
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked + label.css-label,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox:checked + label.css-label {
background-position: 0 -15px; }
div.dropdown-title {
@ -5472,11 +5493,13 @@ div.headerBar {
background-color: none;
border-radius: 2px;
color: #000;
float: right;
font-size: 16px;
height: 36px;
margin-top: -55px;
padding-left: 5px;
padding-right: 5px; }
padding-right: 5px;
right: 0; }
div.headerBar select:focus {
outline: none; }
div.headerBar .infoField {
@ -5552,7 +5575,8 @@ div.headerBar {
padding-bottom: 0;
padding-left: 10px;
padding-right: 0;
padding-top: 0; }
padding-top: 0;
text-transform: capitalize; }
.breadcrumb .fa {
margin-left: 10px;
margin-right: 8px; }
@ -5656,7 +5680,7 @@ div.headerBar {
.modal-body {
color: #736b68;
font-family: 'Lato', sans-serif !important;
font-family: 'Roboto', sans-serif !important;
font-size: 14px;
font-weight: 300;
max-height: 410px; }
@ -6339,7 +6363,7 @@ div .bigtile {
.dataNotReadyYet {
color: #faa732;
font-family: 'Lato', sans-serif;
font-family: 'Roboto', sans-serif;
font-size: 14px;
font-weight: 100;
text-align: center; }
@ -6350,7 +6374,7 @@ div .bigtile {
border-bottom-right-radius: 3px;
box-sizing: border-box;
color: rgba(0, 0, 0, 0.5);
font-family: Lato,sans-serif;
font-family: 'Roboto', sans-serif;
font-size: 11pt;
font-weight: 600;
height: 50px;
@ -6364,7 +6388,7 @@ div .bigtile {
text-transform: uppercase; }
.dashboard-sub-bar .dashboard-sub-bar-title {
color: #000;
font-family: Lato,sans-serif;
font-family: 'Roboto', sans-serif;
font-size: 11pt;
font-weight: 600;
opacity: .5;
@ -6540,7 +6564,8 @@ div .bigtile {
stroke-width: .5px; }
.dashboard-legend .dashboard-legend-inner {
padding: 0 5px 5px 0; }
padding: 0 5px 5px 0;
text-align: right; }
.dashboard-legend .dashboard-legend-inner br {
display: none; }
.dashboard-legend .dashboard-legend-inner span {
@ -6591,8 +6616,8 @@ div .bigtile {
width: 33.3% !important; }
.resizecontainer {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding-left: 10px;
padding-right: 10px; }
@ -8648,31 +8673,37 @@ div .bigtile {
.application-detail-view section.info {
width: 2290px; } }
div.contentWrapper {
padding-bottom: 42px; }
div.headerBar {
background-color: none;
border-radius: 2px;
float: right;
font-size: 16px;
height: 36px;
margin-top: -55px;
position: absolute;
right: 150px; }
div.centralRow {
background: rgba(64, 74, 83, 0.04);
float: left;
height: 100%;
left: 150px;
min-height: 100%;
overflow-y: auto;
position: absolute;
position: relative;
right: 0; }
div.centralContent {
background-color: transparent;
margin-left: -5px;
margin-right: -5px;
box-sizing: border-box;
margin-top: 10px;
min-height: 80px;
padding: 5px;
padding-bottom: 43px;
padding-left: 5px;
padding-right: 5px;
padding-top: 5px;
width: 100%; }
.contentDiv {
list-style: none;
padding: 15px 0 0; }
padding: 0; }
.contentDiv li {
background-color: rgba(0, 0, 0, 0.05); }
.contentDiv a.add {

View File

@ -41,7 +41,7 @@ module.exports = router;
router.use((req, res, next) => {
if (!internal.options()['server.disable-authentication'] && !req.session.uid) {
if (!internal.options()['server.disable-authentication'] && (!req.session || !req.session.uid)) {
res.throw('unauthorized');
}
next();

View File

@ -10578,21 +10578,64 @@ function GraphViewer(svg, width, height, adapterConfig, config) {
var cssClass;
_.each(menuItems, function(menu, name) {
cssClass = '';
if (menu.active) {
cssClass += ' active';
}
else {
cssClass = '';
if (menu.disabled) {
cssClass += ' disabled';
}
$('#subNavigationBar .bottom').append(
'<li class="subMenuEntry ' + cssClass + '"><a>' + name + '</a></li>'
);
if (!menu.disabled) {
$('#subNavigationBar .bottom').children().last().bind('click', function() {
window.App.navigate(menu.route, {trigger: true});
});
}
});
},
buildNodeSubNav: function(node, activeKey, disabled) {
var menus = {
Dashboard: {
route: '#node/' + encodeURIComponent(node)
},
Logs: {
route: '#nLogs/' + encodeURIComponent(node),
disabled: true
}
};
menus[activeKey].active = true;
menus[disabled].disabled = true;
this.buildSubNavBar(menus);
},
//nav for collection view
buildNodesSubNav: function(type) {
var menus = {
Coordinators: {
route: '#cNodes'
},
DBServers: {
route: '#dNodes'
}
};
if (type === 'coordinator') {
menus.Coordinators.active = true;
}
else {
menus.DBServers.active = true;
}
this.buildSubNavBar(menus);
},
//nav for collection view
buildCollectionSubNav: function(collectionName, activeKey) {
@ -13167,7 +13210,7 @@ module.define("underscore", function(exports, module) {
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoError
////////////////////////////////////////////////////////////////////////////////
if(global.ArangoError){exports.ArangoError = global.ArangoError;delete global.ArangoError;}else {exports.ArangoError = function(error){if(error !== undefined){this.error = error.error;this.code = error.code;this.errorNum = error.errorNum;this.errorMessage = error.errorMessage;}};exports.ArangoError.prototype = new Error();}Object.defineProperty(exports.ArangoError.prototype,'message',{configurable:true,enumerable:true,get:function get(){return this.errorMessage;}});exports.ArangoError.prototype.name = 'ArangoError';exports.ArangoError.prototype._PRINT = function(context){context.output += '[' + this.toString() + ']';};exports.ArangoError.prototype.toString = function(){return this.name + ' ' + this.errorNum + ': ' + this.message;}; ////////////////////////////////////////////////////////////////////////////////
if(global.ArangoError){exports.ArangoError = global.ArangoError;delete global.ArangoError;}else {exports.ArangoError = function(error){if(error !== undefined){this.error = error.error;this.code = error.code;this.errorNum = error.errorNum;this.errorMessage = error.errorMessage;}};exports.ArangoError.prototype = new Error();}exports.ArangoError.prototype.isArangoError = true;Object.defineProperty(exports.ArangoError.prototype,'message',{configurable:true,enumerable:true,get:function get(){return this.errorMessage;}});exports.ArangoError.prototype.name = 'ArangoError';exports.ArangoError.prototype._PRINT = function(context){context.output += '[' + this.toString() + ']';};exports.ArangoError.prototype.toString = function(){return this.name + ' ' + this.errorNum + ': ' + this.message;}; ////////////////////////////////////////////////////////////////////////////////
/// @brief threadNumber
////////////////////////////////////////////////////////////////////////////////
exports.threadNumber = 0;if(global.THREAD_NUMBER){exports.threadNumber = global.THREAD_NUMBER;delete global.THREAD_NUMBER;} ////////////////////////////////////////////////////////////////////////////////
@ -14924,7 +14967,7 @@ ArangoStatement.prototype.execute = function(){throw "cannot call abstract metho
/// @author Dr. Frank Celler
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var internal=require("internal");var fs=require("fs");var mimetypes=require("@arangodb/mimetypes").mimeTypes; ////////////////////////////////////////////////////////////////////////////////
var internal=require("internal");var fs=require("fs"); ////////////////////////////////////////////////////////////////////////////////
/// @brief errors
////////////////////////////////////////////////////////////////////////////////
Object.keys(internal.errors).forEach(function(key){exports[key] = internal.errors[key].code;});exports.errors = internal.errors; ////////////////////////////////////////////////////////////////////////////////
@ -14934,12 +14977,6 @@ exports.ArangoError = internal.ArangoError; ////////////////////////////////////
/// @brief defines a module
////////////////////////////////////////////////////////////////////////////////
exports.defineModule = function(path,file){var content;var m;var mc;content = fs.read(file);mc = internal.db._collection("_modules");if(mc === null){mc = internal.db._create("_modules",{isSystem:true});}path = module.normalize(path);m = mc.firstExample({path:path});if(m === null){mc.save({path:path,content:content});}else {mc.replace(m,{path:path,content:content});}}; ////////////////////////////////////////////////////////////////////////////////
/// @brief guessContentType
////////////////////////////////////////////////////////////////////////////////
exports.guessContentType = function(filename,defaultValue){var re=/\.([a-zA-Z0-9]+)$/;var match=re.exec(filename);if(match !== null){var extension=match[1];if(mimetypes.hasOwnProperty(extension)){var type=mimetypes[extension];if(type[1]){ // append charset
return type[0] + "; charset=utf-8";}return type[0];} // fall-through intentional
} // default mimetype
if(defaultValue){return defaultValue;}return "text/plain; charset=utf-8";}; ////////////////////////////////////////////////////////////////////////////////
/// @brief normalizeURL
///
/// If @FA{path} starts with "." or "..", then it is a relative path.
@ -15957,7 +15994,7 @@ var arangodb=require("@arangodb");var ArangoError=arangodb.ArangoError; // forwa
var SimpleQueryArray;var SimpleQueryNear;var SimpleQueryWithin;var SimpleQueryWithinRectangle; ////////////////////////////////////////////////////////////////////////////////
/// @brief array query
////////////////////////////////////////////////////////////////////////////////
function GeneralArrayCursor(documents,skip,limit,data){this._documents = documents;this._countTotal = documents.length;this._skip = skip;this._limit = limit;this._cached = false;this._extra = {};var self=this;if(data !== null && data !== undefined && typeof data === 'object'){['stats','warnings','profile'].forEach(function(d){if(data.hasOwnProperty(d)){self._extra[d] = data[d];}});this._cached = data.cached || false;}this.execute();} ////////////////////////////////////////////////////////////////////////////////
function GeneralArrayCursor(documents,skip,limit,data){this._documents = documents;this._countTotal = documents.length;this._skip = skip;this._limit = limit;this._cached = false;this._extra = {};var self=this;if(data !== null && data !== undefined && typeof data === 'object'){['stats','warnings','profile'].forEach(function(d){if(data.hasOwnProperty(d)){self._extra[d] = data[d];}});this._cached = data.cached || false;}this.execute();}GeneralArrayCursor.prototype.isArangoResultSet = true; ////////////////////////////////////////////////////////////////////////////////
/// @brief executes an array query
////////////////////////////////////////////////////////////////////////////////
GeneralArrayCursor.prototype.execute = function(){if(this._skip === null){this._skip = 0;}var len=this._documents.length;var s=0;var e=len; // skip from the beginning
@ -15987,7 +16024,7 @@ GeneralArrayCursor.prototype.next = function(){if(this._current < this._stop){re
GeneralArrayCursor.prototype.dispose = function(){this._documents = null;this._skip = null;this._limit = null;this._countTotal = null;this._countQuery = null;this._current = null;this._stop = null;this._extra = null;}; ////////////////////////////////////////////////////////////////////////////////
/// @brief simple query
////////////////////////////////////////////////////////////////////////////////
function SimpleQuery(){this._execution = null;this._skip = 0;this._limit = null;this._countQuery = null;this._countTotal = null;this._batchSize = null;} ////////////////////////////////////////////////////////////////////////////////
function SimpleQuery(){this._execution = null;this._skip = 0;this._limit = null;this._countQuery = null;this._countTotal = null;this._batchSize = null;}SimpleQuery.prototype.isArangoResultSet = true; ////////////////////////////////////////////////////////////////////////////////
/// @brief join limits
////////////////////////////////////////////////////////////////////////////////
function joinLimits(query,limit){ // original limit is 0, keep it
@ -20051,6 +20088,7 @@ window.ArangoUsers = Backbone.Collection.extend({
window.setInterval(function() {
if (window.location.hash === '#cluster'
|| window.location.hash === '#') {
var callback = function(data) {
self.rerenderValues(data);
self.rerenderGraphs(data);
@ -20156,17 +20194,36 @@ window.ArangoUsers = Backbone.Collection.extend({
var callback = function(data) {
self.rerenderValues(data);
self.rerenderGraphs(data);
};
}.bind(this);
// now fetch the statistics history
self.getCoordStatHistory(callback);
this.updateValues();
//special case nodes
self.coordinators.fetch({
success: function() {
self.renderNode(true);
},
error: function() {
self.renderNode(false);
}
});
},
rerenderValues: function(data) {
var self = this;
// TODO cache value state like graph data
//TODO cache value state like graph data
//NODE
this.coordinators.fetch({
success: function() {
self.renderNode(true);
},
error: function() {
self.renderNode(false);
}
});
//Connections
this.renderValue('#clusterConnections', Math.round(data.clientConnectionsCurrent));
@ -20176,12 +20233,9 @@ window.ArangoUsers = Backbone.Collection.extend({
var totalMem = data.physicalMemory;
var usedMem = data.residentSizeCurrent;
this.renderValue('#clusterRam', [usedMem, totalMem]);
//NODES
this.renderValue('#clusterNodes', this.statCollectCoord.size());
},
renderValue: function(id, value) {
renderValue: function(id, value, error) {
if (typeof value === 'number') {
$(id).html(value);
}
@ -20191,11 +20245,46 @@ window.ArangoUsers = Backbone.Collection.extend({
var percent = 1 / (b/a) * 100;
$(id).html(percent.toFixed(1) + ' %');
}
else if (typeof value === 'string') {
$(id).html(value);
}
if (error) {
$(id).addClass('negative');
$(id).removeClass('positive');
}
else {
$(id).addClass('positive');
$(id).removeClass('negative');
}
},
updateValues: function() {
this.renderValue('#clusterNodes', this.statCollectCoord.size());
this.renderValue('#clusterRam', [1024, 4096]);
renderNode: function(connection) {
var ok = 0, error = 0;
if (connection) {
this.coordinators.each(function(value) {
if (value.toJSON().status === 'ok') {
ok++;
}
else {
error++;
}
});
if (error > 0) {
var total = error + ok;
this.renderValue('#clusterNodes', ok + '/' + total, true);
}
else {
this.renderValue('#clusterNodes', ok);
}
}
else {
this.renderValue('#clusterNodes', 'OFFLINE', true);
}
},
initValues: function() {
@ -20462,7 +20551,6 @@ window.ArangoUsers = Backbone.Collection.extend({
var mergeHistory = function(data) {
var onetime = ['times'];
var values = [
'physicalMemory',
@ -22829,8 +22917,7 @@ window.ArangoUsers = Backbone.Collection.extend({
"click #databaseSearchSubmit" : "search",
"click #databaseToggle" : "toggleSettingsDropdown",
"click .css-label" : "checkBoxes",
"click #dbSortDesc" : "sorting",
"click .tile" : "switchDatabase"
"click #dbSortDesc" : "sorting"
},
sorting: function() {
@ -24659,7 +24746,7 @@ window.ArangoUsers = Backbone.Collection.extend({
initialize: function () {
//also server online check
var self = this;
window.setInterval(function(){
window.setInterval(function() {
self.getVersion();
}, 15000);
self.getVersion();
@ -24673,6 +24760,8 @@ window.ArangoUsers = Backbone.Collection.extend({
template: templateEngine.createTemplate("footerView.ejs"),
showServerStatus: function(isOnline) {
var self = this;
if (!window.App.isCluster) {
if (isOnline === true) {
$('#healthStatus').removeClass('negative');
@ -24687,6 +24776,55 @@ window.ArangoUsers = Backbone.Collection.extend({
$('.health-icon').html('<i class="fa fa-exclamation-circle"></i>');
}
}
else {
self.collection.fetch({
success: function() {
self.renderClusterState(true);
},
error: function() {
self.renderClusterState(false);
}
});
}
},
renderClusterState: function(connection) {
var ok = 0, error = 0;
if (connection) {
this.collection.each(function(value) {
if (value.toJSON().status === 'ok') {
ok++;
}
else {
error++;
}
});
if (error > 0) {
$('#healthStatus').removeClass('positive');
$('#healthStatus').addClass('negative');
if (error === 1) {
$('.health-state').html(error + ' NODE ERROR');
}
else {
$('.health-state').html(error + ' NODES ERROR');
}
$('.health-icon').html('<i class="fa fa-exclamation-circle"></i>');
}
else {
$('#healthStatus').removeClass('negative');
$('#healthStatus').addClass('positive');
$('.health-state').html('NODES OK');
$('.health-icon').html('<i class="fa fa-check-circle"></i>');
}
}
else {
$('#healthStatus').removeClass('positive');
$('#healthStatus').addClass('negative');
$('.health-state').html(window.location.host + ' OFFLINE');
$('.health-icon').html('<i class="fa fa-exclamation-circle"></i>');
}
},
showShortcutModal: function() {
@ -25159,7 +25297,10 @@ window.ArangoUsers = Backbone.Collection.extend({
}
var info = {
name: window.arangoHelper.escapeHtml($("#new-app-name").val()),
collectionNames: _.map($('#new-app-collections').select2("data"), function(d) {
documentCollections: _.map($('#new-app-document-collections').select2("data"), function(d) {
return window.arangoHelper.escapeHtml(d.text);
}),
edgeCollections: _.map($('#new-app-edge-collections').select2("data"), function(d) {
return window.arangoHelper.escapeHtml(d.text);
}),
// authenticated: window.arangoHelper.escapeHtml($("#new-app-name").val()),
@ -25209,7 +25350,13 @@ window.ArangoUsers = Backbone.Collection.extend({
undefined,
modalEvents
);
$("#new-app-collections").select2({
$("#new-app-document-collections").select2({
tags: [],
showSearchBox: false,
minimumResultsForSearch: -1,
width: "336px"
});
$("#new-app-edge-collections").select2({
tags: [],
showSearchBox: false,
minimumResultsForSearch: -1,
@ -25231,7 +25378,8 @@ window.ArangoUsers = Backbone.Collection.extend({
window.setTimeout(function() {
if ($('.select2-drop').is(':visible')) {
if (!$('#select2-search-field input').is(':focus')) {
$('#s2id_new-app-collections').select2('close');
$('#s2id_new-app-document-collections').select2('close');
$('#s2id_new-app-edge-collections').select2('close');
checkButton();
}
}
@ -26132,6 +26280,25 @@ window.ArangoUsers = Backbone.Collection.extend({
});
}());
/*jshint browser: true */
/*jshint unused: false */
/*global arangoHelper, Backbone, templateEngine, $, window*/
(function () {
"use strict";
window.HelpUsView = Backbone.View.extend({
el: "#content",
template: templateEngine.createTemplate("helpUsView.ejs"),
render: function () {
this.$el.html(this.template.render({}));
}
});
}());
/*jshint browser: true */
/*jshint unused: false */
/*global _, arangoHelper, Backbone, window, templateEngine, $ */
@ -27332,7 +27499,9 @@ window.ArangoUsers = Backbone.Collection.extend({
isCluster: this.isCluster
}));
$(this.subEl).html(this.templateSub.render({}));
$(this.subEl).html(this.templateSub.render({
currentDB: this.currentDB.toJSON()
}));
this.dbSelectionView.render($("#dbSelect"));
this.notificationView.render($("#notificationBar"));
@ -27369,10 +27538,15 @@ window.ArangoUsers = Backbone.Collection.extend({
},
navigateByTab: function (e) {
var tab = e.target || e.srcElement,
navigateTo = tab.id,
dropdown = false;
if ($(tab).hasClass('fa')) {
return;
}
if (navigateTo === "") {
navigateTo = $(tab).attr("class");
}
@ -27455,20 +27629,6 @@ window.ArangoUsers = Backbone.Collection.extend({
view: undefined,
}
],
node: [
{
name: 'Dashboard',
view: undefined,
active: true
},
{
name: 'Logs',
route: 'nodeLogs',
params: {
node: undefined
}
}
],
queries: [
{
name: 'Editor',
@ -27576,6 +27736,7 @@ window.ArangoUsers = Backbone.Collection.extend({
menuItem = menuItem.substr(1, menuItem.length - 1);
}
//Location for selecting MainView Primary Navigaation Entry
if (menuItem === '') {
if (window.App.isCluster) {
menuItem = 'cluster';
@ -27584,6 +27745,9 @@ window.ArangoUsers = Backbone.Collection.extend({
menuItem = 'dashboard';
}
}
else if (menuItem === 'cNodes' || menuItem === 'dNodes') {
menuItem = 'nodes';
}
try {
this.renderSubMenu(menuItem.split('-')[0]);
}
@ -27651,6 +27815,7 @@ window.ArangoUsers = Backbone.Collection.extend({
if (window.App.isCluster) {
this.coordinators = options.coordinators;
this.dbServers = options.dbServers;
this.coordname = options.coordname;
this.updateServerTime();
@ -27667,30 +27832,41 @@ window.ArangoUsers = Backbone.Collection.extend({
},
breadcrumb: function(name) {
console.log("yes");
$('#subNavigationBar .breadcrumb').html("Node: " + name);
},
render: function () {
console.log(1);
this.$el.html(this.template.render({coords: []}));
var callback = function() {
this.continueRender();
this.breadcrumb(this.coordname);
window.arangoHelper.buildNodeSubNav(this.coordname, 'Dashboard', 'Logs');
$(window).trigger('resize');
}.bind(this);
if (!this.initDone) {
this.waitForCoordinators(callback);
var cb =function() {
console.log("dummy");
};
if (!this.initCoordDone) {
this.waitForCoordinators(cb);
}
if (!this.initDBDone) {
this.waitForDBServers(callback);
}
else {
this.coordname = window.location.hash.split('/')[1];
this.coordinator = this.coordinators.findWhere({name: this.coordname});
callback();
}
},
continueRender: function() {
var self = this;
this.dashboards[this.coordinator.get('name')] = new window.DashboardView({
dygraphConfig: window.dygraphConfig,
database: window.App.arangoDatabase,
@ -27702,6 +27878,9 @@ window.ArangoUsers = Backbone.Collection.extend({
}
});
this.dashboards[this.coordinator.get('name')].render();
window.setTimeout(function() {
self.dashboards[self.coordinator.get('name')].resize();
}, 500);
},
waitForCoordinators: function(callback) {
@ -27713,7 +27892,30 @@ window.ArangoUsers = Backbone.Collection.extend({
}
else {
self.coordinator = self.coordinators.findWhere({name: self.coordname});
self.initDone = true;
self.initCoordDone = true;
callback();
}
}, 200);
},
waitForDBServers: function(callback) {
var self = this;
window.setTimeout(function() {
if (self.dbServers[0].length === 0) {
self.waitForDBServers(callback);
}
else {
self.initDBDone = true;
self.dbServer = self.dbServers[0];
self.dbServer.each(function(model) {
if (model.get("name") === 'DBServer1') {
self.dbServer = model;
}
});
console.log(self.dbServer.toJSON());
callback();
}
}, 200);
@ -27740,21 +27942,23 @@ window.ArangoUsers = Backbone.Collection.extend({
knownServers: [],
events: {
"click .pure-table-body .pure-table-row": "navigateToNode"
},
initialize: function (options) {
var self = this;
if (window.App.isCluster) {
this.dbServers = options.dbServers;
this.coordinators = options.coordinators;
this.updateServerTime();
this.toRender = options.toRender;
if (this.toRender !== 'coordinator') {
this.events["click .pure-table-body .pure-table-row"] = "navigateToNode";
}
//start polling with interval
window.setInterval(function() {
if (window.location.hash === '#nodes') {
if (window.location.hash === '#cNodes' || window.location.hash === '#dNodes') {
var callback = function(data) {
};
@ -27770,7 +27974,7 @@ window.ArangoUsers = Backbone.Collection.extend({
},
render: function () {
this.$el.html(this.template.render({coords: []}));
window.arangoHelper.buildNodesSubNav(this.toRender);
var callback = function() {
this.continueRender();
@ -27785,10 +27989,18 @@ window.ArangoUsers = Backbone.Collection.extend({
},
continueRender: function() {
var coords = this.coordinators.toJSON();
console.log(coords);
var coords;
if (this.toRender === 'coordinator') {
coords = this.coordinators.toJSON();
}
else {
coords = this.dbServers.toJSON();
}
this.$el.html(this.template.render({
coords: coords
coords: coords,
type: this.toRender
}));
},
@ -30266,10 +30478,11 @@ window.ArangoUsers = Backbone.Collection.extend({
this.bindParamAceEditor.getSession().setMode("ace/mode/json");
this.bindParamAceEditor.setFontSize("10pt");
this.bindParamAceEditor.getSession().on('change', function() {
this.bindParamAceEditor.getSession().on('change', function(a, b, c) {
try {
self.bindParamTableObj = JSON.parse(self.bindParamAceEditor.getValue());
self.allowParamToggle = true;
self.setCachedQuery(self.aqlEditor.getValue(), JSON.stringify(self.bindParamTableObj));
}
catch (e) {
self.allowParamToggle = false;
@ -34024,6 +34237,7 @@ window.ArangoUsers = Backbone.Collection.extend({
"query2": "query",
"workMonitor": "workMonitor",
"databases": "databases",
"settings": "databases",
"services": "applications",
"service/:mount": "applicationDetail",
"graphs": "graphManagement",
@ -34031,10 +34245,13 @@ window.ArangoUsers = Backbone.Collection.extend({
"users": "userManagement",
"userProfile": "userProfile",
"cluster": "cluster",
"nodes": "nodes",
"nodes": "cNodes",
"cNodes": "cNodes",
"dNodes": "dNodes",
"node/:name": "node",
//"nLogs/:name": "nLogs",
"logs": "logs",
"test": "test"
"helpus": "helpUs"
},
execute: function(callback, args) {
@ -34139,7 +34356,9 @@ window.ArangoUsers = Backbone.Collection.extend({
collection: this.arangoCollectionsStore
});
this.footerView = new window.FooterView();
this.footerView = new window.FooterView({
collection: self.coordinatorCollection
});
this.notificationList = new window.NotificationCollection();
this.currentDB.fetch({
@ -34224,19 +34443,16 @@ window.ArangoUsers = Backbone.Collection.extend({
this.nodeView = new window.NodeView({
coordname: name,
coordinators: this.coordinatorCollection,
dbServers: this.dbServers
});
}
this.nodeView.render();
},
nodeLogs: function (initialized) {
},
nodes: function (initialized) {
cNodes: function (initialized) {
this.checkUser();
if (!initialized || this.isCluster === undefined) {
this.waitForInit(this.nodes.bind(this));
this.waitForInit(this.cNodes.bind(this));
return;
}
if (this.isCluster === false) {
@ -34245,12 +34461,31 @@ window.ArangoUsers = Backbone.Collection.extend({
return;
}
if (!this.nodesView) {
this.nodesView = new window.NodesView({
coordinators: this.coordinatorCollection,
dbServers: this.dbServers
dbServers: this.dbServers[0],
toRender: 'coordinator'
});
this.nodesView.render();
},
dNodes: function (initialized) {
this.checkUser();
if (!initialized || this.isCluster === undefined) {
this.waitForInit(this.dNodes.bind(this));
return;
}
if (this.isCluster === false) {
this.routes[""] = 'dashboard';
this.navigate("#dashboard", {trigger: true});
return;
}
this.nodesView = new window.NodesView({
coordinators: this.coordinatorCollection,
dbServers: this.dbServers[0],
toRender: 'dbserver'
});
this.nodesView.render();
},
@ -34302,6 +34537,39 @@ window.ArangoUsers = Backbone.Collection.extend({
this.logsView.render();
},
/*
nLogs: function (nodename, initialized) {
this.checkUser();
if (!initialized) {
this.waitForInit(this.nLogs.bind(this), nodename);
return;
}
var newLogsAllCollection = new window.ArangoLogs(
{upto: true, loglevel: 4}
),
newLogsDebugCollection = new window.ArangoLogs(
{loglevel: 4}
),
newLogsInfoCollection = new window.ArangoLogs(
{loglevel: 3}
),
newLogsWarningCollection = new window.ArangoLogs(
{loglevel: 2}
),
newLogsErrorCollection = new window.ArangoLogs(
{loglevel: 1}
);
this.nLogsView = new window.LogsView({
logall: newLogsAllCollection,
logdebug: newLogsDebugCollection,
loginfo: newLogsInfoCollection,
logwarning: newLogsWarningCollection,
logerror: newLogsErrorCollection
});
this.nLogsView.render();
},
*/
applicationDetail: function (mount, initialized) {
this.checkUser();
if (!initialized) {
@ -34537,6 +34805,18 @@ window.ArangoUsers = Backbone.Collection.extend({
this.testView.render();
},
*/
helpUs: function (initialized) {
this.checkUser();
if (!initialized) {
this.waitForInit(this.helpUs.bind(this));
return;
}
if (!this.testView) {
this.helpUsView = new window.HelpUsView({
});
}
this.helpUsView.render();
},
workMonitor: function (initialized) {
this.checkUser();

File diff suppressed because one or more lines are too long

View File

@ -27,7 +27,7 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoError
////////////////////////////////////////////////////////////////////////////////
if(global.ArangoError){exports.ArangoError = global.ArangoError;delete global.ArangoError;}else {exports.ArangoError = function(error){if(error !== undefined){this.error = error.error;this.code = error.code;this.errorNum = error.errorNum;this.errorMessage = error.errorMessage;}};exports.ArangoError.prototype = new Error();}Object.defineProperty(exports.ArangoError.prototype,'message',{configurable:true,enumerable:true,get:function get(){return this.errorMessage;}});exports.ArangoError.prototype.name = 'ArangoError';exports.ArangoError.prototype._PRINT = function(context){context.output += '[' + this.toString() + ']';};exports.ArangoError.prototype.toString = function(){return this.name + ' ' + this.errorNum + ': ' + this.message;}; ////////////////////////////////////////////////////////////////////////////////
if(global.ArangoError){exports.ArangoError = global.ArangoError;delete global.ArangoError;}else {exports.ArangoError = function(error){if(error !== undefined){this.error = error.error;this.code = error.code;this.errorNum = error.errorNum;this.errorMessage = error.errorMessage;}};exports.ArangoError.prototype = new Error();}exports.ArangoError.prototype.isArangoError = true;Object.defineProperty(exports.ArangoError.prototype,'message',{configurable:true,enumerable:true,get:function get(){return this.errorMessage;}});exports.ArangoError.prototype.name = 'ArangoError';exports.ArangoError.prototype._PRINT = function(context){context.output += '[' + this.toString() + ']';};exports.ArangoError.prototype.toString = function(){return this.name + ' ' + this.errorNum + ': ' + this.message;}; ////////////////////////////////////////////////////////////////////////////////
/// @brief threadNumber
////////////////////////////////////////////////////////////////////////////////
exports.threadNumber = 0;if(global.THREAD_NUMBER){exports.threadNumber = global.THREAD_NUMBER;delete global.THREAD_NUMBER;} ////////////////////////////////////////////////////////////////////////////////
@ -1784,7 +1784,7 @@ ArangoStatement.prototype.execute = function(){throw "cannot call abstract metho
/// @author Dr. Frank Celler
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var internal=require("internal");var fs=require("fs");var mimetypes=require("@arangodb/mimetypes").mimeTypes; ////////////////////////////////////////////////////////////////////////////////
var internal=require("internal");var fs=require("fs"); ////////////////////////////////////////////////////////////////////////////////
/// @brief errors
////////////////////////////////////////////////////////////////////////////////
Object.keys(internal.errors).forEach(function(key){exports[key] = internal.errors[key].code;});exports.errors = internal.errors; ////////////////////////////////////////////////////////////////////////////////
@ -1794,12 +1794,6 @@ exports.ArangoError = internal.ArangoError; ////////////////////////////////////
/// @brief defines a module
////////////////////////////////////////////////////////////////////////////////
exports.defineModule = function(path,file){var content;var m;var mc;content = fs.read(file);mc = internal.db._collection("_modules");if(mc === null){mc = internal.db._create("_modules",{isSystem:true});}path = module.normalize(path);m = mc.firstExample({path:path});if(m === null){mc.save({path:path,content:content});}else {mc.replace(m,{path:path,content:content});}}; ////////////////////////////////////////////////////////////////////////////////
/// @brief guessContentType
////////////////////////////////////////////////////////////////////////////////
exports.guessContentType = function(filename,defaultValue){var re=/\.([a-zA-Z0-9]+)$/;var match=re.exec(filename);if(match !== null){var extension=match[1];if(mimetypes.hasOwnProperty(extension)){var type=mimetypes[extension];if(type[1]){ // append charset
return type[0] + "; charset=utf-8";}return type[0];} // fall-through intentional
} // default mimetype
if(defaultValue){return defaultValue;}return "text/plain; charset=utf-8";}; ////////////////////////////////////////////////////////////////////////////////
/// @brief normalizeURL
///
/// If @FA{path} starts with "." or "..", then it is a relative path.
@ -2817,7 +2811,7 @@ var arangodb=require("@arangodb");var ArangoError=arangodb.ArangoError; // forwa
var SimpleQueryArray;var SimpleQueryNear;var SimpleQueryWithin;var SimpleQueryWithinRectangle; ////////////////////////////////////////////////////////////////////////////////
/// @brief array query
////////////////////////////////////////////////////////////////////////////////
function GeneralArrayCursor(documents,skip,limit,data){this._documents = documents;this._countTotal = documents.length;this._skip = skip;this._limit = limit;this._cached = false;this._extra = {};var self=this;if(data !== null && data !== undefined && typeof data === 'object'){['stats','warnings','profile'].forEach(function(d){if(data.hasOwnProperty(d)){self._extra[d] = data[d];}});this._cached = data.cached || false;}this.execute();} ////////////////////////////////////////////////////////////////////////////////
function GeneralArrayCursor(documents,skip,limit,data){this._documents = documents;this._countTotal = documents.length;this._skip = skip;this._limit = limit;this._cached = false;this._extra = {};var self=this;if(data !== null && data !== undefined && typeof data === 'object'){['stats','warnings','profile'].forEach(function(d){if(data.hasOwnProperty(d)){self._extra[d] = data[d];}});this._cached = data.cached || false;}this.execute();}GeneralArrayCursor.prototype.isArangoResultSet = true; ////////////////////////////////////////////////////////////////////////////////
/// @brief executes an array query
////////////////////////////////////////////////////////////////////////////////
GeneralArrayCursor.prototype.execute = function(){if(this._skip === null){this._skip = 0;}var len=this._documents.length;var s=0;var e=len; // skip from the beginning
@ -2847,7 +2841,7 @@ GeneralArrayCursor.prototype.next = function(){if(this._current < this._stop){re
GeneralArrayCursor.prototype.dispose = function(){this._documents = null;this._skip = null;this._limit = null;this._countTotal = null;this._countQuery = null;this._current = null;this._stop = null;this._extra = null;}; ////////////////////////////////////////////////////////////////////////////////
/// @brief simple query
////////////////////////////////////////////////////////////////////////////////
function SimpleQuery(){this._execution = null;this._skip = 0;this._limit = null;this._countQuery = null;this._countTotal = null;this._batchSize = null;} ////////////////////////////////////////////////////////////////////////////////
function SimpleQuery(){this._execution = null;this._skip = 0;this._limit = null;this._countQuery = null;this._countTotal = null;this._batchSize = null;}SimpleQuery.prototype.isArangoResultSet = true; ////////////////////////////////////////////////////////////////////////////////
/// @brief join limits
////////////////////////////////////////////////////////////////////////////////
function joinLimits(query,limit){ // original limit is 0, keep it

View File

@ -1,7 +1,7 @@
/*eslint camelcase:0 */
/*jshint esnext:true, -W051:true */
/*eslint-disable */
global.DEFINE_MODULE('internal', (function() {
global.DEFINE_MODULE('internal', (function () {
'use strict';
/*eslint-enable */
@ -42,7 +42,7 @@ if (global.ArangoError) {
exports.ArangoError = global.ArangoError;
delete global.ArangoError;
} else {
exports.ArangoError = function(error) {
exports.ArangoError = function (error) {
if (error !== undefined) {
this.error = error.error;
this.code = error.code;
@ -54,6 +54,8 @@ if (global.ArangoError) {
exports.ArangoError.prototype = new Error();
}
exports.ArangoError.prototype.isArangoError = true;
Object.defineProperty(exports.ArangoError.prototype, 'message', {
configurable: true,
enumerable: true,
@ -335,7 +337,7 @@ if (global.SYS_GET_CURRENT_RESPONSE) {
/// @brief extend
////////////////////////////////////////////////////////////////////////////////
exports.extend = function(target, source) {
exports.extend = function (target, source) {
Object.getOwnPropertyNames(source)
.forEach(function(propName) {
@ -9563,12 +9565,8 @@ module.define("@arangodb/common", function(exports, module) {
////////////////////////////////////////////////////////////////////////////////
var internal = require("internal");
var fs = require("fs");
var mimetypes = require("@arangodb/mimetypes").mimeTypes;
////////////////////////////////////////////////////////////////////////////////
/// @brief errors
@ -9617,37 +9615,6 @@ exports.defineModule = function (path, file) {
}
};
////////////////////////////////////////////////////////////////////////////////
/// @brief guessContentType
////////////////////////////////////////////////////////////////////////////////
exports.guessContentType = function (filename, defaultValue) {
var re = /\.([a-zA-Z0-9]+)$/;
var match = re.exec(filename);
if (match !== null) {
var extension = match[1];
if (mimetypes.hasOwnProperty(extension)) {
var type = mimetypes[extension];
if (type[1]) {
// append charset
return type[0] + "; charset=utf-8";
}
return type[0];
}
// fall-through intentional
}
// default mimetype
if (defaultValue) {
return defaultValue;
}
return "text/plain; charset=utf-8";
};
////////////////////////////////////////////////////////////////////////////////
/// @brief normalizeURL
///
@ -15436,6 +15403,8 @@ function GeneralArrayCursor (documents, skip, limit, data) {
this.execute();
}
GeneralArrayCursor.prototype.isArangoResultSet = true;
////////////////////////////////////////////////////////////////////////////////
/// @brief executes an array query
@ -15586,6 +15555,8 @@ function SimpleQuery () {
this._batchSize = null;
}
SimpleQuery.prototype.isArangoResultSet = true;
////////////////////////////////////////////////////////////////////////////////
/// @brief join limits

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,3 @@
<script src="sharedLibs.js?version=1460720592272"></script>
<script src="libs.js?version=1460720592272"></script>
<script src="app.js?version=1460720592272"></script>
<script src="sharedLibs.js?version=1461089875197"></script>
<script src="libs.js?version=1461089875197"></script>
<script src="app.js?version=1461089875197"></script>

View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/html"><head><meta charset="utf-8"><title>ArangoDB Web Interface</title><meta name="description" content="ArangoDB Admin Web Interface"><meta name="author" content="Heiko Kernbach, Michael Hackstein"><link href="css/style.css" rel="stylesheet"><link href="css/sass.css" rel="stylesheet"><link rel="shortcut icon" type="image/x-icon" href="favicon.ico"><link href="https://fonts.googleapis.com/css?family=Lato:400,300,700" rel="stylesheet" type="text/css"><script id="applicationDetailView.ejs" type="text/template"><div class="application-detail-view">
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/html"><head><meta charset="utf-8"><title>ArangoDB Web Interface</title><meta name="description" content="ArangoDB Admin Web Interface"><meta name="author" content="Heiko Kernbach, Michael Hackstein"><link href="css/style.css" rel="stylesheet"><link href="css/sass.css" rel="stylesheet"><link rel="shortcut icon" type="image/x-icon" href="favicon.ico"><link href="https://fonts.googleapis.com/css?family=Roboto:400,300,500,700" rel="stylesheet" type="text/css"><script id="applicationDetailView.ejs" type="text/template"><div class="application-detail-view">
<div class="headerBar">
<div class="headerButtonBar">
<ul class="headerButtonList">
@ -687,9 +687,6 @@
</ul>
</div>
<div class="pull-left">
<a class="arangoHeader">Databases</a>
</div>
</div>
@ -740,9 +737,13 @@
<%});%>
</div>
</div></script><script id="dbSelectionView.ejs" type="text/template"><a href="#" class="tab" id="dbselection"><div class="dbselection"><i class="fa fa-database"></i><span class="db-name">DB: </span> <%=current%><i class="fa fa-caret-square-o-down"></i></div>
</div></script><script id="dbSelectionView.ejs" type="text/template"><a href="#" class="tab disabled" id="dbselection"><div class="dbselection"><i class="fa fa-database"></i><span class="db-name">DB: </span> <%=current%>
<!-- <i class="fa fa-caret-square-o-down"></i> -->
</div>
<!-- <b class="caret"></b> -->
</a>
<!--
<ul class="link-dropdown-menu" id="dbs_dropdown">
<%
if (list.length > 0) {
@ -769,7 +770,8 @@ if (list.length > 0) {
<a id="databases" class="tab" href="#databases">Manage Databases</a>
</li>
<% } %>
</ul></script><script id="documentView.ejs" type="text/template"><div id="transparentHeader" class="headerBar">
</ul>
--></script><script id="documentView.ejs" type="text/template"><div id="transparentHeader" class="headerBar">
</div>
@ -1206,7 +1208,8 @@ if (list.length > 0) {
<input id="<%=type %>_<%=id%>" type="text" name="<%=type %>_<%=id%>" placeholder="Attribute" maxlength="75" class="input-xlarge">
<button id="remove_<%=type %>_<%=id%>" class="graphViewer-icon-button gv_internal_remove_line gv-icon-small delete" />
</div>
</div></script><script id="indicesView.ejs" type="text/template"><div class="contentIn" id="indexHeaderContent">
</div></script><script id="helpUsView.ejs" type="text/template"><div class="helpUs">
<div class="_form_87"></div><script src="https://arangodb.activehosted.com/f/embed.php?id=87" type="text/javascript" charset="utf-8"></script><script id="indicesView.ejs" type="text/template"><div class="contentIn" id="indexHeaderContent">
<div id="indexEditView">
<table id="collectionEditIndexTable" class="edit-index-table">
<thead>
@ -1564,13 +1567,26 @@ if (list.length > 0) {
-->
<tr class="tableRow">
<th class="collectionInfoTh">
Collections:
Document Collections:
</th>
<th class="collectionInfoTh">
<input type="hidden" id="new-app-collections" value="" placeholder="Collections"></input>
<input type="hidden" id="new-app-document-collections" value="" placeholder="Document Collections"></input>
</th>
<th>
<a class="modalTooltips" title="A list of collections that will be created specifically for this Service. A CRUD API for these will be generated.">
<a class="modalTooltips" title="A list of document collections that will be created specifically for this Service. A CRUD API for these will be generated.">
<span class="arangoicon icon_arangodb_info"></span>
</a>
</th>
</tr>
<tr class="tableRow">
<th class="collectionInfoTh">
Edge Collections:
</th>
<th class="collectionInfoTh">
<input type="hidden" id="new-app-edge-collections" value="" placeholder="Edge Collections"></input>
</th>
<th>
<a class="modalTooltips" title="A list of edge collections that will be created specifically for this Service. A CRUD API for these will be generated.">
<span class="arangoicon icon_arangodb_info"></span>
</a>
</th>
@ -2265,14 +2281,19 @@ if (list.length > 0) {
<% } %>
</div></script><script id="navigationView.ejs" type="text/template"><ul class="navlist arango-collection-ul" id="arangoCollectionUl">
<% if (isCluster) { %>
<li class="navbar-spacer big"></li>
<li class="cluster-menu"><a id="cluster" class="tab" href="#cluster"><i class="fa fa-circle-o"></i>Cluster</a></li>
<li class="nodes-menu"><a id="nodes" class="tab" href="#nodes"><i class="fa fa-server"></i>Nodes</a></li>
<li class="nodes-menu"><a id="nodes" class="tab" href="#cNodes"><i class="fa fa-server"></i>Nodes</a></li>
<% } else { %>
<li class="navbar-spacer big"></li>
<li class="dashboard-menu"><a id="dashboard" class="tab" href="#dashboard"><i class="fa fa-dashboard"></i>Dashboard</a></li>
<% } %>
<li class="navbar-spacer big"></li>
<li id="dbSelect" class="dropdown databases-menu"></li>
<!-- <li id="dbSelect" class="dropdown databases-menu disabled"></li> -->
<li class="collections-menu"><a id="collections" class="tab" href="#collections"><i class="fa fa-folder"></i>Collections</a></li>
<% if (currentDB.get('isSystem')) { %>
<li class="databases-menu"><a id="databases" class="tab" href="#databases"><i class="fa fa-database"></i>Databases</a></li>
<% } %>
<li class="queries-menu"><a id="queries" class="tab" href="#queries"><i class="fa fa-bolt"></i>Queries</a></li>
<li class="graphs-menu"><a id="graphs" class="tab" href="#graphs"><i class="fa fa-area-chart"></i>Graphs</a></li>
<li class="services-menu">
@ -2280,10 +2301,15 @@ if (list.length > 0) {
</li>
<li class="users-menu"><a id="users" class="tab" href="#manage"><i class="fa fa-users"></i>Users</a></li>
<% if (!isCluster) { %>
<li class="logs-menu"><a id="logs" class="tab" href="#manage"><i class="fa fa-list"></i>Logs</a></li>
<li class="logs-menu"><a id="logs" class="tab" href="#manage"><i class="fa fa-file-text"></i>Logs</a></li>
<% } %>
<!--
<% if (currentDB.get('isSystem')) { %>
<li class="navbar-spacer big"></li>
<li class="settings-menu"><a id="settings" class="tab" href="#settings"><i class="fa fa-cog"></i>Settings</a></li>
<% } %>
-->
<li class="helpus-menu" style="position: absolute; bottom: 0;"><a id="helpus" class="tab" href="#helpus"><i class="fa fa-heart"></i>Help Us</a></li>
<!--
<li class="navbar-spacer big"></li>
<li class="dropdown tools-menu" id="toolsDropdown">
@ -2337,14 +2363,28 @@ if (list.length > 0) {
</div></script><script id="nodesView.ejs" type="text/template"><div id="nodesContent" class="innerContent">
<% if(coords.length > 0) { %>
<% if (coords.length > 0) { %>
<% var disabled = ''; %>
<% var genClass = "pure-u-1-" + Object.keys(coords[0]).length; %>
<% if (type !== 'coordinator') { %>
<% disabled = " disabled"; %>
<% } else { %>
<% disabled = " "; %>
<% } %>
<div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title">
<div class="pure-table-row">
<div class="pure-u-1-4 mid">Name</div>
<div class="pure-u-1-4 mid">Address</div>
<div class="pure-u-1-4 mid">Protocol</div>
<div class="pure-u-1-4 mid">Status</div>
<div class="<%= genClass %> mid">Name</div>
<div class="<%= genClass %> mid">Address</div>
<div class="<%= genClass %> mid">Protocol</div>
<% if(type !== 'coordinator' ) { %>
<div class="<%=genClass%> mid">Role</div>
<% } %>
<div class="<%=genClass%> mid">Status</div>
</div>
</div>
@ -2352,16 +2392,20 @@ if (list.length > 0) {
<% _.each(coords, function(node) { %>
<div class="pure-table-row" node="<%=node.name%>">
<div class="pure-table-row <%= disabled %>" node="<%=node.name%>">
<div class="pure-u-1-4 mid"><%= node.name %></div>
<div class="pure-u-1-4 mid"><%= node.address %></div>
<div class="pure-u-1-4 mid"><%= node.protocol %></div>
<div class="<%= genClass %> mid"><%= node.name %></div>
<div class="<%= genClass %> mid"><%= node.address %></div>
<div class="<%= genClass %> mid"><%= node.protocol %></div>
<% if(type !== 'coordinator' ) { %>
<div class="<%=genClass%> mid"><%= node.role %></div>
<% } %>
<% if(node.status === 'ok') { %>
<div class="pure-u-1-4 mid"><i class="fa fa-check-circle"></i></div>
<div class="<%= genClass %> mid"><i class="fa fa-check-circle"></i></div>
<% } else { %>
<div class="pure-u-1-4 mid"><i class="fa fa-exclamation-circle"></i></div>
<div class="<%= genClass %> mid"><i class="fa fa-exclamation-circle"></i></div>
<% } %>
</div>
@ -2662,13 +2706,16 @@ if (list.length > 0) {
<li class="subMenuEntry pull-left">
<div class="breadcrumb"></div>
</li>
<li id="healthStatus" class="subMenuEntry pull-right">
<a class="health-info">HEALTH: </a>
<a class="health-state">GOOD</a>
<a class="health-icon">
<li id="healthStatus" class="infoEntry subMenuEntry pull-right">
<a class="info health-info">HEALTH: </a>
<a class="state health-state">GOOD</a>
<a class="icon health-icon">
<i class="fa fa-check-circle"></i>
</a>
</li>
<li id="dbStatus" class="infoEntry subMenuEntry pull-right">
<a class="info">Database: <%= currentDB.name %> </a>
</li>
<li class="subMenuEntry pull-right" style="margin-right: 10px;">
<div class="usermenu" id="userBar"></div>
<div class="notificationmenu" id="notificationBar"></div>
@ -2884,4 +2931,4 @@ var cutByResolution = function (str) {
</div>
<div id="workMonitorContent" class="innerContent">
</div></script></head><body><nav class="navbar"><div class="primary"><div class="navlogo"><a class="logo big" href="#"><img class="arangodbLogo" src="img/arangodb_logo_big.png"></a> <a class="logo small" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="bodyWrapper"><div class="centralRow"><div id="navbar2" class="secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper" style="clear:both"><div id="content" class="centralContent"></div></div><div class="resizecontainer footerWrapper" style="clear:both"><footer class="footer"><div class="" id="footerBar"></div></footer></div></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js?version=1460720592272"></script><script src="libs.js?version=1460720592272"></script><script src="app.js?version=1460720592272"></script></body></html>
</div></script></head><body><nav class="navbar"><div class="primary"><div class="navlogo"><a class="logo big" href="#"><img class="arangodbLogo" src="img/arangodb_logo_big.png"></a> <a class="logo small" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="bodyWrapper"><div class="centralRow"><div id="navbar2" class="navbarWrapper secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper"><div id="content" class="centralContent"></div><footer class="footer"><div id="footerBar"></div></footer></div></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js?version=1461089875197"></script><script src="libs.js?version=1461089875197"></script><script src="app.js?version=1461089875197"></script></body></html>

View File

@ -10,7 +10,7 @@
<link href="css/style.css" rel="stylesheet">
<link href="css/sass.css" rel="stylesheet">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<link href='https://fonts.googleapis.com/css?family=Lato:400,300,700' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,300,500,700' rel='stylesheet' type='text/css'>
<script id="applicationDetailView.ejs" type="text/template">
<div class="application-detail-view">
@ -742,9 +742,6 @@
</ul>
</div>
<div class="pull-left">
<a class="arangoHeader">Databases</a>
</div>
</div>
@ -800,9 +797,13 @@
</script>
<script id="dbSelectionView.ejs" type="text/template">
<a href="#" class="tab" id="dbselection"><div class="dbselection"><i class="fa fa-database"></i><span class="db-name">DB: </span> <%=current%><i class="fa fa-caret-square-o-down"></i></div>
<a href="#" class="tab disabled" id="dbselection"><div class="dbselection"><i class="fa fa-database"></i><span class="db-name">DB: </span> <%=current%>
<!-- <i class="fa fa-caret-square-o-down"></i> -->
</div>
<!-- <b class="caret"></b> -->
</a>
<!--
<ul class="link-dropdown-menu" id="dbs_dropdown">
<%
if (list.length > 0) {
@ -830,6 +831,7 @@ if (list.length > 0) {
</li>
<% } %>
</ul>
-->
</script>
<script id="documentView.ejs" type="text/template">
@ -1312,6 +1314,14 @@ if (list.length > 0) {
</div>
</script>
<script id="helpUsView.ejs" type="text/template">
<div class="helpUs">
<div class="_form_87"></div><script src="https://arangodb.activehosted.com/f/embed.php?id=87" type="text/javascript" charset="utf-8"></script>
</div>
</script>
<script id="indicesView.ejs" type="text/template">
<div class="contentIn" id="indexHeaderContent">
<div id="indexEditView">
@ -1691,13 +1701,26 @@ if (list.length > 0) {
-->
<tr class="tableRow">
<th class="collectionInfoTh">
Collections:
Document Collections:
</th>
<th class="collectionInfoTh">
<input type="hidden" id="new-app-collections" value="" placeholder="Collections"></input>
<input type="hidden" id="new-app-document-collections" value="" placeholder="Document Collections"></input>
</th>
<th>
<a class="modalTooltips" title="A list of collections that will be created specifically for this Service. A CRUD API for these will be generated.">
<a class="modalTooltips" title="A list of document collections that will be created specifically for this Service. A CRUD API for these will be generated.">
<span class="arangoicon icon_arangodb_info"></span>
</a>
</th>
</tr>
<tr class="tableRow">
<th class="collectionInfoTh">
Edge Collections:
</th>
<th class="collectionInfoTh">
<input type="hidden" id="new-app-edge-collections" value="" placeholder="Edge Collections"></input>
</th>
<th>
<a class="modalTooltips" title="A list of edge collections that will be created specifically for this Service. A CRUD API for these will be generated.">
<span class="arangoicon icon_arangodb_info"></span>
</a>
</th>
@ -2432,14 +2455,19 @@ if (list.length > 0) {
<script id="navigationView.ejs" type="text/template">
<ul class="navlist arango-collection-ul" id="arangoCollectionUl">
<% if (isCluster) { %>
<li class="navbar-spacer big"></li>
<li class="cluster-menu"><a id="cluster" class="tab" href="#cluster"><i class="fa fa-circle-o"></i>Cluster</a></li>
<li class="nodes-menu"><a id="nodes" class="tab" href="#nodes"><i class="fa fa-server"></i>Nodes</a></li>
<li class="nodes-menu"><a id="nodes" class="tab" href="#cNodes"><i class="fa fa-server"></i>Nodes</a></li>
<% } else { %>
<li class="navbar-spacer big"></li>
<li class="dashboard-menu"><a id="dashboard" class="tab" href="#dashboard"><i class="fa fa-dashboard"></i>Dashboard</a></li>
<% } %>
<li class="navbar-spacer big"></li>
<li id="dbSelect" class="dropdown databases-menu"></li>
<!-- <li id="dbSelect" class="dropdown databases-menu disabled"></li> -->
<li class="collections-menu"><a id="collections" class="tab" href="#collections"><i class="fa fa-folder"></i>Collections</a></li>
<% if (currentDB.get('isSystem')) { %>
<li class="databases-menu"><a id="databases" class="tab" href="#databases"><i class="fa fa-database"></i>Databases</a></li>
<% } %>
<li class="queries-menu"><a id="queries" class="tab" href="#queries"><i class="fa fa-bolt"></i>Queries</a></li>
<li class="graphs-menu"><a id="graphs" class="tab" href="#graphs"><i class="fa fa-area-chart"></i>Graphs</a></li>
<li class="services-menu">
@ -2447,10 +2475,15 @@ if (list.length > 0) {
</li>
<li class="users-menu"><a id="users" class="tab" href="#manage"><i class="fa fa-users"></i>Users</a></li>
<% if (!isCluster) { %>
<li class="logs-menu"><a id="logs" class="tab" href="#manage"><i class="fa fa-list"></i>Logs</a></li>
<li class="logs-menu"><a id="logs" class="tab" href="#manage"><i class="fa fa-file-text"></i>Logs</a></li>
<% } %>
<!--
<% if (currentDB.get('isSystem')) { %>
<li class="navbar-spacer big"></li>
<li class="settings-menu"><a id="settings" class="tab" href="#settings"><i class="fa fa-cog"></i>Settings</a></li>
<% } %>
-->
<li class="helpus-menu" style="position: absolute; bottom: 0;"><a id="helpus" class="tab" href="#helpus"><i class="fa fa-heart"></i>Help Us</a></li>
<!--
<li class="navbar-spacer big"></li>
<li class="dropdown tools-menu" id="toolsDropdown">
@ -2516,14 +2549,28 @@ if (list.length > 0) {
<div id="nodesContent" class="innerContent">
<% if(coords.length > 0) { %>
<% if (coords.length > 0) { %>
<% var disabled = ''; %>
<% var genClass = "pure-u-1-" + Object.keys(coords[0]).length; %>
<% if (type !== 'coordinator') { %>
<% disabled = " disabled"; %>
<% } else { %>
<% disabled = " "; %>
<% } %>
<div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title">
<div class="pure-table-row">
<div class="pure-u-1-4 mid">Name</div>
<div class="pure-u-1-4 mid">Address</div>
<div class="pure-u-1-4 mid">Protocol</div>
<div class="pure-u-1-4 mid">Status</div>
<div class="<%= genClass %> mid">Name</div>
<div class="<%= genClass %> mid">Address</div>
<div class="<%= genClass %> mid">Protocol</div>
<% if(type !== 'coordinator' ) { %>
<div class="<%=genClass%> mid">Role</div>
<% } %>
<div class="<%=genClass%> mid">Status</div>
</div>
</div>
@ -2531,16 +2578,20 @@ if (list.length > 0) {
<% _.each(coords, function(node) { %>
<div class="pure-table-row" node="<%=node.name%>">
<div class="pure-table-row <%= disabled %>" node="<%=node.name%>">
<div class="pure-u-1-4 mid"><%= node.name %></div>
<div class="pure-u-1-4 mid"><%= node.address %></div>
<div class="pure-u-1-4 mid"><%= node.protocol %></div>
<div class="<%= genClass %> mid"><%= node.name %></div>
<div class="<%= genClass %> mid"><%= node.address %></div>
<div class="<%= genClass %> mid"><%= node.protocol %></div>
<% if(type !== 'coordinator' ) { %>
<div class="<%=genClass%> mid"><%= node.role %></div>
<% } %>
<% if(node.status === 'ok') { %>
<div class="pure-u-1-4 mid"><i class="fa fa-check-circle"></i></div>
<div class="<%= genClass %> mid"><i class="fa fa-check-circle"></i></div>
<% } else { %>
<div class="pure-u-1-4 mid"><i class="fa fa-exclamation-circle"></i></div>
<div class="<%= genClass %> mid"><i class="fa fa-exclamation-circle"></i></div>
<% } %>
</div>
@ -2897,13 +2948,16 @@ if (list.length > 0) {
<li class="subMenuEntry pull-left">
<div class="breadcrumb"></div>
</li>
<li id="healthStatus" class="subMenuEntry pull-right">
<a class="health-info">HEALTH: </a>
<a class="health-state">GOOD</a>
<a class="health-icon">
<li id="healthStatus" class="infoEntry subMenuEntry pull-right">
<a class="info health-info">HEALTH: </a>
<a class="state health-state">GOOD</a>
<a class="icon health-icon">
<i class="fa fa-check-circle"></i>
</a>
</li>
<li id="dbStatus" class="infoEntry subMenuEntry pull-right">
<a class="info">Database: <%= currentDB.name %> </a>
</li>
<li class="subMenuEntry pull-right" style="margin-right: 10px;">
<div class="usermenu" id="userBar"></div>
<div class="notificationmenu" id="notificationBar"></div>
@ -3167,18 +3221,19 @@ var cutByResolution = function (str) {
<div class="bodyWrapper">
<div class="centralRow">
<div id='navbar2' class="secondary">
<div id='navbar2' class="navbarWrapper secondary">
<div class="subnavmenu" id="subNavigationBar"></div>
</div>
<div class="resizecontainer contentWrapper" style="clear:both;">
<div class="resizecontainer contentWrapper">
<div id="content" class="centralContent"></div>
</div>
<div class="resizecontainer footerWrapper" style="clear:both;">
<footer class="footer">
<div class="" id="footerBar">
</div>
<div id="footerBar"></div>
</footer>
</div>
</div>
</div>
@ -3202,9 +3257,9 @@ var cutByResolution = function (str) {
</div>
</div>
<script src="sharedLibs.js?version=1460720592272"></script>
<script src="libs.js?version=1460720592272"></script>
<script src="app.js?version=1460720592272"></script>
<script src="sharedLibs.js?version=1461089875197"></script>
<script src="libs.js?version=1461089875197"></script>
<script src="app.js?version=1461089875197"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,7 @@ body {
background: rgba(64, 74, 83, 0.04);
color: #333;
display: block;
font-family: 'Lato', sans-serif !important;
font-family: 'Roboto', sans-serif !important;
font-size: 14px;
font-weight: 400;
height: 100%;
@ -15,15 +15,19 @@ body {
overflow: hidden; }
body .bodyWrapper {
height: 100%;
margin: 0 auto -42px;
min-height: 100%; }
left: 150px;
min-height: 100%;
position: absolute;
right: 0; }
body .centralRow {
position: relative; }
body,
input,
textarea,
.page-title span,
.pingback a.url {
font-family: 'Lato', sans-serif !important;
font-family: 'Roboto', sans-serif !important;
font-weight: 400; }
@font-face {
@ -2085,7 +2089,7 @@ textarea,
.user-dropdown-menu, .script-dropdown-menu, .gv-dropdown-menu, .navlogo, .navlist li, div.footer-left, div.footer-left p, div.footer-center, a.headerButton, a.button-gui, div .tile, div .bigtile, div .tile a span.add-Icon, div .bigtile a span.add-Icon, div.centralContent, .contentDiv li, div.dropdownInner ul, .fixedDropdown .notificationItemContent, .innerDropdownInnerUL, .dashboard-full-width-chart .dashboard-full-width-chart-inner, .dashboard-large-chart .dashboard-large-chart-inner, .dashboard-small-chart .dashboard-small-chart-inner, .dashboard-medium-chart, .dashboard-tendency-container, .dashboard-bar-chart-container, .dashboard-full-width-chart, .dashboard-large-chart, .dashboard-small-chart, .dashboard-sub-bar, .dashboard-sub-bar .dashboard-sub-bar-title, .dashboard-full-width-chart .dashboard-full-width-chart-inner .dashboard-interior-chart, .dashboard-large-chart .dashboard-large-chart-inner .dashboard-interior-chart, .dashboard-small-chart .dashboard-small-chart-inner .dashboard-interior-chart, .dashboard-medium-chart .dashboard-interior-chart, .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency, .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-subtitle-bar, .dashboard-tendency-container .dashboard-tendency-chart .dashboard-tendency .dashboard-figure, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .percentage, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-title .absolut, .dashboard-bar-chart-container .dashboard-bar-chart .dashboard-bar-chart-chart, .modal-chart-detail, .modal-chart-detail .modal-body, .modal-chart-detail .modal-dashboard-legend, .modal-chart-detail .modal-inner-detail, .dashboard-half-height-legend, .dashboard-title-bar .dashboard-half-title-bar, .dashboardModal, .pagination-line li a {
float: left; }
div.footer-right, div.footer-right p, ul.headerButtonList li, div .tile .iconSet span, div .bigtile .iconSet span, .search-field, .headerBar > div.headerButtonBar, .fixedDropdown button, .fixedDropdown .notificationItem i, .dashboard-sub-bar-menu, .dashboard-legend, .dashboard-legend .dashboard-legend-inner span, .query-button, .arango-tab li, div.gv_colour_list, .docsThirdCol {
div.footer-right, div.footer-right p, ul.headerButtonList li, div .tile .iconSet span, div .bigtile .iconSet span, .search-field, .headerBar > div.headerButtonBar, .fixedDropdown button, .fixedDropdown .notificationItem i, .dashboard-sub-bar-menu, .dashboard-legend, .query-button, .arango-tab li, div.gv_colour_list, .docsThirdCol {
float: right; }
.tileList:after, .resizecontainer:after, .headerBar > div.headerButtonBar:after, .detail-chart:after, .dashboard-sub-bar:after, .dashboard-medium-chart .dashboard-medium-chart-menu:after, .dashboard-medium-chart .dashboard-medium-chart-inner:after, .dashboard-tendency-container .dashboard-tendency-chart:after, .dashboard-bar-chart-container .dashboard-bar-chart:after, .dashboard-row:after, #distributionChartDiv:after, .lineChartDiv:after, .arango-tab:after, .pagination-line li:after, .document-info .document-info-container .document-inner-info-container .document-attribute:after {
@ -2096,10 +2100,11 @@ div.footer-right, div.footer-right p, ul.headerButtonList li, div .tile .iconSet
height: 0;
visibility: hidden; }
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton i, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .fixedDropdown .notificationItem i, .fullNotification:hover, .contentTables tr.contentRowInactive a, .arango-tab a, .arango-tab li, .pagination-line li a, .link > line, .node, .edit-index-table .icon_arangodb_roundminus {
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton i, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .fixedDropdown .notificationItem i, .fullNotification:hover, .contentTables tr.contentRowInactive a, .arango-tab a, .arango-tab li, .pagination-line li a, .link > line, .node, .edit-index-table .icon_arangodb_roundminus {
cursor: pointer; }
.navbar, footer.footer {
.navbar {
color: #fff;
left: 0;
right: 0;
@ -2334,6 +2339,14 @@ div.queryline input, input.search-input, .modal-body .select2-choices input, .mo
padding-right: 15px;
text-align: center;
width: 10px; }
.navlist li .fa.fa-heart {
color: #ff7a7a;
opacity: 1; }
.navlist li.disabled:hover {
cursor: default; }
.navlist li.disabled:hover a:hover {
cursor: default;
opacity: .8; }
.navlist li.dropdown:hover {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
@ -2344,8 +2357,8 @@ div.queryline input, input.search-input, .modal-body .select2-choices input, .mo
.navlist li.navbar-spacer {
background-color: #fff;
height: 1px;
margin-bottom: 5px;
margin-top: 5px;
margin-bottom: 0;
margin-top: 0;
opacity: .2; }
.navlist .active {
border-left: 2px solid #77cb99; }
@ -2471,21 +2484,18 @@ div.queryline input, input.search-input, .modal-body .select2-choices input, .mo
.arango-logo img {
margin-left: 22px; }
.footerWrapper {
bottom: 0;
height: 42px;
position: absolute; }
.footer {
background-color: rgba(239, 240, 241, 0.8);
font-size: 14px;
left: 0;
right: 0;
left: 160px;
right: 10px;
text-align: center;
z-index: 1000; }
footer.footer {
bottom: 0;
height: 40px; }
height: 43px;
position: fixed; }
footer.footer p {
font-size: 10pt;
font-weight: 100;
@ -2611,7 +2621,7 @@ button.disabled,
margin-left: 0 !important; }
button {
font-family: 'Lato', sans-serif !important; }
font-family: 'Roboto', sans-serif !important; }
button.btn-server {
width: 120px; }
button.gv-zoom-btn {
@ -5201,25 +5211,32 @@ div .bigtile {
.application-detail-view section.info {
width: 2290px; } }
div.contentWrapper {
padding-bottom: 42px; }
div.headerBar {
background-color: none;
border-radius: 2px;
float: right;
font-size: 16px;
height: 36px;
margin-top: -55px;
position: absolute;
right: 150px; }
div.centralRow {
background: rgba(64, 74, 83, 0.04);
float: left;
height: 100%;
left: 150px;
min-height: 100%;
overflow-y: auto;
position: absolute;
position: relative;
right: 0; }
div.centralContent {
background-color: transparent;
box-sizing: border-box;
margin-top: 10px;
min-height: 80px;
padding: 5px;
padding-bottom: 43px;
padding-left: 5px;
padding-right: 5px;
padding-top: 5px;
width: 100%; }
.contentDiv {
@ -5274,7 +5291,8 @@ li a [class*=" icon_arangodb"] {
.fa-minus-circle:hover {
cursor: pointer; }
div.headerDropdown {
div.headerDropdown,
.dropdownImport {
background-color: #fff;
border: 1px solid rgba(140, 138, 137, 0.25);
border-radius: 2px;
@ -5283,11 +5301,14 @@ div.headerDropdown {
padding: 10px;
position: relative;
width: auto; }
div.headerDropdown.smallDropdown .dropdownInner {
div.headerDropdown.smallDropdown .dropdownInner,
.dropdownImport.smallDropdown .dropdownInner {
min-height: 20px; }
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox {
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox {
display: none; }
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label {
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox label.css-label {
background-position: 0 0;
background-repeat: no-repeat;
display: inline-block;
@ -5296,7 +5317,8 @@ div.headerDropdown {
margin-top: 0;
padding-left: 20px;
vertical-align: middle; }
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked + label.css-label {
div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox:checked + label.css-label,
.dropdownImport.headerDropdown input[type=checkbox].css-checkbox:checked + label.css-label {
background-position: 0 -15px; }
div.dropdown-title {
@ -5476,7 +5498,8 @@ div.headerBar {
height: 36px;
margin-top: -55px;
padding-left: 5px;
padding-right: 5px; }
padding-right: 5px;
right: 0; }
div.headerBar select:focus {
outline: none; }
div.headerBar .infoField {
@ -5552,7 +5575,8 @@ div.headerBar {
padding-bottom: 0;
padding-left: 10px;
padding-right: 0;
padding-top: 0; }
padding-top: 0;
text-transform: capitalize; }
.breadcrumb .fa {
margin-left: 10px;
margin-right: 8px; }
@ -5656,7 +5680,7 @@ div.headerBar {
.modal-body {
color: #736b68;
font-family: 'Lato', sans-serif !important;
font-family: 'Roboto', sans-serif !important;
font-size: 14px;
font-weight: 300;
max-height: 410px; }
@ -6115,7 +6139,7 @@ div.headerBar {
border-radius: 3px !important;
box-shadow: none !important;
color: #fff !important;
font-family: 'Lato',sans-serif !important;
font-family: 'Roboto', sans-serif !important;
font-size: 10pt !important;
font-weight: 100 !important;
z-index: 99999999; }
@ -6225,7 +6249,7 @@ div.headerBar {
.dataNotReadyYet {
color: #faa732;
font-family: 'Lato', sans-serif;
font-family: 'Roboto', sans-serif;
font-size: 14px;
font-weight: 100;
text-align: center; }
@ -6236,7 +6260,7 @@ div.headerBar {
border-bottom-right-radius: 3px;
box-sizing: border-box;
color: rgba(0, 0, 0, 0.5);
font-family: Lato,sans-serif;
font-family: 'Roboto', sans-serif;
font-size: 11pt;
font-weight: 600;
height: 50px;
@ -6250,7 +6274,7 @@ div.headerBar {
text-transform: uppercase; }
.dashboard-sub-bar .dashboard-sub-bar-title {
color: #000;
font-family: Lato,sans-serif;
font-family: 'Roboto', sans-serif;
font-size: 11pt;
font-weight: 600;
opacity: .5;
@ -6426,7 +6450,8 @@ div.headerBar {
stroke-width: .5px; }
.dashboard-legend .dashboard-legend-inner {
padding: 0 5px 5px 0; }
padding: 0 5px 5px 0;
text-align: right; }
.dashboard-legend .dashboard-legend-inner br {
display: none; }
.dashboard-legend .dashboard-legend-inner span {
@ -6523,7 +6548,7 @@ div.headerBar {
.dygraph-label.dygraph-title {
color: #000;
font-family: 'Lato', sans-serif;
font-family: 'Roboto', sans-serif;
font-size: 15px;
font-weight: 400;
text-align: left; }
@ -6949,7 +6974,7 @@ toolbar {
.inputEditorWrapper .bindParamEditorWrapper table,
.inputEditorWrapper .aqlEditorWrapper table {
border-top: 0;
font-family: 'Lato', sans-serif; }
font-family: 'Roboto', sans-serif; }
.inputEditorWrapper .bindParamEditorWrapper table tbody,
.inputEditorWrapper .aqlEditorWrapper table tbody {
display: block;
@ -7043,7 +7068,7 @@ toolbar {
cursor: pointer;
font-size: 13pt;
height: 23px;
line-height: 22px;
line-height: 23px;
opacity: .8;
position: absolute;
right: 5px;
@ -7275,8 +7300,8 @@ toolbar {
.pagination-line {
background-color: #fff;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
border-top: 1px solid rgba(104, 103, 102, 0.1);
margin: 20px 0;
margin-bottom: 0;
@ -7285,7 +7310,7 @@ toolbar {
text-align: center; }
.pagination-line li a:hover, .pagination-line li.active a,
.pagination-line li.active span {
background-color: #8f8d8c;
background-color: #404a53;
color: #fff; }
.pagination-line li a {
background-color: #fff;
@ -7296,9 +7321,9 @@ toolbar {
padding: 2px 10px;
text-decoration: none; }
.pagination-line ul {
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
display: inline-block;
margin-bottom: 0;
margin-left: 0; }
@ -7319,9 +7344,9 @@ toolbar {
-webkit-box-shadow: 0;
-moz-box-shadow: 0;
box-shadow: 0;
background: #8f8d8c;
background: #404a53;
border: 0;
color: #000;
color: #fff;
height: 21px;
position: relative;
width: 14px; }
@ -7578,15 +7603,17 @@ textarea,
.dataTables_info {
display: none; }
#arangoLogTable tbody td:nth-child(1) {
#arangoLogTable {
min-height: 444px; }
#arangoLogTable tbody tr {
height: 40px; }
#arangoLogTable tbody td:nth-child(1) {
text-align: center;
width: 80px; }
#arangoLogTable tbody td:nth-child(2) {
width: 70px; }
#arangoLogTable tbody td:nth-child(2) {
text-align: center;
width: 80px; }
#arangoLogTable tbody td:nth-child(3) {
width: 150px; }
#arangoLogTable tbody td:nth-child(3) {
width: auto; }
div.gv_zoom_widget {
@ -7705,7 +7732,7 @@ input.gv-radio-button {
width: auto; }
.collectionTh {
font-family: 'Lato Sans', sans-serif !important;
font-family: 'Roboto', sans-serif !important;
font-size: 14px;
font-weight: 400 !important;
text-align: left;
@ -7901,7 +7928,8 @@ input.gv-radio-button {
padding-right: 20px; }
.headerButtonBar {
display: none; }
div.centralRow {
div.bodyWrapper,
.footer {
left: 40px; } }
@media (min-width: 569px) and (max-width: 738px) {
@ -8120,7 +8148,12 @@ input.gv-radio-button {
background: #3d4246;
border-radius: 3px;
color: #fff;
height: 300px;
overflow: auto;
width: 100%; }
.spotlightWrapper .tt-menu .tt-suggestion:hover {
background-color: #404a53;
cursor: pointer; }
.spotlightWrapper .tt-menu .header-type {
background: #32373b;
clear: both;
@ -8168,7 +8201,7 @@ input.gv-radio-button {
outline-style: none; }
.graphLabel {
font-family: "Lato", sans-serif;
font-family: "Roboto", sans-serif;
font-size: 11pt;
font-weight: 600;
margin-top: -25px;
@ -8180,9 +8213,15 @@ input.gv-radio-button {
.cluster-graphs > div .graphWrapper {
border: 1px solid rgba(140, 138, 137, 0.25);
margin-left: -1px;
margin-top: -1px; }
margin-top: -1px;
padding-bottom: 10px;
padding-left: 20px;
padding-right: 20px;
padding-top: 20px; }
.cluster-graphs > div .graphWrapper .nv-controlsWrap {
display: none; }
.cluster-graphs > div .graphWrapper .nv-legendWrap {
margin-bottom: 10px; }
.cluster-graphs > div .graphWrapper svg {
height: 250px;
margin-left: -17px; }
@ -8194,10 +8233,14 @@ input.gv-radio-button {
margin-left: -1px;
margin-top: -1px; }
.cluster-values > div .valueWrapper .value {
color: #7dbc42;
color: #000;
font-size: 24pt;
line-height: 150px;
text-align: center; }
.cluster-values > div .valueWrapper .value.positive {
color: #7dbc42; }
.cluster-values > div .valueWrapper .value.negative {
color: #da4f49; }
.cluster-values > div .valueWrapper div:first-child {
height: 150px; }
@ -8302,8 +8345,7 @@ input.gv-radio-button {
main {
background-color: #fff;
border: 1px solid rgba(140, 138, 137, 0.25);
border-radius: 3px;
margin-top: 220px; }
border-radius: 3px; }
main .app-info {
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
@ -8408,10 +8450,14 @@ main {
border-bottom: 1px solid rgba(140, 138, 137, 0.25);
color: #8a969f;
font-weight: 100;
line-height: 40px; }
line-height: 40px;
width: 100%; }
.pure-table .pure-table-row:hover {
background-color: #eff0eb;
cursor: pointer; }
.pure-table .pure-table-row.disabled:hover {
background-color: #fff;
cursor: not-allowed; }
.pure-table .pure-table-row .left {
text-align: left; }
.pure-table .pure-table-row .right {
@ -8474,10 +8520,10 @@ main {
height: 27px;
width: 100%; }
.arango-tabbar button {
background-color: #8c8a89;
background-color: #404a53;
border: 0;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
color: #fff;
float: right;
font-weight: 100;
@ -8540,21 +8586,26 @@ main {
-o-transition: all .2s ease-in;
-webkit-transition: all .2s ease-in;
transition: all .2s ease-in; }
.subnavmenu #healthStatus.positive .health-state,
.subnavmenu #healthStatus.positive .health-icon {
.subnavmenu .infoEntry {
line-height: 45px; }
.subnavmenu .infoEntry:hover {
cursor: default; }
.subnavmenu .infoEntry:hover .info {
color: #fff; }
.subnavmenu .infoEntry.positive .health-state,
.subnavmenu .infoEntry.positive .health-icon {
color: #7dbc42; }
.subnavmenu #healthStatus.negative .health-state,
.subnavmenu #healthStatus.negative .health-icon {
.subnavmenu .infoEntry.negative .health-state,
.subnavmenu .infoEntry.negative .health-icon {
color: #da4f49; }
.subnavmenu .health-info,
.subnavmenu .db-info,
.subnavmenu .db-state,
.subnavmenu .health-state {
font-weight: 300; }
.subnavmenu .health-info,
.subnavmenu .db-info,
.subnavmenu .db-icon {
color: rgba(255, 255, 255, 0.95); }
.subnavmenu .info,
.subnavmenu .icon,
.subnavmenu .state {
color: rgba(255, 255, 255, 0.95);
font-weight: 300;
text-transform: uppercase; }
.subnavmenu #dbStatus {
padding-right: 20px; }
.arangoDataTable {
border-spacing: 0 0;
@ -8743,7 +8794,7 @@ table .sorting {
.documentsDropdown .dropdownImport,
.documentsDropdown .headerDropdown {
clear: both;
margin-bottom: 5px; }
margin-bottom: 10px; }
.documents-size {
background-color: #fff !important;

View File

@ -228,21 +228,64 @@
var cssClass;
_.each(menuItems, function(menu, name) {
cssClass = '';
if (menu.active) {
cssClass += ' active';
}
else {
cssClass = '';
if (menu.disabled) {
cssClass += ' disabled';
}
$('#subNavigationBar .bottom').append(
'<li class="subMenuEntry ' + cssClass + '"><a>' + name + '</a></li>'
);
if (!menu.disabled) {
$('#subNavigationBar .bottom').children().last().bind('click', function() {
window.App.navigate(menu.route, {trigger: true});
});
}
});
},
buildNodeSubNav: function(node, activeKey, disabled) {
var menus = {
Dashboard: {
route: '#node/' + encodeURIComponent(node)
},
Logs: {
route: '#nLogs/' + encodeURIComponent(node),
disabled: true
}
};
menus[activeKey].active = true;
menus[disabled].disabled = true;
this.buildSubNavBar(menus);
},
//nav for collection view
buildNodesSubNav: function(type) {
var menus = {
Coordinators: {
route: '#cNodes'
},
DBServers: {
route: '#dNodes'
}
};
if (type === 'coordinator') {
menus.Coordinators.active = true;
}
else {
menus.DBServers.active = true;
}
this.buildSubNavBar(menus);
},
//nav for collection view
buildCollectionSubNav: function(collectionName, activeKey) {

View File

@ -35,8 +35,11 @@
"users": "userManagement",
"userProfile": "userProfile",
"cluster": "cluster",
"nodes": "nodes",
"nodes": "cNodes",
"cNodes": "cNodes",
"dNodes": "dNodes",
"node/:name": "node",
//"nLogs/:name": "nLogs",
"logs": "logs",
"helpus": "helpUs"
},
@ -230,19 +233,16 @@
this.nodeView = new window.NodeView({
coordname: name,
coordinators: this.coordinatorCollection,
dbServers: this.dbServers
});
}
this.nodeView.render();
},
nodeLogs: function (initialized) {
},
nodes: function (initialized) {
cNodes: function (initialized) {
this.checkUser();
if (!initialized || this.isCluster === undefined) {
this.waitForInit(this.nodes.bind(this));
this.waitForInit(this.cNodes.bind(this));
return;
}
if (this.isCluster === false) {
@ -251,12 +251,31 @@
return;
}
if (!this.nodesView) {
this.nodesView = new window.NodesView({
coordinators: this.coordinatorCollection,
dbServers: this.dbServers
dbServers: this.dbServers[0],
toRender: 'coordinator'
});
this.nodesView.render();
},
dNodes: function (initialized) {
this.checkUser();
if (!initialized || this.isCluster === undefined) {
this.waitForInit(this.dNodes.bind(this));
return;
}
if (this.isCluster === false) {
this.routes[""] = 'dashboard';
this.navigate("#dashboard", {trigger: true});
return;
}
this.nodesView = new window.NodesView({
coordinators: this.coordinatorCollection,
dbServers: this.dbServers[0],
toRender: 'dbserver'
});
this.nodesView.render();
},
@ -308,6 +327,39 @@
this.logsView.render();
},
/*
nLogs: function (nodename, initialized) {
this.checkUser();
if (!initialized) {
this.waitForInit(this.nLogs.bind(this), nodename);
return;
}
var newLogsAllCollection = new window.ArangoLogs(
{upto: true, loglevel: 4}
),
newLogsDebugCollection = new window.ArangoLogs(
{loglevel: 4}
),
newLogsInfoCollection = new window.ArangoLogs(
{loglevel: 3}
),
newLogsWarningCollection = new window.ArangoLogs(
{loglevel: 2}
),
newLogsErrorCollection = new window.ArangoLogs(
{loglevel: 1}
);
this.nLogsView = new window.LogsView({
logall: newLogsAllCollection,
logdebug: newLogsDebugCollection,
loginfo: newLogsInfoCollection,
logwarning: newLogsWarningCollection,
logerror: newLogsErrorCollection
});
this.nLogsView.render();
},
*/
applicationDetail: function (mount, initialized) {
this.checkUser();
if (!initialized) {

View File

@ -3,13 +3,17 @@
<% if (isCluster) { %>
<li class="navbar-spacer big"></li>
<li class="cluster-menu"><a id="cluster" class="tab" href="#cluster"><i class="fa fa-circle-o"></i>Cluster</a></li>
<li class="nodes-menu"><a id="nodes" class="tab" href="#nodes"><i class="fa fa-server"></i>Nodes</a></li>
<li class="nodes-menu"><a id="nodes" class="tab" href="#cNodes"><i class="fa fa-server"></i>Nodes</a></li>
<% } else { %>
<li class="navbar-spacer big"></li>
<li class="dashboard-menu"><a id="dashboard" class="tab" href="#dashboard"><i class="fa fa-dashboard"></i>Dashboard</a></li>
<% } %>
<li class="navbar-spacer big"></li>
<!-- <li id="dbSelect" class="dropdown databases-menu disabled"></li> -->
<li class="collections-menu"><a id="collections" class="tab" href="#collections"><i class="fa fa-folder"></i>Collections</a></li>
<% if (currentDB.get('isSystem')) { %>
<li class="databases-menu"><a id="databases" class="tab" href="#databases"><i class="fa fa-database"></i>Databases</a></li>
<% } %>
<li class="queries-menu"><a id="queries" class="tab" href="#queries"><i class="fa fa-bolt"></i>Queries</a></li>
<li class="graphs-menu"><a id="graphs" class="tab" href="#graphs"><i class="fa fa-area-chart"></i>Graphs</a></li>
<li class="services-menu">
@ -19,10 +23,12 @@
<% if (!isCluster) { %>
<li class="logs-menu"><a id="logs" class="tab" href="#manage"><i class="fa fa-file-text"></i>Logs</a></li>
<% } %>
<!--
<% if (currentDB.get('isSystem')) { %>
<li class="navbar-spacer big"></li>
<li class="settings-menu"><a id="settings" class="tab" href="#settings"><i class="fa fa-cog"></i>Settings</a></li>
<% } %>
-->
<li class="helpus-menu" style="position: absolute; bottom: 0;"><a id="helpus" class="tab" href="#helpus"><i class="fa fa-heart"></i>Help Us</a></li>
<!--
<li class="navbar-spacer big"></li>

View File

@ -2,14 +2,28 @@
<div id="nodesContent" class="innerContent">
<% if(coords.length > 0) { %>
<% if (coords.length > 0) { %>
<% var disabled = ''; %>
<% var genClass = "pure-u-1-" + Object.keys(coords[0]).length; %>
<% if (type !== 'coordinator') { %>
<% disabled = " disabled"; %>
<% } else { %>
<% disabled = " "; %>
<% } %>
<div class="pure-g cluster-nodes-title pure-table pure-table-header pure-title">
<div class="pure-table-row">
<div class="pure-u-1-4 mid">Name</div>
<div class="pure-u-1-4 mid">Address</div>
<div class="pure-u-1-4 mid">Protocol</div>
<div class="pure-u-1-4 mid">Status</div>
<div class="<%= genClass %> mid">Name</div>
<div class="<%= genClass %> mid">Address</div>
<div class="<%= genClass %> mid">Protocol</div>
<% if(type !== 'coordinator' ) { %>
<div class="<%=genClass%> mid">Role</div>
<% } %>
<div class="<%=genClass%> mid">Status</div>
</div>
</div>
@ -17,16 +31,20 @@
<% _.each(coords, function(node) { %>
<div class="pure-table-row" node="<%=node.name%>">
<div class="pure-table-row <%= disabled %>" node="<%=node.name%>">
<div class="pure-u-1-4 mid"><%= node.name %></div>
<div class="pure-u-1-4 mid"><%= node.address %></div>
<div class="pure-u-1-4 mid"><%= node.protocol %></div>
<div class="<%= genClass %> mid"><%= node.name %></div>
<div class="<%= genClass %> mid"><%= node.address %></div>
<div class="<%= genClass %> mid"><%= node.protocol %></div>
<% if(type !== 'coordinator' ) { %>
<div class="<%=genClass%> mid"><%= node.role %></div>
<% } %>
<% if(node.status === 'ok') { %>
<div class="pure-u-1-4 mid"><i class="fa fa-check-circle"></i></div>
<div class="<%= genClass %> mid"><i class="fa fa-check-circle"></i></div>
<% } else { %>
<div class="pure-u-1-4 mid"><i class="fa fa-exclamation-circle"></i></div>
<div class="<%= genClass %> mid"><i class="fa fa-exclamation-circle"></i></div>
<% } %>
</div>

View File

@ -27,8 +27,7 @@
"click #databaseSearchSubmit" : "search",
"click #databaseToggle" : "toggleSettingsDropdown",
"click .css-label" : "checkBoxes",
"click #dbSortDesc" : "sorting",
"click .tile" : "switchDatabase"
"click #dbSortDesc" : "sorting"
},
sorting: function() {

View File

@ -63,7 +63,6 @@
isCluster: this.isCluster
}));
console.log(this.currentDB);
$(this.subEl).html(this.templateSub.render({
currentDB: this.currentDB.toJSON()
}));
@ -194,20 +193,6 @@
view: undefined,
}
],
node: [
{
name: 'Dashboard',
view: undefined,
active: true
},
{
name: 'Logs',
route: 'nodeLogs',
params: {
node: undefined
}
}
],
queries: [
{
name: 'Editor',
@ -315,6 +300,7 @@
menuItem = menuItem.substr(1, menuItem.length - 1);
}
//Location for selecting MainView Primary Navigaation Entry
if (menuItem === '') {
if (window.App.isCluster) {
menuItem = 'cluster';
@ -323,6 +309,9 @@
menuItem = 'dashboard';
}
}
else if (menuItem === 'cNodes' || menuItem === 'dNodes') {
menuItem = 'nodes';
}
try {
this.renderSubMenu(menuItem.split('-')[0]);
}

View File

@ -18,6 +18,7 @@
if (window.App.isCluster) {
this.coordinators = options.coordinators;
this.dbServers = options.dbServers;
this.coordname = options.coordname;
this.updateServerTime();
@ -43,17 +44,27 @@
var callback = function() {
this.continueRender();
this.breadcrumb(this.coordname);
window.arangoHelper.buildNodeSubNav(this.coordname, 'Dashboard', 'Logs');
$(window).trigger('resize');
}.bind(this);
if (!this.initDone) {
this.waitForCoordinators(callback);
var cb =function() {
console.log("dummy");
};
if (!this.initCoordDone) {
this.waitForCoordinators(cb);
}
if (!this.initDBDone) {
this.waitForDBServers(callback);
}
else {
this.coordname = window.location.hash.split('/')[1];
this.coordinator = this.coordinators.findWhere({name: this.coordname});
callback();
}
},
continueRender: function() {
@ -84,7 +95,30 @@
}
else {
self.coordinator = self.coordinators.findWhere({name: self.coordname});
self.initDone = true;
self.initCoordDone = true;
callback();
}
}, 200);
},
waitForDBServers: function(callback) {
var self = this;
window.setTimeout(function() {
if (self.dbServers[0].length === 0) {
self.waitForDBServers(callback);
}
else {
self.initDBDone = true;
self.dbServer = self.dbServers[0];
self.dbServer.each(function(model) {
if (model.get("name") === 'DBServer1') {
self.dbServer = model;
}
});
console.log(self.dbServer.toJSON());
callback();
}
}, 200);

View File

@ -12,21 +12,23 @@
knownServers: [],
events: {
"click .pure-table-body .pure-table-row": "navigateToNode"
},
initialize: function (options) {
var self = this;
if (window.App.isCluster) {
this.dbServers = options.dbServers;
this.coordinators = options.coordinators;
this.updateServerTime();
this.toRender = options.toRender;
if (this.toRender !== 'coordinator') {
this.events["click .pure-table-body .pure-table-row"] = "navigateToNode";
}
//start polling with interval
window.setInterval(function() {
if (window.location.hash === '#nodes') {
if (window.location.hash === '#cNodes' || window.location.hash === '#dNodes') {
var callback = function(data) {
};
@ -42,7 +44,7 @@
},
render: function () {
this.$el.html(this.template.render({coords: []}));
window.arangoHelper.buildNodesSubNav(this.toRender);
var callback = function() {
this.continueRender();
@ -57,9 +59,18 @@
},
continueRender: function() {
var coords = this.coordinators.toJSON();
var coords;
if (this.toRender === 'coordinator') {
coords = this.coordinators.toJSON();
}
else {
coords = this.dbServers.toJSON();
}
this.$el.html(this.template.render({
coords: coords
coords: coords,
type: this.toRender
}));
},

View File

@ -133,7 +133,6 @@ main {
background-color: $c-white;
border: 1px solid $c-content-border;
border-radius: 3px;
margin-top: 220px;
.app-info {
@include border-radius(3px);

View File

@ -376,13 +376,13 @@
.dashboard-legend-inner {
padding: 0 5px 5px 0;
text-align: right;
br {
display: none;
}
span {
@extend %pull-right;
padding-left: 10px;
}
}

View File

@ -29,12 +29,20 @@
color: $c-pure-text;
font-weight: 100;
line-height: 40px;
width: 100%;
&:hover {
background-color: rgb(239, 240, 235);
cursor: pointer;
}
&.disabled {
&:hover {
background-color: $c-white;
cursor: not-allowed;
}
}
.left {
text-align: left;
}

File diff suppressed because one or more lines are too long

View File

@ -132,6 +132,7 @@ function computeStatisticsRaw (result, start, clusterId) {
+ " return s",
{ start: start - 2 * STATISTICS_INTERVAL, clusterId: clusterId });
result.enabled = internal.enabledStatistics();
result.times = [];
for (let key in STAT_SERIES) {
@ -394,7 +395,7 @@ function computeStatisticsLong (attrs, clusterId) {
router.use((req, res, next) => {
if (!internal.options()['server.disable-authentication'] && !req.session.uid) {
if (!internal.options()['server.disable-authentication'] && (!req.session || !req.session.uid)) {
throw new httperr.Unauthorized();
}
next();

View File

@ -429,7 +429,7 @@ function analyzeCoreDump(instanceInfo, options, storeArangodPath, pid) {
////////////////////////////////////////////////////////////////////////////////
function analyzeCoreDumpWindows(instanceInfo) {
const coreFN = instanceInfo.tmpDataDir + "\\" + "core.dmp";
const coreFN = instanceInfo.rootDir + "\\" + "core.dmp";
if (!fs.exists(coreFN)) {
print("core file " + coreFN + " not found?");
@ -477,7 +477,7 @@ function checkArangoAlive(arangod, options) {
const storeArangodPath = "/var/tmp/arangod_" + arangod.pid;
print("Core dump written; copying arangod to " +
arangod.tmpDataDir + " for later analysis.");
arangod.rootDir + " for later analysis.");
let corePath = (options.coreDirectory === "") ?
"core" :

View File

@ -76,7 +76,7 @@ function agencyTestSuite () {
function readAndCheck(list) {
var res = readAgency(list);
require ("internal").print(list,res);
// require ("internal").print(list,res);
assertEqual(res.statusCode, 200);
return res.bodyParsed;
}
@ -286,9 +286,17 @@ function agencyTestSuite () {
assertEqual(readAndCheck([["version"]]), [{version:-1}]);
writeAndCheck([[{"version":{"op":"decrement"}}]]); // int before
assertEqual(readAndCheck([["version"]]), [{version:-2}]);
},
testOpInStrangePlaces : function () {
writeAndCheck([[{"/op":12}]]);
assertEqual(readAndCheck([["/op"]]), [{op:12}]);
writeAndCheck([[{"/op":{op:"delete"}}]]);
writeAndCheck([[{"/op/a/b/c": {"op":"set", "new": {op:13}}}]]);
assertEqual(readAndCheck([["/op/a/b/c"]], [{op:{a:{b:{c:{op:13}}}}}]));
writeAndCheck([[{"/op/a/b/d": {"op":"set", "new": {ttl:13}}}]]);
assertEqual(readAndCheck([["/op/a/b/c"]], [{op:{a:{b:{d:{ttl:14}}}}}]));
}
};
}

View File

@ -306,6 +306,15 @@ if (global.SYS_DOWNLOAD) {
delete global.SYS_DOWNLOAD;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not Statistics are enabled
////////////////////////////////////////////////////////////////////////////////
if (global.SYS_ENABLED_STATISTICS) {
exports.enabledStatistics = global.SYS_ENABLED_STATISTICS;
delete global.SYS_ENABLED_STATISTICS;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executeScript
////////////////////////////////////////////////////////////////////////////////

View File

@ -87,6 +87,11 @@ var findOrCreateCollectionByName = function (name, type, noCreate) {
err.errorNum = arangodb.errors.ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION.code;
err.errorMessage = name + arangodb.errors.ERROR_GRAPH_NOT_AN_ARANGO_COLLECTION.message;
throw err;
} else if (type === ArangoCollection.TYPE_EDGE && col.type() !== type) {
var err2 = new ArangoError();
err2.errorNum = arangodb.errors.ERROR_ARANGO_COLLECTION_TYPE_INVALID.code;
err2.errorMessage = name + " cannot be used as relation. It is not an edge collection";
throw err2;
}
return res;
};

View File

@ -41,10 +41,10 @@ const url = require('url');
class Response {
throw(msg) {
if (this.status >= 400) {
let HttpError = httperr[this.status] || httperr[500];
let err = new HttpError(msg || this.message);
err.details = this;
throw err;
throw Object.assign(
httperr(this.status, msg || this.message),
{details: this}
);
}
}
constructor(res, encoding, json) {

View File

@ -26010,7 +26010,7 @@ SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({
SwaggerUi.Views.ParameterView = Backbone.View.extend({
initialize: function(){
Handlebars.registerHelper('isArray', function(param, opts) {
if (param.type.toLowerCase() === 'array' || param.allowMultiple) {
if (param && param.type && param.type.toLowerCase() === 'array' || param.allowMultiple) {
return opts.fn(this);
} else {
return opts.inverse(this);

View File

@ -97,8 +97,10 @@ module.exports = class FoxxContext {
collectionName(name) {
const fqn = (
this.collectionPrefix
+ name.replace(/[^a-z0-9]/ig, '_').replace(/(^_+|_+$)/g, '').substr(0, 64)
this.collectionPrefix + name
.replace(/[^a-z0-9]/ig, '_')
.replace(/(^_+|_+$)/g, '')
.substr(0, 64)
);
assert(fqn.length > 0, `Cannot derive collection name from "${name}"`);
return fqn;

View File

@ -21,8 +21,12 @@
/// @author Alan Plum
////////////////////////////////////////////////////////////////////////////////
const manager = require('@arangodb/foxx/manager');
exports.getExports = function (path) {
return manager.requireApp('/' + path.replace(/(^\/+|\/+$)/, ''));
module.exports = {
get createRouter() {
return require('@arangodb/foxx/router');
},
get queue() {
const queues = require('@arangodb/foxx/queues');
return queues.get('default');
}
};

View File

@ -30,7 +30,12 @@ exports.createQuery = require('@arangodb/foxx/legacy/query').createQuery;
exports.toJSONSchema = require('@arangodb/foxx/legacy/schema').toJSONSchema;
exports.queues = require('@arangodb/foxx/queues');
exports.getExports = require('../').getExports;
const manager = require('@arangodb/foxx/manager');
exports.getExports = function (path) {
return manager.requireApp('/' + path.replace(/(^\/+|\/+$)/, ''));
};
exports.requireApp = function (path) {
return exports.getExports(path);
};

View File

@ -281,7 +281,15 @@ module.exports = class SyntheticResponse {
if (typeof status === 'string') {
status = statuses(status);
}
throw Object.assign(httperr(status, reason), args);
if (reason && typeof reason === 'object') {
args = reason;
reason = undefined;
}
throw Object.assign(
httperr(status, reason),
{statusCode: status, status},
args
);
}
send(body, type) {

View File

@ -481,7 +481,11 @@ function createDependencies(definitions, options) {
enumerable: true,
get() {
const mount = options[name];
return mount ? require('@arangodb/foxx').getExports(mount) : null;
if (!mount) {
return null;
}
const FoxxManager = require('@arangodb/foxx/manager');
return FoxxManager.requireApp('/' + mount.replace(/(^\/+|\/+$)/, ''));
}
});
});

View File

@ -78,7 +78,7 @@ module.exports = function sessionMiddleware(cfg) {
transport.get || transport.set,
'Session transport must have a get and/or set method'
);
return transports;
return transport;
});
assert(transports.length > 0, 'Must specify at least one session transport');
const autoCreate = cfg.autoCreate !== false;

View File

@ -68,6 +68,9 @@ module.exports = function systemStorage(cfg) {
}
},
forClient(session) {
return session && session._key || null;
},
save(session) {
if (!session) {
return null;
}
@ -85,6 +88,7 @@ module.exports = function systemStorage(cfg) {
if (isNew) {
const meta = db._sessions.save(payload);
sid = meta._key;
session._key = sid;
} else {
db._sessions.replace(sid, payload);
}
@ -96,7 +100,7 @@ module.exports = function systemStorage(cfg) {
internal.accessSid(sid);
}
}
return sid;
return session;
},
setUser(session, user) {
if (user) {
@ -113,17 +117,20 @@ module.exports = function systemStorage(cfg) {
}
}
},
clear(sid) {
clear(session) {
if (!session || !session._key) {
return false;
}
try {
db._sessions.remove(sid);
db._sessions.remove(session);
} catch (e) {
if (e.isArangoError && e.errorNum === NOT_FOUND) {
internal.clearSid(sid);
internal.clearSid(session._key);
return false;
}
throw e;
}
internal.clearSid(sid);
internal.clearSid(session._key);
return true;
},
new() {

View File

@ -77,6 +77,9 @@ module.exports = function collectionStorage(cfg) {
}
},
forClient(session) {
return session && session._key || null;
},
save(session) {
if (!session) {
return null;
}
@ -88,14 +91,18 @@ module.exports = function collectionStorage(cfg) {
};
if (!session._key) {
const meta = collection.save(payload);
return meta._key;
}
session._key = meta._key;
} else {
collection.replace(session._key, payload);
return session._key;
}
return session;
},
clear(sid) {
clear(session) {
if (!session || !session._key) {
return false;
}
try {
collection.remove(sid);
collection.remove(session);
} catch (e) {
if (e.isArangoError && e.errorNum === NOT_FOUND) {
return false;

View File

@ -47,9 +47,12 @@ function ahuacatlFailureSuite () {
var e;
var count = 5000;
var assertFailingQuery = function (query) {
var assertFailingQuery = function (query, rulesToExclude) {
if (!rulesToExclude) {
rulesToExclude = [];
}
try {
AQL_EXECUTE(query);
AQL_EXECUTE(query, null, { optimizer: { rules: rulesToExclude } });
fail();
}
catch (err) {
@ -317,7 +320,7 @@ function ahuacatlFailureSuite () {
testCalculationBlock1 : function () {
internal.debugSetFailAt("CalculationBlock::fillBlockWithReference");
assertFailingQuery("FOR i IN " + c.name() + " LET v = i RETURN v");
assertFailingQuery("FOR i IN " + c.name() + " LET v = i RETURN v", [ "-all" ]);
},
////////////////////////////////////////////////////////////////////////////////
@ -335,7 +338,7 @@ function ahuacatlFailureSuite () {
testEnumerateListBlock1 : function () {
internal.debugSetFailAt("EnumerateListBlock::getSome");
assertFailingQuery("LET values = (FOR i IN " + c.name() + " RETURN i) FOR x IN values RETURN x");
assertFailingQuery("LET values = (FOR i IN " + c.name() + " RETURN i) FOR x IN values RETURN x", [ "-all" ]);
assertFailingQuery("FOR i IN 1..10000 RETURN i");
},
@ -345,7 +348,7 @@ function ahuacatlFailureSuite () {
testEnumerateListBlock2 : function () {
internal.debugSetFailAt("EnumerateListBlock::getAqlValue");
assertFailingQuery("FOR year IN [ 2010, 2011, 2012 ] LET quarters = ((FOR q IN [ 1, 2, 3, 4 ] RETURN q)) RETURN LENGTH(quarters)");
assertFailingQuery("FOR year IN [ 2010, 2011, 2012 ] LET quarters = ((FOR q IN [ 1, 2, 3, 4 ] RETURN q)) RETURN LENGTH(quarters)", [ "-all" ]);
},
////////////////////////////////////////////////////////////////////////////////
@ -354,9 +357,9 @@ function ahuacatlFailureSuite () {
testSubqueryBlock1 : function () {
internal.debugSetFailAt("SubqueryBlock::getSome");
assertFailingQuery("FOR year IN [ 2010, 2011, 2012 ] LET quarters = ((FOR q IN [ 1, 2, 3, 4 ] RETURN q)) RETURN LENGTH(quarters)");
assertFailingQuery("LET values = (FOR i IN " + c.name() + " RETURN i) FOR x IN values RETURN x");
assertFailingQuery("LET values = (FOR i IN 1..10000 RETURN i) FOR x IN values RETURN x");
assertFailingQuery("FOR year IN [ 2010, 2011, 2012 ] LET quarters = ((FOR q IN [ 1, 2, 3, 4 ] RETURN q)) RETURN LENGTH(quarters)", [ "-all" ]);
assertFailingQuery("LET values = (FOR i IN " + c.name() + " RETURN i) FOR x IN values RETURN x", [ "-all" ]);
assertFailingQuery("LET values = (FOR i IN 1..10000 RETURN i) FOR x IN values RETURN x", [ "-all" ]);
},
////////////////////////////////////////////////////////////////////////////////
@ -365,8 +368,8 @@ function ahuacatlFailureSuite () {
testSubqueryBlock2 : function () {
internal.debugSetFailAt("SubqueryBlock::executeSubquery");
assertFailingQuery("LET values = (FOR i IN " + c.name() + " RETURN i) FOR x IN values RETURN x");
assertFailingQuery("LET values = (FOR i IN 1..10000 RETURN i) FOR x IN values RETURN x");
assertFailingQuery("LET values = (FOR i IN " + c.name() + " RETURN i) FOR x IN values RETURN x", [ "-all" ]);
assertFailingQuery("LET values = (FOR i IN 1..10000 RETURN i) FOR x IN values RETURN x", [ "-all" ]);
},
////////////////////////////////////////////////////////////////////////////////

View File

@ -156,16 +156,16 @@ static int TypeWeight(VPackSlice const& slice) {
case VPackValueType::Array:
return 4;
case VPackValueType::Object:
case VPackValueType::External:
// External type is used for documents
return 5;
case VPackValueType::External:
return TypeWeight(slice.resolveExternal());
default:
// All other values have equal weight
return 0;
}
}
int VelocyPackHelper::compareNumberValues(VPackSlice const& lhs, VPackSlice const& rhs) {
int VelocyPackHelper::compareNumberValues(VPackSlice lhs, VPackSlice rhs) {
VPackValueType const lType = lhs.type();
if (lType == rhs.type()) {
@ -428,9 +428,12 @@ bool VelocyPackHelper::velocyPackToFile(char const* filename,
return true;
}
int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs,
int VelocyPackHelper::compare(VPackSlice lhs, VPackSlice rhs,
bool useUTF8, VPackOptions const* options,
VPackSlice const* lhsBase, VPackSlice const* rhsBase) {
lhs = lhs.resolveExternal(); // follow externals
rhs = rhs.resolveExternal(); // follow externals
{
int lWeight = TypeWeight(lhs);
int rWeight = TypeWeight(rhs);
@ -542,11 +545,11 @@ int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs,
for (VPackValueLength i = 0; i < n; ++i) {
VPackSlice lhsValue;
if (i < nl) {
lhsValue = lhs.at(i);
lhsValue = lhs.at(i).resolveExternal();
}
VPackSlice rhsValue;
if (i < nr) {
rhsValue = rhs.at(i);
rhsValue = rhs.at(i).resolveExternal();
}
int result = compare(lhsValue, rhsValue, useUTF8, options, &lhs, &rhs);
@ -561,13 +564,15 @@ int VelocyPackHelper::compare(VPackSlice const& lhs, VPackSlice const& rhs,
VPackCollection::keys(lhs, keys);
VPackCollection::keys(rhs, keys);
for (auto const& key : keys) {
VPackSlice lhsValue;
if (lhs.hasKey(key)) {
lhsValue = lhs.get(key);
VPackSlice lhsValue = lhs.get(key).resolveExternal();
if (lhsValue.isNone()) {
// not present => null
lhsValue = VPackSlice::nullSlice();
}
VPackSlice rhsValue;
if (rhs.hasKey(key)) {
rhsValue = rhs.get(key);
VPackSlice rhsValue = rhs.get(key).resolveExternal();
if (rhsValue.isNone()) {
// not present => null
rhsValue = VPackSlice::nullSlice();
}
int result = compare(lhsValue, rhsValue, useUTF8, options, &lhs, &rhs);
@ -626,14 +631,16 @@ double VelocyPackHelper::toDouble(VPackSlice const& slice, bool& failed) {
if (n == 0) {
return 0.0;
} else if (n == 1) {
return VelocyPackHelper::toDouble(slice.at(0), failed);
return VelocyPackHelper::toDouble(slice.at(0).resolveExternal(), failed);
}
break;
}
case VPackValueType::External: {
return VelocyPackHelper::toDouble(slice.resolveExternal(), failed);
}
case VPackValueType::Illegal:
case VPackValueType::Object:
case VPackValueType::UTCDate:
case VPackValueType::External:
case VPackValueType::MinKey:
case VPackValueType::MaxKey:
case VPackValueType::Binary:
@ -649,11 +656,12 @@ double VelocyPackHelper::toDouble(VPackSlice const& slice, bool& failed) {
uint64_t VelocyPackHelper::hashByAttributes(
VPackSlice slice, std::vector<std::string> const& attributes,
bool docComplete, int& error, std::string const& key) {
error = TRI_ERROR_NO_ERROR;
uint64_t hash = TRI_FnvHashBlockInitial();
error = TRI_ERROR_NO_ERROR;
slice = slice.resolveExternal();
if (slice.isObject()) {
for (auto const& attr: attributes) {
VPackSlice sub = slice.get(attr);
for (auto const& attr : attributes) {
VPackSlice sub = slice.get(attr).resolveExternal();
if (sub.isNone()) {
if (attr == "_key" && !key.empty()) {
VPackBuilder temporaryBuilder;

View File

@ -203,15 +203,15 @@ class VelocyPackHelper {
/// @brief Compares two VelocyPack number values
//////////////////////////////////////////////////////////////////////////////
static int compareNumberValues(arangodb::velocypack::Slice const& lhs,
arangodb::velocypack::Slice const& rhs);
static int compareNumberValues(arangodb::velocypack::Slice lhs,
arangodb::velocypack::Slice rhs);
//////////////////////////////////////////////////////////////////////////////
/// @brief Compares two VelocyPack slices
//////////////////////////////////////////////////////////////////////////////
static int compare(arangodb::velocypack::Slice const& lhs,
arangodb::velocypack::Slice const& rhs,
static int compare(arangodb::velocypack::Slice lhs,
arangodb::velocypack::Slice rhs,
bool useUTF8, arangodb::velocypack::Options const* options = &arangodb::velocypack::Options::Defaults,
arangodb::velocypack::Slice const* lhsBase = nullptr,
arangodb::velocypack::Slice const* rhsBase = nullptr);

View File

@ -314,6 +314,7 @@ SimpleHttpResult* SimpleHttpClient::doRequest(
return nullptr;
}
this->close(); // this sets the state to IN_CONNECT for a retry
usleep(5000);
break;
}

View File

@ -108,10 +108,12 @@ v8::Handle<v8::Value> TRI_VPackToV8(v8::Isolate* isolate,
VPackOptions const* options,
VPackSlice const* base) {
switch (slice.type()) {
case VPackValueType::Null:
case VPackValueType::Null: {
return v8::Null(isolate);
case VPackValueType::Bool:
}
case VPackValueType::Bool: {
return v8::Boolean::New(isolate, slice.getBool());
}
case VPackValueType::Double: {
// convert NaN, +inf & -inf to null
double value = slice.getDouble();
@ -145,12 +147,19 @@ v8::Handle<v8::Value> TRI_VPackToV8(v8::Isolate* isolate,
case VPackValueType::SmallInt: {
return v8::Integer::New(isolate, slice.getNumericValue<int32_t>());
}
case VPackValueType::String:
case VPackValueType::String: {
return ObjectVPackString(isolate, slice);
case VPackValueType::Object:
return ObjectVPackObject(isolate, slice, options, base);
case VPackValueType::Array:
}
case VPackValueType::Array: {
return ObjectVPackArray(isolate, slice, options, base);
}
case VPackValueType::Object: {
return ObjectVPackObject(isolate, slice, options, base);
}
case VPackValueType::External: {
// resolve external
return TRI_VPackToV8(isolate, VPackSlice(slice.getExternal()), options, base);
}
case VPackValueType::Custom: {
if (options == nullptr || options->customTypeHandler == nullptr || base == nullptr) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
@ -161,9 +170,10 @@ v8::Handle<v8::Value> TRI_VPackToV8(v8::Isolate* isolate,
return TRI_V8_STD_STRING(id);
}
case VPackValueType::None:
default:
default: {
return v8::Undefined(isolate);
}
}
}
struct BuilderContext {

2
scripts/dumpAgency.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
curl -X POST http://localhost:4001/_api/agency/read -d '[["/"]]' | jq .

44
scripts/startAgency.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
if [ ! -d arangod ] || [ ! -d arangosh ] || [ ! -d UnitTests ] ; then
echo Must be started in the main ArangoDB source directory.
exit 1
fi
rm -rf cluster
mkdir cluster
echo Starting agency...
build/bin/arangod -c etc/relative/arangod.conf \
--agency.size 1 \
--server.endpoint tcp://127.0.0.1:4001 \
--agency.endpoint tcp://127.0.0.1:4001 \
--agency.wait-for-sync false \
--database.directory cluster/data4001 \
--agency.id 0 \
--log.file cluster/4001.log \
--log.requests-file cluster/4001.req \
--server.disable-statistics true \
--server.foxx-queues false \
--server.disable-authentication true \
--javascript.app-path ./js/apps \
--javascript.startup-directory ./js \
> cluster/4001.stdout 2>&1 &
testServer() {
PORT=$1
while true ; do
sleep 1
curl -s -f -X GET "http://127.0.0.1:$PORT/_api/version" > /dev/null 2>&1
if [ "$?" != "0" ] ; then
echo Server on port $PORT does not answer yet.
else
echo Server on port $PORT is ready for business.
break
fi
done
}
testServer 4001
echo Done, your agency is ready at
echo " build/bin/arangosh --server.endpoint tcp://127.0.0.1:4001"

View File

@ -44,11 +44,13 @@ build/bin/arangod -c etc/relative/arangod.conf \
--agency.wait-for-sync false \
--database.directory cluster/data4001 \
--agency.id 0 \
--javascript.v8-contexts 1 \
--log.file cluster/4001.log \
--log.requests-file cluster/4001.req \
--server.disable-statistics true \
--server.foxx-queues false \
--server.disable-authentication true \
--server.threads 16 \
--javascript.app-path ./js/apps \
--javascript.startup-directory ./js \
> cluster/4001.stdout 2>&1 &
@ -247,12 +249,21 @@ if [ -n "$SECONDARIES" ]; then
fi
echo Bootstrapping DBServers...
curl -s -X POST "http://127.0.0.1:8530/_admin/cluster/bootstrapDbServers" \
curl -s -f -X POST "http://127.0.0.1:8530/_admin/cluster/bootstrapDbServers" \
-d '{"isRelaunch":false}' >> cluster/DBServersUpgrade.log 2>&1
if [ "$?" != 0 ] ; then
echo "Bootstrapping DBServers failed"
exit 1;
fi
echo Running DB upgrade on cluster...
curl -s -X POST "http://127.0.0.1:8530/_admin/cluster/upgradeClusterDatabase" \
curl -s -f -X POST "http://127.0.0.1:8530/_admin/cluster/upgradeClusterDatabase" \
-d '{"isRelaunch":false}' >> cluster/DBUpgrade.log 2>&1
if [ "$?" != 0 ] ; then
echo "DB upgrade on cluster failed"
exit 1;
fi
echo Bootstrapping Coordinators...
PIDS=""

View File

@ -14,11 +14,7 @@ if [ "x$@" == "x" ] ; then
`find ./js/common/tests -name "*.js"` \
`find ./js/client/tests -name "*.js"` \
\
`find ./js/apps/system/_system/cerberus/APP -name "*.js"` \
`find ./js/apps/system/_api/gharial/APP -name "*.js"` \
`find ./js/apps/system/_system/sessions/APP -name "*.js"` \
`find ./js/apps/system/_system/simple-auth/APP -name "*.js"` \
`find ./js/apps/system/_system/users/APP -name "*.js"` \
\
`find ./js/apps/system/_admin/aardvark/APP/frontend/js/models -name "*.js"` \
`find ./js/apps/system/_admin/aardvark/APP/frontend/js/views -name "*.js"` \