diff --git a/Documentation/UserManual/Foxx.md b/Documentation/UserManual/Foxx.md index d47a1c7eab..0e9ba726d6 100644 --- a/Documentation/UserManual/Foxx.md +++ b/Documentation/UserManual/Foxx.md @@ -14,7 +14,7 @@ They provide all the HTTP goodness. If you just want to install an existing application, please use the @ref UserManualFoxxManager. If you want to create your own application, -please continue. +please continue reading. Overview ======== @@ -965,3 +965,46 @@ provides a few mechanisms for this: Of course you can also use `console.log` or any other means of logging output. +Deploying a Foxx application{#UserManualFoxxDeployment} +======================================================= + +When a Foxx application is ready to be used in production, it is time to leave the +development mode and deploy the app in a production environment. + +The first step is to copy the application's script directory to the target ArangoDB +server. If your development and production environment are the same, there is +nothing to do. If production runs on a different server, you should copy the +development application directory to some temporary place on the production server. + +When the application code is present on the production server, you can use the +`fetch` and `mount` commands from the @ref UserManualFoxxManager to register the +application in the production ArangoDB instance and make it available. + +Here are the individual steps to carry out: + +- development: + - cd into the directory that application code is in. Then create a tar.gz file with + the application code (replace `app` with the actual name): + + cd /path/to/development/apps/directory + tar cvfz app.tar.gz app + + - copy the tar.gz file to the production server: + + scp app.tar.gz production:/tmp/ + +- production: + - create a temporary directory, e.g. `/tmp/apps` and extract the tar archive into + this directory: + + mkdir /tmp/apps + cd /tmp/apps + tar xvfz /tmp/app.tar.gz + + - start the ArangoDB shell and run the following commands in it: + + fm.fetch("directory", "/tmp/apps/app"); + fm.mount("app", "/app"); + +More information on how to deploy applications from different sources can be +found in the @ref UserManualFoxxManager "Foxx Manager manual". diff --git a/Documentation/UserManual/FoxxTOC.md b/Documentation/UserManual/FoxxTOC.md index 47f921b340..054cf9bfcb 100644 --- a/Documentation/UserManual/FoxxTOC.md +++ b/Documentation/UserManual/FoxxTOC.md @@ -8,3 +8,4 @@ TOC {#UserManualFoxxTOC} - @ref UserManualFoxxDetailsModel - @ref UserManualFoxxDetailsRepository - @ref UserManualFoxxDevelopment + - @ref UserManualFoxxDeployment diff --git a/Documentation/UserManual/UserManual.md b/Documentation/UserManual/UserManual.md index 5655837cdc..016b17c585 100644 --- a/Documentation/UserManual/UserManual.md +++ b/Documentation/UserManual/UserManual.md @@ -3,24 +3,44 @@ ArangoDB's User Manual (@VERSION) {#UserManual} @NAVIGATE_UserManual -@CHAPTER_REF{Installing} -@CHAPTER_REF{FirstStepsArangoDB} -@CHAPTER_REF{UserManualArangosh} -@CHAPTER_REF{UserManualWebInterface} -@CHAPTER_REF{HandlingDatabases} -@CHAPTER_REF{HandlingCollections} -@CHAPTER_REF{HandlingDocuments} -@CHAPTER_REF{HandlingEdges} -@CHAPTER_REF{SimpleQueries} -@CHAPTER_REF{Aql} -@CHAPTER_REF{ExtendingAql} -@CHAPTER_REF{AqlExamples} -@CHAPTER_REF{Graphs} -@CHAPTER_REF{Traversals} -@CHAPTER_REF{Transactions} -@CHAPTER_REF{UserManualReplication} -@CHAPTER_REF{UserManualFoxx} -@CHAPTER_REF{UserManualFoxxManager} -@CHAPTER_REF{HandlingEndpoints} -@CHAPTER_REF{CommandLine} -@CHAPTER_REF{Glossary} +@CHAPTER_REF{Installing}: Downloading and compiling ArangoDB + +@CHAPTER_REF{FirstStepsArangoDB}: An Introduction to ArangoDB + +@CHAPTER_REF{UserManualArangosh}: Using the ArangoDB shell + +@CHAPTER_REF{UserManualWebInterface}: Administering ArangoDB via the web interface + +@CHAPTER_REF{HandlingDatabases}: Organising data in databases + +@CHAPTER_REF{HandlingCollections}: Managing collections + +@CHAPTER_REF{HandlingDocuments}: Saving, updating, and deleting documents + +@CHAPTER_REF{HandlingEdges}: Storing and querying edges + +@CHAPTER_REF{SimpleQueries}: Running more specialised queries + +@CHAPTER_REF{Aql}: The ArangoDB query language for complex querying + +@CHAPTER_REF{ExtendingAql}: How to embed user-defined functions into AQL + +@CHAPTER_REF{AqlExamples}: Example queries for AQL + +@CHAPTER_REF{Graphs}: Managing graphs in ArangoDB + +@CHAPTER_REF{Traversals}: Running custom graph traversals + +@CHAPTER_REF{Transactions}: Wrapping multiple operations in an ACID transaction + +@CHAPTER_REF{UserManualReplication}: Configuring, starting, stopping the replication + +@CHAPTER_REF{UserManualFoxx}: A JavaScript framework to build simple applications and APIs with ArangoDB + +@CHAPTER_REF{UserManualFoxxManager}: Installing and uninstalling Foxx applications + +@CHAPTER_REF{HandlingEndpoints}: Making the server listen on multiple ports + +@CHAPTER_REF{CommandLine}: All the command-line options + +@CHAPTER_REF{Glossary}: The obvious definitions diff --git a/README.md b/README.md index 22ed3dd22d..31c9e6d9b4 100644 --- a/README.md +++ b/README.md @@ -92,3 +92,16 @@ You can use the Google group for improvements, feature requests, comments http://www.arangodb.org/connect + +Citing ArangoDB +--------------- +Please kindly cite ArangoDB in your publications if it helps your research: + +```bibtex +@misc{ArangoDB2013, + Author = {ArangoDB}, + Title = { {ArangoDB}: An Open Source multi-purpose database supporting flexible data models for documents, graphs, and key-values.}, + Year = {2013}, + Howpublished = {\url{http://arangodb.org/} +} +``` diff --git a/UnitTests/Makefile.unittests b/UnitTests/Makefile.unittests index 897ec4c2cc..bdfdee4396 100755 --- a/UnitTests/Makefile.unittests +++ b/UnitTests/Makefile.unittests @@ -119,6 +119,10 @@ SERVER_OPT := \ --server.threads 4 \ $(SERVER_START) +if ENABLE_CLUSTER +SERVER_OPT += --cluster.agency-endpoint tcp://127.0.0.1:4001 --cluster.agency-prefix UnitTests --cluster.my-id arangod --cluster.my-address tcp://127.0.0.1:8529 +endif + CLIENT_OPT := \ --configuration none \ --javascript.startup-directory @top_srcdir@/js \ @@ -365,6 +369,9 @@ SHELL_COMMON = \ @top_srcdir@/js/common/tests/shell-download.js \ @top_srcdir@/js/common/tests/shell-edge.js \ @top_srcdir@/js/common/tests/shell-fs.js \ + @top_srcdir@/js/common/tests/shell-graph-traversal.js \ + @top_srcdir@/js/common/tests/shell-graph-algorithms.js \ + @top_srcdir@/js/common/tests/shell-graph-measurement.js \ @top_srcdir@/js/common/tests/shell-keygen.js \ @top_srcdir@/js/common/tests/shell-simple-query.js \ @top_srcdir@/js/common/tests/shell-statement.js \ @@ -388,22 +395,24 @@ SHELL_SERVER_ONLY = \ @top_srcdir@/js/server/tests/transactions.js \ @top_srcdir@/js/server/tests/routing.js \ @top_srcdir@/js/server/tests/shell-any.js \ - @top_srcdir@/js/common/tests/shell-bitarray-index.js \ + @top_srcdir@/js/server/tests/shell-bitarray-index.js \ @top_srcdir@/js/server/tests/shell-database.js \ - @top_srcdir@/js/common/tests/shell-foxx.js \ - @top_srcdir@/js/common/tests/shell-foxx-repository.js \ - @top_srcdir@/js/common/tests/shell-foxx-model.js \ - @top_srcdir@/js/common/tests/shell-foxx-base-middleware.js \ - @top_srcdir@/js/common/tests/shell-foxx-template-middleware.js \ - @top_srcdir@/js/common/tests/shell-foxx-format-middleware.js \ - @top_srcdir@/js/common/tests/shell-foxx-preprocessor.js \ - @top_srcdir@/js/common/tests/shell-graph-traversal.js \ - @top_srcdir@/js/common/tests/shell-graph-algorithms.js \ - @top_srcdir@/js/common/tests/shell-graph-measurement.js \ - @top_srcdir@/js/common/tests/shell-skiplist-index.js \ + @top_srcdir@/js/server/tests/shell-foxx.js \ + @top_srcdir@/js/server/tests/shell-foxx-repository.js \ + @top_srcdir@/js/server/tests/shell-foxx-model.js \ + @top_srcdir@/js/server/tests/shell-foxx-base-middleware.js \ + @top_srcdir@/js/server/tests/shell-foxx-template-middleware.js \ + @top_srcdir@/js/server/tests/shell-foxx-format-middleware.js \ + @top_srcdir@/js/server/tests/shell-foxx-preprocessor.js \ + @top_srcdir@/js/server/tests/shell-skiplist-index.js \ @top_srcdir@/js/server/tests/shell-skiplist-rm-performance.js \ @top_srcdir@/js/server/tests/shell-skiplist-correctness.js +if ENABLE_CLUSTER +SHELL_SERVER_ONLY += \ + @top_srcdir@/js/server/tests/agency.js +endif + SHELL_SERVER = $(SHELL_COMMON) $(SHELL_SERVER_ONLY) .PHONY: unittests-shell-server diff --git a/arangod/Ahuacatl/ahuacatl-functions.c b/arangod/Ahuacatl/ahuacatl-functions.c index 3f639a4ce4..973a1b48e5 100644 --- a/arangod/Ahuacatl/ahuacatl-functions.c +++ b/arangod/Ahuacatl/ahuacatl-functions.c @@ -150,6 +150,10 @@ static bool CheckArgumentType (TRI_aql_node_t const* parameter, const param_t* const allowed) { param_t found = InitParam(); + if (parameter->_type == TRI_AQL_NODE_REFERENCE) { + return true; + } + if (parameter->_type == TRI_AQL_NODE_PARAMETER) { // node is a bind parameter char* name = TRI_AQL_NODE_STRING(parameter); diff --git a/arangod/Cluster/AgencyComm.cpp b/arangod/Cluster/AgencyComm.cpp index a2ce046310..a0e0ace67d 100644 --- a/arangod/Cluster/AgencyComm.cpp +++ b/arangod/Cluster/AgencyComm.cpp @@ -132,6 +132,21 @@ std::string AgencyCommResult::errorMessage () const { return result; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief extract the error details from the result +/// if there is no error, an empty string will be returned +//////////////////////////////////////////////////////////////////////////////// + +std::string AgencyCommResult::errorDetails () const { + const std::string errorMessage = this->errorMessage(); + + if (errorMessage.empty()) { + return _message; + } + + return _message + " (" + errorMessage + ")"; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief recursively flatten the JSON response into a map //////////////////////////////////////////////////////////////////////////////// @@ -211,6 +226,7 @@ bool AgencyCommResult::processJsonNode (TRI_json_t const* node, // otherwise return value out[prefix] = std::string(value->_value._string.data, value->_value._string.length - 1); } + } } } @@ -297,7 +313,8 @@ AgencyConnectionOptions AgencyComm::_globalConnectionOptions = { /// @brief constructs an agency communication object //////////////////////////////////////////////////////////////////////////////// -AgencyComm::AgencyComm () { +AgencyComm::AgencyComm (bool addNewEndpoints) + : _addNewEndpoints(addNewEndpoints) { } //////////////////////////////////////////////////////////////////////////////// @@ -401,7 +418,8 @@ void AgencyComm::disconnect () { /// @brief adds an endpoint to the endpoints list //////////////////////////////////////////////////////////////////////////////// -bool AgencyComm::addEndpoint (std::string const& endpointSpecification) { +bool AgencyComm::addEndpoint (std::string const& endpointSpecification, + bool toFront) { LOG_TRACE("adding global endpoint '%s'", endpointSpecification.c_str()); { @@ -430,7 +448,12 @@ bool AgencyComm::addEndpoint (std::string const& endpointSpecification) { return false; } - AgencyComm::_globalEndpoints.push_back(agencyEndpoint); + if (toFront) { + AgencyComm::_globalEndpoints.push_front(agencyEndpoint); + } + else { + AgencyComm::_globalEndpoints.push_back(agencyEndpoint); + } } return true; @@ -501,6 +524,12 @@ bool AgencyComm::hasEndpoint (std::string const& endpointSpecification) { //////////////////////////////////////////////////////////////////////////////// void AgencyComm::setPrefix (std::string const& prefix) { + // agency prefix must not be changed + if (! _globalPrefix.empty() && prefix != _globalPrefix) { + LOG_ERROR("agency-prefix cannot be changed at runtime"); + return; + } + _globalPrefix = prefix; // make sure prefix starts with a forward slash @@ -518,6 +547,14 @@ void AgencyComm::setPrefix (std::string const& prefix) { LOG_TRACE("setting agency-prefix to '%s'", prefix.c_str()); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief gets the global prefix for all operations +//////////////////////////////////////////////////////////////////////////////// + +std::string AgencyComm::prefix () { + return _globalPrefix; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief generate a timestamp //////////////////////////////////////////////////////////////////////////////// @@ -539,6 +576,32 @@ std::string AgencyComm::generateStamp () { /// @brief get a stringified version of the endpoints //////////////////////////////////////////////////////////////////////////////// +const std::vector AgencyComm::getEndpoints () { + std::vector result; + + { + // iterate over the list of endpoints + READ_LOCKER(AgencyComm::_globalLock); + + std::list::const_iterator it = AgencyComm::_globalEndpoints.begin(); + + while (it != AgencyComm::_globalEndpoints.end()) { + AgencyEndpoint const* agencyEndpoint = (*it); + + assert(agencyEndpoint != 0); + + result.push_back(agencyEndpoint->_endpoint->getSpecification()); + ++it; + } + } + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief get a stringified version of the endpoints +//////////////////////////////////////////////////////////////////////////////// + const std::string AgencyComm::getEndpointsString () { std::string result; @@ -600,6 +663,27 @@ AgencyEndpoint* AgencyComm::createAgencyEndpoint (std::string const& endpointSpe // --SECTION-- public methods // ----------------------------------------------------------------------------- +//////////////////////////////////////////////////////////////////////////////// +/// @brief gets the backend version +//////////////////////////////////////////////////////////////////////////////// + +std::string AgencyComm::getVersion () { + AgencyCommResult result; + + sendWithFailover(triagens::rest::HttpRequest::HTTP_REQUEST_GET, + _globalConnectionOptions._requestTimeout, + result, + "version", + "", + false); + + if (result.successful()) { + return result._body; + } + + return ""; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief creates a directory in the backend //////////////////////////////////////////////////////////////////////////////// @@ -803,7 +887,7 @@ AgencyEndpoint* AgencyComm::popEndpoint () { /// @brief reinsert an endpoint into the queue //////////////////////////////////////////////////////////////////////////////// -bool AgencyComm::requeueEndpoint (AgencyEndpoint* agencyEndpoint, +void AgencyComm::requeueEndpoint (AgencyEndpoint* agencyEndpoint, bool wasWorking) { WRITE_LOCKER(AgencyComm::_globalLock); const size_t numEndpoints = _globalEndpoints.size(); @@ -825,8 +909,6 @@ bool AgencyComm::requeueEndpoint (AgencyEndpoint* agencyEndpoint, } assert(_globalEndpoints.size() == numEndpoints); - - return wasWorking; } //////////////////////////////////////////////////////////////////////////////// @@ -908,8 +990,21 @@ bool AgencyComm::sendWithFailover (triagens::rest::HttpRequest::HttpRequestType if (! AgencyComm::hasEndpoint(endpoint)) { // redirection to an unknown endpoint + + if (_addNewEndpoints) { + AgencyComm::addEndpoint(endpoint, true); + + // re-check the new endpoint + if (AgencyComm::hasEndpoint(endpoint)) { + ++numEndpoints; + continue; + } + } + LOG_ERROR("found redirection to unknown endpoint '%s'. Will not follow!", endpoint.c_str()); + + // this is an error return false; } @@ -917,10 +1012,16 @@ bool AgencyComm::sendWithFailover (triagens::rest::HttpRequest::HttpRequestType continue; } - // watches might time out, this still counts as a success - const bool wasSuccessful = result.successful() || (isWatch && result._statusCode == 0); + // we can stop iterating over endpoints if the operation succeeded, + // if a watch timed out or + // if the reason for failure was a client-side error + const bool canAbort = result.successful() || + (isWatch && result._statusCode == 0) || + (result._statusCode >= 400 && result._statusCode <= 499); - if (requeueEndpoint(agencyEndpoint, wasSuccessful)) { + requeueEndpoint(agencyEndpoint, canAbort); + + if (canAbort) { // we're done return true; } @@ -954,13 +1055,14 @@ bool AgencyComm::send (triagens::httpclient::GeneralClientConnection* connection assert(! url.empty()); result._statusCode = 0; - - LOG_TRACE("sending %s request to agency at endpoint '%s', url '%s': %s", + +/* + LOG_INFO("sending %s request to agency at endpoint '%s', url '%s': %s", triagens::rest::HttpRequest::translateMethod(method).c_str(), connection->getEndpoint()->getSpecification().c_str(), url.c_str(), body.c_str()); - + */ triagens::httpclient::SimpleHttpClient client(connection, timeout, false); @@ -1014,12 +1116,12 @@ bool AgencyComm::send (triagens::httpclient::GeneralClientConnection* connection if (found) { result._index = triagens::basics::StringUtils::uint64(lastIndex); } - - LOG_TRACE("request to agency returned status code %d, message: '%s', body: '%s'", +/* + LOG_INFO("request to agency returned status code %d, message: '%s', body: '%s'", result._statusCode, result._message.c_str(), result._body.c_str()); - +*/ delete response; return result.successful(); diff --git a/arangod/Cluster/AgencyComm.h b/arangod/Cluster/AgencyComm.h index a2798b8807..43391cc57e 100644 --- a/arangod/Cluster/AgencyComm.h +++ b/arangod/Cluster/AgencyComm.h @@ -147,6 +147,13 @@ namespace triagens { std::string errorMessage () const; +//////////////////////////////////////////////////////////////////////////////// +/// @brief extract the error details from the result +/// if there is no error, an empty string will be returned +//////////////////////////////////////////////////////////////////////////////// + + std::string errorDetails () const; + //////////////////////////////////////////////////////////////////////////////// /// @brief return the location header (might be empty) //////////////////////////////////////////////////////////////////////////////// @@ -202,7 +209,7 @@ namespace triagens { /// @brief creates a communication channel //////////////////////////////////////////////////////////////////////////////// - AgencyComm (); + AgencyComm (bool = true); //////////////////////////////////////////////////////////////////////////////// /// @brief destroys a communication channel @@ -236,31 +243,45 @@ namespace triagens { /// @brief adds an endpoint to the agents list //////////////////////////////////////////////////////////////////////////////// - static bool addEndpoint (std::string const&); + static bool addEndpoint (std::string const&, + bool = false); //////////////////////////////////////////////////////////////////////////////// /// @brief removes an endpoint from the agents list //////////////////////////////////////////////////////////////////////////////// static bool removeEndpoint (std::string const&); + //////////////////////////////////////////////////////////////////////////////// /// @brief checks if an endpoint is present //////////////////////////////////////////////////////////////////////////////// static bool hasEndpoint (std::string const&); +//////////////////////////////////////////////////////////////////////////////// +/// @brief get a stringified version of the endpoints +//////////////////////////////////////////////////////////////////////////////// + + static const std::vector getEndpoints (); + //////////////////////////////////////////////////////////////////////////////// /// @brief get a stringified version of the endpoints //////////////////////////////////////////////////////////////////////////////// static const std::string getEndpointsString (); - + //////////////////////////////////////////////////////////////////////////////// /// @brief sets the global prefix for all operations //////////////////////////////////////////////////////////////////////////////// static void setPrefix (std::string const&); +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the global prefix for all operations +//////////////////////////////////////////////////////////////////////////////// + + static std::string prefix (); + //////////////////////////////////////////////////////////////////////////////// /// @brief generate a timestamp //////////////////////////////////////////////////////////////////////////////// @@ -281,6 +302,12 @@ namespace triagens { // --SECTION-- public methods // ----------------------------------------------------------------------------- +//////////////////////////////////////////////////////////////////////////////// +/// @brief gets the backend version +//////////////////////////////////////////////////////////////////////////////// + + std::string getVersion (); + //////////////////////////////////////////////////////////////////////////////// /// @brief creates a directory in the backend //////////////////////////////////////////////////////////////////////////////// @@ -351,7 +378,7 @@ namespace triagens { /// @brief reinsert an endpoint into the queue //////////////////////////////////////////////////////////////////////////////// - bool requeueEndpoint (AgencyEndpoint*, + void requeueEndpoint (AgencyEndpoint*, bool); //////////////////////////////////////////////////////////////////////////////// @@ -389,22 +416,10 @@ namespace triagens { private: //////////////////////////////////////////////////////////////////////////////// -/// @brief connect timeout +/// @brief automatically add unknown endpoints if redirected to by agency? //////////////////////////////////////////////////////////////////////////////// - double _connectTimeout; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief request timeout -//////////////////////////////////////////////////////////////////////////////// - - double _requestTimeout; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief connect retries -//////////////////////////////////////////////////////////////////////////////// - - size_t _connectRetries; + bool _addNewEndpoints; // ----------------------------------------------------------------------------- // --SECTION-- private static variables diff --git a/arangod/Cluster/ApplicationCluster.cpp b/arangod/Cluster/ApplicationCluster.cpp index 7441d485ca..70d55df658 100644 --- a/arangod/Cluster/ApplicationCluster.cpp +++ b/arangod/Cluster/ApplicationCluster.cpp @@ -205,15 +205,20 @@ bool ApplicationCluster::start () { _myAddress.c_str()); } - ServerState::instance()->setRole(role); ServerState::instance()->setState(ServerState::STATE_STARTUP); + + AgencyComm comm; + const std::string version = comm.getVersion(); - LOG_INFO("Cluster feature is turned on. Server id: '%s', internal address: %s, role: %s, agency endpoints: %s", + LOG_INFO("Cluster feature is turned on. " + "Agency version: %s, Agency endpoints: %s, " + "server id: '%s', internal address: %s, role: %s", + version.c_str(), + endpoints.c_str(), _myId.c_str(), _myAddress.c_str(), - ServerState::roleToString(role).c_str(), - endpoints.c_str()); + ServerState::roleToString(role).c_str()); // start heartbeat thread _heartbeat = new HeartbeatThread(_myId, _heartbeatInterval * 1000, 5); diff --git a/arangod/Cluster/ApplicationCluster.h b/arangod/Cluster/ApplicationCluster.h index ad04cb3107..dace1d3c49 100644 --- a/arangod/Cluster/ApplicationCluster.h +++ b/arangod/Cluster/ApplicationCluster.h @@ -70,6 +70,10 @@ namespace triagens { public: +//////////////////////////////////////////////////////////////////////////////// +/// @brief whether or not the cluster is enabled +//////////////////////////////////////////////////////////////////////////////// + inline bool enabled () const { return _enableCluster; } diff --git a/arangod/RestServer/ArangoServer.cpp b/arangod/RestServer/ArangoServer.cpp index 77275fcc89..a2658607a9 100644 --- a/arangod/RestServer/ArangoServer.cpp +++ b/arangod/RestServer/ArangoServer.cpp @@ -277,7 +277,6 @@ ArangoServer::ArangoServer (int argc, char** argv) _databasePath(), _defaultMaximalSize(TRI_JOURNAL_DEFAULT_MAXIMAL_SIZE), _defaultWaitForSync(false), - _developmentMode(false), _forceSyncProperties(true), _unusedForceSyncShapes(false), _disableReplicationLogger(false), @@ -501,6 +500,7 @@ void ArangoServer::buildApplicationServer () { #ifdef TRI_ENABLE_CLUSTER _applicationCluster = new ApplicationCluster(); + if (_applicationCluster == 0) { LOG_FATAL_AND_EXIT("out of memory"); } @@ -576,10 +576,9 @@ void ArangoServer::buildApplicationServer () { // configure v8 w/ development-mode if (_applicationServer->programOptions().has("development-mode")) { - _developmentMode = true; _applicationV8->enableDevelopmentMode(); } - + // ............................................................................. // set language of default collator // ............................................................................. @@ -656,6 +655,12 @@ void ArangoServer::buildApplicationServer () { mode == OperationMode::MODE_UNITTESTS || mode == OperationMode::MODE_JSLINT || mode == OperationMode::MODE_SCRIPT) { + +#ifdef TRI_ENABLE_CLUSTER + // we need to prepare the cluster even in console mode + _applicationCluster->prepare(); +#endif + int res = executeConsole(mode); TRI_EXIT_FUNCTION(res, NULL); @@ -663,6 +668,11 @@ void ArangoServer::buildApplicationServer () { #ifdef TRI_ENABLE_MRUBY else if (mode == OperationMode::MODE_RUBY_CONSOLE) { + +#ifdef TRI_ENABLE_CLUSTER + // we need to prepare the cluster even in console mode + _applicationCluster->prepare(); +#endif int res = executeRubyConsole(); TRI_EXIT_FUNCTION(res, NULL); diff --git a/arangod/RestServer/ArangoServer.h b/arangod/RestServer/ArangoServer.h index 8c2267d389..a028775b14 100644 --- a/arangod/RestServer/ArangoServer.h +++ b/arangod/RestServer/ArangoServer.h @@ -349,21 +349,6 @@ namespace triagens { bool _defaultWaitForSync; -//////////////////////////////////////////////////////////////////////////////// -/// @brief development mode -/// -/// @CMDOPT{\--development-mode} -/// -/// Specifying this option will start the server in development mode. The -/// development mode forces reloading of all actions and Foxx applications on -/// every HTTP request. This is very resource-intensive and slow, but makes -/// developing server-side actions and Foxx applications much easier. -/// -/// Never use this option in production. -//////////////////////////////////////////////////////////////////////////////// - - bool _developmentMode; - //////////////////////////////////////////////////////////////////////////////// /// @brief force syncing of collection properties /// @@ -518,6 +503,21 @@ namespace triagens { string _defaultLanguage; +//////////////////////////////////////////////////////////////////////////////// +/// @brief development mode +/// +/// @CMDOPT{\--development-mode} +/// +/// Specifying this option will start the server in development mode. The +/// development mode forces reloading of all actions and Foxx applications on +/// every HTTP request. This is very resource-intensive and slow, but makes +/// developing server-side actions and Foxx applications much easier. +/// +/// Never use this option in production. +//////////////////////////////////////////////////////////////////////////////// + + bool _developmentMode; /* variable is only used for documentation generation */ + //////////////////////////////////////////////////////////////////////////////// /// @brief the server //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/V8Server/ApplicationV8.cpp b/arangod/V8Server/ApplicationV8.cpp index 7c8b1568b2..5c8903a088 100644 --- a/arangod/V8Server/ApplicationV8.cpp +++ b/arangod/V8Server/ApplicationV8.cpp @@ -764,8 +764,10 @@ bool ApplicationV8::prepareV8Instance (const size_t i) { { v8::HandleScope scope; - TRI_AddGlobalVariableVocbase(context->_context, "APP_PATH", v8::String::New(_appPath.c_str())); - TRI_AddGlobalVariableVocbase(context->_context, "DEV_APP_PATH", v8::String::New(_devAppPath.c_str())); + char const* logfile = TRI_GetFilenameLogging(); + TRI_AddGlobalVariableVocbase(context->_context, "LOGFILE_PATH", logfile != 0 ? v8::String::New(logfile) : v8::Null()); + TRI_AddGlobalVariableVocbase(context->_context, "APP_PATH", v8::String::New(_appPath.c_str(), _appPath.size())); + TRI_AddGlobalVariableVocbase(context->_context, "DEV_APP_PATH", v8::String::New(_devAppPath.c_str(), _devAppPath.size())); TRI_AddGlobalVariableVocbase(context->_context, "DEVELOPMENT_MODE", v8::Boolean::New(_developmentMode)); } diff --git a/arangod/V8Server/v8-vocbase.cpp b/arangod/V8Server/v8-vocbase.cpp index 59f64c682d..1baf69aa4d 100644 --- a/arangod/V8Server/v8-vocbase.cpp +++ b/arangod/V8Server/v8-vocbase.cpp @@ -76,6 +76,10 @@ #include "v8.h" #include "V8/JSLoader.h" +#ifdef TRI_ENABLE_CLUSTER +#include "Cluster/AgencyComm.h" +#endif + #include "unicode/timezone.h" #include "unicode/utypes.h" #include "unicode/datefmt.h" @@ -2205,6 +2209,309 @@ static TRI_general_cursor_t* UnwrapGeneralCursor (v8::Handle cursorO /// @} //////////////////////////////////////////////////////////////////////////////// +// ----------------------------------------------------------------------------- +// --SECTION-- agency functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief compares and swaps a value in the agency +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_CasAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() < 3) { + TRI_V8_EXCEPTION_USAGE(scope, "set(, , , )"); + } + + const std::string key = TRI_ObjectToString(argv[0]); + const std::string oldValue = TRI_ObjectToString(argv[1]); + const std::string newValue = TRI_ObjectToString(argv[2]); + + bool shouldThrow = false; + if (argv.Length() > 3) { + shouldThrow = TRI_ObjectToBoolean(argv[3]); + } + + AgencyComm comm; + AgencyCommResult result = comm.casValue(key, oldValue, newValue); + + if (! result.successful()) { + if (! shouldThrow) { + return scope.Close(v8::False()); + } + + const std::string errorDetails = result.errorDetails(); + v8::Handle err = v8::String::New(errorDetails.c_str(), errorDetails.size()); + return scope.Close(v8::ThrowException(err)); + } + + return scope.Close(v8::True()); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief creates a directory in the agency +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_CreateDirectoryAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() != 1) { + TRI_V8_EXCEPTION_USAGE(scope, "createDirectory()"); + } + + const std::string key = TRI_ObjectToString(argv[0]); + + AgencyComm comm; + AgencyCommResult result = comm.createDirectory(key); + + if (! result.successful()) { + const std::string errorDetails = result.errorDetails(); + v8::Handle err = v8::String::New(errorDetails.c_str(), errorDetails.size()); + return scope.Close(v8::ThrowException(err)); + } + + return scope.Close(v8::True()); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief gets a value from the agency +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_GetAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() < 1) { + TRI_V8_EXCEPTION_USAGE(scope, "get(, )"); + } + + const std::string key = TRI_ObjectToString(argv[0]); + bool recursive = false; + + if (argv.Length() > 1) { + recursive = TRI_ObjectToBoolean(argv[1]); + } + + AgencyComm comm; + AgencyCommResult result = comm.getValues(key, recursive); + + if (! result.successful()) { + const std::string errorDetails = result.errorDetails(); + v8::Handle err = v8::String::New(errorDetails.c_str(), errorDetails.size()); + return scope.Close(v8::ThrowException(err)); + } + + std::map out; + + result.flattenJson(out, "", false); + std::map::const_iterator it = out.begin(); + + v8::Handle l = v8::Object::New(); + + while (it != out.end()) { + const std::string key = (*it).first; + const std::string value = (*it).second; + + l->Set(v8::String::New(key.c_str(), key.size()), v8::String::New(value.c_str(), value.size())); + ++it; + } + + return scope.Close(l); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief removes a value from the agency +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_RemoveAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() < 1) { + TRI_V8_EXCEPTION_USAGE(scope, "remove(, )"); + } + + const std::string key = TRI_ObjectToString(argv[0]); + bool recursive = false; + + if (argv.Length() > 1) { + recursive = TRI_ObjectToBoolean(argv[1]); + } + + AgencyComm comm; + AgencyCommResult result = comm.removeValues(key, recursive); + + if (! result.successful()) { + const std::string errorDetails = result.errorDetails(); + v8::Handle err = v8::String::New(errorDetails.c_str(), errorDetails.size()); + return scope.Close(v8::ThrowException(err)); + } + + return scope.Close(v8::True()); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief sets a value in the agency +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_SetAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() < 2) { + TRI_V8_EXCEPTION_USAGE(scope, "set(, )"); + } + + const std::string key = TRI_ObjectToString(argv[0]); + const std::string value = TRI_ObjectToString(argv[1]); + + AgencyComm comm; + AgencyCommResult result = comm.setValue(key, value); + + if (! result.successful()) { + const std::string errorDetails = result.errorDetails(); + v8::Handle err = v8::String::New(errorDetails.c_str(), errorDetails.size()); + return scope.Close(v8::ThrowException(err)); + } + + return scope.Close(v8::True()); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief watches a value in the agency +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_WatchAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() < 1) { + TRI_V8_EXCEPTION_USAGE(scope, "watch(, , 1) { + waitIndex = TRI_ObjectToUInt64(argv[1], true); + } + if (argv.Length() > 2) { + timeout = TRI_ObjectToDouble(argv[2]); + } + + AgencyComm comm; + AgencyCommResult result = comm.watchValue(key, waitIndex, timeout); + + if (result._statusCode == 0) { + // watch timed out + return scope.Close(v8::False()); + } + + if (! result.successful()) { + const std::string errorDetails = result.errorDetails(); + v8::Handle err = v8::String::New(errorDetails.c_str(), errorDetails.size()); + return scope.Close(v8::ThrowException(err)); + } + + std::map out; + result.flattenJson(out, "", false); + std::map::const_iterator it = out.begin(); + + v8::Handle l = v8::Object::New(); + + while (it != out.end()) { + const std::string key = (*it).first; + const std::string value = (*it).second; + + l->Set(v8::String::New(key.c_str(), key.size()), v8::String::New(value.c_str(), value.size())); + ++it; + } + + return scope.Close(l); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the agency endpoints +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_EndpointsAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() != 0) { + TRI_V8_EXCEPTION_USAGE(scope, "endpoints()"); + } + + const std::vector endpoints = AgencyComm::getEndpoints(); + + v8::Handle l = v8::Array::New(); + + for (size_t i = 0; i < endpoints.size(); ++i) { + const std::string endpoint = endpoints[i]; + + l->Set((uint32_t) i, v8::String::New(endpoint.c_str(), endpoint.size())); + } + + return scope.Close(l); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the agency prefix +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_PrefixAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() != 0) { + TRI_V8_EXCEPTION_USAGE(scope, "prefix()"); + } + + const std::string prefix = AgencyComm::prefix(); + + return scope.Close(v8::String::New(prefix.c_str(), prefix.size())); +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the agency version +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + +static v8::Handle JS_VersionAgency (v8::Arguments const& argv) { + v8::HandleScope scope; + + if (argv.Length() != 0) { + TRI_V8_EXCEPTION_USAGE(scope, "version()"); + } + + AgencyComm comm; + const std::string version = comm.getVersion(); + + return scope.Close(v8::String::New(version.c_str(), version.size())); +} +#endif + // ----------------------------------------------------------------------------- // --SECTION-- javascript functions // ----------------------------------------------------------------------------- @@ -9027,6 +9334,31 @@ void TRI_InitV8VocBridge (v8::Handle context, TRI_AddGlobalFunctionVocbase(context, "LIST_ENDPOINTS", JS_ListEndpoints, true); TRI_AddGlobalFunctionVocbase(context, "RELOAD_AUTH", JS_ReloadAuth, true); TRI_AddGlobalFunctionVocbase(context, "TRANSACTION", JS_Transaction, true); + +#ifdef TRI_ENABLE_CLUSTER + // ............................................................................. + // generate the agency template + // ............................................................................. + + ft = v8::FunctionTemplate::New(); + ft->SetClassName(TRI_V8_SYMBOL("ArangoAgency")); + + rt = ft->InstanceTemplate(); + rt->SetInternalFieldCount(2); + + TRI_AddMethodVocbase(rt, "cas", JS_CasAgency); + TRI_AddMethodVocbase(rt, "createDirectory", JS_CreateDirectoryAgency); + TRI_AddMethodVocbase(rt, "get", JS_GetAgency); + TRI_AddMethodVocbase(rt, "remove", JS_RemoveAgency); + TRI_AddMethodVocbase(rt, "set", JS_SetAgency); + TRI_AddMethodVocbase(rt, "watch", JS_WatchAgency); + TRI_AddMethodVocbase(rt, "endpoints", JS_EndpointsAgency); + TRI_AddMethodVocbase(rt, "prefix", JS_PrefixAgency); + TRI_AddMethodVocbase(rt, "version", JS_VersionAgency); + + v8g->AgencyTempl = v8::Persistent::New(isolate, rt); + TRI_AddGlobalFunctionVocbase(context, "ArangoAgency", ft->GetFunction()); +#endif // ............................................................................. // create global variables diff --git a/js/actions/api-foxx.js b/js/actions/api-foxx.js index 91c94b40cb..bcc1e8491e 100644 --- a/js/actions/api-foxx.js +++ b/js/actions/api-foxx.js @@ -272,7 +272,8 @@ actions.defineHttp({ callback : function (req, res) { var result = { appPath: module.appPath(), - devAppPath: internal.developmentMode ? module.devAppPath() : null + devAppPath: internal.developmentMode ? module.devAppPath() : null, + logFilePath: internal.logfilePath }; actions.resultOk(req, res, actions.HTTP_OK, { result: result }); diff --git a/js/apps/system/aardvark/frontend/css/openSansFont.css b/js/apps/system/aardvark/frontend/css/openSansFont.css new file mode 100644 index 0000000000..b5d5cbf9ca --- /dev/null +++ b/js/apps/system/aardvark/frontend/css/openSansFont.css @@ -0,0 +1,36 @@ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/opensans/OpenSansLight.woff) format('woff'); +} +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans'), local('OpenSans'), url(../fonts/opensans/OpenSans.woff) format('woff'); +} +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/opensans/OpenSansBold.woff) format('woff'); +} +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 300; + src: local('Open Sans Light Italic'), local('OpenSansLight-Italic'), url(../fonts/opensans/OpenSansLightItalic.woff) format('woff'); +} +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), url(../fonts/opensans/OpenSansItalic.woff) format('woff'); +} +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 700; + src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), url(../fonts/opensans/OpenSansBoldItalic.woff) format('woff'); +} diff --git a/js/apps/system/aardvark/frontend/fonts/opensans/OpenSans.woff b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSans.woff new file mode 100644 index 0000000000..58e6cb3818 Binary files /dev/null and b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSans.woff differ diff --git a/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansBold.woff b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansBold.woff new file mode 100644 index 0000000000..a8b5bc261e Binary files /dev/null and b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansBold.woff differ diff --git a/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansBoldItalic.woff b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansBoldItalic.woff new file mode 100644 index 0000000000..6a1833811e Binary files /dev/null and b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansBoldItalic.woff differ diff --git a/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansItalic.woff b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansItalic.woff new file mode 100644 index 0000000000..039a294953 Binary files /dev/null and b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansItalic.woff differ diff --git a/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansLight.woff b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansLight.woff new file mode 100644 index 0000000000..8025ba6cb5 Binary files /dev/null and b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansLight.woff differ diff --git a/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansLightItalic.woff b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansLightItalic.woff new file mode 100644 index 0000000000..c1e29dc534 Binary files /dev/null and b/js/apps/system/aardvark/frontend/fonts/opensans/OpenSansLightItalic.woff differ diff --git a/js/apps/system/aardvark/frontend/js/bootstrap/module-internal.js b/js/apps/system/aardvark/frontend/js/bootstrap/module-internal.js index 08c19b2346..9da5250c43 100644 --- a/js/apps/system/aardvark/frontend/js/bootstrap/module-internal.js +++ b/js/apps/system/aardvark/frontend/js/bootstrap/module-internal.js @@ -18,7 +18,7 @@ COLOR_BOLD_WHITE, COLOR_YELLOW, COLOR_BOLD_YELLOW, COLOR_CYAN, COLOR_BOLD_CYAN, COLOR_MAGENTA, COLOR_BOLD_MAGENTA, PRETTY_PRINT, VALGRIND, VERSION, UPGRADE, BYTES_SENT_DISTRIBUTION, BYTES_RECEIVED_DISTRIBUTION, CONNECTION_TIME_DISTRIBUTION, - REQUEST_TIME_DISTRIBUTION, DEVELOPMENT_MODE, THREAD_NUMBER, + REQUEST_TIME_DISTRIBUTION, DEVELOPMENT_MODE, THREAD_NUMBER, LOGFILE_PATH, SYS_PLATFORM */ //////////////////////////////////////////////////////////////////////////////// @@ -128,6 +128,15 @@ SYS_LOG("warning", "################################################################################"); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief logfilePath +//////////////////////////////////////////////////////////////////////////////// + + if (typeof LOGFILE_PATH !== "undefined") { + exports.logfilePath = LOGFILE_PATH; + delete LOGFILE_PATH; + } + //////////////////////////////////////////////////////////////////////////////// /// @brief quiet //////////////////////////////////////////////////////////////////////////////// diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/jasmineTestLinks.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/jasmineTestLinks.html deleted file mode 100644 index 15bea4a365..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/jasmineTestLinks.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerAll.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerAll.html deleted file mode 100644 index b01e81a832..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerAll.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - Jasmine Test Graph Interface - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerArangoAdapter.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerArangoAdapter.html deleted file mode 100644 index 087559bd42..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerArangoAdapter.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - Jasmine Test Arango Adapter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerColourMapper.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerColourMapper.html deleted file mode 100644 index 31c88503fe..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerColourMapper.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - Jasmine Test Edge Shaper - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEdgeShaper.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEdgeShaper.html deleted file mode 100644 index 00dd0e8615..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEdgeShaper.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - Jasmine Test Edge Shaper - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEventDispatcher.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEventDispatcher.html deleted file mode 100644 index e712b76ba0..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEventDispatcher.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - Jasmine Test Event Dispatcher - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEventLibrary.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEventLibrary.html deleted file mode 100644 index 2f01364e18..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerEventLibrary.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - Jasmine Test Event Library - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerForceLayouter.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerForceLayouter.html deleted file mode 100644 index d11f56dff0..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerForceLayouter.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - Jasmine Test Force Layouter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerGraphViewer.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerGraphViewer.html deleted file mode 100644 index 7f2a9a5be6..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerGraphViewer.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - Jasmine Test Graph Viewer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerJSLint.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerJSLint.html deleted file mode 100644 index 1b4928c060..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerJSLint.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - Jasmine Test JSLint - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerJSONAdapter.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerJSONAdapter.html deleted file mode 100644 index fce1d07333..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerJSONAdapter.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - Jasmine Test JSON Adapter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerNodeReducer.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerNodeReducer.html deleted file mode 100644 index 25bf9a697a..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerNodeReducer.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - Jasmine Test Zoom Manager - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerNodeShaper.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerNodeShaper.html deleted file mode 100644 index 45089e852b..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerNodeShaper.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - Jasmine Test Node Shaper - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerZoomManager.html b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerZoomManager.html deleted file mode 100644 index 64776f4f75..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/runnerZoomManager.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - Jasmine Test Zoom Manager - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- Back to List -

- - diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/specJSLint/jsLintSpec.js b/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/specJSLint/jsLintSpec.js deleted file mode 100644 index fb48a51e0c..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/jasmine_test/specJSLint/jsLintSpec.js +++ /dev/null @@ -1,78 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */ -/*global beforeEach, afterEach */ -/*global describe, it, expect, jasmine, spyOn*/ -/*global waitsFor, runs, waits */ -/*global _, JSLINT*/ -/*global document*/ - -(function () { - "use strict"; - describe('JSLint', function () { - var options = {}, - lint = /^\/specJSLint|[\w\W]jsLintSpec\.js$/; - - function get(path) { - path = path + "?" + new Date().getTime(); - - var xhr; - try { - xhr = new jasmine.XmlHttpRequest(); - xhr.open("GET", path, false); - xhr.send(null); - } catch (e) { - throw new Error("couldn't fetch " + path + ": " + e); - } - if (xhr.status < 200 || xhr.status > 299) { - throw new Error("Could not load '" + path + "'."); - } - - return xhr.responseText; - } - - describe('checking codeFiles', function() { - var files = /^([\w\W]*lib\/[\w\W]*)|([\w\W]*Spec\.js)$/; - - _.each(document.getElementsByTagName('script'), function (element) { - var script = element.getAttribute('src'); - if (script === null || files.test(script)) { - return; - } - it(script, function () { - var self = this, - source = get(script), - result = JSLINT(source, options); - _.each(JSLINT.errors, function (error) { - self.addMatcherResult(new jasmine.ExpectationResult({ - passed: false, - message: "line " + error.line + ' - ' + error.reason + ' - ' + error.evidence - })); - }); - expect(true).toBe(true); // force spec to show up if there are no errors - }); - }); - }); - - describe('checking specFiles', function() { - var files = /^\/spec*|[\w\W]*Spec\.js$/; - - _.each(document.getElementsByTagName('script'), function (element) { - var script = element.getAttribute('src'); - if (!files.test(script) || lint.test(script)) { - return; - } - it(script, function () { - var self = this, - source = get(script), - result = JSLINT(source, options); - _.each(JSLINT.errors, function (error) { - self.addMatcherResult(new jasmine.ExpectationResult({ - passed: false, - message: "line " + error.line + ' - ' + error.reason + ' - ' + error.evidence - })); - }); - expect(true).toBe(true); // force spec to show up if there are no errors - }); - }); - }); - }); -}()); \ No newline at end of file diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/karma/karma.conf.js b/js/apps/system/aardvark/frontend/js/graphViewer/karma/karma.conf.js deleted file mode 100644 index 9350abdda2..0000000000 --- a/js/apps/system/aardvark/frontend/js/graphViewer/karma/karma.conf.js +++ /dev/null @@ -1,149 +0,0 @@ -// Karma configuration -// Generated on Thu Jul 04 2013 11:39:34 GMT+0200 (CEST) - -module.exports = function(karma) { - karma.set({ - - // base path, that will be used to resolve files and exclude - basePath: '../jasmine_test/', - - - // frameworks to use - frameworks: ['jasmine'], - - - // list of files / patterns to load in the browser - files: [ - 'lib/jasmine-1.3.1/jasmine-html.js', - 'lib/jslint.js', - '../../lib/d3.v3.min.js', - '../../lib/d3.fisheye.js', - '../../lib/underscore.js', - '../../lib/jquery-1.8.3.js', - '../../lib/bootstrap.js', - '../../lib/jquery.livequery.js', - '../../lib/jquery-ui-1.9.2.custom.js', - - // Mocks - 'helper/eventHelper.js', - 'helper/objectsHelper.js', - 'helper/mocks.js', - 'helper/commMock.js', - 'helper/uiMatchers.js', - - // Core Modules - '../graphViewer.js', - '../graph/domObserverFactory.js', - '../graph/colourMapper.js', - '../graph/communityNode.js', - '../graph/webWorkerWrapper.js', - '../graph/nodeShaper.js', - '../graph/abstractAdapter.js', - '../graph/jsonAdapter.js', - '../graph/arangoAdapter.js', - '../graph/foxxAdapter.js', - '../graph/previewAdapter.js', - '../graph/edgeShaper.js', - '../graph/forceLayouter.js', - '../graph/eventDispatcher.js', - '../graph/eventLibrary.js', - '../graph/zoomManager.js', - '../graph/nodeReducer.js', - '../graph/modularityJoiner.js', - // UI Modules - '../ui/modalDialogHelper.js', - '../ui/nodeShaperControls.js', - '../ui/edgeShaperControls.js', - '../ui/arangoAdapterControls.js', - '../ui/layouterControls.js', - '../ui/uiComponentsHelper.js', - '../ui/eventDispatcherControls.js', - '../ui/graphViewerUI.js', - '../ui/graphViewerWidget.js', - '../ui/graphViewerPreview.js', - - // Specs - - 'specColourMapper/colourMapperSpec.js', - 'specWindowObjects/domObserverFactorySpec.js', - 'specCommunityNode/communityNodeSpec.js', - 'specAdapter/interfaceSpec.js', - 'specAdapter/abstractAdapterSpec.js', - 'specAdapter/jsonAdapterSpec.js', - 'specAdapter/arangoAdapterSpec.js', - 'specAdapter/foxxAdapterSpec.js', - 'specAdapter/previewAdapterSpec.js', - 'specAdapter/arangoAdapterUISpec.js', - 'specNodeShaper/nodeShaperSpec.js', - 'specNodeShaper/nodeShaperUISpec.js', - 'specEdgeShaper/edgeShaperSpec.js', - 'specEdgeShaper/edgeShaperUISpec.js', - 'specForceLayouter/forceLayouterSpec.js', - 'specForceLayouter/forceLayouterUISpec.js', - 'specEvents/eventLibrarySpec.js', - 'specEvents/eventDispatcherSpec.js', - 'specEvents/eventDispatcherUISpec.js', - 'specZoomManager/zoomManagerSpec.js', - 'specGraphViewer/graphViewerSpec.js', - 'specGraphViewer/graphViewerUISpec.js', - 'specGraphViewer/graphViewerWidgetSpec.js', - 'specGraphViewer/graphViewerPreviewSpec.js', - 'specNodeReducer/nodeReducerSpec.js', - 'specNodeReducer/modularityJoinerSpec.js', - 'specWindowObjects/workerWrapperSpec.js', - 'specJSLint/jsLintSpec.js' - ], - - - // list of files to exclude - exclude: [ - - ], - - - // test results reporter to use - // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' - reporters: ['progress'], - - - // web server port - port: 9876, - - - // cli runner port - runnerPort: 9100, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: karma.LOG_DISABLE || karma.LOG_ERROR || karma.LOG_WARN || karma.LOG_INFO || karma.LOG_DEBUG - logLevel: karma.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - - // Start these browsers, currently available: - // - Chrome - // - ChromeCanary - // - Firefox - // - Opera - // - Safari (only Mac) - // - PhantomJS - // - IE (only Windows) - browsers: [], - - - // If browser does not capture in given timeout [ms], kill it - captureTimeout: 60000, - - - // Continuous Integration mode - // if true, it capture browsers, run tests and exit - singleRun: false - }); -}; diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/ui/arangoAdapterControls.js b/js/apps/system/aardvark/frontend/js/graphViewer/ui/arangoAdapterControls.js index c2d62d24fb..860cb4064d 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/ui/arangoAdapterControls.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/ui/arangoAdapterControls.js @@ -37,15 +37,13 @@ function ArangoAdapterControls(list, adapter) { if (adapter === undefined) { throw "The ArangoAdapter has to be given."; } - var baseClass = "adapter"; - this.addControlChangeCollections = function(callback) { var prefix = "control_adapter_collections", idprefix = prefix + "_"; adapter.getCollections(function(nodeCols, edgeCols) { adapter.getGraphs(function(graphs) { - uiComponentsHelper.createButton(baseClass, list, "Collections", prefix, function() { + uiComponentsHelper.createButton(list, "Collections", prefix, function() { modalDialogHelper.createModalDialog("Switch Collections", idprefix, [{ type: "decission", @@ -132,7 +130,7 @@ function ArangoAdapterControls(list, adapter) { prioList = adapter.getPrioList(), label = "Group vertices"; - uiComponentsHelper.createButton(baseClass, list, label, prefix, function() { + uiComponentsHelper.createButton(list, label, prefix, function() { modalDialogHelper.createModalChangeDialog(label, idprefix, [{ type: "extendable", @@ -155,7 +153,7 @@ function ArangoAdapterControls(list, adapter) { }); /* adapter.getCollections(function(nodeCols, edgeCols) { - uiComponentsHelper.createButton(baseClass, list, "Collections", prefix, function() { + uiComponentsHelper.createButton(list, "Collections", prefix, function() { modalDialogHelper.createModalDialog("Switch Collections", idprefix, [{ type: "list", diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/ui/edgeShaperControls.js b/js/apps/system/aardvark/frontend/js/graphViewer/ui/edgeShaperControls.js index 6df9be8843..ea8de4b218 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/ui/edgeShaperControls.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/ui/edgeShaperControls.js @@ -37,13 +37,12 @@ function EdgeShaperControls(list, shaper) { if (shaper === undefined) { throw "The EdgeShaper has to be given."; } - var self = this, - baseClass = "graph"; + var self = this; this.addControlOpticShapeNone = function() { var prefix = "control_edge_none", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "None", prefix, function() { + uiComponentsHelper.createButton(list, "None", prefix, function() { shaper.changeTo({ shape: { type: EdgeShaper.shapes.NONE @@ -55,7 +54,7 @@ function EdgeShaperControls(list, shaper) { this.addControlOpticShapeArrow = function() { var prefix = "control_edge_arrow", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Arrow", prefix, function() { + uiComponentsHelper.createButton(list, "Arrow", prefix, function() { shaper.changeTo({ shape: { type: EdgeShaper.shapes.ARROW @@ -69,7 +68,7 @@ function EdgeShaperControls(list, shaper) { this.addControlOpticLabel = function() { var prefix = "control_edge_label", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Label", prefix, function() { + uiComponentsHelper.createButton(list, "Label", prefix, function() { modalDialogHelper.createModalDialog("Switch Label Attribute", idprefix, [{ type: "text", @@ -90,7 +89,7 @@ function EdgeShaperControls(list, shaper) { this.addControlOpticSingleColour = function() { var prefix = "control_edge_singlecolour", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Single Colour", prefix, function() { + uiComponentsHelper.createButton(list, "Single Colour", prefix, function() { modalDialogHelper.createModalDialog("Switch to Colour", idprefix, [{ type: "text", @@ -111,7 +110,7 @@ function EdgeShaperControls(list, shaper) { this.addControlOpticAttributeColour = function() { var prefix = "control_edge_attributecolour", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Colour by Attribute", prefix, function() { + uiComponentsHelper.createButton(list, "Colour by Attribute", prefix, function() { modalDialogHelper.createModalDialog("Display colour by attribute", idprefix, [{ type: "text", @@ -132,7 +131,7 @@ function EdgeShaperControls(list, shaper) { this.addControlOpticGradientColour = function() { var prefix = "control_edge_gradientcolour", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Gradient Colour", prefix, function() { + uiComponentsHelper.createButton(list, "Gradient Colour", prefix, function() { modalDialogHelper.createModalDialog("Change colours for gradient", idprefix, [{ type: "text", @@ -173,4 +172,4 @@ function EdgeShaperControls(list, shaper) { self.addAllActions(); }; -} \ No newline at end of file +} diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/ui/eventDispatcherControls.js b/js/apps/system/aardvark/frontend/js/graphViewer/ui/eventDispatcherControls.js index e53e353349..538c44c96a 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/ui/eventDispatcherControls.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/ui/eventDispatcherControls.js @@ -76,7 +76,6 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig) edit: "edit", view: "view" }, - baseClass = "event", dispatcher = new EventDispatcher(nodeShaper, edgeShaper, dispatcherConfig), setCursorIcon = function(icon) { @@ -102,7 +101,6 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig) }, createButton = function(title, callback) { uiComponentsHelper.createButton( - baseClass, list, title, "control_event_" + title, diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/ui/graphViewerUI.js b/js/apps/system/aardvark/frontend/js/graphViewer/ui/graphViewerUI.js index fd9d088f4e..06edd75a2f 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/ui/graphViewerUI.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/ui/graphViewerUI.js @@ -299,9 +299,9 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConf slider = document.createElement("div"); slider.id = "gv_zoom_slider"; slider.className = "gv_zoom_slider"; - + + background.appendChild(zoomUI); background.insertBefore(zoomUI, svg[0][0]); - zoomUI.appendChild(zoomButtons); zoomUI.appendChild(slider); $( "#gv_zoom_slider" ).slider({ diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/ui/layouterControls.js b/js/apps/system/aardvark/frontend/js/graphViewer/ui/layouterControls.js index 88e4272af8..e5f90dd141 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/ui/layouterControls.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/ui/layouterControls.js @@ -37,13 +37,12 @@ function LayouterControls(list, layouter) { if (layouter === undefined) { throw "The Layouter has to be given."; } - var self = this, - baseClass = "layout"; + var self = this; this.addControlGravity = function() { var prefix = "control_layout_gravity", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Gravity", prefix, function() { + uiComponentsHelper.createButton(list, "Gravity", prefix, function() { modalDialogHelper.createModalDialog("Switch Gravity Strength", idprefix, [{ type: "text", @@ -61,7 +60,7 @@ function LayouterControls(list, layouter) { this.addControlCharge = function() { var prefix = "control_layout_charge", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Charge", prefix, function() { + uiComponentsHelper.createButton(list, "Charge", prefix, function() { modalDialogHelper.createModalDialog("Switch Charge Strength", idprefix, [{ type: "text", @@ -79,7 +78,7 @@ function LayouterControls(list, layouter) { this.addControlDistance = function() { var prefix = "control_layout_distance", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Distance", prefix, function() { + uiComponentsHelper.createButton(list, "Distance", prefix, function() { modalDialogHelper.createModalDialog("Switch Distance Strength", idprefix, [{ type: "text", @@ -101,4 +100,4 @@ function LayouterControls(list, layouter) { self.addControlCharge(); }; -} \ No newline at end of file +} diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/ui/nodeShaperControls.js b/js/apps/system/aardvark/frontend/js/graphViewer/ui/nodeShaperControls.js index 1f058b7d4f..ea0e7edfda 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/ui/nodeShaperControls.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/ui/nodeShaperControls.js @@ -38,7 +38,6 @@ function NodeShaperControls(list, shaper) { throw "The NodeShaper has to be given."; } var self = this, - baseClass = "graph", colourDiv, fillColourDiv = function(mapping) { @@ -63,7 +62,7 @@ function NodeShaperControls(list, shaper) { }; this.addControlOpticShapeNone = function() { - uiComponentsHelper.createButton(baseClass, list, "None", "control_node_none", function() { + uiComponentsHelper.createButton(list, "None", "control_node_none", function() { shaper.changeTo({ shape: { type: NodeShaper.shapes.NONE @@ -75,7 +74,7 @@ function NodeShaperControls(list, shaper) { this.addControlOpticShapeCircle = function() { var prefix = "control_node_circle", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Circle", prefix, function() { + uiComponentsHelper.createButton(list, "Circle", prefix, function() { modalDialogHelper.createModalDialog("Switch to Circle", idprefix, [{ type: "text", @@ -96,7 +95,7 @@ function NodeShaperControls(list, shaper) { this.addControlOpticShapeRect = function() { var prefix = "control_node_rect", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Rectangle", prefix, function() { + uiComponentsHelper.createButton(list, "Rectangle", prefix, function() { modalDialogHelper.createModalDialog("Switch to Rectangle", "control_node_rect_", [{ type: "text", @@ -122,7 +121,7 @@ function NodeShaperControls(list, shaper) { this.addControlOpticLabel = function() { var prefix = "control_node_label", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Label", prefix, function() { + uiComponentsHelper.createButton(list, "Label", prefix, function() { modalDialogHelper.createModalChangeDialog("Change label attribute", idprefix, [{ type: "text", @@ -144,7 +143,7 @@ function NodeShaperControls(list, shaper) { this.addControlOpticSingleColour = function() { var prefix = "control_node_singlecolour", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Single Colour", prefix, function() { + uiComponentsHelper.createButton(list, "Single Colour", prefix, function() { modalDialogHelper.createModalDialog("Switch to Colour", idprefix, [{ type: "text", @@ -170,7 +169,7 @@ function NodeShaperControls(list, shaper) { this.addControlOpticAttributeColour = function() { var prefix = "control_node_attributecolour", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Colour by Attribute", prefix, function() { + uiComponentsHelper.createButton(list, "Colour by Attribute", prefix, function() { modalDialogHelper.createModalDialog("Display colour by attribute", idprefix, [{ type: "text", @@ -191,7 +190,7 @@ function NodeShaperControls(list, shaper) { this.addControlOpticExpandColour = function() { var prefix = "control_node_expandcolour", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Expansion Colour", prefix, function() { + uiComponentsHelper.createButton(list, "Expansion Colour", prefix, function() { modalDialogHelper.createModalDialog("Display colours for expansion", idprefix, [{ type: "text", @@ -221,7 +220,7 @@ function NodeShaperControls(list, shaper) { this.addControlOpticLabelAndColour = function(adapter) { var prefix = "control_node_labelandcolour", idprefix = prefix + "_"; - uiComponentsHelper.createButton(baseClass, list, "Label", prefix, function() { + uiComponentsHelper.createButton(list, "Label", prefix, function() { modalDialogHelper.createModalChangeDialog("Change label attribute", idprefix, [{ type: "text", diff --git a/js/apps/system/aardvark/frontend/js/graphViewer/ui/uiComponentsHelper.js b/js/apps/system/aardvark/frontend/js/graphViewer/ui/uiComponentsHelper.js index 323d998190..8ded61658e 100644 --- a/js/apps/system/aardvark/frontend/js/graphViewer/ui/uiComponentsHelper.js +++ b/js/apps/system/aardvark/frontend/js/graphViewer/ui/uiComponentsHelper.js @@ -33,23 +33,24 @@ var uiComponentsHelper = uiComponentsHelper || {}; (function componentsHelper() { "use strict"; - uiComponentsHelper.createButton = function(baseclass, list, title, prefix, callback) { + uiComponentsHelper.createButton = function(list, title, prefix, callback) { var li = document.createElement("li"), button = document.createElement("button"); - li.className = baseclass + "_control " + prefix; + li.className = "graph_control " + prefix; li.id = prefix; li.appendChild(button); button.className = "btn btn-primary gv_dropdown_entry"; button.appendChild(document.createTextNode(title)); list.appendChild(li); + button.id = prefix + "_button"; button.onclick = callback; }; - uiComponentsHelper.createListEntry = function(baseclass, list, title, prefix, callback) { + uiComponentsHelper.createListEntry = function(list, title, prefix, callback) { var button = document.createElement("li"), a = document.createElement("a"), label = document.createElement("label"); - button.className = baseclass + "_control " + prefix; + button.className = "graph_control " + prefix; button.id = prefix; button.appendChild(a); a.className = "gv_dropdown_entry"; diff --git a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph-common.js b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph-common.js index 9d7fe9811e..62db68571a 100644 --- a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph-common.js +++ b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph-common.js @@ -523,6 +523,30 @@ Vertex.prototype.addOutEdge = function (ine, id, label, data) { return this._graph.addEdge(this, ine, id, label, data); }; +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the number of edges +//////////////////////////////////////////////////////////////////////////////// + +Vertex.prototype.degree = function () { + return this.getEdges().length; +}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the number of in-edges +//////////////////////////////////////////////////////////////////////////////// + +Vertex.prototype.inDegree = function () { + return this.getInEdges().length; +}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the number of out-edges +//////////////////////////////////////////////////////////////////////////////// + +Vertex.prototype.outDegree = function () { + return this.getOutEdges().length; +}; + //////////////////////////////////////////////////////////////////////////////// /// @brief returns the identifier of a vertex /// diff --git a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph.js b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph.js index 2ae475c90b..82b7a7df06 100644 --- a/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph.js +++ b/js/apps/system/aardvark/frontend/js/modules/org/arangodb/graph.js @@ -60,6 +60,7 @@ Edge.prototype.setProperty = function (name, value) { update = this._properties; update[name] = value; + this._graph.emptyCachedPredecessors(); results = GraphAPI.putEdge(this._graph._properties._key, this._properties._key, update); @@ -279,6 +280,8 @@ Graph.prototype.drop = function () { Graph.prototype._saveEdge = function(id, out_vertex_id, in_vertex_id, params) { var results; + + this.emptyCachedPredecessors(); params._key = id; params._from = out_vertex_id; @@ -379,6 +382,7 @@ Graph.prototype.getEdges = function () { //////////////////////////////////////////////////////////////////////////////// Graph.prototype.removeVertex = function (vertex) { + this.emptyCachedPredecessors(); GraphAPI.deleteVertex(this._properties._key, vertex._properties._key); vertex._properties = undefined; }; @@ -388,7 +392,9 @@ Graph.prototype.removeVertex = function (vertex) { //////////////////////////////////////////////////////////////////////////////// Graph.prototype.removeEdge = function (edge) { + this.emptyCachedPredecessors(); GraphAPI.deleteEdge(this._properties._key, edge._properties._key); + this._edgesCache[edge._properties._id] = undefined; edge._properties = undefined; }; diff --git a/js/apps/system/aardvark/frontend/js/templates/queryView.ejs b/js/apps/system/aardvark/frontend/js/templates/queryView.ejs index 26c26e0986..3c59150a76 100644 --- a/js/apps/system/aardvark/frontend/js/templates/queryView.ejs +++ b/js/apps/system/aardvark/frontend/js/templates/queryView.ejs @@ -61,6 +61,7 @@
Submit: CTRL/CMD + Return ; Undo: CTRL/CMD + Z ; Redo: CTRL/CMD + SHIFT + Z ; Toggle Comments: CTRL/CMD + SHIFT + C +
Warning: Right now there is a bug in Safari, the cursor is misplaced. Please use a different browser for now. Fix in progress.
diff --git a/js/apps/system/aardvark/index.html b/js/apps/system/aardvark/index.html index 650b762443..811a0bbd83 100644 --- a/js/apps/system/aardvark/index.html +++ b/js/apps/system/aardvark/index.html @@ -9,7 +9,7 @@ - + diff --git a/js/apps/system/aardvark/manifest.json b/js/apps/system/aardvark/manifest.json index 39d91675de..d62b11b581 100644 --- a/js/apps/system/aardvark/manifest.json +++ b/js/apps/system/aardvark/manifest.json @@ -75,7 +75,7 @@ "frontend/js/lib/handlebars-1.0.rc.1.js", "frontend/js/lib/underscore.js", "frontend/js/lib/backbone.js", - "frontend/js/lib/d3.v3.js", + "frontend/js/lib/d3.v3.min.js", "frontend/js/lib/nv.d3.js", "frontend/js/lib/d3.fisheye.js", "frontend/js/lib/ColVis.js", @@ -93,6 +93,7 @@ "css/style.css": { "files": [ + "frontend/css/openSansFont.css", "frontend/css/swagger/hightlight.default.css", "frontend/css/bootstrap.css", "frontend/css/arangodbIcons.css", diff --git a/js/apps/system/aardvark/test/karma/karma.conf.js b/js/apps/system/aardvark/test/karma/karma.conf.js index 15abb81f54..bf1789595d 100644 --- a/js/apps/system/aardvark/test/karma/karma.conf.js +++ b/js/apps/system/aardvark/test/karma/karma.conf.js @@ -32,7 +32,7 @@ module.exports = function(karma) { 'frontend/js/lib/handlebars-1.0.rc.1.js', 'frontend/js/lib/underscore.js', 'frontend/js/lib/backbone.js', - 'frontend/js/lib/d3.v3.js', + 'frontend/js/lib/d3.v3.min.js', 'frontend/js/lib/nv.d3.js', 'frontend/js/lib/d3.fisheye.js', 'frontend/js/lib/ejs_0.9_alpha_1_production.js', @@ -171,9 +171,7 @@ module.exports = function(karma) { //Templates {pattern: 'frontend/js/templates/*.ejs', served:true, included:false, watched: true}, - // Specs - // GraphViewer 'test/specs/graphViewer/specColourMapper/colourMapperSpec.js', 'test/specs/graphViewer/specWindowObjects/domObserverFactorySpec.js', @@ -184,23 +182,23 @@ module.exports = function(karma) { 'test/specs/graphViewer/specAdapter/arangoAdapterSpec.js', 'test/specs/graphViewer/specAdapter/foxxAdapterSpec.js', 'test/specs/graphViewer/specAdapter/previewAdapterSpec.js', - // 'test/specs/graphViewer/specAdapter/arangoAdapterUISpec.js', + 'test/specs/graphViewer/specAdapter/arangoAdapterUISpec.js', 'test/specs/graphViewer/specNodeShaper/nodeShaperSpec.js', - // 'test/specs/graphViewer/specNodeShaper/nodeShaperUISpec.js', + 'test/specs/graphViewer/specNodeShaper/nodeShaperUISpec.js', 'test/specs/graphViewer/specEdgeShaper/edgeShaperSpec.js', - // 'test/specs/graphViewer/specEdgeShaper/edgeShaperUISpec.js', + 'test/specs/graphViewer/specEdgeShaper/edgeShaperUISpec.js', 'test/specs/graphViewer/specForceLayouter/forceLayouterSpec.js', - // 'test/specs/graphViewer/specForceLayouter/forceLayouterUISpec.js', + 'test/specs/graphViewer/specForceLayouter/forceLayouterUISpec.js', 'test/specs/graphViewer/specEvents/eventLibrarySpec.js', 'test/specs/graphViewer/specEvents/eventDispatcherSpec.js', - // 'test/specs/graphViewer/specEvents/eventDispatcherUISpec.js', - // 'test/specs/graphViewer/specZoomManager/zoomManagerSpec.js', - // 'test/specs/graphViewer/specGraphViewer/graphViewerSpec.js', + 'test/specs/graphViewer/specEvents/eventDispatcherUISpec.js', + 'test/specs/graphViewer/specZoomManager/zoomManagerSpec.js', + 'test/specs/graphViewer/specGraphViewer/graphViewerSpec.js', 'test/specs/graphViewer/specGraphViewer/graphViewerUISpec.js', 'test/specs/graphViewer/specGraphViewer/graphViewerWidgetSpec.js', 'test/specs/graphViewer/specGraphViewer/graphViewerPreviewSpec.js', 'test/specs/graphViewer/specNodeReducer/nodeReducerSpec.js', - // 'test/specs/graphViewer/specNodeReducer/modularityJoinerSpec.js', + 'test/specs/graphViewer/specNodeReducer/modularityJoinerSpec.js', 'test/specs/graphViewer/specWindowObjects/workerWrapperSpec.js', // Arango @@ -221,7 +219,6 @@ module.exports = function(karma) { // Router 'test/specs/router/routerSpec.js', - // JSLint 'test/specJSLint/jsLintSpec.js' ], diff --git a/js/apps/system/aardvark/test/specs/graphViewer/helper/uiMatchers.js b/js/apps/system/aardvark/test/specs/graphViewer/helper/uiMatchers.js index 53f9584ceb..c9a6166292 100644 --- a/js/apps/system/aardvark/test/specs/graphViewer/helper/uiMatchers.js +++ b/js/apps/system/aardvark/test/specs/graphViewer/helper/uiMatchers.js @@ -95,7 +95,6 @@ var uiMatchers = uiMatchers || {}; expect(btn).toBeTag("button"); expect(btn).toBeOfClass("btn"); expect(btn).toBeOfClass("btn-icon"); - // Correctness of buttons is checked in eventDispatcherUISpec. }); return true; }, diff --git a/js/apps/system/aardvark/test/specs/graphViewer/specAdapter/arangoAdapterUISpec.js b/js/apps/system/aardvark/test/specs/graphViewer/specAdapter/arangoAdapterUISpec.js index 46eee15b42..52b365409d 100644 --- a/js/apps/system/aardvark/test/specs/graphViewer/specAdapter/arangoAdapterUISpec.js +++ b/js/apps/system/aardvark/test/specs/graphViewer/specAdapter/arangoAdapterUISpec.js @@ -100,12 +100,13 @@ var idPrefix = "#control_adapter_collections"; beforeEach(function() { - adapterUI.addControlChangeCollections(); - - expect($("#control_adapter_list " + idPrefix).length).toEqual(1); - expect($("#control_adapter_list " + idPrefix)[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_adapter_collections"); - expect($(idPrefix + "_modal").length).toEqual(1); + runs(function() { + adapterUI.addControlChangeCollections(); + expect($("#control_adapter_list " + idPrefix).length).toEqual(1); + expect($("#control_adapter_list " + idPrefix)[0]).toConformToListCSS(); + helper.simulateMouseEvent("click", idPrefix.substr(1) + "_button"); + expect($(idPrefix + "_modal").length).toEqual(1); + }); }); afterEach(function() { @@ -191,25 +192,29 @@ }); describe('change priority list control', function() { + + var idPrefix; + beforeEach(function() { + idPrefix = "#control_adapter_priority"; adapterUI.addControlChangePriority(); - expect($("#control_adapter_list #control_adapter_priority").length).toEqual(1); - expect($("#control_adapter_list #control_adapter_priority")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_adapter_priority"); - expect($("#control_adapter_priority_modal").length).toEqual(1); + expect($("#control_adapter_list " + idPrefix).length).toEqual(1); + expect($("#control_adapter_list " + idPrefix)[0]).toConformToListCSS(); + helper.simulateMouseEvent("click", idPrefix.substr(1) + "_button"); + expect($(idPrefix + "_modal").length).toEqual(1); }); afterEach(function() { waitsFor(function() { - return $("#control_adapter_priority_modal").length === 0; + return $(idPrefix + "_modal").length === 0; }, 2000, "The modal dialog should disappear."); }); it('should be added to the list', function() { runs(function() { - $("#control_adapter_priority_attribute_1").attr("value", "foo"); - helper.simulateMouseEvent("click", "control_adapter_priority_submit"); + $(idPrefix + "_attribute_1").attr("value", "foo"); + helper.simulateMouseEvent("click", idPrefix.substr(1) + "_submit"); expect(adapter.changeTo).toHaveBeenCalledWith({ prioList: ["foo"] }); @@ -218,8 +223,8 @@ it('should not add empty attributes to priority', function() { runs(function() { - $("#control_adapter_priority_attribute_1").attr("value", ""); - helper.simulateMouseEvent("click", "control_adapter_priority_submit"); + $(idPrefix + "_attribute_1").attr("value", ""); + helper.simulateMouseEvent("click", idPrefix.substr(1) + "_submit"); expect(adapter.changeTo).toHaveBeenCalledWith({ prioList: [] }); @@ -228,13 +233,13 @@ it('should add a new line to priority on demand', function() { runs(function() { - helper.simulateMouseEvent("click", "control_adapter_priority_attribute_addLine"); - expect($("#control_adapter_priority_attribute_1").length).toEqual(1); - expect($("#control_adapter_priority_attribute_2").length).toEqual(1); - expect($("#control_adapter_priority_attribute_addLine").length).toEqual(1); - $("#control_adapter_priority_attribute_1").attr("value", "foo"); - $("#control_adapter_priority_attribute_2").attr("value", "bar"); - helper.simulateMouseEvent("click", "control_adapter_priority_submit"); + helper.simulateMouseEvent("click", idPrefix.substr(1) + "_attribute_addLine"); + expect($(idPrefix + "_attribute_1").length).toEqual(1); + expect($(idPrefix + "_attribute_2").length).toEqual(1); + expect($(idPrefix + "_attribute_addLine").length).toEqual(1); + $(idPrefix + "_attribute_1").attr("value", "foo"); + $(idPrefix + "_attribute_2").attr("value", "bar"); + helper.simulateMouseEvent("click", idPrefix.substr(1) + "_submit"); expect(adapter.changeTo).toHaveBeenCalledWith({ prioList: ["foo", "bar"] }); @@ -291,6 +296,8 @@ }); }); }); + + /* TO_DO it('should load the current prioList from the adapter', function() { @@ -326,7 +333,7 @@ helper.simulateMouseEvent("click", "control_adapter_priority_cancel"); }); }); - + */ }); it('should be able to add all controls to the list', function() { diff --git a/js/apps/system/aardvark/test/specs/graphViewer/specEdgeShaper/edgeShaperUISpec.js b/js/apps/system/aardvark/test/specs/graphViewer/specEdgeShaper/edgeShaperUISpec.js index 3a077736b2..7a09038815 100644 --- a/js/apps/system/aardvark/test/specs/graphViewer/specEdgeShaper/edgeShaperUISpec.js +++ b/js/apps/system/aardvark/test/specs/graphViewer/specEdgeShaper/edgeShaperUISpec.js @@ -74,7 +74,7 @@ expect($("#control_edge_list #control_edge_none").length).toEqual(1); expect($("#control_edge_list #control_edge_none")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_edge_none"); + helper.simulateMouseEvent("click", "control_edge_none_button"); expect(shaper.changeTo).toHaveBeenCalledWith({ shape: { @@ -91,7 +91,7 @@ expect($("#control_edge_list #control_edge_arrow").length).toEqual(1); expect($("#control_edge_list #control_edge_arrow")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_edge_arrow"); + helper.simulateMouseEvent("click", "control_edge_arrow_button"); expect(shaper.changeTo).toHaveBeenCalledWith({ shape: { @@ -109,7 +109,7 @@ expect($("#control_edge_list #control_edge_label").length).toEqual(1); expect($("#control_edge_list #control_edge_label")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_edge_label"); + helper.simulateMouseEvent("click", "control_edge_label_button"); $("#control_edge_label_key").attr("value", "theAnswer"); helper.simulateMouseEvent("click", "control_edge_label_submit"); @@ -131,7 +131,7 @@ expect($("#control_edge_list #control_edge_singlecolour").length).toEqual(1); expect($("#control_edge_list #control_edge_singlecolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_edge_singlecolour"); + helper.simulateMouseEvent("click", "control_edge_singlecolour_button"); $("#control_edge_singlecolour_stroke").attr("value", "#123456"); helper.simulateMouseEvent("click", "control_edge_singlecolour_submit"); @@ -156,7 +156,7 @@ expect($("#control_edge_list #control_edge_attributecolour").length).toEqual(1); expect($("#control_edge_list #control_edge_attributecolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_edge_attributecolour"); + helper.simulateMouseEvent("click", "control_edge_attributecolour_button"); $("#control_edge_attributecolour_key").attr("value", "label"); helper.simulateMouseEvent("click", "control_edge_attributecolour_submit"); @@ -181,7 +181,7 @@ expect($("#control_edge_list #control_edge_gradientcolour").length).toEqual(1); expect($("#control_edge_list #control_edge_gradientcolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_edge_gradientcolour"); + helper.simulateMouseEvent("click", "control_edge_gradientcolour_button"); $("#control_edge_gradientcolour_source").attr("value", "#123456"); $("#control_edge_gradientcolour_target").attr("value", "#654321"); helper.simulateMouseEvent("click", "control_edge_gradientcolour_submit"); diff --git a/js/apps/system/aardvark/test/specs/graphViewer/specEvents/eventDispatcherUISpec.js b/js/apps/system/aardvark/test/specs/graphViewer/specEvents/eventDispatcherUISpec.js index 2eaec3642d..baa91c2777 100644 --- a/js/apps/system/aardvark/test/specs/graphViewer/specEvents/eventDispatcherUISpec.js +++ b/js/apps/system/aardvark/test/specs/graphViewer/specEvents/eventDispatcherUISpec.js @@ -252,7 +252,9 @@ expect(adapter.createNode).toHaveBeenCalledWith( {}, - jasmine.any(Function) + jasmine.any(Function), + jasmine.any(Number), // Number not yet correctly tested + jasmine.any(Number) ); /* expect(adapter.createNode).toHaveBeenCalledWith( diff --git a/js/apps/system/aardvark/test/specs/graphViewer/specForceLayouter/forceLayouterUISpec.js b/js/apps/system/aardvark/test/specs/graphViewer/specForceLayouter/forceLayouterUISpec.js index 90206ba8ae..5c62d69879 100644 --- a/js/apps/system/aardvark/test/specs/graphViewer/specForceLayouter/forceLayouterUISpec.js +++ b/js/apps/system/aardvark/test/specs/graphViewer/specForceLayouter/forceLayouterUISpec.js @@ -75,7 +75,7 @@ expect($("#control_layout_list #control_layout_gravity").length).toEqual(1); expect($("#control_layout_list #control_layout_gravity")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_layout_gravity"); + helper.simulateMouseEvent("click", "control_layout_gravity_button"); expect($("#control_layout_gravity_modal").length).toEqual(1); @@ -100,7 +100,7 @@ expect($("#control_layout_list #control_layout_distance").length).toEqual(1); expect($("#control_layout_list #control_layout_distance")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_layout_distance"); + helper.simulateMouseEvent("click", "control_layout_distance_button"); expect($("#control_layout_distance_modal").length).toEqual(1); @@ -125,7 +125,7 @@ expect($("#control_layout_list #control_layout_charge").length).toEqual(1); expect($("#control_layout_list #control_layout_charge")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_layout_charge"); + helper.simulateMouseEvent("click", "control_layout_charge_button"); expect($("#control_layout_charge_modal").length).toEqual(1); diff --git a/js/apps/system/aardvark/test/specs/graphViewer/specNodeReducer/modularityJoinerSpec.js b/js/apps/system/aardvark/test/specs/graphViewer/specNodeReducer/modularityJoinerSpec.js index 45043b703f..96f4decc54 100644 --- a/js/apps/system/aardvark/test/specs/graphViewer/specNodeReducer/modularityJoinerSpec.js +++ b/js/apps/system/aardvark/test/specs/graphViewer/specNodeReducer/modularityJoinerSpec.js @@ -936,17 +936,26 @@ this.addMatchers({ toContainKarateClubCommunities: function() { var c1 = [ - "10", "15", "16", "19", "21", "23", "27", - "30", "31", "33", "34", "9" + "10", "15", "16", "19", "21", "23", + "30", "33", "34" ].sort().join(), c2 = ["1", "12", "13", "14", "18", "2", "20", "22", "3", "4", "8"].sort().join(), c3 = ["11", "17", "5", "6", "7"].sort().join(), c4 = ["24", "25", "26", "28", "29", "32"].sort().join(), + swap = ["9", "27", "31"], comms = this.actual, failed = false, msg = "Found incorrect: "; _.each(comms, function(o) { - var check = o.nodes.sort().join(); + var check = o.nodes; + _.each(swap, function (s) { + var index = _.indexOf(check, s); + if (index > -1) { + check = _.without(check, s); + swap = _.without(swap, s); + } + }); + check = check.sort().join(); switch (check) { case c1: c1 = ""; @@ -980,6 +989,9 @@ if (c4 !== "") { notFound += "[" + c4 + "] "; } + if (swap.length > 0) { + notFound += "[" + swap.join() + "] "; + } return msg + " and did not find: " + notFound; }; return !failed; @@ -2058,4 +2070,4 @@ }); }); -}()); \ No newline at end of file +}()); diff --git a/js/apps/system/aardvark/test/specs/graphViewer/specNodeShaper/nodeShaperUISpec.js b/js/apps/system/aardvark/test/specs/graphViewer/specNodeShaper/nodeShaperUISpec.js index 9c83bb48db..e8a648234c 100644 --- a/js/apps/system/aardvark/test/specs/graphViewer/specNodeShaper/nodeShaperUISpec.js +++ b/js/apps/system/aardvark/test/specs/graphViewer/specNodeShaper/nodeShaperUISpec.js @@ -87,7 +87,7 @@ expect($("#control_node_list #control_node_none").length).toEqual(1); expect($("#control_node_list #control_node_none")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_none"); + helper.simulateMouseEvent("click", "control_node_none_button"); expect(shaper.changeTo).toHaveBeenCalledWith({ shape: { @@ -103,13 +103,11 @@ expect($("#control_node_list #control_node_circle").length).toEqual(1); expect($("#control_node_list #control_node_circle")[0]).toConformToListCSS(); - - helper.simulateMouseEvent("click", "control_node_circle"); + helper.simulateMouseEvent("click", "control_node_circle_button"); expect($("#control_node_circle_modal").length).toEqual(1); - $("#control_node_circle_radius").attr("value", 42); helper.simulateMouseEvent("click", "control_node_circle_submit"); - + expect(shaper.changeTo).toHaveBeenCalledWith({ shape: { type: NodeShaper.shapes.CIRCLE, @@ -131,7 +129,7 @@ expect($("#control_node_list #control_node_rect").length).toEqual(1); expect($("#control_node_list #control_node_rect")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_rect"); + helper.simulateMouseEvent("click", "control_node_rect_button"); $("#control_node_rect_width").attr("value", 42); $("#control_node_rect_height").attr("value", 12); helper.simulateMouseEvent("click", "control_node_rect_submit"); @@ -158,7 +156,7 @@ expect($("#control_node_list #control_node_label").length).toEqual(1); expect($("#control_node_list #control_node_label")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_label"); + helper.simulateMouseEvent("click", "control_node_label_button"); $("#control_node_label_key").attr("value", "theAnswer"); helper.simulateMouseEvent("click", "control_node_label_submit"); @@ -180,7 +178,7 @@ expect($("#control_node_list #control_node_singlecolour").length).toEqual(1); expect($("#control_node_list #control_node_singlecolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_singlecolour"); + helper.simulateMouseEvent("click", "control_node_singlecolour_button"); $("#control_node_singlecolour_fill").attr("value", "#123456"); $("#control_node_singlecolour_stroke").attr("value", "#654321"); helper.simulateMouseEvent("click", "control_node_singlecolour_submit"); @@ -207,7 +205,7 @@ expect($("#control_node_list #control_node_attributecolour").length).toEqual(1); expect($("#control_node_list #control_node_attributecolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_attributecolour"); + helper.simulateMouseEvent("click", "control_node_attributecolour_button"); $("#control_node_attributecolour_key").attr("value", "label"); helper.simulateMouseEvent("click", "control_node_attributecolour_submit"); @@ -232,7 +230,7 @@ expect($("#control_node_list #control_node_expandcolour").length).toEqual(1); expect($("#control_node_list #control_node_expandcolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_expandcolour"); + helper.simulateMouseEvent("click", "control_node_expandcolour_button"); $("#control_node_expandcolour_expanded").attr("value", "#123456"); $("#control_node_expandcolour_collapsed").attr("value", "#654321"); helper.simulateMouseEvent("click", "control_node_expandcolour_submit"); @@ -324,7 +322,7 @@ expect($("#control_node_list #control_node_expandcolour").length).toEqual(1); expect($("#control_node_list #control_node_expandcolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_expandcolour"); + helper.simulateMouseEvent("click", "control_node_expandcolour_button"); $("#control_node_expandcolour_expanded").attr("value", "#123456"); $("#control_node_expandcolour_collapsed").attr("value", "#654321"); @@ -355,7 +353,7 @@ expect($("#control_node_list #control_node_labelandcolour").length).toEqual(1); expect($("#control_node_list #control_node_labelandcolour")[0]).toConformToListCSS(); - helper.simulateMouseEvent("click", "control_node_labelandcolour"); + helper.simulateMouseEvent("click", "control_node_labelandcolour_button"); $("#control_node_labelandcolour_label-attribute").attr("value", "label"); helper.simulateMouseEvent("click", "control_node_labelandcolour_submit"); diff --git a/js/client/modules/org/arangodb/foxx/manager.js b/js/client/modules/org/arangodb/foxx/manager.js index 1850c4a7e1..0de641bc8a 100644 --- a/js/client/modules/org/arangodb/foxx/manager.js +++ b/js/client/modules/org/arangodb/foxx/manager.js @@ -367,7 +367,8 @@ function processSource (src) { processGithubRepository(src); } else { - throwBadParameter("Unknown application type '" + src.type + "'"); + throwBadParameter("Unknown application type '" + src.type + "'. " + + "expected type: 'github', 'zip', or 'directory'."); } // upload file to the server @@ -1444,7 +1445,9 @@ exports.help = function () { } arangodb.print(); - arangodb.print("use foxx-manager --help to show a list of global options"); + arangodb.print("Use foxx-manager --help to show a list of global options\n"); + arangodb.print("There is also an online manual available at:"); + arangodb.print("https://www.arangodb.org/manuals/current/UserManualFoxxManager.html"); // additional newline arangodb.print(); diff --git a/js/client/modules/org/arangodb/graph.js b/js/client/modules/org/arangodb/graph.js index ff63a94733..4cbcd2b297 100644 --- a/js/client/modules/org/arangodb/graph.js +++ b/js/client/modules/org/arangodb/graph.js @@ -59,6 +59,7 @@ Edge.prototype.setProperty = function (name, value) { update = this._properties; update[name] = value; + this._graph.emptyCachedPredecessors(); results = GraphAPI.putEdge(this._graph._properties._key, this._properties._key, update); @@ -278,6 +279,8 @@ Graph.prototype.drop = function () { Graph.prototype._saveEdge = function(id, out_vertex_id, in_vertex_id, params) { var results; + + this.emptyCachedPredecessors(); params._key = id; params._from = out_vertex_id; @@ -378,6 +381,7 @@ Graph.prototype.getEdges = function () { //////////////////////////////////////////////////////////////////////////////// Graph.prototype.removeVertex = function (vertex) { + this.emptyCachedPredecessors(); GraphAPI.deleteVertex(this._properties._key, vertex._properties._key); vertex._properties = undefined; }; @@ -387,7 +391,9 @@ Graph.prototype.removeVertex = function (vertex) { //////////////////////////////////////////////////////////////////////////////// Graph.prototype.removeEdge = function (edge) { + this.emptyCachedPredecessors(); GraphAPI.deleteEdge(this._properties._key, edge._properties._key); + this._edgesCache[edge._properties._id] = undefined; edge._properties = undefined; }; diff --git a/js/common/bootstrap/module-internal.js b/js/common/bootstrap/module-internal.js index 08c19b2346..9da5250c43 100644 --- a/js/common/bootstrap/module-internal.js +++ b/js/common/bootstrap/module-internal.js @@ -18,7 +18,7 @@ COLOR_BOLD_WHITE, COLOR_YELLOW, COLOR_BOLD_YELLOW, COLOR_CYAN, COLOR_BOLD_CYAN, COLOR_MAGENTA, COLOR_BOLD_MAGENTA, PRETTY_PRINT, VALGRIND, VERSION, UPGRADE, BYTES_SENT_DISTRIBUTION, BYTES_RECEIVED_DISTRIBUTION, CONNECTION_TIME_DISTRIBUTION, - REQUEST_TIME_DISTRIBUTION, DEVELOPMENT_MODE, THREAD_NUMBER, + REQUEST_TIME_DISTRIBUTION, DEVELOPMENT_MODE, THREAD_NUMBER, LOGFILE_PATH, SYS_PLATFORM */ //////////////////////////////////////////////////////////////////////////////// @@ -128,6 +128,15 @@ SYS_LOG("warning", "################################################################################"); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief logfilePath +//////////////////////////////////////////////////////////////////////////////// + + if (typeof LOGFILE_PATH !== "undefined") { + exports.logfilePath = LOGFILE_PATH; + delete LOGFILE_PATH; + } + //////////////////////////////////////////////////////////////////////////////// /// @brief quiet //////////////////////////////////////////////////////////////////////////////// diff --git a/js/common/modules/org/arangodb/graph-common.js b/js/common/modules/org/arangodb/graph-common.js index 6f865cb686..393bad85c5 100644 --- a/js/common/modules/org/arangodb/graph-common.js +++ b/js/common/modules/org/arangodb/graph-common.js @@ -522,6 +522,30 @@ Vertex.prototype.addOutEdge = function (ine, id, label, data) { return this._graph.addEdge(this, ine, id, label, data); }; +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the number of edges +//////////////////////////////////////////////////////////////////////////////// + +Vertex.prototype.degree = function () { + return this.getEdges().length; +}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the number of in-edges +//////////////////////////////////////////////////////////////////////////////// + +Vertex.prototype.inDegree = function () { + return this.getInEdges().length; +}; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the number of out-edges +//////////////////////////////////////////////////////////////////////////////// + +Vertex.prototype.outDegree = function () { + return this.getOutEdges().length; +}; + //////////////////////////////////////////////////////////////////////////////// /// @brief returns the identifier of a vertex /// diff --git a/js/common/tests/shell-graph-algorithms.js b/js/common/tests/shell-graph-algorithms.js index 5ffc024727..086c75ae5a 100644 --- a/js/common/tests/shell-graph-algorithms.js +++ b/js/common/tests/shell-graph-algorithms.js @@ -175,8 +175,6 @@ function dijkstraSuite() { try { // Drop the graph if it exsits graph = new Graph(graph_name); - print("FOUND: "); - PRINT_OBJECT(graph); graph.drop(); } catch (err1) { } @@ -293,7 +291,7 @@ function dijkstraSuite() { e2 = graph.addEdge(v2, v3), e3, pathes = v1.pathTo(v3, {cached: true}); - + e3 = graph.addEdge(v1, v3); pathes = v1.pathTo(v3, {cached: true}); diff --git a/js/server/modules/org/arangodb/ahuacatl.js b/js/server/modules/org/arangodb/ahuacatl.js index 2fc8a2f45b..a2aca06cc2 100644 --- a/js/server/modules/org/arangodb/ahuacatl.js +++ b/js/server/modules/org/arangodb/ahuacatl.js @@ -261,13 +261,17 @@ function FIX_VALUE (value) { } if (type === 'object') { + var result = { }; for (i in value) { if (value.hasOwnProperty(i)) { - value[i] = FIX_VALUE(value[i]); + if (typeof value[i] === 'function') { + continue; + } + result[i] = FIX_VALUE(value[i]); } } - return value; + return result; } return null; diff --git a/js/server/modules/org/arangodb/graph.js b/js/server/modules/org/arangodb/graph.js index e351d9dd01..9cd647f332 100644 --- a/js/server/modules/org/arangodb/graph.js +++ b/js/server/modules/org/arangodb/graph.js @@ -325,30 +325,6 @@ Vertex.prototype.setProperty = function (name, value) { return value; }; -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns the number of edges -//////////////////////////////////////////////////////////////////////////////// - -Vertex.prototype.degree = function () { - return this.getEdges().length; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns the number of in-edges -//////////////////////////////////////////////////////////////////////////////// - -Vertex.prototype.inDegree = function () { - return this.getInEdges().length; -}; - -//////////////////////////////////////////////////////////////////////////////// -/// @brief returns the number of out-edges -//////////////////////////////////////////////////////////////////////////////// - -Vertex.prototype.outDegree = function () { - return this.getOutEdges().length; -}; - //////////////////////////////////////////////////////////////////////////////// /// @} //////////////////////////////////////////////////////////////////////////////// @@ -500,7 +476,7 @@ Graph.prototype.initialize = function (name, vertices, edges, waitForSync) { this._verticesCache = {}; this._edgesCache = {}; - // and store the cashes + // and store the caches this.predecessors = {}; this.distances = {}; }; diff --git a/js/server/tests/agency.js b/js/server/tests/agency.js new file mode 100644 index 0000000000..346b163232 --- /dev/null +++ b/js/server/tests/agency.js @@ -0,0 +1,451 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief test the agency communication layer +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2010-2012 triagens 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 triAGENS GmbH, Cologne, Germany +/// +/// @author Jan Steemann +/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var jsunity = require("jsunity"); +var internal = require("internal"); + +// ----------------------------------------------------------------------------- +// --SECTION-- agency +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test suite: agency +//////////////////////////////////////////////////////////////////////////////// + +function AgencySuite () { + var agency; + + return { + + setUp : function () { + agency = new ArangoAgency(); + + try { + agency.remove("UnitTestsAgency", true); + } + catch (err) { + // dir may not exist. this is not a problem + } + + agency.createDirectory("UnitTestsAgency"); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test version +//////////////////////////////////////////////////////////////////////////////// + + testVersion : function () { + assertMatch(/^etcd/, agency.version()); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test watch +//////////////////////////////////////////////////////////////////////////////// + + testWatchTimeout : function () { + assertTrue(agency.set("UnitTestsAgency/foo", "bar")); + + var wait = 3; + var start = require("internal").time(); + assertFalse(agency.watch("UnitTestsAgency/foo", 0, wait)); + var end = require("internal").time(); + assertEqual(wait, Math.round(end - start)); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test watch +//////////////////////////////////////////////////////////////////////////////// + + testWatchChange : function () { + assertTrue(agency.set("UnitTestsAgency/foo", "bar")); + + var wait = 1; + var start = require("internal").time(); + assertFalse(agency.watch("UnitTestsAgency/foo", 0, wait)); + var end = require("internal").time(); + assertEqual(wait, Math.round(end - start)); + + assertTrue(agency.set("UnitTestsAgency/foo", "baz")); + assertTrue(agency.set("UnitTestsAgency/foo", "bart")); + start = require("internal").time(); + var result = agency.watch("UnitTestsAgency/foo", 1, wait); + end = require("internal").time(); + + assertEqual(0, Math.round(end - start)); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test cas +//////////////////////////////////////////////////////////////////////////////// + + testCas : function () { + assertTrue(agency.set("UnitTestsAgency/foo", "bar")); + + assertTrue(agency.cas("UnitTestsAgency/foo", "bar", "baz")); + assertTrue(agency.cas("UnitTestsAgency/foo", "baz", "bart")); + assertFalse(agency.cas("UnitTestsAgency/foo", "foo", "bar")); + + try { + agency.cas("UnitTestsAgency/foo", "foo", "bar", true); + fail(); + } + catch (err) { + } + + assertTrue(agency.cas("UnitTestsAgency/foo", "bart", "baz", true)); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test createDir +//////////////////////////////////////////////////////////////////////////////// + + testCreateDir : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + try { + // re-create an existing dir + agency.createDir("UnitTestsAgency/someDir"); + fail(); + } + catch (err) { + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test createDir / remove +//////////////////////////////////////////////////////////////////////////////// + + testCreateRemoveDir : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + assertTrue(agency.remove("UnitTestsAgency/someDir", true)); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test removeDir +//////////////////////////////////////////////////////////////////////////////// + + testRemoveDirNonRecursive : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + try { + assertTrue(agency.remove("UnitTestsAgency/someDir", false)); + fail(); + } + catch (err) { + // not a file + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test removeDir +//////////////////////////////////////////////////////////////////////////////// + + testRemoveDirRecursive1 : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/2/1")); + agency.set("UnitTestsAgency/1/1/foo", "bar"); + agency.set("UnitTestsAgency/2/1/foo", "baz"); + + assertTrue(agency.remove("UnitTestsAgency/1/1", true)); + assertTrue(agency.remove("UnitTestsAgency/1/2", true)); + assertTrue(agency.remove("UnitTestsAgency/1", true)); + assertTrue(agency.remove("UnitTestsAgency/2", true)); + + var values = agency.get("UnitTestsAgency", true); + assertEqual({ }, values); // empty + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test removeDir +//////////////////////////////////////////////////////////////////////////////// + + testRemoveDirRecursive2 : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/2/1")); + agency.set("UnitTestsAgency/1/1/foo", "bar"); + agency.set("UnitTestsAgency/2/1/foo", "baz"); + + assertTrue(agency.remove("UnitTestsAgency/1", true)); + + try { + agency.get("UnitTestsAgency/1", true); + fail(); + } + catch (err) { + // key not found + } + + var values = agency.get("UnitTestsAgency/2", true); + assertEqual({ "UnitTestsAgency/2/1/foo" : "baz" }, values); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test removeDir +//////////////////////////////////////////////////////////////////////////////// + + testRemoveDirRecursive3 : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2/1")); + assertTrue(agency.createDirectory("UnitTestsAgency/1/2/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/2")); + assertTrue(agency.createDirectory("UnitTestsAgency/2/1")); + agency.set("UnitTestsAgency/1/1/foo", "bar"); + agency.set("UnitTestsAgency/2/1/foo", "baz"); + + assertTrue(agency.remove("UnitTestsAgency", true)); + + try { + agency.get("UnitTestsAgency", true); + fail(); + } + catch (err) { + // key not found + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test removeDir +//////////////////////////////////////////////////////////////////////////////// + + testRemoveDirNonExisting : function () { + try { + assertTrue(agency.remove("UnitTestsAgency/someDir", true)); + fail(); + } + catch (err) { + // key not found + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test remove +//////////////////////////////////////////////////////////////////////////////// + + testRemoveKeys : function () { + var i; + + for (i = 0; i < 100; ++i) { + assertTrue(agency.set("UnitTestsAgency/" + i, "value" + i)); + } + + for (i = 10; i < 90; ++i) { + assertTrue(agency.remove("UnitTestsAgency/" + i)); + } + + var values; + for (i = 0; i < 100; ++i) { + if (i >= 10 && i < 90) { + try { + values = agency.get("UnitTestsAgency/" + i); + fail(); + } + catch (err) { + } + } + else { + values = agency.get("UnitTestsAgency/" + i); + assertTrue(values.hasOwnProperty("UnitTestsAgency/" + i)); + assertEqual(values["UnitTestsAgency/" + i], "value" + i); + } + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test set / get +//////////////////////////////////////////////////////////////////////////////// + + testGet : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + agency.set("UnitTestsAgency/someDir/foo", "bar"); + + var values = agency.get("UnitTestsAgency/someDir/foo"); + assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo")); + assertEqual(values["UnitTestsAgency/someDir/foo"], "bar"); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test set / get directory +//////////////////////////////////////////////////////////////////////////////// + + testGetDirectory : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + assertTrue(agency.set("UnitTestsAgency/someDir/foo", "bar")); + + var values = agency.get("UnitTestsAgency", false); + assertEqual({ }, values); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test set / get multi +//////////////////////////////////////////////////////////////////////////////// + + testGetMulti : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + assertTrue(agency.set("UnitTestsAgency/someDir/foo", "bar")); + assertTrue(agency.set("UnitTestsAgency/someDir/baz", "bart")); + + var values = agency.get("UnitTestsAgency", true); + assertEqual({ "UnitTestsAgency/someDir/baz" : "bart", "UnitTestsAgency/someDir/foo" : "bar" }, values); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test set / get +//////////////////////////////////////////////////////////////////////////////// + + testGetUpdated : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + agency.set("UnitTestsAgency/someDir/foo", "bar"); + + var values = agency.get("UnitTestsAgency/someDir/foo"); + assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo")); + assertEqual(values["UnitTestsAgency/someDir/foo"], "bar"); + + agency.set("UnitTestsAgency/someDir/foo", "baz"); + values = agency.get("UnitTestsAgency/someDir/foo"); + assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo")); + assertEqual(values["UnitTestsAgency/someDir/foo"], "baz"); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test set / get +//////////////////////////////////////////////////////////////////////////////// + + testGetDeleted : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + agency.set("UnitTestsAgency/someDir/foo", "bar"); + + var values = agency.get("UnitTestsAgency/someDir/foo"); + assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo")); + assertEqual(values["UnitTestsAgency/someDir/foo"], "bar"); + + agency.remove("UnitTestsAgency/someDir/foo"); + + try { + values = agency.get("UnitTestsAgency/someDir/foo"); + fail(); + } + catch (err) { + // key not found + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test get +//////////////////////////////////////////////////////////////////////////////// + + testGetNonExisting1 : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + try { + agency.get("UnitTestsAgency/someDir/foo"); + fail(); + } + catch (err) { + // key not found + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test get +//////////////////////////////////////////////////////////////////////////////// + + testGetNonExisting2 : function () { + try { + agency.get("UnitTestsAgency/someOtherDir"); + fail(); + } + catch (err) { + // key not found + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test set / get +//////////////////////////////////////////////////////////////////////////////// + + testGetUrlEncodedValue : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + var value = "bar=BAT;foo=%47abc;degf=2343%20hihi aha\nabc"; + agency.set("UnitTestsAgency/someDir/foobar", value); + + var values = agency.get("UnitTestsAgency/someDir/foobar"); + assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foobar")); + assertEqual(values["UnitTestsAgency/someDir/foobar"], value); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test set / get +//////////////////////////////////////////////////////////////////////////////// + + testGetUrlEncodedKey : function () { + assertTrue(agency.createDirectory("UnitTestsAgency/someDir")); + + var key = "foo bar baz / hihi"; + agency.set("UnitTestsAgency/someDir/" + encodeURIComponent(key), "something"); + + var values = agency.get("UnitTestsAgency/someDir/" + encodeURIComponent(key)); + assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/" + key)); + assertEqual(values["UnitTestsAgency/someDir/" + key], "something"); + } + + }; +} + +// ----------------------------------------------------------------------------- +// --SECTION-- main +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes the test suites +//////////////////////////////////////////////////////////////////////////////// + +jsunity.run(AgencySuite); + +return jsunity.done(); + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)" +// End: + diff --git a/js/server/tests/compaction.js b/js/server/tests/compaction.js index f2fd4accac..ebe0f50703 100644 --- a/js/server/tests/compaction.js +++ b/js/server/tests/compaction.js @@ -29,7 +29,7 @@ var jsunity = require("jsunity"); var internal = require("internal"); // ----------------------------------------------------------------------------- -// --SECTION-- collection methods +// --SECTION-- compaction // ----------------------------------------------------------------------------- //////////////////////////////////////////////////////////////////////////////// diff --git a/js/common/tests/shell-bitarray-index.js b/js/server/tests/shell-bitarray-index.js similarity index 100% rename from js/common/tests/shell-bitarray-index.js rename to js/server/tests/shell-bitarray-index.js diff --git a/js/common/tests/shell-foxx-base-middleware.js b/js/server/tests/shell-foxx-base-middleware.js similarity index 100% rename from js/common/tests/shell-foxx-base-middleware.js rename to js/server/tests/shell-foxx-base-middleware.js diff --git a/js/common/tests/shell-foxx-format-middleware.js b/js/server/tests/shell-foxx-format-middleware.js similarity index 100% rename from js/common/tests/shell-foxx-format-middleware.js rename to js/server/tests/shell-foxx-format-middleware.js diff --git a/js/common/tests/shell-foxx-model.js b/js/server/tests/shell-foxx-model.js similarity index 100% rename from js/common/tests/shell-foxx-model.js rename to js/server/tests/shell-foxx-model.js diff --git a/js/common/tests/shell-foxx-preprocessor.js b/js/server/tests/shell-foxx-preprocessor.js similarity index 100% rename from js/common/tests/shell-foxx-preprocessor.js rename to js/server/tests/shell-foxx-preprocessor.js diff --git a/js/common/tests/shell-foxx-repository.js b/js/server/tests/shell-foxx-repository.js similarity index 100% rename from js/common/tests/shell-foxx-repository.js rename to js/server/tests/shell-foxx-repository.js diff --git a/js/common/tests/shell-foxx-template-middleware.js b/js/server/tests/shell-foxx-template-middleware.js similarity index 100% rename from js/common/tests/shell-foxx-template-middleware.js rename to js/server/tests/shell-foxx-template-middleware.js diff --git a/js/common/tests/shell-foxx.js b/js/server/tests/shell-foxx.js similarity index 100% rename from js/common/tests/shell-foxx.js rename to js/server/tests/shell-foxx.js diff --git a/js/common/tests/shell-skiplist-index.js b/js/server/tests/shell-skiplist-index.js similarity index 100% rename from js/common/tests/shell-skiplist-index.js rename to js/server/tests/shell-skiplist-index.js diff --git a/lib/BasicsC/logging.c b/lib/BasicsC/logging.c index 4d670ffdae..342e79fb0c 100644 --- a/lib/BasicsC/logging.c +++ b/lib/BasicsC/logging.c @@ -107,6 +107,12 @@ static bool Initialised = false; static bool ShutdownInitalised = false; +//////////////////////////////////////////////////////////////////////////////// +/// @brief name of first log file +//////////////////////////////////////////////////////////////////////////////// + +static char* LogfileName = 0; + //////////////////////////////////////////////////////////////////////////////// /// @brief log appenders //////////////////////////////////////////////////////////////////////////////// @@ -1706,6 +1712,11 @@ TRI_log_appender_t* TRI_CreateLogAppenderFile (char const* filename, TRI_PushBackVectorPointer(&Appenders, &appender->base); TRI_UnlockSpin(&AppendersLock); + // register the name of the first logfile + if (LogfileName == NULL) { + LogfileName = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, filename); + } + // and return base structure return &appender->base; } @@ -1962,6 +1973,14 @@ TRI_log_appender_t* TRI_CreateLogAppenderSyslog (char const* name, /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief return global log file name +//////////////////////////////////////////////////////////////////////////////// + +char const* TRI_GetFilenameLogging () { + return LogfileName; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief initialises the logging components //////////////////////////////////////////////////////////////////////////////// @@ -2023,6 +2042,11 @@ bool TRI_ShutdownLogging (bool clearBuffers) { // logging is now inactive (this will terminate the logging thread) LoggingActive = 0; + if (LogfileName != NULL) { + TRI_Free(TRI_CORE_MEM_ZONE, LogfileName); + LogfileName = 0; + } + // join with the logging thread if (ThreadedLogging) { TRI_LockCondition(&LogCondition); diff --git a/lib/BasicsC/logging.h b/lib/BasicsC/logging.h index a67426c8c1..5d05695440 100644 --- a/lib/BasicsC/logging.h +++ b/lib/BasicsC/logging.h @@ -544,6 +544,12 @@ struct TRI_log_appender_s* TRI_CreateLogAppenderSyslog (char const*, /// @{ //////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +/// @brief return global log file name +//////////////////////////////////////////////////////////////////////////////// + +char const* TRI_GetFilenameLogging (void); + //////////////////////////////////////////////////////////////////////////////// /// @brief initialises the logging components /// diff --git a/lib/V8/v8-globals.cpp b/lib/V8/v8-globals.cpp index 219de27ce9..b8c6c541aa 100644 --- a/lib/V8/v8-globals.cpp +++ b/lib/V8/v8-globals.cpp @@ -39,10 +39,10 @@ TRI_v8_global_s::TRI_v8_global_s (v8::Isolate* isolate) : JSBarriers(), JSCollections(), + AgencyTempl(), ErrorTempl(), GeneralCursorTempl(), ShapedJsonTempl(), - TransactionTempl(), VocbaseColTempl(), VocbaseTempl(), diff --git a/lib/V8/v8-globals.h b/lib/V8/v8-globals.h index b50d319549..3645f5b05a 100644 --- a/lib/V8/v8-globals.h +++ b/lib/V8/v8-globals.h @@ -209,6 +209,14 @@ typedef struct TRI_v8_global_s { // --SECTION-- JAVASCRIPT OBJECT TEMPLATES // ----------------------------------------------------------------------------- +//////////////////////////////////////////////////////////////////////////////// +/// @brief agency template +//////////////////////////////////////////////////////////////////////////////// + +#ifdef TRI_ENABLE_CLUSTER + v8::Persistent AgencyTempl; +#endif + //////////////////////////////////////////////////////////////////////////////// /// @brief error template //////////////////////////////////////////////////////////////////////////////// @@ -227,12 +235,6 @@ typedef struct TRI_v8_global_s { v8::Persistent ShapedJsonTempl; -//////////////////////////////////////////////////////////////////////////////// -/// @brief transaction template -//////////////////////////////////////////////////////////////////////////////// - - v8::Persistent TransactionTempl; - //////////////////////////////////////////////////////////////////////////////// /// @brief TRI_vocbase_col_t template ////////////////////////////////////////////////////////////////////////////////