Merge branch 'devel' of github.com:arangodb/ArangoDB into pipeline
10
CHANGELOG
|
@ -1,6 +1,8 @@
|
|||
devel
|
||||
-----
|
||||
|
||||
* fixed issue #2012
|
||||
|
||||
* added a memory expection in case V8 memory gets too low
|
||||
|
||||
* fixed epoch computation in hybrid logical clock
|
||||
|
@ -46,6 +48,14 @@ devel
|
|||
v3.0.6 (XXXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* fixed issue #2018
|
||||
|
||||
* fixed issue #2015
|
||||
|
||||
* fixed issue #2012
|
||||
|
||||
* fixed wrong default value for arangoimp's `--on-duplicate` value
|
||||
|
||||
* fix execution of AQL traversal expressions when there are multiple
|
||||
conditions that refer to variables set outside the traversal
|
||||
|
||||
|
|
|
@ -130,11 +130,20 @@ find_program (GIT_EXE git)
|
|||
if (DEFINED GIT_EXE AND IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git")
|
||||
execute_process(
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
|
||||
COMMAND ${GIT_EXE} describe --all --tags --long --dirty=-dirty
|
||||
OUTPUT_VARIABLE GIT_OUTPUT)
|
||||
|
||||
# this may fail on shallow clones that only knows about a limited number of commits.
|
||||
# if there is an older merged revision the head, it may not be available to git.
|
||||
if (NOT GIT_OUTPUT)
|
||||
set(ARANGODB_BUILD_REPOSITORY "GIT FAILED TO RETRIEVE THE VERSION - SHALLOW CLONE?")
|
||||
set(HAVE_ARANGODB_BUILD_REPOSITORY "1")
|
||||
else()
|
||||
string(STRIP ${GIT_OUTPUT} REPOSITORY_VERSION)
|
||||
set(ARANGODB_BUILD_REPOSITORY ${REPOSITORY_VERSION})
|
||||
set(HAVE_ARANGODB_BUILD_REPOSITORY "1")
|
||||
endif()
|
||||
else ()
|
||||
set(ARANGODB_BUILD_REPOSITORY "")
|
||||
set(HAVE_ARANGODB_BUILD_REPOSITORY "0")
|
||||
|
@ -889,3 +898,5 @@ endif()
|
|||
add_custom_target(packages
|
||||
DEPENDS ${PACKAGES_LIST}
|
||||
)
|
||||
|
||||
message(INFO " Building for git revision: ${ARANGODB_BUILD_REPOSITORY}")
|
||||
|
|
|
@ -259,4 +259,4 @@ The above referenced chapters describe the various APIs of ArangoDBs graph engin
|
|||
|
||||
!SUBSECTION Higher volume graph examples
|
||||
|
||||
All of the above examples are rather small so they are easier to comprehend and can demonstrate the way the functionality works. There are however several datasets freely available on the web that are a lot bigger. [We collected some of them with import scripts](https://github.com/triAGENS/ArangoDB-Data/) so you may play around with them. Another huge graph is the [Pokec social network](https://snap.stanford.edu/data/soc-pokec.html) from Slovakia that we [used for performance testing on several databases](https://www.arangodb.com/2015/06/multi-model-benchmark/); You will find importing scripts etc. in this blogpost.
|
||||
All of the above examples are rather small so they are easier to comprehend and can demonstrate the way the functionality works. There are however several datasets freely available on the web that are a lot bigger. [We collected some of them with import scripts](https://github.com/arangodb/example-datasets) so you may play around with them. Another huge graph is the [Pokec social network](https://snap.stanford.edu/data/soc-pokec.html) from Slovakia that we [used for performance testing on several databases](https://www.arangodb.com/2015/06/multi-model-benchmark/); You will find importing scripts etc. in this blogpost.
|
||||
|
|
|
@ -320,6 +320,8 @@ ________________________________________________________________________________
|
|||
|
||||
Linux Cordeumps
|
||||
===============
|
||||
Hint: on Ubuntu the `apport` package may interfere with this.
|
||||
|
||||
So that the unit testing framework can autorun gdb it needs to reliably find the corefiles.
|
||||
In Linux this is configured via the `/proc` filesystem, you can make this reboot permanent by
|
||||
creating the file `/etc/sysctl.d/corepattern.conf` (or add the following lines to `/etc/sysctl.conf`)
|
||||
|
|
|
@ -229,8 +229,16 @@ void AgencyFeature::start() {
|
|||
_agent->load();
|
||||
}
|
||||
|
||||
void AgencyFeature::unprepare() {
|
||||
void AgencyFeature::beginShutdown() {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// pass shutdown event to _agent so it can notify all its sub-threads
|
||||
_agent->beginShutdown();
|
||||
}
|
||||
|
||||
void AgencyFeature::unprepare() {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
/// @author Kaveh Vahedipour
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_AGENCY_APPLICATION_AGENCY_H
|
||||
#define ARANGOD_AGENCY_APPLICATION_AGENCY_H 1
|
||||
#ifndef ARANGOD_AGENCY_AGENCY_FEATURE_H
|
||||
#define ARANGOD_AGENCY_AGENCY_FEATURE_H 1
|
||||
|
||||
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||
|
||||
|
@ -40,6 +40,7 @@ class AgencyFeature : virtual public application_features::ApplicationFeature {
|
|||
void validateOptions(std::shared_ptr<options::ProgramOptions>) override final;
|
||||
void prepare() override final;
|
||||
void start() override final;
|
||||
void beginShutdown() override final;
|
||||
void unprepare() override final;
|
||||
|
||||
private:
|
||||
|
|
|
@ -681,6 +681,10 @@ static AqlValue MergeParameters(arangodb::aql::Query* query,
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
if (n == 1) {
|
||||
// only one parameter. now add original document
|
||||
builder.add(initialSlice);
|
||||
}
|
||||
return AqlValue(builder);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ DispatcherFeature::DispatcherFeature(
|
|||
application_features::ApplicationServer* server)
|
||||
: ApplicationFeature(server, "Dispatcher"),
|
||||
_nrStandardThreads(0),
|
||||
_nrExtraThreads(0),
|
||||
_nrExtraThreads(-1),
|
||||
_nrAqlThreads(0),
|
||||
_queueSize(16384),
|
||||
_dispatcher(nullptr) {
|
||||
|
@ -72,7 +72,7 @@ void DispatcherFeature::collectOptions(
|
|||
|
||||
options->addHiddenOption("--server.extra-threads",
|
||||
"number of extra threads that can additionally be created when all regular threads are blocked and the client requests thread creation",
|
||||
new UInt64Parameter(&_nrExtraThreads));
|
||||
new Int64Parameter(&_nrExtraThreads));
|
||||
|
||||
options->addHiddenOption("--server.aql-threads",
|
||||
"number of threads for basic operations (0 = automatic)",
|
||||
|
@ -102,7 +102,7 @@ void DispatcherFeature::validateOptions(std::shared_ptr<ProgramOptions>) {
|
|||
|
||||
TRI_ASSERT(_nrAqlThreads >= 1);
|
||||
|
||||
if (_nrExtraThreads == 0) {
|
||||
if (_nrExtraThreads < 0) {
|
||||
_nrExtraThreads = _nrStandardThreads;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,9 @@ void DispatcherFeature::buildDispatcher() {
|
|||
|
||||
void DispatcherFeature::buildStandardQueue() {
|
||||
LOG_TOPIC(DEBUG, Logger::STARTUP) << "setting up a standard queue with "
|
||||
<< _nrStandardThreads << " threads";
|
||||
<< _nrStandardThreads << " threads"
|
||||
<< " and " << _nrExtraThreads
|
||||
<< " extra threads";
|
||||
|
||||
_dispatcher->addStandardQueue(static_cast<size_t>(_nrStandardThreads),
|
||||
static_cast<size_t>(_nrExtraThreads),
|
||||
|
|
|
@ -53,7 +53,7 @@ class DispatcherFeature final
|
|||
|
||||
private:
|
||||
uint64_t _nrStandardThreads;
|
||||
uint64_t _nrExtraThreads;
|
||||
int64_t _nrExtraThreads;
|
||||
uint64_t _nrAqlThreads;
|
||||
uint64_t _queueSize;
|
||||
|
||||
|
|
|
@ -484,7 +484,7 @@ bool HttpCommTask::processRead() {
|
|||
LOG(DEBUG) << "connection close requested by client";
|
||||
_closeRequested = true;
|
||||
} else if (_requestAsHttp()->isHttp10() && connectionType != "keep-alive") {
|
||||
// HTTP 1.0 request, and no "Connection: Keep-Alive" header sent
|
||||
// HTTP 1.0 request, and no "Connection: keep-alive" header sent
|
||||
// we should close the connection
|
||||
LOG(DEBUG) << "no keep-alive, connection close requested by client";
|
||||
_closeRequested = true;
|
||||
|
|
|
@ -406,13 +406,15 @@ int Syncer::applyCollectionDumpMarker(
|
|||
res = opRes.code;
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
res = ex.code();
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
errorMsg = "document insert/replace operation failed: " +
|
||||
std::string(TRI_errno_string(res));
|
||||
} catch (std::exception const& ex) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
errorMsg = "document insert/replace operation failed: " +
|
||||
std::string(ex.what());
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
errorMsg = "document insert/replace operation failed: unknown exception";
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -436,13 +438,14 @@ int Syncer::applyCollectionDumpMarker(
|
|||
res = opRes.code;
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
res = ex.code();
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
errorMsg = "document remove operation failed: " +
|
||||
std::string(TRI_errno_string(res));
|
||||
} catch (std::exception const& ex) {
|
||||
errorMsg = "document remove operation failed: " +
|
||||
std::string(ex.what());
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
errorMsg = "document remove operation failed: unknown exception";
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -137,7 +137,7 @@ void DatabaseFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
ctx->getCheckPath(_databasePath, "database.directory");
|
||||
ctx->getCheckPath(_databasePath, "database.directory", false);
|
||||
|
||||
if (_maximalJournalSize < TRI_JOURNAL_MINIMAL_SIZE) {
|
||||
LOG(FATAL) << "invalid value for '--database.maximal-journal-size'. "
|
||||
|
|
|
@ -155,7 +155,7 @@ void V8DealerFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
ctx->getCheckPath(_startupPath, "javascript.startup-directory");
|
||||
ctx->getCheckPath(_startupPath, "javascript.startup-directory", true);
|
||||
|
||||
_startupLoader.setDirectory(_startupPath);
|
||||
ServerState::instance()->setJavaScriptPath(_startupPath);
|
||||
|
@ -166,7 +166,7 @@ void V8DealerFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
ctx->getCheckPath(_appPath, "javascript.app-directory");
|
||||
ctx->getCheckPath(_appPath, "javascript.app-directory", true);
|
||||
|
||||
// use a minimum of 1 second for GC
|
||||
if (_gcFrequency < 1) {
|
||||
|
|
|
@ -612,17 +612,24 @@ static int WriteBeginMarker(TRI_transaction_t* trx) {
|
|||
arangodb::wal::TransactionMarker marker(TRI_DF_MARKER_VPACK_BEGIN_TRANSACTION, trx->_vocbase->_id, trx->_id);
|
||||
res = GetLogfileManager()->allocateAndWrite(marker, false).errorCode;
|
||||
|
||||
TRI_IF_FAILURE("TransactionWriteBeginMarkerThrow") {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
trx->_beginWritten = true;
|
||||
} else {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
res = ex.code();
|
||||
LOG(WARN) << "could not save transaction begin marker in log: " << ex.what();
|
||||
} catch (std::exception const& ex) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
LOG(WARN) << "could not save transaction begin marker in log: " << ex.what();
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG(WARN) << "could not save transaction begin marker in log: " << TRI_errno_string(res);
|
||||
LOG(WARN) << "could not save transaction begin marker in log: unknown exception";
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -650,14 +657,23 @@ static int WriteAbortMarker(TRI_transaction_t* trx) {
|
|||
try {
|
||||
arangodb::wal::TransactionMarker marker(TRI_DF_MARKER_VPACK_ABORT_TRANSACTION, trx->_vocbase->_id, trx->_id);
|
||||
res = GetLogfileManager()->allocateAndWrite(marker, false).errorCode;
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
res = ex.code();
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
|
||||
TRI_IF_FAILURE("TransactionWriteAbortMarkerThrow") {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG(WARN) << "could not save transaction abort marker in log: " << TRI_errno_string(res);
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
res = ex.code();
|
||||
LOG(WARN) << "could not save transaction abort marker in log: " << ex.what();
|
||||
} catch (std::exception const& ex) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
LOG(WARN) << "could not save transaction abort marker in log: " << ex.what();
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
LOG(WARN) << "could not save transaction abort marker in log: unknown exception";
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -693,15 +709,24 @@ static int WriteCommitMarker(TRI_transaction_t* trx) {
|
|||
// also sync RocksDB WAL
|
||||
RocksDBFeature::syncWal();
|
||||
}
|
||||
#endif
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
res = ex.code();
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
|
||||
TRI_IF_FAILURE("TransactionWriteCommitMarkerThrow") {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG(WARN) << "could not save transaction commit marker in log: " << TRI_errno_string(res);
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
#endif
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
res = ex.code();
|
||||
LOG(WARN) << "could not save transaction commit marker in log: " << ex.what();
|
||||
} catch (std::exception const& ex) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
LOG(WARN) << "could not save transaction commit marker in log: " << ex.what();
|
||||
} catch (...) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
LOG(WARN) << "could not save transaction commit marker in log: unknown exception";
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -278,6 +278,9 @@ int CollectorThread::waitForResult(uint64_t timeout) {
|
|||
void CollectorThread::beginShutdown() {
|
||||
Thread::beginShutdown();
|
||||
|
||||
// deactivate write-throttling on shutdown
|
||||
_logfileManager->throttleWhenPending(0);
|
||||
|
||||
CONDITION_LOCKER(guard, _condition);
|
||||
guard.signal();
|
||||
}
|
||||
|
@ -656,6 +659,7 @@ int CollectorThread::processCollectionOperations(CollectorCache* cache) {
|
|||
true); // already locked by guard above
|
||||
trx.addHint(TRI_TRANSACTION_HINT_NO_COMPACTION_LOCK,
|
||||
true); // already locked above
|
||||
trx.addHint(TRI_TRANSACTION_HINT_NO_THROTTLING, true);
|
||||
trx.addHint(TRI_TRANSACTION_HINT_NO_BEGIN_MARKER, true);
|
||||
trx.addHint(TRI_TRANSACTION_HINT_NO_ABORT_MARKER, true);
|
||||
trx.addHint(TRI_TRANSACTION_HINT_TRY_LOCK, true);
|
||||
|
@ -1004,12 +1008,15 @@ int CollectorThread::queueOperations(arangodb::wal::Logfile* logfile,
|
|||
|
||||
if (maxNumPendingOperations > 0 &&
|
||||
_numPendingOperations < maxNumPendingOperations &&
|
||||
(_numPendingOperations + numOperations) >= maxNumPendingOperations) {
|
||||
(_numPendingOperations + numOperations) >= maxNumPendingOperations &&
|
||||
!isStopping()) {
|
||||
// activate write-throttling!
|
||||
_logfileManager->activateWriteThrottling();
|
||||
LOG_TOPIC(WARN, Logger::COLLECTOR)
|
||||
<< "queued more than " << maxNumPendingOperations
|
||||
<< " pending WAL collector operations. now activating write-throttling";
|
||||
<< " pending WAL collector operations."
|
||||
<< " current queue size: " << (_numPendingOperations + numOperations)
|
||||
<< ". now activating write-throttling";
|
||||
}
|
||||
|
||||
_numPendingOperations += numOperations;
|
||||
|
|
|
@ -107,7 +107,7 @@ LogfileManager::LogfileManager(ApplicationServer* server)
|
|||
_droppedCollections(),
|
||||
_droppedDatabases(),
|
||||
_idLock(),
|
||||
_writeThrottled(0),
|
||||
_writeThrottled(false),
|
||||
_shutdown(0) {
|
||||
LOG(TRACE) << "creating WAL logfile manager";
|
||||
TRI_ASSERT(!_allowWrites);
|
||||
|
@ -454,7 +454,15 @@ bool LogfileManager::open() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void LogfileManager::beginShutdown() {
|
||||
throttleWhenPending(0); // deactivate write-throttling on shutdown
|
||||
}
|
||||
|
||||
void LogfileManager::unprepare() {
|
||||
// deactivate write-throttling (again) on shutdown in case it was set again
|
||||
// after beginShutdown
|
||||
throttleWhenPending(0);
|
||||
|
||||
_shutdown = 1;
|
||||
|
||||
LOG(TRACE) << "shutting down WAL";
|
||||
|
|
|
@ -116,6 +116,7 @@ class LogfileManager final : public application_features::ApplicationFeature {
|
|||
void validateOptions(std::shared_ptr<options::ProgramOptions>) override final;
|
||||
void prepare() override final;
|
||||
void start() override final;
|
||||
void beginShutdown() override final;
|
||||
void unprepare() override final;
|
||||
|
||||
public:
|
||||
|
@ -186,13 +187,13 @@ class LogfileManager final : public application_features::ApplicationFeature {
|
|||
inline void maxThrottleWait(uint64_t value) { _maxThrottleWait = value; }
|
||||
|
||||
// whether or not write-throttling is currently enabled
|
||||
inline bool isThrottled() { return (_writeThrottled != 0); }
|
||||
inline bool isThrottled() { return _writeThrottled; }
|
||||
|
||||
// activate write-throttling
|
||||
void activateWriteThrottling() { _writeThrottled = 1; }
|
||||
void activateWriteThrottling() { _writeThrottled = true; }
|
||||
|
||||
// deactivate write-throttling
|
||||
void deactivateWriteThrottling() { _writeThrottled = 0; }
|
||||
void deactivateWriteThrottling() { _writeThrottled = false; }
|
||||
|
||||
// allow or disallow writes to the WAL
|
||||
inline void allowWrites(bool value) { _allowWrites = value; }
|
||||
|
@ -537,7 +538,7 @@ class LogfileManager final : public application_features::ApplicationFeature {
|
|||
Mutex _idLock;
|
||||
|
||||
// whether or not write-throttling is currently enabled
|
||||
int _writeThrottled;
|
||||
bool _writeThrottled;
|
||||
|
||||
// whether or not we have been shut down already
|
||||
volatile sig_atomic_t _shutdown;
|
||||
|
|
|
@ -817,7 +817,7 @@ void V8ShellFeature::initGlobals() {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
ctx->getCheckPath(_startupDirectory, "javascript.startup-directory");
|
||||
ctx->getCheckPath(_startupDirectory, "javascript.startup-directory", true);
|
||||
|
||||
// initialize standard modules
|
||||
std::string modules =
|
||||
|
|
|
@ -113,8 +113,8 @@ configure_file (
|
|||
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
get_cmake_property(_variableNames VARIABLES)
|
||||
foreach (_variableName ${_variableNames})
|
||||
message(STATUS "${_variableName}=${${_variableName}}")
|
||||
endforeach()
|
||||
#get_cmake_property(_variableNames VARIABLES)
|
||||
#foreach (_variableName ${_variableNames})
|
||||
# message(STATUS "${_variableName}=${${_variableName}}")
|
||||
#endforeach()
|
||||
#--------------------------------------------------------------------------------
|
||||
|
|
|
@ -1024,7 +1024,7 @@ if (list.length > 0) {
|
|||
</div> <%});%> </div>
|
||||
</div></script><script id="graphSettingsView.ejs" type="text/template"> <% var genClass = 'pure-u-1-3'; %> <% var genClass2 = 'pure-u-2-3'; %> <% var formatName = function(name) { %> <% var formattedName = %> <% return name.charAt(0).toUpperCase() + string.slice(1);%> <% }; %> <div id="graphSettingsView" class="innerContent">
|
||||
|
||||
<div class="pure-g" style="margin-top: -15px">
|
||||
<div class="pure-g" style="margin-top: -13px">
|
||||
<div class="pure-u-1-1 pure-u-md-1-1 pure-u-lg-1-1 pure-u-xl-1-1">
|
||||
|
||||
<div class="pure-g pure-table pure-table-body"> <% _.each(general, function(val, key) { %> <% if (val.type === 'divider') { %> <div class="pure-u-1-1 left heading"><%=val.name%></div> <% } else { %> <div class="<%= genClass %> left"> <%=val.name%> </div>
|
||||
|
@ -1076,7 +1076,7 @@ if (list.length > 0) {
|
|||
<li class="enabled">
|
||||
<a id="selectNodes" class="headerButton">
|
||||
<span title="Lasso tool - Select and delete multiple nodes">
|
||||
<i class="fa fa-pencil fa-stack-1x"></i>
|
||||
<i class="fa fa-paint-brush fa-stack-1x"></i>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -2739,4 +2739,4 @@ var cutByResolution = function (str) {
|
|||
</div>
|
||||
|
||||
<div id="workMonitorContent" class="innerContent">
|
||||
</div></script></head><body><nav class="navbar" style="display: none"><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><a class="version"><span>VERSION: </span><span id="currentVersion"></span></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div id="modalPlaceholder"></div><div class="bodyWrapper" style="display: none"><div class="centralRow"><div id="navbar2" class="navbarWrapper secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper"><div id="loadingScreen" class="loadingScreen" style="display: none"><i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw margin-bottom"></i> <span class="sr-only">Loading...</span></div><div id="content" class="centralContent"></div><footer class="footer"><div id="footerBar"></div></footer></div></div></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div id="graphSettingsContent" style="display: none"></div><div id="offlinePlaceholder" style="display:none"><div class="offline-div"><div class="pure-u"><div class="pure-u-1-4"></div><div class="pure-u-1-2 offline-window"><div class="offline-header"><h3>You have been disconnected from the server</h3></div><div class="offline-body"><p>The connection to the server has been lost. The server may be under heavy load.</p><p>Trying to reconnect in <span id="offlineSeconds">10</span> seconds.</p><p class="animation_state"><span><button class="button-success">Reconnect now</button></span></p></div></div><div class="pure-u-1-4"></div></div></div></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="libs.js?version=1472022235976"></script><script src="app.js?version=1472022235976"></script></body></html>
|
||||
</div></script></head><body><nav class="navbar" style="display: none"><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><a class="version"><span>VERSION: </span><span id="currentVersion"></span></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div id="modalPlaceholder"></div><div class="bodyWrapper" style="display: none"><div class="centralRow"><div id="navbar2" class="navbarWrapper secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper"><div id="loadingScreen" class="loadingScreen" style="display: none"><i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw margin-bottom"></i> <span class="sr-only">Loading...</span></div><div id="content" class="centralContent"></div><footer class="footer"><div id="footerBar"></div></footer></div></div></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div id="graphSettingsContent" style="display: none"></div><div id="offlinePlaceholder" style="display:none"><div class="offline-div"><div class="pure-u"><div class="pure-u-1-4"></div><div class="pure-u-1-2 offline-window"><div class="offline-header"><h3>You have been disconnected from the server</h3></div><div class="offline-body"><p>The connection to the server has been lost. The server may be under heavy load.</p><p>Trying to reconnect in <span id="offlineSeconds">10</span> seconds.</p><p class="animation_state"><span><button class="button-success">Reconnect now</button></span></p></div></div><div class="pure-u-1-4"></div></div></div></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="libs.js?version=1472049166163"></script><script src="app.js?version=1472049166163"></script></body></html>
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 893 B |
Before Width: | Height: | Size: 622 B |
Before Width: | Height: | Size: 618 B |
Before Width: | Height: | Size: 893 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 22 KiB |
|
@ -279,10 +279,10 @@
|
|||
buildGraphSubNav: function (graph, activeKey) {
|
||||
var menus = {
|
||||
Content: {
|
||||
route: '#graph2/' + encodeURIComponent(graph)
|
||||
route: '#graph/' + encodeURIComponent(graph)
|
||||
},
|
||||
Settings: {
|
||||
route: '#graph2/' + encodeURIComponent(graph) + '/settings'
|
||||
route: '#graph/' + encodeURIComponent(graph) + '/settings'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
'node/:name': 'node',
|
||||
'logs': 'logs',
|
||||
'helpus': 'helpUs',
|
||||
'graph2/:name': 'graph2',
|
||||
'graph2/:name/settings': 'graph2settings',
|
||||
'graph/:name': 'graph',
|
||||
'graph/:name/settings': 'graphSettings',
|
||||
'support': 'support'
|
||||
},
|
||||
|
||||
|
@ -54,9 +54,9 @@
|
|||
callback.apply(this, args);
|
||||
}
|
||||
|
||||
if (this.graphViewer2) {
|
||||
if (this.graphViewer2.graphSettingsView) {
|
||||
this.graphViewer2.graphSettingsView.hide();
|
||||
if (this.graphViewer) {
|
||||
if (this.graphViewer.graphSettingsView) {
|
||||
this.graphViewer.graphSettingsView.hide();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -681,31 +681,31 @@
|
|||
this.queryView.render();
|
||||
},
|
||||
|
||||
graph2: function (name, initialized) {
|
||||
graph: function (name, initialized) {
|
||||
this.checkUser();
|
||||
if (!initialized) {
|
||||
this.waitForInit(this.graph2.bind(this), name);
|
||||
this.waitForInit(this.graph.bind(this), name);
|
||||
return;
|
||||
}
|
||||
if (this.graphViewer2) {
|
||||
if (this.graphViewer2.graphSettingsView) {
|
||||
this.graphViewer2.graphSettingsView.remove();
|
||||
if (this.graphViewer) {
|
||||
if (this.graphViewer.graphSettingsView) {
|
||||
this.graphViewer.graphSettingsView.remove();
|
||||
}
|
||||
this.graphViewer2.remove();
|
||||
this.graphViewer.remove();
|
||||
}
|
||||
this.graphViewer2 = new window.GraphViewer2({
|
||||
this.graphViewer = new window.GraphViewer2({
|
||||
name: name,
|
||||
documentStore: this.arangoDocumentStore,
|
||||
collection: new window.GraphCollection(),
|
||||
userConfig: this.userConfig
|
||||
});
|
||||
this.graphViewer2.render();
|
||||
this.graphViewer.render();
|
||||
},
|
||||
|
||||
graph2settings: function (name, initialized) {
|
||||
graphSettings: function (name, initialized) {
|
||||
this.checkUser();
|
||||
if (!initialized) {
|
||||
this.waitForInit(this.graph2settings.bind(this), name);
|
||||
this.waitForInit(this.graphSettings.bind(this), name);
|
||||
return;
|
||||
}
|
||||
if (this.graphSettingsView) {
|
||||
|
@ -893,8 +893,8 @@
|
|||
if (this.naviView) {
|
||||
this.naviView.resize();
|
||||
}
|
||||
if (this.graphViewer2) {
|
||||
this.graphViewer2.resize();
|
||||
if (this.graphViewer) {
|
||||
this.graphViewer.resize();
|
||||
}
|
||||
if (this.documentsView) {
|
||||
this.documentsView.resize();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<div id="graphSettingsView" class="innerContent">
|
||||
|
||||
<div class="pure-g" style="margin-top: -15px">
|
||||
<div class="pure-g" style="margin-top: -13px">
|
||||
<div class="pure-u-1-1 pure-u-md-1-1 pure-u-lg-1-1 pure-u-xl-1-1">
|
||||
|
||||
<div class="pure-g pure-table pure-table-body">
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<li class="enabled">
|
||||
<a id="selectNodes" class="headerButton">
|
||||
<span title="Lasso tool - Select and delete multiple nodes">
|
||||
<i class="fa fa-pencil fa-stack-1x"></i>
|
||||
<i class="fa fa-paint-brush fa-stack-1x"></i>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
'keyup #graphManagementSearchInput': 'search',
|
||||
'click #graphManagementSearchSubmit': 'search',
|
||||
'click .tile-graph': 'redirectToGraphViewer',
|
||||
'click #gv2': 'redirectToGraphViewer2',
|
||||
'click #graphManagementToggle': 'toggleGraphDropdown',
|
||||
'click .css-label': 'checkBoxes',
|
||||
'change #graphSortDesc': 'sorting'
|
||||
|
@ -47,15 +46,7 @@
|
|||
redirectToGraphViewer: function (e) {
|
||||
var name = $(e.currentTarget).attr('id');
|
||||
name = name.substr(0, name.length - 5);
|
||||
window.location.hash = window.location.hash.substr(0, window.location.hash.length - 1) + '2/' + encodeURIComponent(name);
|
||||
},
|
||||
|
||||
// please remove this when gv2 is launched
|
||||
redirectToGraphViewer2: function (e) {
|
||||
e.preventDefault();
|
||||
var name = $(e.currentTarget).parent().parent().attr('id');
|
||||
name = name.substr(0, name.length - 5);
|
||||
window.App.navigate('graph2/' + encodeURIComponent(name), {trigger: true});
|
||||
window.location.hash = window.location.hash.substr(0, window.location.hash.length - 1) + '/' + encodeURIComponent(name);
|
||||
},
|
||||
|
||||
loadGraphViewer: function (graphName, refetch) {
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
},
|
||||
'nodeStart': {
|
||||
type: 'string',
|
||||
name: 'Starting node',
|
||||
name: 'Startnode',
|
||||
desc: 'A valid node id. If empty, a random node will be chosen.',
|
||||
value: 2
|
||||
},
|
||||
'layout': {
|
||||
type: 'select',
|
||||
name: 'Layout algorithm',
|
||||
name: 'Layout',
|
||||
desc: 'Different graph algorithms. No overlap is very fast (more than 5000 nodes), force is slower (less than 5000 nodes) and fruchtermann is the slowest (less than 500 nodes). The calculation time strongly depends on your nodes and edges counts.',
|
||||
noverlap: {
|
||||
name: 'No overlap',
|
||||
|
@ -57,7 +57,7 @@
|
|||
'depth': {
|
||||
desc: 'Search depth, starting from your start node.',
|
||||
type: 'number',
|
||||
name: 'Search depth',
|
||||
name: 'Search Depth',
|
||||
value: 2
|
||||
},
|
||||
'limit': {
|
||||
|
@ -81,7 +81,7 @@
|
|||
},
|
||||
'nodeLabelByCollection': {
|
||||
type: 'select',
|
||||
name: 'Use collection name',
|
||||
name: 'Use Collection Name',
|
||||
desc: 'Set label text by collection. If activated node label attribute will be ignored.',
|
||||
yes: {
|
||||
name: 'Yes',
|
||||
|
@ -94,7 +94,7 @@
|
|||
},
|
||||
'nodeColorByCollection': {
|
||||
type: 'select',
|
||||
name: 'Use collection color',
|
||||
name: 'Use Collection Color',
|
||||
no: {
|
||||
name: 'No',
|
||||
val: 'false'
|
||||
|
@ -113,12 +113,12 @@
|
|||
},
|
||||
'nodeColorAttribute': {
|
||||
type: 'string',
|
||||
name: 'Color attribute',
|
||||
name: 'Color Attribute',
|
||||
desc: 'If an attribute is given, nodes will then be colorized by the attribute. This setting ignores default node color if set.'
|
||||
},
|
||||
'nodeSizeByEdges': {
|
||||
type: 'select',
|
||||
name: 'Size by edge count',
|
||||
name: 'Size By Edges',
|
||||
yes: {
|
||||
name: 'Yes',
|
||||
val: 'true'
|
||||
|
@ -127,11 +127,11 @@
|
|||
name: 'No',
|
||||
val: 'false'
|
||||
},
|
||||
desc: 'Should nodes be sized by their edges? If enabled, node sizing attribute will be ignored.'
|
||||
desc: 'Should nodes be sized by their edges count? If enabled, node sizing attribute will be ignored.'
|
||||
},
|
||||
'nodeSize': {
|
||||
type: 'string',
|
||||
name: 'Sizing attribute',
|
||||
name: 'Sizing Attribute',
|
||||
desc: 'Default node size. Numeric value > 0.'
|
||||
},
|
||||
'edges': {
|
||||
|
@ -145,7 +145,7 @@
|
|||
},
|
||||
'edgeLabelByCollection': {
|
||||
type: 'select',
|
||||
name: 'Use collection name',
|
||||
name: 'Use Collection Name',
|
||||
desc: 'Set label text by collection. If activated edge label attribute will be ignored.',
|
||||
yes: {
|
||||
name: 'Yes',
|
||||
|
@ -158,7 +158,7 @@
|
|||
},
|
||||
'edgeColorByCollection': {
|
||||
type: 'select',
|
||||
name: 'Use collection color',
|
||||
name: 'Use Collection Color',
|
||||
no: {
|
||||
name: 'No',
|
||||
val: 'false'
|
||||
|
@ -177,7 +177,7 @@
|
|||
},
|
||||
'edgeColorAttribute': {
|
||||
type: 'string',
|
||||
name: 'Color attribute',
|
||||
name: 'Color Attribute',
|
||||
desc: 'If an attribute is given, edges will then be colorized by the attribute. This setting ignores default edge color if set.'
|
||||
},
|
||||
'edgeEditable': {
|
||||
|
@ -251,11 +251,13 @@
|
|||
},
|
||||
|
||||
checkinput: function (e) {
|
||||
if ((new Date() - this.lastSaved > 500)) {
|
||||
if (e.currentTarget.id === this.lastFocussed) {
|
||||
if (this.lastFocussedValue !== $(e.currentTarget).val()) {
|
||||
this.saveGraphSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
checkEnterKey: function (e) {
|
||||
|
@ -284,6 +286,7 @@
|
|||
|
||||
saveGraphSettings: function (event, color, nodeStart, overwrite) {
|
||||
var self = this;
|
||||
self.lastSaved = new Date();
|
||||
var combinedName = window.App.currentDB.toJSON().name + '_' + this.name;
|
||||
|
||||
var config = {};
|
||||
|
@ -337,20 +340,21 @@
|
|||
layout: 'force',
|
||||
renderer: 'canvas',
|
||||
depth: '2',
|
||||
limit: '250',
|
||||
nodeColor: '#2ecc71',
|
||||
nodeColorAttribute: '',
|
||||
nodeColorByCollection: 'true',
|
||||
edgeColor: '#cccccc',
|
||||
edgeColorAttribute: '',
|
||||
edgeColorByCollection: 'false',
|
||||
edgeColorByCollection: 'true',
|
||||
nodeLabel: '_key',
|
||||
edgeLabel: '',
|
||||
edgeType: 'arrow',
|
||||
nodeSize: '',
|
||||
nodeSizeByEdges: 'true',
|
||||
edgeEditable: 'true',
|
||||
edgeEditable: 'false',
|
||||
nodeLabelByCollection: 'false',
|
||||
edgeLabelByCollection: 'true',
|
||||
edgeLabelByCollection: 'false',
|
||||
nodeStart: '',
|
||||
barnesHutOptimize: true
|
||||
};
|
||||
|
@ -382,6 +386,7 @@
|
|||
|
||||
render: function () {
|
||||
this.getGraphSettings(true);
|
||||
this.lastSaved = new Date();
|
||||
},
|
||||
|
||||
handleDependencies: function () {
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
resize: function () {
|
||||
// adjust container widht + height
|
||||
$('#graph-container').width($('.centralContent').width());
|
||||
$('#graph-container').height($('.centralRow').height() - 150);
|
||||
$('#graph-container').height($('.centralRow').height() - 155);
|
||||
},
|
||||
|
||||
toggleSettings: function () {
|
||||
|
@ -356,7 +356,7 @@
|
|||
|
||||
// clear dom
|
||||
$('#nodeContextMenu').remove();
|
||||
var string = '<div id="nodeContextMenu" class="nodeContextMenu"></div>';
|
||||
var string = '<div id="nodeContextMenu" class="nodeContextMenu animated zoomIn"></div>';
|
||||
$('#graph-container').append(string);
|
||||
|
||||
// clear state
|
||||
|
@ -369,8 +369,6 @@
|
|||
// clear events
|
||||
var c = document.getElementsByClassName('sigma-mouse')[0];
|
||||
c.removeEventListener('mousemove', self.drawLine.bind(this), false);
|
||||
|
||||
// clear info div
|
||||
},
|
||||
|
||||
trackCursorPosition: function (e) {
|
||||
|
@ -779,15 +777,20 @@
|
|||
});
|
||||
},
|
||||
|
||||
// right click nodes context menu
|
||||
createNodesContextMenu: function (e) {
|
||||
var self = this;
|
||||
nodesContextMenuCheck: function (e) {
|
||||
this.nodesContextEventState = e;
|
||||
this.openNodesDate = new Date();
|
||||
},
|
||||
|
||||
// click nodes context menu
|
||||
/*
|
||||
createNodesContextMenu: function () {
|
||||
var self = this;
|
||||
var e = self.nodesContextEventState;
|
||||
|
||||
// if right click
|
||||
if (e.which === 3) {
|
||||
var x = e.clientX - 50;
|
||||
var y = e.clientY - 50;
|
||||
this.clearOldContextMenu();
|
||||
self.clearOldContextMenu();
|
||||
|
||||
var generateMenu = function (e) {
|
||||
var Wheelnav = wheelnav;
|
||||
|
@ -833,10 +836,8 @@
|
|||
$('#nodeContextMenu').height(100);
|
||||
|
||||
generateMenu(e);
|
||||
} else {
|
||||
self.clearOldContextMenu();
|
||||
}
|
||||
},
|
||||
*/
|
||||
|
||||
// right click background context menu
|
||||
createContextMenu: function (e) {
|
||||
|
@ -887,7 +888,7 @@
|
|||
generateMenu(e);
|
||||
},
|
||||
|
||||
// right click edge context menu
|
||||
// click edge context menu
|
||||
createEdgeContextMenu: function (edgeId, e) {
|
||||
var self = this;
|
||||
var x = this.cursorX - 165;
|
||||
|
@ -939,7 +940,7 @@
|
|||
generateMenu(e, edgeId);
|
||||
},
|
||||
|
||||
// right click node context menu
|
||||
// click node context menu
|
||||
createNodeContextMenu: function (nodeId, e) {
|
||||
var self = this;
|
||||
var x; var y; var size;
|
||||
|
@ -988,9 +989,17 @@
|
|||
wheel.colors = hotaru;
|
||||
wheel.multiSelect = false;
|
||||
wheel.clickModeRotate = false;
|
||||
wheel.sliceHoverAttr = {stroke: '#fff', 'stroke-width': 4};
|
||||
wheel.sliceHoverAttr = {stroke: '#fff', 'stroke-width': 2};
|
||||
wheel.slicePathFunction = slicePath().DonutSlice;
|
||||
wheel.createWheel([icon.edit, icon.trash, icon.flag, icon.connect, icon.expand]);
|
||||
wheel.createWheel([
|
||||
'imgsrc:img/gv_edit.png',
|
||||
'imgsrc:img/gv_trash.png',
|
||||
'imgsrc:img/gv_flag.png',
|
||||
'imgsrc:img/gv_link.png',
|
||||
'imgsrc:img/gv_expand.png'
|
||||
]);
|
||||
|
||||
$('#nodeContextMenu').addClass('animated bounceIn');
|
||||
|
||||
window.setTimeout(function () {
|
||||
// add menu events
|
||||
|
@ -1021,6 +1030,7 @@
|
|||
self.contextState.fromY = y;
|
||||
|
||||
var c = document.getElementsByClassName('sigma-mouse')[0];
|
||||
self.drawHelp('Now click destination node, or click background to cancel.');
|
||||
c.addEventListener('mousemove', self.drawLine.bind(this), false);
|
||||
|
||||
self.clearOldContextMenu();
|
||||
|
@ -1032,7 +1042,22 @@
|
|||
self.expandNode(nodeId);
|
||||
};
|
||||
|
||||
// on hover
|
||||
// add menu hover functions
|
||||
|
||||
var descriptions = [
|
||||
'Edit the node.',
|
||||
'Delete node.',
|
||||
'Set as startnode.',
|
||||
'Draw edge.',
|
||||
'Expand the node.'
|
||||
];
|
||||
|
||||
// hover functions
|
||||
_.each(descriptions, function (val, key) {
|
||||
wheel.navItems[key].navTitle.mouseover(function () { self.drawHelp(val); });
|
||||
wheel.navItems[key].navTitle.mouseout(function () { self.removeHelp(); });
|
||||
});
|
||||
|
||||
/* TODO
|
||||
wheel.navItems[0].navSlice.mouseover(function (a) {
|
||||
$(a.target).css('opacity', '1');
|
||||
|
@ -1061,6 +1086,20 @@
|
|||
generateMenu(e, nodeId);
|
||||
},
|
||||
|
||||
drawHelp: function (val) {
|
||||
if (document.getElementById('helpTooltip') === null) {
|
||||
$(this.el).append('<div id="helpTooltip" class="helpTooltip"><span>' + val + '</span></div>');
|
||||
} else {
|
||||
$('#helpTooltip span').text(val);
|
||||
}
|
||||
|
||||
$('#helpTooltip').show();
|
||||
},
|
||||
|
||||
removeHelp: function () {
|
||||
$('#helpTooltip').remove();
|
||||
},
|
||||
|
||||
clearMouseCanvas: function () {
|
||||
var c = document.getElementsByClassName('sigma-mouse')[0];
|
||||
var ctx = c.getContext('2d');
|
||||
|
@ -1177,7 +1216,7 @@
|
|||
*/
|
||||
|
||||
drawLine: function (e) {
|
||||
var context = window.App.graphViewer2.contextState;
|
||||
var context = window.App.graphViewer.contextState;
|
||||
|
||||
if (context.createEdge) {
|
||||
var fromX = context.fromX;
|
||||
|
@ -1287,6 +1326,16 @@
|
|||
});
|
||||
}
|
||||
|
||||
var style = 'position: absolute; right: 25px; bottom: 45px;';
|
||||
|
||||
if (!$('#deleteNodes').is(':visible')) {
|
||||
$(self.el).append(
|
||||
'<button style=" ' + style + ' "id="deleteNodes" class="button-danger fadeIn animated">Delete selected nodes</button>'
|
||||
);
|
||||
var c = document.getElementById('deleteNodes');
|
||||
c.addEventListener('click', self.deleteNodesModal.bind(self), false);
|
||||
}
|
||||
|
||||
self.activeNodes = nodes;
|
||||
sigmaInstance.refresh();
|
||||
});
|
||||
|
@ -1312,13 +1361,13 @@
|
|||
});
|
||||
}
|
||||
|
||||
var style = 'position: absolute; left: 25px; bottom: 45px;';
|
||||
var style = 'position: absolute; left: 25px; bottom: 50px;';
|
||||
if (this.aqlMode) {
|
||||
style = 'position: absolute; left: 30px; margin-top: -37px;';
|
||||
}
|
||||
|
||||
$(this.el).append(
|
||||
'<div style="' + style + '">' +
|
||||
'<div style="' + style + ' animated fadeIn">' +
|
||||
'<span style="margin-right: 10px" class="arangoState"><span id="nodesCount">' + graph.nodes.length + '</span> nodes</span>' +
|
||||
'<span class="arangoState"><span id="edgesCount">' + graph.edges.length + '</span> edges</span>' +
|
||||
'</div>'
|
||||
|
@ -1352,7 +1401,7 @@
|
|||
defaultNodeBorderColor: '#8c8c8c',
|
||||
doubleClickEnabled: false,
|
||||
minNodeSize: 5,
|
||||
labelThreshold: 15,
|
||||
labelThreshold: 10,
|
||||
maxNodeSize: 15,
|
||||
batchEdgesDrawing: true,
|
||||
minEdgeSize: 10,
|
||||
|
@ -1373,11 +1422,12 @@
|
|||
};
|
||||
|
||||
// halo settings
|
||||
settings.nodeHaloColor = '#FF7A7A';
|
||||
// settings.nodeHaloColor = '#FF7A7A';
|
||||
settings.nodeHaloColor = 'rgba(146,197,192, 0.8)';
|
||||
settings.nodeHaloStroke = false;
|
||||
settings.nodeHaloStrokeColor = '#000';
|
||||
settings.nodeHaloStrokeWidth = 0.5;
|
||||
settings.nodeHaloSize = 15;
|
||||
settings.nodeHaloStrokeWidth = 0;
|
||||
settings.nodeHaloSize = 25;
|
||||
settings.nodeHaloClustering = false;
|
||||
settings.nodeHaloClusteringMaxRadius = 1000;
|
||||
settings.edgeHaloColor = '#fff';
|
||||
|
@ -1486,18 +1536,19 @@
|
|||
var callback = function (error, data) {
|
||||
if (!error) {
|
||||
var attributes = '';
|
||||
attributes += 'ID <span class="nodeId">' + data._id + '</span>';
|
||||
attributes += '<span>ID </span> <span class="nodeId">' + data._id + '</span>';
|
||||
if (Object.keys(data).length > 3) {
|
||||
attributes += 'KEYS ';
|
||||
attributes += '<span>KEYS </span>';
|
||||
}
|
||||
_.each(data, function (value, key) {
|
||||
if (key !== '_key' && key !== '_id' && key !== '_rev' && key !== '_from' && key !== '_to') {
|
||||
attributes += '<span class="nodeAttribute">' + key + '</span>';
|
||||
}
|
||||
});
|
||||
var string = '<div id="nodeInfoDiv" class="nodeInfoDiv">' + attributes + '</div>';
|
||||
var string = '<div id="nodeInfoDiv" class="nodeInfoDiv" style="display: none;">' + attributes + '</div>';
|
||||
|
||||
$(self.el).append(string);
|
||||
$('#nodeInfoDiv').fadeIn('slow');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1512,6 +1563,9 @@
|
|||
|
||||
s.bind('clickNode', function (e) {
|
||||
if (self.contextState.createEdge === true) {
|
||||
self.clearMouseCanvas();
|
||||
self.removeHelp();
|
||||
|
||||
// create the edge
|
||||
self.contextState._to = e.data.node.id;
|
||||
var fromCollection = self.contextState._from.split('/')[0];
|
||||
|
@ -1520,6 +1574,7 @@
|
|||
// validate edgeDefinitions
|
||||
var foundEdgeDefinitions = self.getEdgeDefinitionCollections(fromCollection, toCollection);
|
||||
self.addEdgeModal(foundEdgeDefinitions, self.contextState._from, self.contextState._to);
|
||||
self.clearOldContextMenu(true);
|
||||
} else {
|
||||
if (!self.dragging) {
|
||||
if (self.contextState.createEdge === true) {
|
||||
|
@ -1557,6 +1612,10 @@
|
|||
if (e.data.captor.isDragging) {
|
||||
self.clearOldContextMenu(true);
|
||||
self.clearMouseCanvas();
|
||||
} else if (self.contextState.createEdge === true) {
|
||||
self.clearOldContextMenu(true);
|
||||
self.clearMouseCanvas();
|
||||
self.removeHelp();
|
||||
} else {
|
||||
// stage menu
|
||||
if (!$('#nodeContextMenu').is(':visible')) {
|
||||
|
@ -1799,10 +1858,16 @@
|
|||
},
|
||||
|
||||
toggleLasso: function () {
|
||||
var self = this;
|
||||
|
||||
if (this.graphLasso.isActive) {
|
||||
var y = document.getElementById('deleteNodes');
|
||||
y.removeEventListener('click', self.deleteNodesModal, false);
|
||||
$('#deleteNodes').remove();
|
||||
|
||||
// remove event
|
||||
var c = document.getElementsByClassName('sigma-lasso')[0];
|
||||
c.removeEventListener('mouseup', this.createNodesContextMenu.bind(this), false);
|
||||
c.removeEventListener('mouseup', this.nodesContextMenuCheck.bind(this), false);
|
||||
|
||||
$('#selectNodes').removeClass('activated');
|
||||
this.graphLasso.deactivate();
|
||||
|
@ -1817,7 +1882,7 @@
|
|||
|
||||
// add event
|
||||
var x = document.getElementsByClassName('sigma-lasso')[0];
|
||||
x.addEventListener('mouseup', this.createNodesContextMenu.bind(this), false);
|
||||
x.addEventListener('mouseup', self.nodesContextMenuCheck.bind(this), false);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
.nodeInfoDiv {
|
||||
border-radius: 3px;
|
||||
bottom: 0;
|
||||
bottom: 4px;
|
||||
color: $c-bluegrey-dark;
|
||||
font-weight: 500;
|
||||
height: 25px;
|
||||
|
@ -63,16 +63,31 @@
|
|||
font-weight: 100;
|
||||
margin-right: 5px;
|
||||
padding: 2px 5px;
|
||||
|
||||
&::selection {
|
||||
background: rgba(64, 74, 83, .8);
|
||||
}
|
||||
|
||||
&::-moz-selection {
|
||||
background: rgba(64, 74, 83, .8);
|
||||
}
|
||||
}
|
||||
|
||||
.nodeId {
|
||||
background-color: $c-positive;
|
||||
}
|
||||
|
||||
span {
|
||||
float: left;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.nodeContextMenu {
|
||||
|
||||
animation-duration: .15s !important;
|
||||
position: fixed;
|
||||
|
||||
svg {
|
||||
|
@ -122,8 +137,9 @@
|
|||
min-width: 400px;
|
||||
position: fixed;
|
||||
right: -1px;
|
||||
top: 103px;
|
||||
top: 100px;
|
||||
width: 400px;
|
||||
z-index: 10;
|
||||
|
||||
.pure-g {
|
||||
|
||||
|
@ -153,6 +169,8 @@
|
|||
}
|
||||
|
||||
.pure-u-1-3 {
|
||||
font-size: 9pt;
|
||||
font-weight: 100;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
|
@ -169,9 +187,17 @@
|
|||
}
|
||||
|
||||
.heading {
|
||||
border-bottom: 1px solid $c-white;
|
||||
background: rgba(0, 0, 0, .3);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, .2);
|
||||
border-top: 1px solid rgba(255, 255, 255, .2);
|
||||
font-size: 12pt;
|
||||
font-weight: 100;
|
||||
height: 10px;
|
||||
line-height: 9pt;
|
||||
margin-bottom: 15px;
|
||||
margin-left: -10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.rangeLabel {
|
||||
|
@ -215,7 +241,24 @@
|
|||
}
|
||||
|
||||
.pure-table {
|
||||
overflow-x: hidden;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.helpTooltip {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
top: 120px;
|
||||
width: 100%;
|
||||
|
||||
span {
|
||||
background-color: $c-bluegrey-dark;
|
||||
border-radius: 2px;
|
||||
color: $c-white;
|
||||
padding: 10px;
|
||||
padding-left: 150px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,6 @@
|
|||
margin: 0;
|
||||
|
||||
&.top {
|
||||
//background-color: $c-navbar-main-color;
|
||||
background-color: $c-bluegrey-dark;
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
|
|
|
@ -1452,7 +1452,7 @@ function startInstanceAgency (instanceInfo, protocol, options,
|
|||
}
|
||||
let dir = fs.join(rootDir, 'agency-' + i);
|
||||
fs.makeDirectoryRecursive(dir);
|
||||
|
||||
fs.makeDirectoryRecursive(instanceArgs['database.directory']);
|
||||
instanceInfo.arangods.push(startArango(protocol, options, instanceArgs, rootDir, 'agent'));
|
||||
|
||||
}
|
||||
|
@ -2656,6 +2656,7 @@ testFuncs.dfdb = function (options) {
|
|||
const dataDir = fs.getTempFile();
|
||||
const args = ['-c', 'etc/relative/arango-dfdb.conf', dataDir];
|
||||
|
||||
fs.makeDirectoryRecursive(dataDir);
|
||||
let results = {};
|
||||
|
||||
results.dfdb = executeAndWait(ARANGOD_BIN, args, options, 'dfdb');
|
||||
|
|
|
@ -614,6 +614,23 @@ function StatementSuite () {
|
|||
assertTrue(stats.hasOwnProperty("filtered"));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test potentially unsupported types
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testUnsupportedTypes : function () {
|
||||
var st = db._createStatement({ query : "LET d = (FOR doc IN _apps LIMIT 1 RETURN MERGE(doc)) RETURN d" });
|
||||
var result = st.execute();
|
||||
|
||||
var docs = [ ];
|
||||
while (result.hasNext()) {
|
||||
docs.push(result.next());
|
||||
}
|
||||
|
||||
assertEqual(1, docs.length);
|
||||
assertTrue(typeof docs[0] === 'object');
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test bind method
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -5017,6 +5017,135 @@ function transactionServerFailuresSuite () {
|
|||
|
||||
testHelper.waitUnload(c);
|
||||
|
||||
assertEqual(100, c.count());
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: cannot write begin marker for trx
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testNoBeginMarkerThrow : function () {
|
||||
internal.debugClearFailAt();
|
||||
|
||||
db._drop(cn);
|
||||
c = db._create(cn);
|
||||
|
||||
var i;
|
||||
for (i = 0; i < 100; ++i) {
|
||||
c.save({ _key: "test" + i, a: i });
|
||||
}
|
||||
assertEqual(100, c.count());
|
||||
|
||||
internal.wal.flush(true, true);
|
||||
internal.debugSetFailAt("TransactionWriteBeginMarkerThrow");
|
||||
|
||||
try {
|
||||
TRANSACTION({
|
||||
collections: {
|
||||
write: [ cn ],
|
||||
},
|
||||
action: function () {
|
||||
c.save({ _key: "test100" });
|
||||
fail();
|
||||
}
|
||||
});
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||
}
|
||||
|
||||
assertEqual(100, c.count());
|
||||
internal.debugClearFailAt();
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: cannot write commit marker for trx
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testNoCommitMarkerThrow : function () {
|
||||
internal.debugClearFailAt();
|
||||
|
||||
db._drop(cn);
|
||||
c = db._create(cn);
|
||||
|
||||
var i;
|
||||
for (i = 0; i < 100; ++i) {
|
||||
c.save({ _key: "test" + i, a: i });
|
||||
}
|
||||
assertEqual(100, c.count());
|
||||
|
||||
internal.wal.flush(true, true);
|
||||
internal.debugSetFailAt("TransactionWriteCommitMarkerThrow");
|
||||
|
||||
try {
|
||||
TRANSACTION({
|
||||
collections: {
|
||||
write: [ cn ],
|
||||
},
|
||||
action: function () {
|
||||
var i;
|
||||
for (i = 100; i < 1000; ++i) {
|
||||
c.save({ _key: "test" + i, a: i });
|
||||
}
|
||||
|
||||
assertEqual(1000, c.count());
|
||||
}
|
||||
});
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
assertEqual(internal.errors.ERROR_INTERNAL.code, err.errorNum);
|
||||
}
|
||||
|
||||
assertEqual(100, c.count());
|
||||
internal.debugClearFailAt();
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: cannot write abort marker for trx
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testNoAbortMarkerThrow : function () {
|
||||
internal.debugClearFailAt();
|
||||
|
||||
db._drop(cn);
|
||||
c = db._create(cn);
|
||||
|
||||
var i;
|
||||
for (i = 0; i < 100; ++i) {
|
||||
c.save({ _key: "test" + i, a: i });
|
||||
}
|
||||
assertEqual(100, c.count());
|
||||
|
||||
internal.wal.flush(true, true);
|
||||
internal.debugSetFailAt("TransactionWriteAbortMarkerThrow");
|
||||
|
||||
try {
|
||||
TRANSACTION({
|
||||
collections: {
|
||||
write: [ cn ],
|
||||
},
|
||||
action: function () {
|
||||
var i;
|
||||
for (i = 100; i < 1000; ++i) {
|
||||
c.save({ _key: "test" + i, a: i });
|
||||
}
|
||||
|
||||
assertEqual(1000, c.count());
|
||||
|
||||
throw "rollback!";
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
// ignore the intentional error
|
||||
}
|
||||
|
||||
internal.debugClearFailAt();
|
||||
|
||||
testHelper.waitUnload(c);
|
||||
|
||||
assertEqual(100, c.count());
|
||||
}
|
||||
|
||||
|
|
|
@ -273,11 +273,14 @@ void ArangoGlobalContext::tempPathAvailable() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ArangoGlobalContext::getCheckPath(std::string &path, const char *whichPath) {
|
||||
void ArangoGlobalContext::getCheckPath(std::string &path, const char *whichPath, bool fatal) {
|
||||
if (!arangodb::basics::FileUtils::exists(path)) {
|
||||
std::string directory;
|
||||
directory = arangodb::basics::FileUtils::buildFilename(_runRoot, path);
|
||||
if (!arangodb::basics::FileUtils::exists(directory)) {
|
||||
if (!fatal) {
|
||||
return;
|
||||
}
|
||||
LOG(ERR) << "failed to locate " << whichPath << " directory, its neither available in '" << path << "' nor in '" << directory << "'";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class ArangoGlobalContext {
|
|||
public:
|
||||
std::string binaryName() { return _binaryName; }
|
||||
std::string runRoot() { return _runRoot; }
|
||||
void getCheckPath(std::string &path, const char *whichPath);
|
||||
void getCheckPath(std::string &path, const char *whichPath, bool fatal);
|
||||
int exit(int ret);
|
||||
void installHup();
|
||||
void installSegv();
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
using namespace arangodb::basics;
|
||||
|
||||
static size_t const MinReserveValue = 32;
|
||||
|
||||
void VelocyPackDumper::handleUnsupportedType(VPackSlice const* slice) {
|
||||
TRI_string_buffer_t* buffer = _buffer->stringBuffer();
|
||||
|
||||
|
@ -42,6 +44,9 @@ void VelocyPackDumper::handleUnsupportedType(VPackSlice const* slice) {
|
|||
TRI_AppendStringUnsafeStringBuffer(buffer, "null", 4);
|
||||
return;
|
||||
} else if (options->unsupportedTypeBehavior == VPackOptions::ConvertUnsupportedType) {
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
TRI_ASSERT(strlen("\"(non-representable type)\"") + 1 < MinReserveValue);
|
||||
#endif
|
||||
TRI_AppendStringUnsafeStringBuffer(buffer, "\"(non-representable type)\"");
|
||||
return;
|
||||
}
|
||||
|
@ -52,7 +57,8 @@ void VelocyPackDumper::handleUnsupportedType(VPackSlice const* slice) {
|
|||
void VelocyPackDumper::appendUInt(uint64_t v) {
|
||||
TRI_string_buffer_t* buffer = _buffer->stringBuffer();
|
||||
|
||||
int res = TRI_ReserveStringBuffer(buffer, 21);
|
||||
TRI_ASSERT(MinReserveValue > 20);
|
||||
int res = TRI_ReserveStringBuffer(buffer, MinReserveValue);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -142,7 +148,8 @@ void VelocyPackDumper::dumpInteger(VPackSlice const* slice) {
|
|||
} else if (slice->isType(VPackValueType::Int)) {
|
||||
TRI_string_buffer_t* buffer = _buffer->stringBuffer();
|
||||
|
||||
int res = TRI_ReserveStringBuffer(buffer, 21);
|
||||
TRI_ASSERT(MinReserveValue > 20);
|
||||
int res = TRI_ReserveStringBuffer(buffer, MinReserveValue);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -218,7 +225,8 @@ void VelocyPackDumper::dumpInteger(VPackSlice const* slice) {
|
|||
} else if (slice->isType(VPackValueType::SmallInt)) {
|
||||
TRI_string_buffer_t* buffer = _buffer->stringBuffer();
|
||||
|
||||
int res = TRI_ReserveStringBuffer(buffer, 21);
|
||||
TRI_ASSERT(MinReserveValue > 20);
|
||||
int res = TRI_ReserveStringBuffer(buffer, MinReserveValue);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -391,8 +399,8 @@ void VelocyPackDumper::dumpValue(VPackSlice const* slice, VPackSlice const* base
|
|||
|
||||
TRI_string_buffer_t* buffer = _buffer->stringBuffer();
|
||||
|
||||
// alloc at least 16 bytes
|
||||
int res = TRI_ReserveStringBuffer(buffer, 16);
|
||||
// alloc at least 32 bytes
|
||||
int res = TRI_ReserveStringBuffer(buffer, 32);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
|
|
@ -54,6 +54,9 @@ BASE=4001
|
|||
NATH=$(( $NRDBSERVERS + $NRCOORDINATORS + $NRAGENTS ))
|
||||
|
||||
rm -rf cluster
|
||||
if [ -d cluster-init ];then
|
||||
cp -a cluster-init cluster
|
||||
fi
|
||||
mkdir -p cluster
|
||||
echo Starting agency ...
|
||||
for aid in `seq 0 $(( $NRAGENTS - 1 ))`; do
|
||||
|
|