From 88d8c31029713d4e3a20cb97cfa8397e65202d69 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 10:24:04 +0200 Subject: [PATCH 01/35] GraphViewer: Finished implementation of community joining, display and reverse action to be implemented --- .../js/graphViewer/graph/arangoAdapter.js | 31 ++++++++++++++++--- .../specAdapter/arangoAdapterSpec.js | 19 ++++++++---- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index 93c5cc3501..1c242c6298 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -187,7 +187,7 @@ function ArangoAdapter(nodes, edges, config) { removeEdgesForNode = function (node) { var i; - for ( i = 0; i < edges.length; i++ ) { + for (i = 0; i < edges.length; i++ ) { if (edges[i].source === node) { node._outboundCounter--; edges[i].target._inboundCounter--; @@ -202,6 +202,27 @@ function ArangoAdapter(nodes, edges, config) { } }, + combineCommunityEdges = function (nodes, commNode) { + var i, j, s, t; + for (i = 0; i < edges.length; i++ ) { + // s and t keep old values yay! + s = edges[i].source; + t = edges[i].target; + for (j = 0; j < nodes.length; j++) { + if (s === nodes[j]) { + edges[i].source = commNode; + } + if (t === nodes[j]) { + edges[i].target = commNode; + } + } + if (edges[i].source === commNode && edges[i].target === commNode) { + edges.splice( i, 1 ); + i--; + } + } + }, + // Helper function to easily remove all outbound edges for one node removeOutboundEdgesFromNode = function ( node ) { if (node._outboundCounter > 0) { @@ -260,17 +281,17 @@ function ArangoAdapter(nodes, edges, config) { var commId = "community_1", commNode = { _id: commId, - x: 1, - y: 1 + edges: [] }, nodesToRemove = _.map(community, function(id) { return findNode(id); }); + commNode.x = nodesToRemove[0].x; + commNode.y = nodesToRemove[0].y; cachedCommunities[commId] = nodesToRemove; - + combineCommunityEdges(nodesToRemove, commNode); _.each(nodesToRemove, function(n) { removeNode(n); - removeEdgesForNode(n); }); nodes.push(commNode); }, diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index bf3c65f866..fe9c106020 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -877,21 +877,27 @@ runs(function() { adapter.setNodeLimit(6); - spyOn(this, "fakeReducerRequest"); + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return [c0]; + }); adapter.loadNodeFromTreeById(c1, checkCallbackFunction); expect(this.fakeReducerRequest).toHaveBeenCalledWith(6, nodeWithID(c1)); }); }); it('should not trigger the reducer if the limit is set large enough', function() { - spyOn(this, "fakeReducerRequest"); + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return [c0]; + }); adapter.setNodeLimit(10); expect(this.fakeReducerRequest).not.toHaveBeenCalled(); }); it('should trigger the reducer if the limit is set too small', function() { - spyOn(this, "fakeReducerRequest"); + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return [c0]; + }); adapter.setNodeLimit(2); expect(this.fakeReducerRequest).toHaveBeenCalledWith(2); }); @@ -911,10 +917,11 @@ notExistNodes([c0, c1, c2]); existNode("community_1"); - existNodes([c3]); - expect(nodes.length).toEqual(2); + existNodes([c3, c4]); + expect(nodes.length).toEqual(3); existEdge("community_1", c3); - expect(edges.length).toEqual(1); + existEdge("community_1", c4); + expect(edges.length).toEqual(2); expect(called).toBeTruthy(); }); From 30b60f771549f3849e6e2d798d25a97e129cb088 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 10:34:00 +0200 Subject: [PATCH 02/35] GraphViewer: All tests pass --- html/admin/js/graphViewer/graph/nodeReducer.js | 7 +++++-- .../jasmine_test/specAdapter/arangoAdapterSpec.js | 3 +-- .../jasmine_test/specNodeReducer/nodeReducerSpec.js | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/html/admin/js/graphViewer/graph/nodeReducer.js b/html/admin/js/graphViewer/graph/nodeReducer.js index 839bb36a03..334d3767cd 100644 --- a/html/admin/js/graphViewer/graph/nodeReducer.js +++ b/html/admin/js/graphViewer/graph/nodeReducer.js @@ -148,7 +148,7 @@ function NodeReducer(nodes, edges) { _.each(nodes, function (n) { var id = n._id, c1, c2; - if (id == sID || id == lID) { + if (id === sID || id === lID) { return null; } c1 = getDQValue(dQ, id, sID); @@ -277,6 +277,7 @@ function NodeReducer(nodes, edges) { res = [], dist = {}, dist2 = {}, + detectSteps = true, sortByDistance = function (a, b) { var d1 = dist[_.min(a,minDist(dist))], d2 = dist[_.min(b,minDist(dist))], @@ -290,7 +291,9 @@ function NodeReducer(nodes, edges) { throw "Load some nodes first."; } populateValues(dQ, a, heap); - while (communityDetectionStep(dQ, a, heap, coms)) {} + while (detectSteps) { + detectSteps = communityDetectionStep(dQ, a, heap, coms); + } res = _.pluck(_.values(coms), "com"); if (focus !== undefined) { dist = floatDist(focus._id); diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index fe9c106020..c682776db3 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -921,8 +921,7 @@ expect(nodes.length).toEqual(3); existEdge("community_1", c3); existEdge("community_1", c4); - expect(edges.length).toEqual(2); - + expect(edges.length).toEqual(2); expect(called).toBeTruthy(); }); diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js index 73d69f90d0..384b37d18e 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js @@ -149,7 +149,7 @@ edges.push(helper.createSimpleEdge(nodes, 5, 7)); var com = reducer.getCommunity(6); - expect(com).toContainNodes([0, 1, 2]); + expect(com).toContainNodes([0, 1, 2, 3]); }); }); From d7b64d4ae221f894d7a09058d1d8ef323340d3bb Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Tue, 21 May 2013 11:33:43 +0200 Subject: [PATCH 03/35] merged patches by @guidoreina --- arangod/Actions/RestActionHandler.cpp | 2 +- arangod/Actions/RestActionHandler.h | 2 +- arangod/Ahuacatl/ahuacatl-ast-node.c | 11 +++++++---- arangod/RestHandler/RestBatchHandler.cpp | 2 +- arangod/RestHandler/RestBatchHandler.h | 2 +- arangod/RestHandler/RestDocumentHandler.cpp | 2 +- arangod/RestHandler/RestDocumentHandler.h | 2 +- arangod/RestHandler/RestImportHandler.cpp | 2 +- arangod/RestHandler/RestImportHandler.h | 2 +- arangod/RestHandler/RestUploadHandler.cpp | 2 +- arangod/RestHandler/RestUploadHandler.h | 2 +- arangod/VocBase/headers.c | 8 ++------ lib/Admin/RestVersionHandler.cpp | 2 +- lib/Admin/RestVersionHandler.h | 2 +- lib/Basics/StringBuffer.h | 18 +++++++++++++++++- lib/BasicsC/files.c | 3 +++ lib/BasicsC/logging.c | 16 ++++++++++++++++ lib/BasicsC/string-buffer.c | 9 +++++++++ lib/BasicsC/string-buffer.h | 6 ++++++ lib/Rest/Handler.cpp | 2 +- lib/Rest/Handler.h | 2 +- lib/Rest/HttpResponse.cpp | 3 +-- lib/Scheduler/SocketTask.cpp | 14 +++++++++----- lib/Scheduler/SocketTask.h | 6 ------ lib/SimpleHttpClient/ClientConnection.cpp | 10 +++++++--- lib/SimpleHttpClient/SslClientConnection.cpp | 12 ++++++++---- 26 files changed, 99 insertions(+), 45 deletions(-) diff --git a/arangod/Actions/RestActionHandler.cpp b/arangod/Actions/RestActionHandler.cpp index 8b843a9d77..d54ef1196a 100644 --- a/arangod/Actions/RestActionHandler.cpp +++ b/arangod/Actions/RestActionHandler.cpp @@ -103,7 +103,7 @@ bool RestActionHandler::isDirect () { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// -string const& RestActionHandler::queue () { +string const& RestActionHandler::queue () const { return _queue; } diff --git a/arangod/Actions/RestActionHandler.h b/arangod/Actions/RestActionHandler.h index 3c90e2ba5d..6cacfa27bd 100644 --- a/arangod/Actions/RestActionHandler.h +++ b/arangod/Actions/RestActionHandler.h @@ -126,7 +126,7 @@ namespace triagens { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// - string const& queue (); + string const& queue () const; //////////////////////////////////////////////////////////////////////////////// /// {@inheritDoc} diff --git a/arangod/Ahuacatl/ahuacatl-ast-node.c b/arangod/Ahuacatl/ahuacatl-ast-node.c index 41bd476115..7b37ab5d43 100644 --- a/arangod/Ahuacatl/ahuacatl-ast-node.c +++ b/arangod/Ahuacatl/ahuacatl-ast-node.c @@ -437,10 +437,13 @@ TRI_aql_node_t* TRI_CreateNodeVariableAql (TRI_aql_context_t* const context, ABORT_OOM } - if (! TRI_AddVariableScopeAql(context, name, definingNode)) { - // duplicate variable name - TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_VARIABLE_REDECLARED, name); - return NULL; + // if not a temporary variable + if (*name != '_') { + if (! TRI_AddVariableScopeAql(context, name, definingNode)) { + // duplicate variable name + TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_VARIABLE_REDECLARED, name); + return NULL; + } } TRI_AQL_NODE_STRING(node) = (char*) name; diff --git a/arangod/RestHandler/RestBatchHandler.cpp b/arangod/RestHandler/RestBatchHandler.cpp index 3d4bbf02b0..ccb7923f53 100644 --- a/arangod/RestHandler/RestBatchHandler.cpp +++ b/arangod/RestHandler/RestBatchHandler.cpp @@ -87,7 +87,7 @@ bool RestBatchHandler::isDirect () { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// -string const& RestBatchHandler::queue () { +string const& RestBatchHandler::queue () const { static string const client = "STANDARD"; return client; diff --git a/arangod/RestHandler/RestBatchHandler.h b/arangod/RestHandler/RestBatchHandler.h index 793ff2b315..979af30ce7 100644 --- a/arangod/RestHandler/RestBatchHandler.h +++ b/arangod/RestHandler/RestBatchHandler.h @@ -153,7 +153,7 @@ namespace triagens { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// - string const& queue (); + string const& queue () const; //////////////////////////////////////////////////////////////////////////////// /// {@inheritDoc} diff --git a/arangod/RestHandler/RestDocumentHandler.cpp b/arangod/RestHandler/RestDocumentHandler.cpp index 4651c30464..409b0dad78 100644 --- a/arangod/RestHandler/RestDocumentHandler.cpp +++ b/arangod/RestHandler/RestDocumentHandler.cpp @@ -85,7 +85,7 @@ bool RestDocumentHandler::isDirect () { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// -string const& RestDocumentHandler::queue () { +string const& RestDocumentHandler::queue () const { static string const client = "STANDARD"; return client; diff --git a/arangod/RestHandler/RestDocumentHandler.h b/arangod/RestHandler/RestDocumentHandler.h index 21c579f952..de6d0c831c 100644 --- a/arangod/RestHandler/RestDocumentHandler.h +++ b/arangod/RestHandler/RestDocumentHandler.h @@ -94,7 +94,7 @@ namespace triagens { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// - string const& queue (); + string const& queue () const; //////////////////////////////////////////////////////////////////////////////// /// {@inheritDoc} diff --git a/arangod/RestHandler/RestImportHandler.cpp b/arangod/RestHandler/RestImportHandler.cpp index f7e5a8e8aa..8810cf58d8 100644 --- a/arangod/RestHandler/RestImportHandler.cpp +++ b/arangod/RestHandler/RestImportHandler.cpp @@ -83,7 +83,7 @@ bool RestImportHandler::isDirect () { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// -string const& RestImportHandler::queue () { +string const& RestImportHandler::queue () const { static string const client = "STANDARD"; return client; diff --git a/arangod/RestHandler/RestImportHandler.h b/arangod/RestHandler/RestImportHandler.h index a1cc7631a9..dbece94f34 100644 --- a/arangod/RestHandler/RestImportHandler.h +++ b/arangod/RestHandler/RestImportHandler.h @@ -94,7 +94,7 @@ namespace triagens { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// - string const& queue (); + string const& queue () const; //////////////////////////////////////////////////////////////////////////////// /// {@inheritDoc} diff --git a/arangod/RestHandler/RestUploadHandler.cpp b/arangod/RestHandler/RestUploadHandler.cpp index 9b42c126b2..f478a20fe7 100644 --- a/arangod/RestHandler/RestUploadHandler.cpp +++ b/arangod/RestHandler/RestUploadHandler.cpp @@ -87,7 +87,7 @@ bool RestUploadHandler::isDirect () { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// -string const& RestUploadHandler::queue () { +string const& RestUploadHandler::queue () const { static string const client = "STANDARD"; return client; diff --git a/arangod/RestHandler/RestUploadHandler.h b/arangod/RestHandler/RestUploadHandler.h index 9f84809a3e..cb98faead8 100644 --- a/arangod/RestHandler/RestUploadHandler.h +++ b/arangod/RestHandler/RestUploadHandler.h @@ -105,7 +105,7 @@ namespace triagens { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// - string const& queue (); + string const& queue () const; //////////////////////////////////////////////////////////////////////////////// /// {@inheritDoc} diff --git a/arangod/VocBase/headers.c b/arangod/VocBase/headers.c index 1309488ea9..2325dd3442 100644 --- a/arangod/VocBase/headers.c +++ b/arangod/VocBase/headers.c @@ -235,18 +235,14 @@ static void MoveHeader (TRI_headers_t* h, headers->_begin = header; } else if (headers->_begin == header) { - if (header->_next != NULL) { - headers->_begin = header->_next; - } + headers->_begin = header->_next; } if (old->_next == NULL) { headers->_end = header; } else if (headers->_end == header) { - if (header->_prev != NULL) { - headers->_end = header->_prev; - } + headers->_end = header->_prev; } if (header->_prev != NULL) { diff --git a/lib/Admin/RestVersionHandler.cpp b/lib/Admin/RestVersionHandler.cpp index 4799358458..0c44a08888 100644 --- a/lib/Admin/RestVersionHandler.cpp +++ b/lib/Admin/RestVersionHandler.cpp @@ -84,7 +84,7 @@ bool RestVersionHandler::isDirect () { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// -string const& RestVersionHandler::queue () { +string const& RestVersionHandler::queue () const { return _queue; } diff --git a/lib/Admin/RestVersionHandler.h b/lib/Admin/RestVersionHandler.h index 81f6d52fd6..fc5418eeed 100644 --- a/lib/Admin/RestVersionHandler.h +++ b/lib/Admin/RestVersionHandler.h @@ -122,7 +122,7 @@ namespace triagens { /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// - string const& queue (); + string const& queue () const; //////////////////////////////////////////////////////////////////////////////// /// @brief returns the server version number diff --git a/lib/Basics/StringBuffer.h b/lib/Basics/StringBuffer.h index eebd1420cd..7c1e7d9bda 100644 --- a/lib/Basics/StringBuffer.h +++ b/lib/Basics/StringBuffer.h @@ -182,6 +182,14 @@ namespace triagens { return TRI_EndStringBuffer(&_buffer); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns pointer to the end of the character buffer +//////////////////////////////////////////////////////////////////////////////// + + char * end () { + return const_cast(TRI_EndStringBuffer(&_buffer)); + } + //////////////////////////////////////////////////////////////////////////////// /// @brief returns length of the character buffer //////////////////////////////////////////////////////////////////////////////// @@ -190,6 +198,14 @@ namespace triagens { return TRI_LengthStringBuffer(&_buffer); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief increases length of the character buffer +//////////////////////////////////////////////////////////////////////////////// + + void increaseLength (size_t n) { + TRI_IncreaseLengthStringBuffer(&_buffer, n); + } + //////////////////////////////////////////////////////////////////////////////// /// @brief returns true if buffer is empty //////////////////////////////////////////////////////////////////////////////// @@ -257,7 +273,7 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- -// --SECTION-- STRING AND CHARATCER APPENDERS +// --SECTION-- STRING AND CHARACTER APPENDERS // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- diff --git a/lib/BasicsC/files.c b/lib/BasicsC/files.c index cef17f659e..68607c6e57 100644 --- a/lib/BasicsC/files.c +++ b/lib/BasicsC/files.c @@ -167,6 +167,9 @@ static void RemoveAllLockedFiles (void) { TRI_RemoveVector(&FileDescriptors, i); } + TRI_DestroyVectorString(&FileNames); + TRI_DestroyVector(&FileDescriptors); + TRI_WriteUnlockReadWriteLock(&FileNamesLock); } diff --git a/lib/BasicsC/logging.c b/lib/BasicsC/logging.c index 1acc7bde11..777dd05950 100644 --- a/lib/BasicsC/logging.c +++ b/lib/BasicsC/logging.c @@ -1770,6 +1770,8 @@ void TRI_InitialiseLogging (bool threaded) { //////////////////////////////////////////////////////////////////////////////// bool TRI_ShutdownLogging () { + size_t i, j; + if (! Initialised) { return ThreadedLogging; } @@ -1798,6 +1800,20 @@ bool TRI_ShutdownLogging () { TRI_UnlockSpin(&OutputPrefixLock); + // cleanup output buffers + TRI_LockMutex(&BufferLock); + + for (i = 0; i < OUTPUT_LOG_LEVELS; i++) { + for (j = 0; j < OUTPUT_BUFFER_SIZE; j++) { + if (BufferOutput[i][j]._text != NULL) { + TRI_FreeString(TRI_CORE_MEM_ZONE, BufferOutput[i][j]._text); + BufferOutput[i][j]._text = NULL; + } + } + } + + TRI_UnlockMutex(&BufferLock); + // cleanup locks TRI_DestroySpin(&OutputPrefixLock); TRI_DestroySpin(&AppendersLock); diff --git a/lib/BasicsC/string-buffer.c b/lib/BasicsC/string-buffer.c index a8ce83ea5e..c0b9140d06 100644 --- a/lib/BasicsC/string-buffer.c +++ b/lib/BasicsC/string-buffer.c @@ -288,6 +288,15 @@ size_t TRI_LengthStringBuffer (TRI_string_buffer_t const * self) { return (size_t) (self->_current - self->_buffer); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief increases length of the character buffer +//////////////////////////////////////////////////////////////////////////////// + +void TRI_IncreaseLengthStringBuffer (TRI_string_buffer_t * self, size_t n) +{ + self->_current += n; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief returns true if buffer is empty //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/BasicsC/string-buffer.h b/lib/BasicsC/string-buffer.h index 4ea6d7a088..9866580b44 100644 --- a/lib/BasicsC/string-buffer.h +++ b/lib/BasicsC/string-buffer.h @@ -164,6 +164,12 @@ char const * TRI_EndStringBuffer (TRI_string_buffer_t const * self); size_t TRI_LengthStringBuffer (TRI_string_buffer_t const * self); +//////////////////////////////////////////////////////////////////////////////// +/// @brief increases length of the character buffer +//////////////////////////////////////////////////////////////////////////////// + +void TRI_IncreaseLengthStringBuffer (TRI_string_buffer_t * self, size_t n); + //////////////////////////////////////////////////////////////////////////////// /// @brief returns true if buffer is empty //////////////////////////////////////////////////////////////////////////////// diff --git a/lib/Rest/Handler.cpp b/lib/Rest/Handler.cpp index 44633e8abc..b8d7c9da83 100644 --- a/lib/Rest/Handler.cpp +++ b/lib/Rest/Handler.cpp @@ -78,7 +78,7 @@ Job::JobType Handler::type () { /// @brief returns the queue name //////////////////////////////////////////////////////////////////////////////// -string const& Handler::queue () { +string const& Handler::queue () const { static string standard = "STANDARD"; return standard; } diff --git a/lib/Rest/Handler.h b/lib/Rest/Handler.h index b9c7992713..23f9f1e084 100644 --- a/lib/Rest/Handler.h +++ b/lib/Rest/Handler.h @@ -144,7 +144,7 @@ namespace triagens { /// @brief returns the queue name //////////////////////////////////////////////////////////////////////////////// - virtual string const& queue (); + virtual string const& queue () const; //////////////////////////////////////////////////////////////////////////////// /// @brief sets the thread which currently dealing with the job diff --git a/lib/Rest/HttpResponse.cpp b/lib/Rest/HttpResponse.cpp index 72529a9772..80db5d19ce 100644 --- a/lib/Rest/HttpResponse.cpp +++ b/lib/Rest/HttpResponse.cpp @@ -552,8 +552,7 @@ void HttpResponse::setCookie (string const& name, string const& value, } char const* l = StringUtils::duplicate(buffer->c_str()); - buffer->clear(); - free(buffer); + delete buffer; _cookies.push_back(l); _freeables.push_back(l); diff --git a/lib/Scheduler/SocketTask.cpp b/lib/Scheduler/SocketTask.cpp index 1a16cd8e58..a2e5966f38 100644 --- a/lib/Scheduler/SocketTask.cpp +++ b/lib/Scheduler/SocketTask.cpp @@ -67,7 +67,6 @@ SocketTask::SocketTask (TRI_socket_t socket, double keepAliveTimeout) ownBuffer(true), writeLength(0) { _readBuffer = new StringBuffer(TRI_UNKNOWN_MEM_ZONE); - tmpReadBuffer = new char[READ_BLOCK_SIZE]; ConnectionStatisticsAgent::acquire(); ConnectionStatisticsAgentSetStart(this); @@ -102,8 +101,6 @@ SocketTask::~SocketTask () { delete _readBuffer; - delete[] tmpReadBuffer; - ConnectionStatisticsAgentSetEnd(this); ConnectionStatisticsAgent::release(); } @@ -151,12 +148,19 @@ void SocketTask::setKeepAliveTimeout (double timeout) { bool SocketTask::fillReadBuffer (bool& closed) { closed = false; + // reserve some memory for reading + if (_readBuffer->reserve(READ_BLOCK_SIZE) == TRI_ERROR_OUT_OF_MEMORY) { + // out of memory + LOGGER_TRACE("out of memory"); - int nr = TRI_READ_SOCKET(_commSocket, tmpReadBuffer, READ_BLOCK_SIZE, 0); + return false; + } + + int nr = TRI_READ_SOCKET(_commSocket, _readBuffer->end(), READ_BLOCK_SIZE, 0); if (nr > 0) { - _readBuffer->appendText(tmpReadBuffer, nr); + _readBuffer->increaseLength(nr); return true; } else if (nr == 0) { diff --git a/lib/Scheduler/SocketTask.h b/lib/Scheduler/SocketTask.h index a2d35d9eb5..31b78540b7 100644 --- a/lib/Scheduler/SocketTask.h +++ b/lib/Scheduler/SocketTask.h @@ -374,12 +374,6 @@ namespace triagens { TRI_tid_t tid; -//////////////////////////////////////////////////////////////////////////////// -/// @brief temporary static buffer for read requests -//////////////////////////////////////////////////////////////////////////////// - - char * tmpReadBuffer; - }; } } diff --git a/lib/SimpleHttpClient/ClientConnection.cpp b/lib/SimpleHttpClient/ClientConnection.cpp index c3c59fed1c..3a1199c171 100644 --- a/lib/SimpleHttpClient/ClientConnection.cpp +++ b/lib/SimpleHttpClient/ClientConnection.cpp @@ -231,9 +231,13 @@ bool ClientConnection::readClientConnection (StringBuffer& stringBuffer) { assert(_socket.fileHandle > 0); do { - char buffer[READBUFFER_SIZE]; + // reserve some memory for reading + if (stringBuffer.reserve(READBUFFER_SIZE) == TRI_ERROR_OUT_OF_MEMORY) { + // out of memory + return false; + } - int lenRead = TRI_READ_SOCKET(_socket, buffer, READBUFFER_SIZE - 1, 0); + int lenRead = TRI_READ_SOCKET(_socket, stringBuffer.end(), READBUFFER_SIZE - 1, 0); if (lenRead == -1) { // error occurred @@ -245,7 +249,7 @@ bool ClientConnection::readClientConnection (StringBuffer& stringBuffer) { break; } - stringBuffer.appendText(buffer, lenRead); + stringBuffer.increaseLength(lenRead); } while (readable()); diff --git a/lib/SimpleHttpClient/SslClientConnection.cpp b/lib/SimpleHttpClient/SslClientConnection.cpp index c92b281a49..abccc06c7c 100644 --- a/lib/SimpleHttpClient/SslClientConnection.cpp +++ b/lib/SimpleHttpClient/SslClientConnection.cpp @@ -227,7 +227,7 @@ bool SslClientConnection::writeClientConnection (void* buffer, size_t length, si case SSL_ERROR_WANT_CONNECT: case SSL_ERROR_SYSCALL: default: { - /* fallthrough */ + /* fall through */ } } @@ -244,13 +244,17 @@ bool SslClientConnection::readClientConnection (StringBuffer& stringBuffer) { } do { - char buffer[READBUFFER_SIZE]; + // reserve some memory for reading + if (stringBuffer.reserve(READBUFFER_SIZE) == TRI_ERROR_OUT_OF_MEMORY) { + // out of memory + return false; + } - int lenRead = SSL_read(_ssl, buffer, READBUFFER_SIZE - 1); + int lenRead = SSL_read(_ssl, stringBuffer.end(), READBUFFER_SIZE - 1); switch (SSL_get_error(_ssl, lenRead)) { case SSL_ERROR_NONE: - stringBuffer.appendText(buffer, lenRead); + stringBuffer.increaseLength(lenRead); break; case SSL_ERROR_ZERO_RETURN: From bf749438f0c5e8a58d0307258711887e0b9c020e Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 11:53:12 +0200 Subject: [PATCH 04/35] GraphViewer: Added tests for expansion of community-nodes --- .../admin/js/graphViewer/graph/JSONAdapter.js | 4 + .../js/graphViewer/graph/arangoAdapter.js | 8 +- .../specAdapter/arangoAdapterSpec.js | 203 ++++++++++++++---- .../jasmine_test/specAdapter/interfaceSpec.js | 1 + 4 files changed, 178 insertions(+), 38 deletions(-) diff --git a/html/admin/js/graphViewer/graph/JSONAdapter.js b/html/admin/js/graphViewer/graph/JSONAdapter.js index d9a9d8e2a9..3d12f00e07 100644 --- a/html/admin/js/graphViewer/graph/JSONAdapter.js +++ b/html/admin/js/graphViewer/graph/JSONAdapter.js @@ -159,4 +159,8 @@ function JSONAdapter(jsonPath, nodes, edges, width, height) { }; + self.expandCommunity = function (commNode, callback) { + + }; + } \ No newline at end of file diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index 1c242c6298..c52376aedf 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -278,7 +278,7 @@ function ArangoAdapter(nodes, edges, config) { }, collapseCommunity = function (community) { - var commId = "community_1", + var commId = "*community_" + Math.floor(Math.random()* 1000000), commNode = { _id: commId, edges: [] @@ -593,4 +593,10 @@ function ArangoAdapter(nodes, edges, config) { } }; + self.expandCommunity = function (commNode, callback) { + if (callback !== undefined) { + callback(); + } + }; + } \ No newline at end of file diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index c682776db3..c257c4df77 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -58,6 +58,17 @@ checkCallbackFunction = function() { callbackCheck = true; }, + + getCommunityNodes = function() { + return _.filter(nodes, function(n) { + return n._id.match(/^\*community/); + }); + }, + + getCommunityNodesIds = function() { + return _.pluck(getCommunityNodes(), "_id"); + }, + nodeWithID = function(id) { return $.grep(nodes, function(e){ return e._id === id; @@ -885,44 +896,52 @@ }); }); - it('should not trigger the reducer if the limit is set large enough', function() { - spyOn(this, "fakeReducerRequest").andCallFake(function() { - return [c0]; - }); - adapter.setNodeLimit(10); - expect(this.fakeReducerRequest).not.toHaveBeenCalled(); - }); - - - it('should trigger the reducer if the limit is set too small', function() { - spyOn(this, "fakeReducerRequest").andCallFake(function() { - return [c0]; - }); - adapter.setNodeLimit(2); - expect(this.fakeReducerRequest).toHaveBeenCalledWith(2); - }); - describe('checking community nodes', function() { - it('should create a community node if limit is set too small', function() { - var called = false, - callback = function() { - called = true; - }; + it('should not trigger the reducer if the limit is set large enough', function() { spyOn(this, "fakeReducerRequest").andCallFake(function() { - return [c0, c1, c2]; + return [c0]; }); - adapter.setNodeLimit(2, callback); + adapter.setNodeLimit(10); + expect(this.fakeReducerRequest).not.toHaveBeenCalled(); + }); + + + it('should trigger the reducer if the limit is set too small', function() { + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return [c0]; + }); + adapter.setNodeLimit(2); + expect(this.fakeReducerRequest).toHaveBeenCalledWith(2); + }); - notExistNodes([c0, c1, c2]); - existNode("community_1"); - existNodes([c3, c4]); - expect(nodes.length).toEqual(3); - existEdge("community_1", c3); - existEdge("community_1", c4); - expect(edges.length).toEqual(2); - expect(called).toBeTruthy(); + it('should create a community node if limit is set too small', function() { + var called; + + runs(function() { + callbackCheck = false; + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return [c0, c1, c2]; + }); + adapter.setNodeLimit(2, checkCallbackFunction); + }); + + waitsFor(function() { + return callbackCheck; + }); + + runs(function() { + var commId = getCommunityNodesIds()[0]; + notExistNodes([c0, c1, c2]); + existNode(commId); + existNodes([c3, c4]); + expect(nodes.length).toEqual(3); + existEdge(commId, c3); + existEdge(commId, c4); + expect(edges.length).toEqual(2); + expect(called).toBeTruthy(); + }); }); it('should create a community node if too many nodes are added', function() { @@ -939,20 +958,130 @@ }); runs(function() { + var commId = getCommunityNodesIds()[0]; notExistNodes([c0, c1, c2, c3]); - existNode("community_1"); + existNode(commId); existNodes([c4, c5, c6, c7]); expect(nodes.length).toEqual(5); - existEdge("community_1", c4); - existEdge("community_1", c5); - existEdge("community_1", c6); - existEdge("community_1", c7); + existEdge(commId, c4); + existEdge(commId, c5); + existEdge(commId, c6); + existEdge(commId, c7); expect(edges.length).toEqual(4); }); }); + describe('that displays a community node already', function() { + + var firstCommId, + fakeResult; + + beforeEach(function() { + runs(function() { + callbackCheck = false; + adapter.setNodeLimit(7); + fakeResult = [c0, c2]; + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return fakeResult; + }); + adapter.loadNodeFromTreeById(c1, checkCallbackFunction); + }); + + waitsFor(function() { + return callbackCheck; + }); + + runs(function() { + firstCommId = getCommunityNodesIds()[0]; + }); + }); + + it('should expand a community if enough space is available', function() { + runs(function() { + adapter.setNodeLimit(10); + callbackCheck = false; + adapter.expandCommunity(nodeWithID(firstCommId), checkCallbackFunction); + }); + + waitsFor(function() { + return callbackCheck; + }); + + runs(function() { + expect(getCommunityNodes().length).toEqual(0); + existNodes([c0, c1, c2, c3, c4, c5, c6, c7]); + existEdge(c0, c1); + existEdge(c0, c2); + existEdge(c0, c3); + existEdge(c0, c4); + }); + + }); + + it('should expand a community and join another one if not enough space is available', function() { + runs(function() { + fakeResult = [c1, c7]; + callbackCheck = false; + adapter.expandCommunity(nodeWithID(firstCommId), checkCallbackFunction); + }); + + waitsFor(function() { + return callbackCheck; + }); + + runs(function() { + var newCommId = getCommunityNodesIds()[0]; + expect(getCommunityNodes().length).toEqual(1); + existNodes([c0, c2, c3, c4, c5, c6, newCommId]); + notExistNodes([c1, c7]); + + existEdge(c0, c2); + existEdge(c0, c3); + existEdge(c0, c4); + + existEdge(c0, newCommId); + existEdge(newCommId, c5); + existEdge(newCommId, c6); + }); + }); + + it('should join another community if space is further reduced', function() { + runs(function() { + fakeResult = [c1, c7]; + callbackCheck = false; + adapter.setNodeLimit(6, checkCallbackFunction); + }); + + waitsFor(function() { + return callbackCheck; + }); + + runs(function() { + expect(getCommunityNodes().length).toEqual(2); + var ids = getCommunityNodesIds(), + newCommId; + + if (firstCommId === ids[0]) { + newCommId = ids[1]; + } else { + newCommId = ids[0]; + } + + existNodes([c3, c4, c5, c6, firstCommId, newCommId]); + notExistNodes([c0, c1, c2, c7]); + + existEdge(firstCommId, c3); + existEdge(firstCommId, c4); + existEdge(firstCommId, newCommId); + existEdge(newCommId, c5); + existEdge(newCommId, c6); + }); + }); + + }); + }); describe('that has loaded several queries', function() { diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js index eefd4b42e3..d3011970da 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js @@ -66,6 +66,7 @@ var describeInterface = function (testee) { expect(testee).toHaveFunction("deleteNode", 2); expect(testee).toHaveFunction("patchNode", 3); expect(testee).toHaveFunction("setNodeLimit", 2); + expect(testee).toHaveFunction("expandCommunity", 2); }); }; From f43f0568f7d70ddc194bdb27ace695b46bb7a3cd Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 13:22:12 +0200 Subject: [PATCH 05/35] GraphViewer: Simple expansion of Communities now possible --- .../js/graphViewer/graph/arangoAdapter.js | 68 +++++++++++++++++-- .../specAdapter/arangoAdapterSpec.js | 6 +- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index c52376aedf..a7f7f7fff6 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -118,7 +118,7 @@ function ArangoAdapter(nodes, edges, config) { if (res.length === 1) { return res[0]; } - throw "Too many nodes with the same ID, should never happen"; + throw "Too many edges with the same ID, should never happen"; }, insertNode = function(data) { @@ -203,22 +203,48 @@ function ArangoAdapter(nodes, edges, config) { }, combineCommunityEdges = function (nodes, commNode) { - var i, j, s, t; + var i, j, s, t, + cachedCommEdges = cachedCommunities[commNode._id].edges, + edgeToPush; for (i = 0; i < edges.length; i++ ) { + edgeToPush = {}; // s and t keep old values yay! s = edges[i].source; t = edges[i].target; for (j = 0; j < nodes.length; j++) { if (s === nodes[j]) { + if (edgeToPush.type !== undefined) { + edges[i].target = edgeToPush.target; + delete edgeToPush.target; + edgeToPush.type = "b"; + edgeToPush.edge = edges[i]; + edges.splice( i, 1 ); + i--; + break; + } edges[i].source = commNode; + edgeToPush.type = "s"; + edgeToPush.id = edges[i]._id; + edgeToPush.source = s; } if (t === nodes[j]) { + if (edgeToPush.type !== undefined) { + edges[i].source = edgeToPush.source; + delete edgeToPush.source; + edgeToPush.type = "b"; + edgeToPush.edge = edges[i]; + edges.splice( i, 1 ); + i--; + break; + } edges[i].target = commNode; + edgeToPush.type = "t"; + edgeToPush.id = edges[i]._id; + edgeToPush.target = t; } } - if (edges[i].source === commNode && edges[i].target === commNode) { - edges.splice( i, 1 ); - i--; + if (edgeToPush.type !== undefined) { + cachedCommEdges.push(edgeToPush); } } }, @@ -288,7 +314,9 @@ function ArangoAdapter(nodes, edges, config) { }); commNode.x = nodesToRemove[0].x; commNode.y = nodesToRemove[0].y; - cachedCommunities[commId] = nodesToRemove; + cachedCommunities[commId] = {}; + cachedCommunities[commId].nodes = nodesToRemove; + cachedCommunities[commId].edges = []; combineCommunityEdges(nodesToRemove, commNode); _.each(nodesToRemove, function(n) { removeNode(n); @@ -296,6 +324,33 @@ function ArangoAdapter(nodes, edges, config) { nodes.push(commNode); }, + expandCommunity = function (commNode) { + var commId = commNode._id, + nodesToAdd = cachedCommunities[commId].nodes, + edgesToChange = cachedCommunities[commId].edges; + removeNode(commNode); + _.each(nodesToAdd, function(n) { + nodes.push(n); + }); + _.each(edgesToChange, function(e) { + var edge; + switch(e.type) { + case "t": + edge = findEdge(e.id); + edge.target = e.target; + break; + case "s": + edge = findEdge(e.id); + edge.source = e.source; + break; + case "b": + edges.push(e.edge); + break; + } + }); + delete cachedCommunities[commId]; + }, + parseResultOfTraversal = function (result, callback) { result = result[0]; _.each(result, function(visited) { @@ -594,6 +649,7 @@ function ArangoAdapter(nodes, edges, config) { }; self.expandCommunity = function (commNode, callback) { + expandCommunity(commNode); if (callback !== undefined) { callback(); } diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index c257c4df77..fd44b7f323 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -939,8 +939,7 @@ expect(nodes.length).toEqual(3); existEdge(commId, c3); existEdge(commId, c4); - expect(edges.length).toEqual(2); - expect(called).toBeTruthy(); + expect(edges.length).toEqual(2); }); }); @@ -998,7 +997,7 @@ }); }); - it('should expand a community if enough space is available', function() { + it('should expand a community if enough space is available', function() { runs(function() { adapter.setNodeLimit(10); callbackCheck = false; @@ -1011,6 +1010,7 @@ runs(function() { expect(getCommunityNodes().length).toEqual(0); + console.log(edges); existNodes([c0, c1, c2, c3, c4, c5, c6, c7]); existEdge(c0, c1); existEdge(c0, c2); From 86400bd756ccfc6fa87724919f4eb70c040a80e1 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 13:30:05 +0200 Subject: [PATCH 06/35] GraphViewer: Now collapses another community if community is expanded but no space is available --- html/admin/js/graphViewer/graph/arangoAdapter.js | 7 ++++++- .../jasmine_test/specAdapter/arangoAdapterSpec.js | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index a7f7f7fff6..eb42488b3f 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -327,8 +327,13 @@ function ArangoAdapter(nodes, edges, config) { expandCommunity = function (commNode) { var commId = commNode._id, nodesToAdd = cachedCommunities[commId].nodes, - edgesToChange = cachedCommunities[commId].edges; + edgesToChange = cachedCommunities[commId].edges, + com; removeNode(commNode); + if (limit < nodes.length + nodesToAdd.length) { + com = reducer.getCommunity(limit); + collapseCommunity(com); + } _.each(nodesToAdd, function(n) { nodes.push(n); }); diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index fd44b7f323..babdd9b2f1 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -1010,7 +1010,6 @@ runs(function() { expect(getCommunityNodes().length).toEqual(0); - console.log(edges); existNodes([c0, c1, c2, c3, c4, c5, c6, c7]); existEdge(c0, c1); existEdge(c0, c2); @@ -1020,7 +1019,8 @@ }); - it('should expand a community and join another one if not enough space is available', function() { + it('should expand a community and join another ' + + 'one if not enough space is available', function() { runs(function() { fakeResult = [c1, c7]; callbackCheck = false; From bb92f2ee29db4a6fd43df2d0ce873baa25e69eee Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 14:02:07 +0200 Subject: [PATCH 07/35] GraphViewer: Added NodeReducer to index.html of WebInterface --- html/admin/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/html/admin/index.html b/html/admin/index.html index 1ff35e8b67..3f43b8de3f 100644 --- a/html/admin/index.html +++ b/html/admin/index.html @@ -110,6 +110,7 @@ + From 7ced744d211395733bf465f3ebc6aa3b9ccd9ccf Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 14:02:43 +0200 Subject: [PATCH 08/35] GraphViewer: Added test for reshaping if community is formed --- html/admin/js/graphViewer/graphViewer.js | 2 +- .../jasmine_test/specGraphViewer/graphViewerSpec.js | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/html/admin/js/graphViewer/graphViewer.js b/html/admin/js/graphViewer/graphViewer.js index fafdf81048..ffcab615d3 100644 --- a/html/admin/js/graphViewer/graphViewer.js +++ b/html/admin/js/graphViewer/graphViewer.js @@ -85,7 +85,7 @@ function GraphViewer(svg, width, height, adapterConfig, config) { }, nodeLimitCallBack = function(limit) { - self.adapter.setNodeLimit(limit); + self.adapter.setNodeLimit(limit, self.start); }, parseZoomConfig = function(config) { diff --git a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js index e74f3b6d5d..62e314bd9a 100644 --- a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js @@ -270,6 +270,15 @@ describe("Graph Viewer", function() { expect(viewer.adapter.setNodeLimit).wasCalled(); }); + it('should trigger the start function if node limit is reduced to far', function() { + spyOn(viewer.adapter, "setNodeLimit").andCallFake(function(l, callback) { + callback(); + }); + spyOn(viewer, "start"); + helper.simulateScrollUpMouseEvent("outersvg"); + expect(viewer.start).wasCalled(); + }); + }); From 4755bb701ec12c882e0630dcce4bb2151b8ed77d Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 15:41:42 +0200 Subject: [PATCH 09/35] GraphViewer: Added tests for NodeShaper to shape Community-Nodes --- .../specNodeShaper/nodeShaperSpec.js | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js index 119e7e134b..7058539ef4 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js @@ -988,6 +988,54 @@ expect(n.attr("transform")).toEqual("translate(10,10)scale(1)"); }); }); + + describe('testing community nodes', function() { + var shaper; + + beforeEach(function() { + shaper = new NodeShaper(d3.select("svg")); + }); + + it('should render community nodes', function() { + var nodes = helper.createSimpleNodes([0, 1, 2]), + commNode = { + _id: "*community_42", + _inboundCounter: 0, + _outboundCounter: 0, + position: { + x: 1, + y: 1, + z: 1 + } + }; + nodes.push(commNode); + shaper.drawNodes(nodes); + expect($("svg .node").length).toEqual(4); + expect($("svg #\\*community_42")[0]).toBeDefined(); + }); + + it('should render communtiy nodes as stars', function() { + var nodes = helper.createSimpleNodes([0, 1, 2]), + commNode = { + _id: "*community_42", + _inboundCounter: 0, + _outboundCounter: 0, + position: { + x: 1, + y: 1, + z: 1 + } + }, + star; + nodes.push(commNode); + shaper.drawNodes(nodes); + expect($("svg .communitynode").length).toEqual(1); + expect($("svg #\\*community_42")[0]).toBeDefined(); + star = $("svg #\\*community_42 polygon")[0]; + expect(star).toBeDefined(); + expect(star.points).toEqual("0,-25 -16,20 23,-10 -23,-10 16,20"); + }); + }); }); From 0f2560c38991f1b7d2edd3826a64f283c9343377 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 21:14:40 +0200 Subject: [PATCH 10/35] GraphViewer: Implemented rendering Community Nodes as Stars --- html/admin/js/graphViewer/graph/nodeShaper.js | 21 ++++++++++++++++--- .../specAdapter/arangoAdapterSpec.js | 1 - .../specNodeShaper/nodeShaperSpec.js | 6 +++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/html/admin/js/graphViewer/graph/nodeShaper.js b/html/admin/js/graphViewer/graph/nodeShaper.js index 3d80af419e..b4412d28d0 100644 --- a/html/admin/js/graphViewer/graph/nodeShaper.js +++ b/html/admin/js/graphViewer/graph/nodeShaper.js @@ -64,6 +64,7 @@ function NodeShaper(parent, flags, idfunc) { "use strict"; var self = this, + communityRegEx = /^\*community/, nodes = [], visibleLabels = true, noop = function (node) { @@ -158,7 +159,12 @@ function NodeShaper(parent, flags, idfunc) { // Append the group and class to all new g.enter() .append("g") - .attr("class", "node") // node is CSS class that might be edited + .attr("class", function(d) { + if (communityRegEx.test(d._id)) { + return "node communitynode"; + } + return "node"; + }) // node is CSS class that might be edited .attr("id", idFunction); // Remove all old g.exit().remove(); @@ -176,8 +182,17 @@ function NodeShaper(parent, flags, idfunc) { case NodeShaper.shapes.CIRCLE: radius = shape.radius || 25; addShape = function (node) { - node.append("circle") // Display nodes as circles - .attr("r", radius); // Set radius + node.filter(function(n) { + return communityRegEx.test(n._id); + }) + .append("polygon") + .attr("points", "0,-25 -16,20 23,-10 -23,-10 16,20"); + + node.filter(function(n) { + return !communityRegEx.test(n._id); + }) + .append("circle") // Display nodes as circles + .attr("r", radius); // Set radius }; break; case NodeShaper.shapes.RECT: diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index babdd9b2f1..63926e00c3 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -907,7 +907,6 @@ expect(this.fakeReducerRequest).not.toHaveBeenCalled(); }); - it('should trigger the reducer if the limit is set too small', function() { spyOn(this, "fakeReducerRequest").andCallFake(function() { return [c0]; diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js index 7058539ef4..99fe68b8c1 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js @@ -1031,9 +1031,9 @@ shaper.drawNodes(nodes); expect($("svg .communitynode").length).toEqual(1); expect($("svg #\\*community_42")[0]).toBeDefined(); - star = $("svg #\\*community_42 polygon")[0]; - expect(star).toBeDefined(); - expect(star.points).toEqual("0,-25 -16,20 23,-10 -23,-10 16,20"); + star = $("svg #\\*community_42 polygon"); + expect(star.length).toEqual(1); + expect(star.attr("points")).toEqual("0,-25 -16,20 23,-10 -23,-10 16,20"); }); }); From d81d136cb513f053be7e1dc4bd2b369fefc39098 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Tue, 21 May 2013 23:32:06 +0200 Subject: [PATCH 11/35] GraphViewer: Added the community behaviour to the event lib --- .../admin/js/graphViewer/graph/JSONAdapter.js | 3 ++ .../js/graphViewer/graph/arangoAdapter.js | 4 ++ .../js/graphViewer/graph/eventLibrary.js | 16 +++++--- html/admin/js/graphViewer/graphViewer.js | 2 +- .../graphViewer/jasmine_test/helper/mocks.js | 4 +- .../jasmine_test/specAdapter/interfaceSpec.js | 1 + .../specEvents/eventDispatcherSpec.js | 9 ++--- .../specEvents/eventDispatcherUISpec.js | 8 ++-- .../specEvents/eventLibrarySpec.js | 37 +++++++++++++------ .../specGraphViewer/graphViewerSpec.js | 4 +- .../specNodeShaper/nodeShaperSpec.js | 1 + 11 files changed, 60 insertions(+), 29 deletions(-) diff --git a/html/admin/js/graphViewer/graph/JSONAdapter.js b/html/admin/js/graphViewer/graph/JSONAdapter.js index 3d12f00e07..cfa894b226 100644 --- a/html/admin/js/graphViewer/graph/JSONAdapter.js +++ b/html/admin/js/graphViewer/graph/JSONAdapter.js @@ -79,6 +79,9 @@ function JSONAdapter(jsonPath, nodes, edges, width, height) { return this.start + Math.random() * this.range; }; + self.loadNode = function(nodeId, callback) { + self.loadNodeFromTreeById(nodeId, callback); + }; self.loadNodeFromTreeById = function(nodeId, callback) { var json = jsonPath + nodeId + ".json"; diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index eb42488b3f..f256b667df 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -489,6 +489,10 @@ function ArangoAdapter(nodes, edges, config) { }); }; + self.loadNode = function(nodeId, callback) { + self.loadNodeFromTreeById(nodeId, callback); + }; + self.loadNodeFromTreeById = function(nodeId, callback) { sendQuery(queries.traversalById, { id: nodeId diff --git a/html/admin/js/graphViewer/graph/eventLibrary.js b/html/admin/js/graphViewer/graph/eventLibrary.js index 67198b1cb7..3cefa65244 100644 --- a/html/admin/js/graphViewer/graph/eventLibrary.js +++ b/html/admin/js/graphViewer/graph/eventLibrary.js @@ -67,8 +67,8 @@ function EventLibrary() { if (config.startCallback === undefined) { throw "A callback to the Start-method has to be defined"; } - if (config.loadNode === undefined) { - throw "A callback to load a node has to be defined"; + if (config.adapter === undefined) { + throw "An adapter to load data has to be defined"; } if (config.reshapeNodes === undefined) { throw "A callback to reshape nodes has to be defined"; @@ -81,7 +81,9 @@ function EventLibrary() { var edges = config.edges, nodes = config.nodes, startCallback = config.startCallback, - loadNode = config.loadNode, + adapter = config.adapter, + loadNode = adapter.loadNode, + expandCom = adapter.expandCommunity, reshapeNodes = config.reshapeNodes, removeNode = function (node) { var i; @@ -126,8 +128,12 @@ function EventLibrary() { }, expandNode = function(n) { - n._expanded = true; - loadNode(n._id, startCallback); + if (/^\*community/.test(n._id)) { + expandCom(n, startCallback); + } else { + n._expanded = true; + loadNode(n._id, startCallback); + } }; return function(n) { diff --git a/html/admin/js/graphViewer/graphViewer.js b/html/admin/js/graphViewer/graphViewer.js index ffcab615d3..75cc74e204 100644 --- a/html/admin/js/graphViewer/graphViewer.js +++ b/html/admin/js/graphViewer/graphViewer.js @@ -174,7 +174,7 @@ function GraphViewer(svg, width, height, adapterConfig, config) { edges: edges, nodes: nodes, startCallback: self.start, - loadNode: self.adapter.loadNodeFromTreeById, + adapter: self.adapter, reshapeNodes: self.nodeShaper.reshapeNodes }, drag: { diff --git a/html/admin/js/graphViewer/jasmine_test/helper/mocks.js b/html/admin/js/graphViewer/jasmine_test/helper/mocks.js index f11f015c7b..da8e5270db 100644 --- a/html/admin/js/graphViewer/jasmine_test/helper/mocks.js +++ b/html/admin/js/graphViewer/jasmine_test/helper/mocks.js @@ -43,7 +43,9 @@ var mocks = mocks || {}; patchNode: function(){}, createEdge: function(){}, deleteEdge: function(){}, - patchEdge: function(){} + patchEdge: function(){}, + loadNode: function(){}, + expandCommunity: function(){} }; }()); \ No newline at end of file diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js index d3011970da..485dd09d1b 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js @@ -56,6 +56,7 @@ var describeInterface = function (testee) { }); // Add functions to load here: + expect(testee).toHaveFunction("loadNode", 2); expect(testee).toHaveFunction("loadNodeFromTreeById", 2); expect(testee).toHaveFunction("requestCentralityChildren", 2); expect(testee).toHaveFunction("loadNodeFromTreeByAttributeValue", 3); diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js index 2aea9bda5f..ac7bd7ee46 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js @@ -62,6 +62,8 @@ spyOn(adapter, "createEdge"); spyOn(adapter, "patchEdge"); spyOn(adapter, "deleteEdge"); + spyOn(adapter, "loadNode"); + spyOn(adapter, "expandCommunity"); }; beforeEach(function() { @@ -74,9 +76,6 @@ nodes = []; edges = []; - this.loadNode = function() {}; - spyOn(this, "loadNode"); - defaultPosition = { x: 1, y: 1, @@ -87,7 +86,7 @@ edges: edges, nodes: nodes, startCallback: function() {}, - loadNode: this.loadNode, + adapter: adapter, reshapeNodes: function() {} }; @@ -437,7 +436,7 @@ }); waitsFor(function() { - return this.loadNode.wasCalled; + return adapter.loadNode.wasCalled; }, 1000, "The loadNode function should have been called."); runs(function() { diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js index f49038b680..e641dccb45 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js @@ -51,6 +51,8 @@ spyOn(adapter, "createEdge"); spyOn(adapter, "patchEdge"); spyOn(adapter, "deleteEdge"); + spyOn(adapter, "loadNode"); + spyOn(adapter, "expandCommunity"); }; @@ -87,15 +89,13 @@ }]; adapter = mocks.adapter; layouter = mocks.layouter; - this.loadNode = function() {}; - spyOn(this, "loadNode"); addSpies(); var expandConfig = { edges: edges, nodes: nodes, startCallback: function() {}, - loadNode: this.loadNode, + adapter: adapter, reshapeNodes: function() {} }, @@ -307,7 +307,7 @@ helper.simulateMouseEvent("click", "1"); - expect(this.loadNode).toHaveBeenCalledWith(nodes[0]._id, jasmine.any(Function)); + expect(adapter.loadNode).toHaveBeenCalledWith(nodes[0]._id, jasmine.any(Function)); }); }); diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js index 377a58fc9f..a87de74c62 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js @@ -1,6 +1,6 @@ /*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */ /*global beforeEach, afterEach */ -/*global describe, it, expect */ +/*global describe, it, expect, jasmine */ /*global runs, spyOn, waitsFor */ /*global window, eb, loadFixtures, document, $ */ /*global EventLibrary*/ @@ -40,13 +40,15 @@ var eventLib, nodeShaperDummy = {}, - edgeShaperDummy = {}; + edgeShaperDummy = {}, + adapterDummy = {}; beforeEach(function() { eventLib = new EventLibrary(); nodeShaperDummy.reshapeNodes = function() {}; edgeShaperDummy.reshapeEdges = function() {}; - + adapterDummy.loadNode = function() {}; + adapterDummy.expandCommunity = function() {}; spyOn(nodeShaperDummy, "reshapeNodes"); spyOn(edgeShaperDummy, "reshapeEdges"); }); @@ -59,10 +61,6 @@ edges, loadedNodes, started, - loadNodeCallback = function(node) { - loaded++; - loadedNodes.push(node); - }, reshapeNodesCallback = function() { reshaped++; }, @@ -84,7 +82,7 @@ edges: edges, nodes: nodes, startCallback: startCallback, - loadNode: loadNodeCallback, + adapter: adapterDummy, reshapeNodes: reshapeNodesCallback }; }); @@ -96,6 +94,11 @@ _inboundCounter: 0 }; nodes.push(node); + spyOn(adapterDummy, "loadNode").andCallFake(function(node) { + loaded++; + loadedNodes.push(node); + }); + //config.adapter = adapterDummy.loadNode; testee = eventLib.Expand(config); testee(node); @@ -206,7 +209,19 @@ expect(c2._outboundCounter).toEqual(1); }); - + it('should expand a community node properly', function() { + var comm = { + _id: "*community_1" + }; + nodes.push(comm); + + spyOn(adapterDummy, "expandCommunity"); + + testee = eventLib.Expand(config); + testee(comm); + + expect(adapterDummy.expandCommunity).toHaveBeenCalledWith(comm, jasmine.any(Function)); + }); describe('setup process', function() { @@ -248,14 +263,14 @@ function() { eventLib.Expand(testConfig); } - ).toThrow("A callback to load a node has to be defined"); + ).toThrow("An adapter to load data has to be defined"); }); it('should throw an error if reshape node callback is not given', function() { testConfig.edges = []; testConfig.nodes = []; testConfig.startCallback = function(){}; - testConfig.loadNode = function(){}; + testConfig.adapter = adapterDummy; expect( function() { eventLib.Expand(testConfig); diff --git a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js index 62e314bd9a..4dc6c49423 100644 --- a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js @@ -153,7 +153,7 @@ describe("Graph Viewer", function() { edges: [], nodes: [], startCallback: jasmine.any(Function), - loadNode: jasmine.any(Function), + adapter: jasmine.any(Object), reshapeNodes: jasmine.any(Function) }, drag: { @@ -172,7 +172,7 @@ describe("Graph Viewer", function() { edges: [], nodes: [], startCallback: jasmine.any(Function), - loadNode: jasmine.any(Function), + adapter: jasmine.any(Object), reshapeNodes: jasmine.any(Function) }); expect(viewer.dispatcherConfig.drag).toEqual({ diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js index 99fe68b8c1..ea629425f9 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js @@ -1035,6 +1035,7 @@ expect(star.length).toEqual(1); expect(star.attr("points")).toEqual("0,-25 -16,20 23,-10 -23,-10 16,20"); }); + }); }); From 21bb9c330d59aab839b201421b306d68fb897799 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 22 May 2013 08:55:56 +0200 Subject: [PATCH 12/35] remove .setup-directories explicitly for some reason, a `make doxygen` otherwise fails after a previous `make clean` --- Documentation/Makefile.files | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/Makefile.files b/Documentation/Makefile.files index df571ab137..dc1feb042a 100644 --- a/Documentation/Makefile.files +++ b/Documentation/Makefile.files @@ -295,7 +295,8 @@ man: Doxygen/.setup-directories ################################################################################ CLEANUP += \ - Doxygen/* + Doxygen/.setup-directories \ + Doxygen/* ## ----------------------------------------------------------------------------- ## --SECTION-- EXAMPLES From f0a82e83d99e2c72da4e38cd14acb64824005eae Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 22 May 2013 09:01:42 +0200 Subject: [PATCH 13/35] removed non-existing files from asset list --- js/apps/aardvark/manifest.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/js/apps/aardvark/manifest.json b/js/apps/aardvark/manifest.json index 9c2d5c96fb..3ac357938f 100644 --- a/js/apps/aardvark/manifest.json +++ b/js/apps/aardvark/manifest.json @@ -29,8 +29,6 @@ "../../../html/admin/js/modules/org/arangodb/arango-collection-common.js", "../../../html/admin/js/modules/org/arangodb/arango-collection.js", "../../../html/admin/js/modules/org/arangodb/arango-database.js", - "../../../html/admin/js/modules/org/arangodb/arango-error-common.js", - "../../../html/admin/js/modules/org/arangodb/arango-error.js", "../../../html/admin/js/modules/org/arangodb/arango-query-cursor.js", "../../../html/admin/js/modules/org/arangodb/arango-statement-common.js", "../../../html/admin/js/modules/org/arangodb/arango-statement.js", From 3b73c8f900e903a73bd61ceaf4f54aef3cbaf0d5 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 22 May 2013 11:09:58 +0200 Subject: [PATCH 14/35] dont write currently unnecessary data on collection creation and deletion --- arangod/VocBase/vocbase.c | 92 -------------------------------------- js/server/version-check.js | 18 -------- 2 files changed, 110 deletions(-) diff --git a/arangod/VocBase/vocbase.c b/arangod/VocBase/vocbase.c index acfb172e12..a6886bbba8 100644 --- a/arangod/VocBase/vocbase.c +++ b/arangod/VocBase/vocbase.c @@ -215,96 +215,6 @@ static bool EqualKeyCollectionName (TRI_associative_pointer_t* array, void const /// @{ //////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// @brief create a JSON array with collection meta data -/// -/// this function is called when a collection is created or dropped -//////////////////////////////////////////////////////////////////////////////// - -static TRI_json_t* CreateJsonCollectionInfo (TRI_vocbase_col_t const* collection, - const char* situation) { - TRI_json_t* json; - TRI_json_t* details; - char* cidString; - - details = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE); - TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, details, "type", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, TRI_TypeNameCollection(collection->_type))); - TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, details, "name", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, collection->_name)); - TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, details, "action", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, situation)); - - cidString = TRI_StringUInt64((uint64_t) collection->_cid); - - json = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE); - TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "id", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, cidString)); - TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "type", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, "collection")); - TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "details", details); - - TRI_FreeString(TRI_CORE_MEM_ZONE, cidString); - - return json; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief insert the id of a collection into the "_ids" collection -//////////////////////////////////////////////////////////////////////////////// - -static int InsertIdCallback (TRI_transaction_collection_t* trxCollection, - void* data) { - TRI_shaped_json_t* shaped; - TRI_primary_collection_t* primary; - TRI_json_t* json; - TRI_doc_mptr_t mptr; - int res; - - primary = (TRI_primary_collection_t*) trxCollection->_collection->_collection; - json = data; - - shaped = TRI_ShapedJsonJson(primary->_shaper, json); - - if (shaped == NULL) { - return TRI_ERROR_OUT_OF_MEMORY; - } - - res = primary->insert(trxCollection, NULL, &mptr, TRI_DOC_MARKER_KEY_DOCUMENT, shaped, NULL, false, false); - TRI_FreeShapedJson(primary->_shaper, shaped); - - return res; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief save collection info on create or drop -/// -/// the info will be stored permanently in the "_ids" collection, so we can -/// later reconstruct ids of collections that are/were dropped -//////////////////////////////////////////////////////////////////////////////// - -static bool WriteCollectionInfo (TRI_vocbase_t* vocbase, - TRI_vocbase_col_t const* collection, - const char* situation) { - TRI_json_t* json; - int res; - - if (collection == NULL) { - return false; - } - - json = CreateJsonCollectionInfo(collection, situation); - - if (json == NULL) { - return false; - } - - res = TRI_ExecuteSingleOperationTransaction(vocbase, - "_ids", - TRI_TRANSACTION_WRITE, - InsertIdCallback, - json); - - TRI_FreeJson(TRI_CORE_MEM_ZONE, json); - - return (res == TRI_ERROR_NO_ERROR); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief returns the current tick value, without using a lock //////////////////////////////////////////////////////////////////////////////// @@ -456,8 +366,6 @@ static void FreeCollection (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collectio //////////////////////////////////////////////////////////////////////////////// static bool UnregisterCollection (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* collection) { - WriteCollectionInfo(vocbase, collection, "drop"); - TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase); TRI_RemoveKeyAssociativePointer(&vocbase->_collectionsByName, collection->_name); diff --git a/js/server/version-check.js b/js/server/version-check.js index 3317f85254..756f43c202 100644 --- a/js/server/version-check.js +++ b/js/server/version-check.js @@ -373,24 +373,6 @@ return true; }); - // set up the collection _ids - addTask("setupIds", "setup _ids collection", function () { - return createSystemCollection("_ids", { waitForSync : false }); - }); - - // create a cap constraint for _ids - addTask("ensureIdsCap", "ensureCapConstraint for _ids collection", function () { - var ids = getCollection("_ids"); - - if (! ids) { - return false; - } - - ids.ensureCapConstraint(50); - - return true; - }); - // set up the collection _trx addTask("setupTrx", "setup _trx collection", function () { return createSystemCollection("_trx", { waitForSync : false }); From 42b94054040ca611ffe1cb5248469ffd1d0dbc5b Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 11:57:53 +0200 Subject: [PATCH 15/35] dashboard css --- html/admin/css/dashboardView.css | 14 +++++++++----- html/admin/js/lib/nv.d3.js | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/html/admin/css/dashboardView.css b/html/admin/css/dashboardView.css index 1efd58413a..86d7d53980 100644 --- a/html/admin/css/dashboardView.css +++ b/html/admin/css/dashboardView.css @@ -66,8 +66,8 @@ .statClient { float: left; - height: 150px; - width: 280px; + height: 120px; + width: 205px; margin-left: 9px; margin-bottom: 15px; border: 1px solid black; @@ -77,7 +77,11 @@ } .statChart { + margin-left: -15px !important; +} +.nv-axislabel { + margin-left: 20px; } .nv-axisMaxMin > text { @@ -87,15 +91,15 @@ .svgClass { margin-top: 0 !important; padding-top: 0 !important; - height: 150px; - width: 270px; + height: 140px; + width: 220px; } .svgDetailClass { margin-top: 0 !important; padding-top: 0 !important; height: 300px; - width: 877px; + width: 887px; } .boxHeader { diff --git a/html/admin/js/lib/nv.d3.js b/html/admin/js/lib/nv.d3.js index 61734e2db1..8653e427f7 100644 --- a/html/admin/js/lib/nv.d3.js +++ b/html/admin/js/lib/nv.d3.js @@ -565,7 +565,7 @@ nv.models.axis = function() { .attr('text-anchor', rotateYLabel ? 'middle' : 'end') .attr('transform', rotateYLabel ? 'rotate(-90)' : '') //Edited 25 in next line -> origin was 12 - .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + 28) : -10); //TODO: consider calculating this based on largest tick width... OR at least expose this on chart + .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + 40) : -10); //TODO: consider calculating this based on largest tick width... OR at least expose this on chart axisLabel .attr('x', rotateYLabel ? (-scale.range()[0] / 2) : -axis.tickPadding()); if (showMaxMin) { From 2070615631af7e55ec164efa8f0f16a597449ef2 Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 12:15:30 +0200 Subject: [PATCH 16/35] extra class for last checkbox divider --- html/admin/css/dashboardView.css | 4 ++++ html/admin/js/views/dashboardView.js | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/html/admin/css/dashboardView.css b/html/admin/css/dashboardView.css index 86d7d53980..bc248223c3 100644 --- a/html/admin/css/dashboardView.css +++ b/html/admin/css/dashboardView.css @@ -12,6 +12,10 @@ } */ +.dbNotVisible { + opacity: 0 !important; +} + #dashboardHeader .btn-group { margin-left: 10px; margin-top: 6px; diff --git a/html/admin/js/views/dashboardView.js b/html/admin/js/views/dashboardView.js index b7c4fabf75..7775995a65 100644 --- a/html/admin/js/views/dashboardView.js +++ b/html/admin/js/views/dashboardView.js @@ -70,15 +70,19 @@ var dashboardView = Backbone.View.extend({ "seconds" ); + var counter = 1; $.each(this.options.description.models[0].attributes.groups, function () { + console.log(self.options.description.models[0].attributes.groups.length); $('.thumbnails').append( '
    ' + '

    ' + this.name + '

    ' + '
'); - $('#menuGroups').append( - '' + - '
  • ' - ); + $('#menuGroups').append(''); + $('#menuGroups').append('
  • '); + if (self.options.description.models[0].attributes.groups.length === counter) { + $('#'+this.group+'Divider').addClass('dbNotVisible'); + } + counter++; }); $.each(this.options.description.models[0].attributes.figures, function () { From fb1dfcfdd891806fc762d2ed2300933d07359aa3 Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 13:46:24 +0200 Subject: [PATCH 17/35] css + closeable groups --- html/admin/css/dashboardView.css | 12 +++++++++++- html/admin/js/lib/nv.d3.js | 3 ++- html/admin/js/views/dashboardView.js | 29 ++++++++++++++++++++++------ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/html/admin/css/dashboardView.css b/html/admin/css/dashboardView.css index bc248223c3..6adc6846d6 100644 --- a/html/admin/css/dashboardView.css +++ b/html/admin/css/dashboardView.css @@ -21,16 +21,26 @@ margin-top: 6px; } +.group-close, .group-open { + float:right; + margin-top: 17px !important; + margin-right: 7px !important; +} + .db-zoom, .db-minimize, .db-hide, .db-info { float: right; margin-top: -4px !important; margin-right: 4px !important; } -.db-zoom:hover, .db-minimize:hover, .db-hide, .db-info:hover { +.db-zoom:hover, .db-minimize:hover, .db-hide, .db-info:hover, .group-close:hover, .group-open:hover { cursor:pointer; } +.groupHidden li { + display:none; +} + .statGroups { margin-left: 0px; float:left; diff --git a/html/admin/js/lib/nv.d3.js b/html/admin/js/lib/nv.d3.js index 8653e427f7..64065ad344 100644 --- a/html/admin/js/lib/nv.d3.js +++ b/html/admin/js/lib/nv.d3.js @@ -479,8 +479,9 @@ nv.models.axis = function() { .attr('transform', function(d,i,j) { return 'rotate(' + rotateLabels + ' 0,0)' }) .attr('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end'); } - axisLabel.enter().append('text').attr('class', 'nv-axislabel') + axisLabel.enter().append('text').attr('class', 'nv-axislabel nv-x-axislabel') .attr('text-anchor', 'middle') + .attr('class', 'heikotestclass') .attr('y', xLabelMargin); var w = (scale.range().length==2) ? scale.range()[1] : (scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])); axisLabel diff --git a/html/admin/js/views/dashboardView.js b/html/admin/js/views/dashboardView.js index 7775995a65..69d6d7504f 100644 --- a/html/admin/js/views/dashboardView.js +++ b/html/admin/js/views/dashboardView.js @@ -3,7 +3,7 @@ var dashboardView = Backbone.View.extend({ updateInterval: 1000, // 1 second, constant updateFrequency: 5, // the actual update rate (5 s) updateCounter: 0, - arraySize: 99, // how many values will we keep per figure? + arraySize: 20, // how many values will we keep per figure? seriesData: {}, charts: {}, units: [], @@ -47,10 +47,12 @@ var dashboardView = Backbone.View.extend({ events: { "click .dashboard-dropdown li" : "checkEnabled", - "click .interval-dropdown li" : "checkInterval", - "click .db-zoom" : "renderDetailChart", - "click .db-minimize" : "checkDetailChart", - "click .db-hide" : "hideChart" + "click .interval-dropdown li" : "checkInterval", + "click .db-zoom" : "renderDetailChart", + "click .db-minimize" : "checkDetailChart", + "click .db-hide" : "hideChart", + "click .group-close" : "hideGroup", + "click .group-open" : "showGroup" }, template: new EJS({url: 'js/templates/dashboardView.ejs'}), @@ -72,9 +74,10 @@ var dashboardView = Backbone.View.extend({ var counter = 1; $.each(this.options.description.models[0].attributes.groups, function () { - console.log(self.options.description.models[0].attributes.groups.length); + console.log(this); $('.thumbnails').append( '
      ' + + '' + '

      ' + this.name + '

      ' + '
    '); $('#menuGroups').append(''); @@ -214,6 +217,20 @@ var dashboardView = Backbone.View.extend({ } }, + hideGroup: function (a) { + var group = $(a.target).parent(); + $(a.target).removeClass('icon-minus group-close'); + $(a.target).addClass('icon-plus group-open'); + $(group).addClass("groupHidden"); + }, + + showGroup: function (a) { + var group = $(a.target).parent(); + $(a.target).removeClass('icon-plus group-open'); + $(a.target).addClass('icon-minus group-close'); + $(group).removeClass("groupHidden"); + }, + hideChart: function (a) { var figure = $(a.target).attr("value"); $('#'+figure+'Checkbox').prop('checked', false); From e6277147633891c77edba7452b964dd99980e762 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 22 May 2013 14:08:13 +0200 Subject: [PATCH 18/35] GraphViewer: CommunityNodes now tell the outer world how many nodes are inside --- html/admin/js/graphViewer/graph/nodeShaper.js | 39 ++++++++++++------- .../specNodeShaper/nodeShaperSpec.js | 21 ++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/html/admin/js/graphViewer/graph/nodeShaper.js b/html/admin/js/graphViewer/graph/nodeShaper.js index b4412d28d0..d60e7cd1cd 100644 --- a/html/admin/js/graphViewer/graph/nodeShaper.js +++ b/html/admin/js/graphViewer/graph/nodeShaper.js @@ -92,7 +92,17 @@ function NodeShaper(parent, flags, idfunc) { addColor = noop, addShape = noop, addLabel = noop, - + addCommunityShape = function(g) { + g.append("polygon") + .attr("points", "0,-25 -16,20 23,-10 -23,-10 16,20"); + }, + addCommunityLabel = function(g) { + g.append("text") // Append a label for the node + .attr("text-anchor", "middle") // Define text-anchor + .text(function(d) { + return d._size; + }); + }, unbindEvents = function() { // Hard unbind the dragging self.parent @@ -121,9 +131,18 @@ function NodeShaper(parent, flags, idfunc) { }, addQue = function (g) { - addShape(g); + var community = g.filter(function(n) { + return communityRegEx.test(n._id); + }), + normal = g.filter(function(n) { + return !communityRegEx.test(n._id); + }); + addCommunityShape(community); + addShape(normal); + if (visibleLabels) { - addLabel(g); + addCommunityLabel(community); + addLabel(normal); } addColor(g); addEvents(g); @@ -182,17 +201,9 @@ function NodeShaper(parent, flags, idfunc) { case NodeShaper.shapes.CIRCLE: radius = shape.radius || 25; addShape = function (node) { - node.filter(function(n) { - return communityRegEx.test(n._id); - }) - .append("polygon") - .attr("points", "0,-25 -16,20 23,-10 -23,-10 16,20"); - - node.filter(function(n) { - return !communityRegEx.test(n._id); - }) - .append("circle") // Display nodes as circles - .attr("r", radius); // Set radius + node + .append("circle") // Display nodes as circles + .attr("r", radius); // Set radius }; break; case NodeShaper.shapes.RECT: diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js index ea629425f9..b60db1b0f2 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js @@ -1018,6 +1018,7 @@ var nodes = helper.createSimpleNodes([0, 1, 2]), commNode = { _id: "*community_42", + _size: 4, _inboundCounter: 0, _outboundCounter: 0, position: { @@ -1036,6 +1037,26 @@ expect(star.attr("points")).toEqual("0,-25 -16,20 23,-10 -23,-10 16,20"); }); + it('should print the size of the capsulated community', function() { + var nodes = helper.createSimpleNodes([0, 1, 2]), + commNode = { + _id: "*community_42", + _size: 4, + _inboundCounter: 0, + _outboundCounter: 0, + position: { + x: 1, + y: 1, + z: 1 + } + }, + text; + nodes.push(commNode); + shaper.drawNodes(nodes); + text = $("svg #\\*community_42 text")[0].textContent; + expect(text).toEqual("4"); + }); + }); }); From 6a80d3ca63c80c86e8c18e3fe53da2926c4e215e Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 16:18:19 +0200 Subject: [PATCH 19/35] changed checkbox & graph styling --- html/admin/css/dashboardView.css | 61 +++++++++++++++++++- html/admin/img/dark-check-green.png | Bin 0 -> 3204 bytes html/admin/js/templates/collectionsView.ejs | 41 +++++++++++-- html/admin/js/views/dashboardView.js | 12 +++- 4 files changed, 103 insertions(+), 11 deletions(-) create mode 100644 html/admin/img/dark-check-green.png diff --git a/html/admin/css/dashboardView.css b/html/admin/css/dashboardView.css index 6adc6846d6..a0784a7759 100644 --- a/html/admin/css/dashboardView.css +++ b/html/admin/css/dashboardView.css @@ -90,8 +90,12 @@ box-shadow: 0 0 3px #333333; } -.statChart { - margin-left: -15px !important; +#detailGraphChart { + margin-left: -10px !important; +} + +.statGroups .statChart { + margin-left: -45px !important; } .nv-axislabel { @@ -106,7 +110,7 @@ margin-top: 0 !important; padding-top: 0 !important; height: 140px; - width: 220px; + width: 255px; } .svgDetailClass { @@ -161,3 +165,54 @@ .nv-point { display: none; } + +/*Dashboard Dropdown*/ + +.dropdown-menu li > a { + padding: 0px 20px !important; +} + +.checkboxLabel { + margin-top: 4px; + padding-left: 0; +} + +.svgClass .nv-axisMaxMin text { + visibility: hidden; +} + +.svgClass .major text { + visibility: hidden; +} + +.svgClass .nv-axislabel { + visibility: hidden; +} + +/*Dashboard Checkbox*/ + +input[type=checkbox].css-checkbox { + display:none; +} + +input[type=checkbox].css-checkbox + label.css-label { + padding-left:20px; + margin-top: 0px; + margin-bottom: -0px; + height:15px; + display:inline-block; + line-height:15px; + background-repeat:no-repeat; + background-position: 0 0; + font-size:15px; + vertical-align:middle; + cursor:pointer; +} + +input[type=checkbox].css-checkbox:checked + label.css-label { + background-position: 0 -15px; +} + +.css-label { + background-image:url(../img/dark-check-green.png); +} diff --git a/html/admin/img/dark-check-green.png b/html/admin/img/dark-check-green.png new file mode 100644 index 0000000000000000000000000000000000000000..cb6c4f5958ecbf019d61a904a85c2aa323e57479 GIT binary patch literal 3204 zcmV-~414p5P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z00056Nkl?xAzeDln5INhOLRW35F*dcvwI z*4m15ZbpH+sv2u8s)~s8^(`U>s4IXm1`*k-K_$CzFRMM_qv}6=1bE$hA3_KNL*DxU ztPAig&+~Rs6v2B>zbc9%WLee*UMTR`ITt(UZUH9;xOfei10L=6oCAJP*E{F=*CTmq zGSJ!bY`n9Fi{#j(<;LA9&RwY=Zo-aV@=V>HpjI8Bnrd%29`#hm%U|oX>tKib;LW9&k6$CkrX6Rl1+q`V=T}321P{OfZq4##ZV2DnCTkk -
  • -
  • -
  • +
  • + +
  • + +
  • + +
  • + +
  • + +
  • +
  • -
  • -
  • + +
  • + +
  • + +
  • + +
  • +
  • diff --git a/html/admin/js/views/dashboardView.js b/html/admin/js/views/dashboardView.js index 69d6d7504f..18f4f7d0f6 100644 --- a/html/admin/js/views/dashboardView.js +++ b/html/admin/js/views/dashboardView.js @@ -308,8 +308,12 @@ var dashboardView = Backbone.View.extend({ .call(chart) .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ]) .transition().duration(500); - } + else { + } + + //disable ticks for small charts + //disable label for small charts d3.select("#" + identifier + "Chart svg") .call(chart) @@ -402,8 +406,10 @@ var dashboardView = Backbone.View.extend({ ); $('#' + figure.group + 'Divider').before( - '
  • ' + '
  • ' ); $('.db-info').tooltip({ placement: "top" From 74179e697da3572c9d0b730216a4c8819b9cb8ce Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 22 May 2013 16:46:49 +0200 Subject: [PATCH 20/35] GraphViewer: Added tests for expanding/collapsing of nodes if communitynodes are inside the graph --- .../specAdapter/arangoAdapterSpec.js | 30 ++++- .../specEvents/eventLibrarySpec.js | 124 ++++++++++++++++-- 2 files changed, 143 insertions(+), 11 deletions(-) diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index 63926e00c3..1a130ab783 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -466,6 +466,12 @@ }); }); + it('should map loadNode to loadByID', function() { + spyOn(adapter, "loadNodeFromTreeById"); + adapter.loadNode("a", "b"); + expect(adapter.loadNodeFromTreeById).toHaveBeenCalledWith("a", "b"); + }); + it('should be able to load a tree node from ArangoDB' + ' by internal attribute and value', function() { @@ -996,7 +1002,7 @@ }); }); - it('should expand a community if enough space is available', function() { + it('should expand a community if enough space is available', function() { runs(function() { adapter.setNodeLimit(10); callbackCheck = false; @@ -1019,7 +1025,7 @@ }); it('should expand a community and join another ' - + 'one if not enough space is available', function() { + + 'one if not enough space is available', function() { runs(function() { fakeResult = [c1, c7]; callbackCheck = false; @@ -1079,6 +1085,26 @@ }); }); + it('should connect edges to community-internal nodes', function() { + + runs(function() { + insertEdge(edgesCollection, c3, c0); + + adapter.setNodeLimit(20); + callbackCheck = false; + adapter.loadNode(c3, checkCallbackFunction); + }); + + waitsFor(function() { + return callbackCheck; + }); + + runs(function() { + existEdge(c3, firstCommId); + }); + + }); + }); }); diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js index a87de74c62..6a39dc7b7e 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js @@ -209,21 +209,127 @@ expect(c2._outboundCounter).toEqual(1); }); - it('should expand a community node properly', function() { - var comm = { - _id: "*community_1" - }; - nodes.push(comm); + describe('with community nodes', function() { - spyOn(adapterDummy, "expandCommunity"); + it('should expand a community node properly', function() { + var comm = { + _id: "*community_1" + }; + nodes.push(comm); - testee = eventLib.Expand(config); - testee(comm); + spyOn(adapterDummy, "expandCommunity"); + + testee = eventLib.Expand(config); + testee(comm); + + expect(adapterDummy.expandCommunity).toHaveBeenCalledWith(comm, jasmine.any(Function)); + }); + + it('should remove a community if last pointer to it is collapsed', function() { + + runs(function() { + var c0 = { + _id: 0, + _outboundCounter: 1, + _inboundCounter: 0 + }, + c1 = { + _id: 1, + _expanded: true, + _outboundCounter: 1, + _inboundCounter: 1 + }, + comm = { + _id: "*community_1", + _outboundCounter: 1, + _inboundCounter: 1 + }, + c2 = { + _id: 1, + _outboundCounter: 0, + _inboundCounter: 1 + }, + e0 = { + source: c0, + target: c1 + }, + e1 = { + source: c1, + target: comm + }, + e2 = { + source: comm, + target: c2 + }; + nodes.push(c0); + nodes.push(c1); + nodes.push(comm); + nodes.push(c2); + edges.push(e0); + edges.push(e1); + edges.push(e2); + + testee = eventLib.Expand(config); + testee(c1); + + expect(nodes).toEqual([c0, c1]); + expect(edges).toEqual([e0]); + }); + + }); + + it('should not remove a community if a pointer to it still exists', function() { + + runs(function() { + var c0 = { + _id: 0, + _outboundCounter: 2, + _inboundCounter: 0 + }, + c1 = { + _id: 1, + _expanded: true, + _outboundCounter: 1, + _inboundCounter: 1 + }, + comm = { + _id: "*community_1", + _outboundCounter: 0, + _inboundCounter: 2 + }, + e0 = { + source: c0, + target: c1 + }, + e1 = { + source: c0, + target: comm + }, + e2 = { + source: c1, + target: comm + }; + nodes.push(c0); + nodes.push(c1); + nodes.push(comm); + edges.push(e0); + edges.push(e1); + edges.push(e2); + + testee = eventLib.Expand(config); + testee(c1); + + expect(nodes).toEqual([c0, c1, comm]); + expect(edges).toEqual([e0, e1]); + }); + + }); - expect(adapterDummy.expandCommunity).toHaveBeenCalledWith(comm, jasmine.any(Function)); }); + + describe('setup process', function() { var testConfig = {}; From e0e4760abcb334012dc0a0af440cc32c37597c15 Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 17:07:01 +0200 Subject: [PATCH 21/35] changed css+radio buttons styling --- html/admin/css/dashboardView.css | 31 ++++++++++++++++++++- html/admin/js/templates/collectionsView.ejs | 24 ++++++++++++++-- html/admin/js/templates/dashboardView.ejs | 10 +++---- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/html/admin/css/dashboardView.css b/html/admin/css/dashboardView.css index a0784a7759..6f84f71056 100644 --- a/html/admin/css/dashboardView.css +++ b/html/admin/css/dashboardView.css @@ -190,7 +190,6 @@ } /*Dashboard Checkbox*/ - input[type=checkbox].css-checkbox { display:none; } @@ -216,3 +215,33 @@ input[type=checkbox].css-checkbox:checked + label.css-label { .css-label { background-image:url(../img/dark-check-green.png); } + +/*Dashboard Radio */ + +.dropdown-menu .radio { + margin-left: -21px; +} + +input[type="radio"] { + display:none; +} + +input[type="radio"] + label { + /*color:#f2f2f2;*/ + /*font-family:Arial, sans-serif; + font-size:14px;*/ +} + +input[type="radio"] + label span { + display:inline-block; + width:19px; + height:19px; + margin:-1px 4px 0 0; + vertical-align:middle; + background:url(../img/check_radio_sheet.png) -38px top no-repeat; + cursor:pointer; +} + +input[type="radio"]:checked + label span { + background:url(../img/check_radio_sheet.png) -57px top no-repeat; +} diff --git a/html/admin/js/templates/collectionsView.ejs b/html/admin/js/templates/collectionsView.ejs index 1754499a83..42ce3355de 100644 --- a/html/admin/js/templates/collectionsView.ejs +++ b/html/admin/js/templates/collectionsView.ejs @@ -47,9 +47,27 @@ -
  • -
  • -
  • + +
  • + +
  • + +
  • + +
  • + +
  • + +
  • diff --git a/html/admin/js/templates/dashboardView.ejs b/html/admin/js/templates/dashboardView.ejs index af1e83b8ea..eaf616e132 100644 --- a/html/admin/js/templates/dashboardView.ejs +++ b/html/admin/js/templates/dashboardView.ejs @@ -22,11 +22,11 @@ From fef0d543aaa424fa38c92d124976fddb8b4d4d9c Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 17:25:15 +0200 Subject: [PATCH 22/35] faster detailgraph switching, changed checkbox img --- html/admin/img/check_radio_sheet.png | Bin 0 -> 4328 bytes html/admin/js/views/dashboardView.js | 14 +++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 html/admin/img/check_radio_sheet.png diff --git a/html/admin/img/check_radio_sheet.png b/html/admin/img/check_radio_sheet.png new file mode 100644 index 0000000000000000000000000000000000000000..fcb4776faac5db1f25d0f659573f12ad16054c4c GIT binary patch literal 4328 zcmVP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000IPNklN`dl{A}$hYrE(Dxk&r5(M5 zgDXpmQS0Ktsp${G`ooo_#RY&bKm17Qjh7ZK90wi(jsR25%S*sT;IA{YbLV&J_-Qhsx{ta`o9 z(ET50?O#`30Dd+zJNIgja}&VVg%FQ>TIZC~NGY2Pi!ljtlGL1Y&jHWQ%+4)uA=LX~ zwFP@%`cO5K@dK?rl#&P`>F1^coU<5XNs^d)J=$D)^YTE;K7Hs@w|w8v?}k;aZnFQO zFEah)_gMMcUwG~N-+2M}+RW@+z2%_N`WY$23E%TkS|f!3(Ih*Ebq&giEf z6c=oM|d+d5gsnA_~-@&<*Y z$GXIdu3e>ccAlhCer#rTZVezC3_R*-_KDU{ZDT6x)Epew>U zS;knr$s*$?C$WcNS+B6HSFnd+{NyCwWD#R*DogI=7F;fGQ1gAt<&7PQWvZ3Ot}HG7 zqP-~?b3~~|o%z2={g+7yffNFzG}f3ST^mdXD~du!K0D6(Jt4QEkk~n5=eQMxtl!hH zMNyc_+B3l_l?sKU$9V9?KT|k*jB=Ib_oT4&UWgUN5&6#?X5#c2E?-?^;`EueEln)XB$#v&-uHs`&h7nQ zH4%_Wo!hXb&)pNjJnd2X$7{G(U&lZ2F_y1a+oJV~m30p3d4yqj8z+;^S!;~KIh=Di zC$`zaU86OymP|Hh`>}jqQ-1^e&!@BMZ-DRXRMwuPq!5CffYRA{qH9;%LiLIjNI@o( z>C4Fm10`b;Y*VmC_eS5&&b9g|laLJtO8r>ApCw*cC4Q%R8zp|HO1!X&?`Kn4vb&Mo zUJU29e(e@3lgScD*(F-HSdvU8yCo|K_FYVj#Uu&V8mx6VXFJ4eMV@V+8cdRq7)ucB zyV#GVltf-zq4v@`;VU7@%^Jzg8sRG;wU^eB*H%zUrm{4EYrlwS_E}qny>0w#x~rY6 zOeO>MkkZ+C3Qs))&=pzRu|^BU=j&nZOKZ1QyjD-=-0h94b1kt9Q5-Qkc6U5lC_cXx zOKXkz?<&#T?^5}7(rjEczMn;D-It}c_Au5UjBKWp+tJa;ScBGHcPE{~^0Y^`UZ-?+ zzL6Tv;b|XZ%$BU?I6pEvb}mWcM=Bd@_|`{hx8-qW-_Qsnqhsem6C>coFzW|;<~%>zX1Rx W9p+DBeAv(c0000' + '' + @@ -151,6 +157,7 @@ var dashboardView = Backbone.View.extend({ }, checkInterval: function (a) { + var self = this; this.updateFrequency = a.target.value; self.calculateSeries(); self.renderCharts(); @@ -243,13 +250,14 @@ var dashboardView = Backbone.View.extend({ $.each(this.options.description.models[0].attributes.figures, function () { if(this.identifier === self.detailGraph) { $('#detailGraphHeader').text(this.name); - self.calculateSeries(); - self.renderCharts(); $("html, body").animate({ scrollTop: 0 }, "slow"); $('#detailGraphChart').show(); $('#detailGraph').height(300); $('#dbHideSwitch').addClass('icon-minus'); $('#dbHideSwitch').removeClass('icon-plus'); + self.calculateSeries(); + self.renderCharts(); + self.updateNOW = true; } }); }, From 0660035260b3323f20be28bb86a1e2139211e998 Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 18:29:13 +0200 Subject: [PATCH 23/35] fix --- html/admin/js/views/dashboardView.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/html/admin/js/views/dashboardView.js b/html/admin/js/views/dashboardView.js index 4859ff7c5e..8a541a66ac 100644 --- a/html/admin/js/views/dashboardView.js +++ b/html/admin/js/views/dashboardView.js @@ -1,6 +1,6 @@ var dashboardView = Backbone.View.extend({ el: '#content', - updateInterval: 1000, // 1 second, constant + updateInterval: 500, // 0.5 second, constant updateFrequency: 5, // the actual update rate (5 s) updateCounter: 0, arraySize: 20, // how many values will we keep per figure? @@ -69,7 +69,7 @@ var dashboardView = Backbone.View.extend({ $(this.el).html(this.template.text); //Client calculated charts - self.genCustomCategories(); + /*self.genCustomCategories(); self.genCustomChartDescription( "userTime + systemTime", "custom", @@ -77,7 +77,7 @@ var dashboardView = Backbone.View.extend({ "Total Time (User+System)", "accumulated", "seconds" - ); + );*/ var counter = 1; $.each(this.options.description.models[0].attributes.groups, function () { @@ -120,7 +120,7 @@ var dashboardView = Backbone.View.extend({ }, //generate function for all custom categories genCustomCategories: function () { - this.genCustomCategory("Client calculated charts", "custom", "Customized Charts"); + //this.genCustomCategory("Client calculated charts", "custom", "Customized Charts"); }, //generate a custom category genCustomCategory: function(description, group, name) { @@ -145,7 +145,7 @@ var dashboardView = Backbone.View.extend({ }, //calculate customized chart value functions here updateCustomChartValues: function () { - this.totalTime2(); + //this.totalTime2(); }, //custom chart value calculation for totalTime2 @@ -255,9 +255,9 @@ var dashboardView = Backbone.View.extend({ $('#detailGraph').height(300); $('#dbHideSwitch').addClass('icon-minus'); $('#dbHideSwitch').removeClass('icon-plus'); + self.updateNOW = true; self.calculateSeries(); self.renderCharts(); - self.updateNOW = true; } }); }, From e5aef17523f1f09aad9b66e60d67408a7214f006 Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 18:47:35 +0200 Subject: [PATCH 24/35] css changes dashboard --- html/admin/css/dashboardView.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/html/admin/css/dashboardView.css b/html/admin/css/dashboardView.css index 6f84f71056..1b6d844d2e 100644 --- a/html/admin/css/dashboardView.css +++ b/html/admin/css/dashboardView.css @@ -81,9 +81,9 @@ .statClient { float: left; height: 120px; - width: 205px; + width: 203px; margin-left: 9px; - margin-bottom: 15px; + margin-bottom: 12px; border: 1px solid black; border-radius: 2px 2px 2px 2px; background-color: #F4F3F3; @@ -132,6 +132,7 @@ } .statsHeader { + margin-top: 12px; margin-left: -10px; width: 940px; background-color: #686766; From 7e1a107aa80588452c966c20be104ea15f053dc2 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 22 May 2013 19:13:49 +0200 Subject: [PATCH 25/35] fixed typo --- arangod/V8Server/ApplicationV8.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arangod/V8Server/ApplicationV8.cpp b/arangod/V8Server/ApplicationV8.cpp index 37f6dd4f96..c0137c783c 100644 --- a/arangod/V8Server/ApplicationV8.cpp +++ b/arangod/V8Server/ApplicationV8.cpp @@ -527,7 +527,7 @@ void ApplicationV8::setupOptions (map ("javascript.gc-frequency", &_gcFrequency, "JavaScript time-based garbage collection frequency (each x seconds)") ("javascript.action-directory", &_actionPath, "path to the JavaScript action directory") ("javascript.app-path", &_appPath, "one directory for applications") - ("javascript.dev-app-path", &_devAppPath, "one directory for dev aaplications") + ("javascript.dev-app-path", &_devAppPath, "one directory for dev applications") ("javascript.modules-path", &_modulesPath, "one or more directories separated by semi-colons") ("javascript.package-path", &_packagePath, "one or more directories separated by semi-colons") ("javascript.startup-directory", &_startupPath, "path to the directory containing alternate JavaScript startup scripts") From af413c3cf0b4ab7b7f7413d76857200611cb0100 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 22 May 2013 19:14:35 +0200 Subject: [PATCH 26/35] unified case --- lib/HttpServer/ApplicationEndpointServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/HttpServer/ApplicationEndpointServer.cpp b/lib/HttpServer/ApplicationEndpointServer.cpp index 5065a4b356..23c4f44c44 100644 --- a/lib/HttpServer/ApplicationEndpointServer.cpp +++ b/lib/HttpServer/ApplicationEndpointServer.cpp @@ -230,8 +230,8 @@ void ApplicationEndpointServer::setupOptions (map Date: Wed, 22 May 2013 21:46:02 +0200 Subject: [PATCH 27/35] issue #536: 1.3 fails to compile (lib_libarango_a-Logger.o) Added solution for GENTOO from http://code.google.com/p/fritzing/issues/detail?id=1854 --- lib/Zip/ioapi.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Zip/ioapi.h b/lib/Zip/ioapi.h index 8dcbdb06e3..014737b6f0 100644 --- a/lib/Zip/ioapi.h +++ b/lib/Zip/ioapi.h @@ -21,6 +21,11 @@ #ifndef _ZLIBIOAPI64_H #define _ZLIBIOAPI64_H +#ifdef _Z_OF +#undef OF +#define OF _Z_OF +#endif + #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) // Linux needs this to support file operation on files larger then 4+GB From bebef82c74c283eef226f5acc4d0d4a32e18f181 Mon Sep 17 00:00:00 2001 From: Heiko Kernbach Date: Wed, 22 May 2013 22:33:29 +0200 Subject: [PATCH 28/35] added ability for custom charts --- html/admin/css/dashboardView.css | 10 +- .../admin/js/collections/arangoCollections.js | 3 + html/admin/js/templates/dashboardView.ejs | 10 ++ html/admin/js/views/dashboardView.js | 150 ++++++++++++------ 4 files changed, 126 insertions(+), 47 deletions(-) diff --git a/html/admin/css/dashboardView.css b/html/admin/css/dashboardView.css index 1b6d844d2e..5de5ab45ee 100644 --- a/html/admin/css/dashboardView.css +++ b/html/admin/css/dashboardView.css @@ -27,13 +27,14 @@ margin-right: 7px !important; } -.db-zoom, .db-minimize, .db-hide, .db-info { +.db-zoom, .db-minimize, .db-hide, .db-info, #db-collectionMinimize { float: right; margin-top: -4px !important; margin-right: 4px !important; } -.db-zoom:hover, .db-minimize:hover, .db-hide, .db-info:hover, .group-close:hover, .group-open:hover { +.db-zoom:hover, .db-minimize:hover, .db-hide, .db-info:hover, .group-close:hover, .group-open:hover, +#db-collectionMinimize:hover { cursor:pointer; } @@ -106,6 +107,11 @@ font: 10px sans-serif; } +.svgCollections { + height: 300px; + width: 300px; +} + .svgClass { margin-top: 0 !important; padding-top: 0 !important; diff --git a/html/admin/js/collections/arangoCollections.js b/html/admin/js/collections/arangoCollections.js index b3bd1b0ac1..b13889694b 100644 --- a/html/admin/js/collections/arangoCollections.js +++ b/html/admin/js/collections/arangoCollections.js @@ -17,6 +17,9 @@ window.arangoCollections = Backbone.Collection.extend({ }, translateStatus : function (status) { + if (status == 0) { + return 'corrupted'; + } if (status == 1) { return 'new born collection'; } diff --git a/html/admin/js/templates/dashboardView.ejs b/html/admin/js/templates/dashboardView.ejs index eaf616e132..028612dece 100644 --- a/html/admin/js/templates/dashboardView.ejs +++ b/html/admin/js/templates/dashboardView.ejs @@ -35,6 +35,16 @@
      +
    • +
      +
      Collections
      + +
      +
      + +
      +
    • +
    • User Time
      diff --git a/html/admin/js/views/dashboardView.js b/html/admin/js/views/dashboardView.js index 8a541a66ac..3310f36b6e 100644 --- a/html/admin/js/views/dashboardView.js +++ b/html/admin/js/views/dashboardView.js @@ -8,15 +8,25 @@ var dashboardView = Backbone.View.extend({ charts: {}, units: [], updateNOW: false, + collectionsStats: { + "corrupted": 0, + "new born collection" : 0, + "unloaded" : 0, + "loaded" : 0, + "in the process of being unloaded" : 0, + "deleted" : 0 + }, detailGraph: "userTime", initialize: function () { var self = this; this.initUnits(); + self.addCustomCharts(); this.collection.fetch({ success: function() { + self.countCollections(); self.calculateSeries(); self.renderCharts(); @@ -64,6 +74,16 @@ var dashboardView = Backbone.View.extend({ template: new EJS({url: 'js/templates/dashboardView.ejs'}), + countCollections: function() { + var self = this; + $.each(window.arangoCollectionsStore.models, function(k,v) { + if ( self.collectionsStats[this.attributes.status] === undefined ) { + self.collectionsStats[this.attributes.status] = 0; + } + self.collectionsStats[this.attributes.status]++; + }); + }, + render: function() { var self = this; $(this.el).html(this.template.text); @@ -118,42 +138,41 @@ var dashboardView = Backbone.View.extend({ } return this; }, - //generate function for all custom categories - genCustomCategories: function () { - //this.genCustomCategory("Client calculated charts", "custom", "Customized Charts"); - }, - //generate a custom category - genCustomCategory: function(description, group, name) { - this.options.description.models[0].attributes.groups.push({ - "description":description, - "group":group, - "name":name - }); - }, - //generate a custom description - genCustomChartDescription: function (description, group, identifier, name, type, units) { - var figure = { - "description" : description, - "group" : group, - "identifier" : identifier, - "name" : name, - "type" : type, - "units" : units - }; - this.options.description.models[0].attributes.figures.push(figure); - this.renderFigure(figure); - }, - //calculate customized chart value functions here - updateCustomChartValues: function () { - //this.totalTime2(); - }, - //custom chart value calculation for totalTime2 - totalTime2: function () { - var val1 = this.collection.models[0].attributes.system.userTime; - var val2 = this.collection.models[0].attributes.system.systemTime; - var totalTime2Value = val1+val2; - this.collection.models[0].attributes["custom"] = {"totalTime2":totalTime2Value}; + addCustomCharts: function () { + var self = this; + var figure = { + "description" : "my custom chart", + "group" : "custom", + "identifier" : "custom1", + "name" : "Custom1", + "type" : "accumulated", + "units" : "seconds", + "exec" : function () { + var val1 = self.collection.models[0].attributes.system.userTime; + var val2 = self.collection.models[0].attributes.system.systemTime; + var totalTime2Value = val1+val2; + return totalTime2Value; + } + }; + + var addGroup = true; + + $.each(this.options.description.models[0].attributes.groups, function(k, v) { + if (self.options.description.models[0].attributes.groups[k].group === figure.group) { + addGroup = false; + } + }); + + if (addGroup == true) { + self.options.description.models[0].attributes.groups.push({ + "description" : "custom", + "group" : "custom", + "name" : "custom" + }); + } + + this.options.description.models[0].attributes.figures.push(figure); }, checkInterval: function (a) { @@ -262,9 +281,44 @@ var dashboardView = Backbone.View.extend({ }); }, + renderCollectionsChart: function () { + var self = this; + nv.addGraph(function() { + var chart = nv.models.pieChart() + .x(function(d) { return d.label }) + .y(function(d) { return d.value }) + .showLabels(true); + + d3.select("#detailCollectionsChart svg") + .datum(self.convertCollections()) + .transition().duration(1200) + .call(chart); + + return chart; + }); + + }, + + convertCollections: function () { + var self = this; + var collValues = []; + $.each(self.collectionsStats, function(k,v) { + collValues.push({ + "label" : k, + "value" : v, + }); + }); + + return [{ + key: "Collections Status", + values: collValues + }]; + }, + renderCharts: function () { var self = this; $('#every'+self.updateFrequency+'seconds').prop('checked',true); + self.renderCollectionsChart(); $.each(self.options.description.models[0].attributes.figures, function () { var figure = this; @@ -313,9 +367,9 @@ var dashboardView = Backbone.View.extend({ } if (self.detailGraph === identifier) { d3.select("#detailGraphChart svg") - .call(chart) - .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ]) - .transition().duration(500); + .call(chart) + .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ]) + .transition().duration(500); } else { } @@ -324,15 +378,14 @@ var dashboardView = Backbone.View.extend({ //disable label for small charts d3.select("#" + identifier + "Chart svg") - .call(chart) - .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ]) - .transition().duration(500); + .call(chart) + .datum([ { values: self.seriesData[identifier].values, key: identifier, color: "#8AA051" } ]) + .transition().duration(500); }); }, calculateSeries: function (flush) { var self = this; - self.updateCustomChartValues(); var timeStamp = Math.round(new Date() * 10); @@ -353,7 +406,14 @@ var dashboardView = Backbone.View.extend({ return; } - var responseValue = self.collection.models[0].attributes[figure.group][identifier]; + var responseValue; + + if (figure.exec) { + responseValue = figure.exec(); + } + else { + responseValue = self.collection.models[0].attributes[figure.group][identifier]; + } if (responseValue !== undefined && responseValue !== null) { if (responseValue.sum !== undefined) { @@ -415,8 +475,8 @@ var dashboardView = Backbone.View.extend({ $('#' + figure.group + 'Divider').before( '
    • ' ); $('.db-info').tooltip({ From f196496bd81bf042b7bbc8e72fa3635db05c909e Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 23 May 2013 09:13:33 +0200 Subject: [PATCH 29/35] GraphViewer: Tests for CommunityNodes and adding edges to them --- .../specAdapter/arangoAdapterSpec.js | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index 1a130ab783..f0c3c6d17d 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -977,6 +977,88 @@ }); + describe('expanding after a while', function() { + it('should connect edges of internal nodes accordingly', function() { + + var commNode, called, counterCallback, + v0, v1, v2, v3, v4; + + runs(function() { + var v = "vertices", + e = "edges", + e0_1 = insertEdge(e, v0, v1), + e0_2 = insertEdge(e, v0, v2), + e1_3 = insertEdge(e, v1, v3), + e1_4 = insertEdge(e, v1, v4), + e2_3 = insertEdge(e, v2, v3), + e2_4 = insertEdge(e, v2, v4); + v0 = insertNode(v, 0); + v1 = insertNode(v, 1); + v2 = insertNode(v, 2); + v3 = insertNode(v, 3); + v4 = insertNode(v, 4); + called = 0; + counterCallback = function() { + called++; + }; + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return [c0, c1, c2, c3]; + }); + adapter.setNodeLimit(3); + + adapter.changeTo(v, e); + adapter.loadNode(v0, counterCallback); + adapter.loadNode(v1, counterCallback); + + }); + + waitsFor(function() { + return called === 2; + }); + + runs(function() { + adapter.loadNode(v2, counterCallback); + commNode = getCommunityNodesIds()[0]; + }); + + waitsFor(function() { + return called === 3; + }); + + runs(function() { + // Check start condition + existNodes([commNode, v0, v2]); + expect(nodes.length).toEqual(3); + + existEdge(v0, v2); + existEdge(v0, commNode); + existEdge(v2, commNode); + expect(edges.length).toEqual(3); + + adapter.setNodeLimit(20); + adapter.expandCommunity(commNode, counterCallback); + }); + + waitsFor(function() { + return called === 4; + }); + + runs(function() { + existNodes([v0, v1, v2, v3, v4]); + expect(nodes.length).toEqual(5); + + existEdge(v0, v1); + existEdge(v0, v2); + existEdge(v1, v3); + existEdge(v1, v4); + existEdge(v2, v3); + existEdge(v2, v4); + expect(edges.length).toEqual(6); + + }); + }); + }); + describe('that displays a community node already', function() { var firstCommId, @@ -1085,7 +1167,7 @@ }); }); - it('should connect edges to community-internal nodes', function() { + it('should connect edges to internal nodes', function() { runs(function() { insertEdge(edgesCollection, c3, c0); From 65c959e9d6ba4a6f63a2f642c28385c66c817482 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 23 May 2013 10:30:03 +0200 Subject: [PATCH 30/35] GraphViewer: Edges are bound to community nodes correctly --- .../js/graphViewer/graph/arangoAdapter.js | 32 +++++++++++++++--- .../specAdapter/arangoAdapterSpec.js | 33 +++++++++++-------- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index f256b667df..769f5e68fe 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -53,6 +53,7 @@ function ArangoAdapter(nodes, edges, config) { api = {}, queries = {}, cachedCommunities = {}, + joinedInCommunities = {}, nodeCollection, edgeCollection, limit, @@ -96,9 +97,10 @@ function ArangoAdapter(nodes, edges, config) { }, findNode = function(id) { - var res = $.grep(nodes, function(e){ - return e._id === id; - }); + var intId = joinedInCommunities[id] || id, + res = $.grep(nodes, function(e){ + return e._id === intId; + }); if (res.length === 0) { return false; } @@ -145,7 +147,8 @@ function ArangoAdapter(nodes, edges, config) { _data: data, _id: data._id }, - e = findEdge(edge._id); + e = findEdge(edge._id), + edgeToPush; if (e) { return e; } @@ -162,6 +165,24 @@ function ArangoAdapter(nodes, edges, config) { edges.push(edge); source._outboundCounter++; target._inboundCounter++; + if (cachedCommunities[source._id] !== undefined) { + edgeToPush = {}; + edgeToPush.type = "s"; + edgeToPush.id = edge._id; + edgeToPush.source = $.grep(cachedCommunities[source._id].nodes, function(e){ + return e._id === data._from; + })[0]; + cachedCommunities[source._id].edges.push(edgeToPush); + } + if (cachedCommunities[target._id] !== undefined) { + edgeToPush = {}; + edgeToPush.type = "t"; + edgeToPush.id = edge._id; + edgeToPush.target = $.grep(cachedCommunities[target._id].nodes, function(e){ + return e._id === data._to; + })[0]; + cachedCommunities[target._id].edges.push(edgeToPush); + } return edge; }, @@ -317,8 +338,10 @@ function ArangoAdapter(nodes, edges, config) { cachedCommunities[commId] = {}; cachedCommunities[commId].nodes = nodesToRemove; cachedCommunities[commId].edges = []; + combineCommunityEdges(nodesToRemove, commNode); _.each(nodesToRemove, function(n) { + joinedInCommunities[n._id] = commId; removeNode(n); }); nodes.push(commNode); @@ -335,6 +358,7 @@ function ArangoAdapter(nodes, edges, config) { collapseCommunity(com); } _.each(nodesToAdd, function(n) { + delete joinedInCommunities[n._id]; nodes.push(n); }); _.each(edgesToChange, function(e) { diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index f0c3c6d17d..fdd0343af6 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -978,31 +978,35 @@ }); describe('expanding after a while', function() { + it('should connect edges of internal nodes accordingly', function() { var commNode, called, counterCallback, - v0, v1, v2, v3, v4; + v0, v1, v2, v3, v4, + e0_1, e0_2, e1_3, e1_4, e2_3, e2_4; runs(function() { var v = "vertices", - e = "edges", - e0_1 = insertEdge(e, v0, v1), - e0_2 = insertEdge(e, v0, v2), - e1_3 = insertEdge(e, v1, v3), - e1_4 = insertEdge(e, v1, v4), - e2_3 = insertEdge(e, v2, v3), - e2_4 = insertEdge(e, v2, v4); + e = "edges"; + nodes.length = 0; + edges.length = 0; v0 = insertNode(v, 0); v1 = insertNode(v, 1); v2 = insertNode(v, 2); v3 = insertNode(v, 3); v4 = insertNode(v, 4); + e0_1 = insertEdge(e, v0, v1); + e0_2 = insertEdge(e, v0, v2); + e1_3 = insertEdge(e, v1, v3); + e1_4 = insertEdge(e, v1, v4); + e2_3 = insertEdge(e, v2, v3); + e2_4 = insertEdge(e, v2, v4); called = 0; counterCallback = function() { called++; }; spyOn(this, "fakeReducerRequest").andCallFake(function() { - return [c0, c1, c2, c3]; + return [v1, v3, v4]; }); adapter.setNodeLimit(3); @@ -1018,7 +1022,7 @@ runs(function() { adapter.loadNode(v2, counterCallback); - commNode = getCommunityNodesIds()[0]; + commNode = getCommunityNodes()[0]; }); waitsFor(function() { @@ -1026,14 +1030,15 @@ }); runs(function() { + var commId = commNode._id; // Check start condition - existNodes([commNode, v0, v2]); + existNodes([commId, v0, v2]); expect(nodes.length).toEqual(3); existEdge(v0, v2); - existEdge(v0, commNode); - existEdge(v2, commNode); - expect(edges.length).toEqual(3); + existEdge(v0, commId); + existEdge(v2, commId); + expect(edges.length).toEqual(4); adapter.setNodeLimit(20); adapter.expandCommunity(commNode, counterCallback); From a67f7edb28959e9e9e2b2b2833cd9bed29d9701c Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 23 May 2013 10:59:10 +0200 Subject: [PATCH 31/35] GraphViewer: In/Outbound counter for nodes is set correctly even after community joins. All Tests pass on usefull browsers and 99% on IE9 --- .../js/graphViewer/graph/arangoAdapter.js | 10 ++- .../specAdapter/arangoAdapterSpec.js | 74 +++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index 769f5e68fe..b85c52e635 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -163,8 +163,8 @@ function ArangoAdapter(nodes, edges, config) { edge.source = source; edge.target = target; edges.push(edge); - source._outboundCounter++; - target._inboundCounter++; + + if (cachedCommunities[source._id] !== undefined) { edgeToPush = {}; edgeToPush.type = "s"; @@ -172,7 +172,10 @@ function ArangoAdapter(nodes, edges, config) { edgeToPush.source = $.grep(cachedCommunities[source._id].nodes, function(e){ return e._id === data._from; })[0]; + edgeToPush.source._outboundCounter++; cachedCommunities[source._id].edges.push(edgeToPush); + } else { + source._outboundCounter++; } if (cachedCommunities[target._id] !== undefined) { edgeToPush = {}; @@ -181,7 +184,10 @@ function ArangoAdapter(nodes, edges, config) { edgeToPush.target = $.grep(cachedCommunities[target._id].nodes, function(e){ return e._id === data._to; })[0]; + edgeToPush.target._inboundCounter++; cachedCommunities[target._id].edges.push(edgeToPush); + } else { + target._inboundCounter++; } return edge; }, diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index fdd0343af6..3385c59ed4 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -1062,6 +1062,80 @@ }); }); + + it('set inbound and outboundcounter correctly', function() { + + var commNode, called, counterCallback, + v0, v1, v2, v3, v4, + e0_1, e0_2, e1_3, e1_4, e2_3, e2_4; + + runs(function() { + var v = "vertices", + e = "edges"; + nodes.length = 0; + edges.length = 0; + v0 = insertNode(v, 0); + v1 = insertNode(v, 1); + v2 = insertNode(v, 2); + v3 = insertNode(v, 3); + v4 = insertNode(v, 4); + e0_1 = insertEdge(e, v0, v1); + e0_2 = insertEdge(e, v0, v2); + e1_3 = insertEdge(e, v1, v3); + e1_4 = insertEdge(e, v1, v4); + e2_3 = insertEdge(e, v2, v3); + e2_4 = insertEdge(e, v2, v4); + called = 0; + counterCallback = function() { + called++; + }; + spyOn(this, "fakeReducerRequest").andCallFake(function() { + return [v1, v3, v4]; + }); + adapter.setNodeLimit(3); + + adapter.changeTo(v, e); + adapter.loadNode(v0, counterCallback); + adapter.loadNode(v1, counterCallback); + + }); + + waitsFor(function() { + return called === 2; + }); + + runs(function() { + adapter.loadNode(v2, counterCallback); + commNode = getCommunityNodes()[0]; + }); + + waitsFor(function() { + return called === 3; + }); + + runs(function() { + adapter.setNodeLimit(20); + adapter.expandCommunity(commNode, counterCallback); + }); + + waitsFor(function() { + return called === 4; + }); + + runs(function() { + var checkNodeWithInAndOut = function(id, inbound, outbound) { + var n = nodeWithID(id); + expect(n._outboundCounter).toEqual(outbound); + expect(n._inboundCounter).toEqual(inbound); + }; + checkNodeWithInAndOut(v0, 0, 2); + checkNodeWithInAndOut(v1, 1, 2); + checkNodeWithInAndOut(v2, 1, 2); + checkNodeWithInAndOut(v3, 2, 0); + checkNodeWithInAndOut(v4, 2, 0); + }); + }); + }); describe('that displays a community node already', function() { From aca42ef9fdab0cd40246e482e122079b67aea7ad Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Thu, 23 May 2013 12:17:57 +0200 Subject: [PATCH 32/35] issue #540: merged patch by @guidoreina, added test --- arangod/Ahuacatl/ahuacatl-codegen.c | 13 +++++++++- js/server/tests/ahuacatl-queries-variables.js | 26 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/arangod/Ahuacatl/ahuacatl-codegen.c b/arangod/Ahuacatl/ahuacatl-codegen.c index 9ae2d7a5a6..ad0d63b7db 100644 --- a/arangod/Ahuacatl/ahuacatl-codegen.c +++ b/arangod/Ahuacatl/ahuacatl-codegen.c @@ -668,7 +668,7 @@ static void InitArray (TRI_aql_codegen_js_t* const generator, static void EnterSymbol (TRI_aql_codegen_js_t* const generator, const char* const name, const TRI_aql_codegen_register_t registerIndex) { - TRI_aql_codegen_scope_t* scope = CurrentScope(generator); + TRI_aql_codegen_scope_t* scope; TRI_aql_codegen_variable_t* variable = CreateVariable(name, registerIndex); if (variable == NULL) { @@ -676,6 +676,17 @@ static void EnterSymbol (TRI_aql_codegen_js_t* const generator, return; } + // if not a temporary variable + if (*name != '_') { + scope = CurrentScope(generator); + } + else { + assert(generator->_scopes._length > 0); + + // get scope at level 0 + scope = (TRI_aql_codegen_scope_t*) TRI_AtVectorPointer(&generator->_scopes, 0); + } + if (TRI_InsertKeyAssociativePointer(&scope->_variables, name, (void*) variable, false)) { // variable already exists in symbol table. this should never happen LOG_TRACE("variable already registered: %s", name); diff --git a/js/server/tests/ahuacatl-queries-variables.js b/js/server/tests/ahuacatl-queries-variables.js index 6629967e96..1bfe2ac548 100644 --- a/js/server/tests/ahuacatl-queries-variables.js +++ b/js/server/tests/ahuacatl-queries-variables.js @@ -343,6 +343,32 @@ function ahuacatlQueryVariablesTestSuite () { var actual = getQueryResults(query); assertEqual(expected, actual); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief collect and return (should omit any temporary variables) +//////////////////////////////////////////////////////////////////////////////// + + testTemporaryVariables : function () { + var data = [ { name: "baz" }, { name: "bar" } ]; + var expected = [ { "criteria" : "bar", "g" : [ { "y" : { "test" : "test", "name" : "bar" } } ] }, { "criteria" : "baz", "g" : [ { "y" : { "test" : "test", "name" : "baz" } } ] } ]; + + var query = "FOR y IN (FOR x IN " + JSON.stringify(data) + " LET object = (FOR a IN [ '1', '2' ] RETURN a) RETURN { test: \"test\", name: x.name }) COLLECT criteria = y.name INTO g RETURN { criteria: criteria, g: g }"; + + var actual = getQueryResults("LET result = (" + query + ") RETURN result"); + assertEqual([ expected ], actual); + + actual = getQueryResults(query); + assertEqual(expected, actual); + + // omit creating sub-objects + query = "FOR y IN (FOR x IN " + JSON.stringify(data) + " RETURN { test: \"test\", name: x.name }) COLLECT criteria = y.name INTO g RETURN { criteria: criteria, g: g }"; + + actual = getQueryResults("LET result = (" + query + ") RETURN result"); + assertEqual([ expected ], actual); + + actual = getQueryResults(query); + assertEqual(expected, actual); } }; From bf1fbd9799aaeb0805d801cd79c929be50eecba1 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Thu, 23 May 2013 13:30:02 +0200 Subject: [PATCH 33/35] less-verbose error messages for several cases --- CHANGELOG | 2 ++ js/actions/api-aqlfunction.js | 2 +- js/actions/api-collection.js | 16 ++++----- js/actions/api-cursor.js | 4 +-- js/actions/api-edges.js | 2 +- js/actions/api-explain.js | 4 +-- js/actions/api-graph.js | 4 +-- js/actions/api-index.js | 2 +- js/actions/api-query.js | 2 +- js/actions/api-simple.js | 24 ++++++------- js/actions/api-structure.js | 2 +- js/actions/api-system.js | 4 +-- js/actions/api-user.js | 2 +- js/actions/key-value.js | 4 +-- js/server/modules/org/arangodb/actions.js | 42 +++++++++++------------ 15 files changed, 59 insertions(+), 57 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5caf9c529b..d1de3ddf99 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,8 @@ v1.4 v1.3.1 (2013-XX-XX) ------------------- +* issue #540: suppress return of temporary internal variables in AQL + * issue #530: ReferenceError: ArangoError is not a constructor * issue #535: Problem with AQL user functions javascript API diff --git a/js/actions/api-aqlfunction.js b/js/actions/api-aqlfunction.js index f8860c1349..97802da138 100644 --- a/js/actions/api-aqlfunction.js +++ b/js/actions/api-aqlfunction.js @@ -241,7 +241,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-collection.js b/js/actions/api-collection.js index 40957a6edd..383fcd7d2f 100644 --- a/js/actions/api-collection.js +++ b/js/actions/api-collection.js @@ -235,7 +235,7 @@ function post_api_collection (req, res) { actions.resultOk(req, res, actions.HTTP_OK, result, headers); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } @@ -668,7 +668,7 @@ function put_api_collection_load (req, res, collection) { actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } @@ -720,7 +720,7 @@ function put_api_collection_unload (req, res, collection) { actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } @@ -750,7 +750,7 @@ function put_api_collection_truncate (req, res, collection) { actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } @@ -812,7 +812,7 @@ function put_api_collection_properties (req, res, collection) { actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } @@ -870,7 +870,7 @@ function put_api_collection_rename (req, res, collection) { actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } @@ -979,7 +979,7 @@ function delete_api_collection (req, res) { actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } } @@ -1012,7 +1012,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-cursor.js b/js/actions/api-cursor.js index 87499a1a96..0a5dfa80b0 100644 --- a/js/actions/api-cursor.js +++ b/js/actions/api-cursor.js @@ -235,7 +235,7 @@ function POST_api_cursor(req, res) { // error occurred if (cursor instanceof Error) { - actions.resultException(req, res, cursor); + actions.resultException(req, res, cursor, undefined, false); return; } @@ -404,7 +404,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-edges.js b/js/actions/api-edges.js index aa2ebc6520..c8ca64b66d 100644 --- a/js/actions/api-edges.js +++ b/js/actions/api-edges.js @@ -131,7 +131,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-explain.js b/js/actions/api-explain.js index d0cd1bf156..9dcc7bb527 100644 --- a/js/actions/api-explain.js +++ b/js/actions/api-explain.js @@ -137,7 +137,7 @@ function POST_api_explain (req, res) { var result = EXPLAIN(json.query, json.bindVars); if (result instanceof Error) { - actions.resultException(req, res, result); + actions.resultException(req, res, result, undefined, false); return; } @@ -169,7 +169,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-graph.js b/js/actions/api-graph.js index 4adc6d1738..7adc5b75eb 100644 --- a/js/actions/api-graph.js +++ b/js/actions/api-graph.js @@ -1770,7 +1770,7 @@ function post_graph_vertex_edges (req, res, g) { // error occurred if (cursor instanceof Error) { - actions.resultException(req, res, cursor); + actions.resultException(req, res, cursor, undefined, false); return; } @@ -2039,7 +2039,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-index.js b/js/actions/api-index.js index 1881d1eaea..fbb2300691 100644 --- a/js/actions/api-index.js +++ b/js/actions/api-index.js @@ -890,7 +890,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-query.js b/js/actions/api-query.js index 74dd046bbe..a09cbe4a48 100644 --- a/js/actions/api-query.js +++ b/js/actions/api-query.js @@ -126,7 +126,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-simple.js b/js/actions/api-simple.js index e575b82ebd..bcea15cd64 100644 --- a/js/actions/api-simple.js +++ b/js/actions/api-simple.js @@ -115,7 +115,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -193,7 +193,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -312,7 +312,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -430,7 +430,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -522,7 +522,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -611,7 +611,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -688,7 +688,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -734,7 +734,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -828,7 +828,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -904,7 +904,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -990,7 +990,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -1083,7 +1083,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-structure.js b/js/actions/api-structure.js index 8a2140b204..611dd4d64c 100644 --- a/js/actions/api-structure.js +++ b/js/actions/api-structure.js @@ -141,7 +141,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-system.js b/js/actions/api-system.js index 711a9e42c5..1b3708d431 100644 --- a/js/actions/api-system.js +++ b/js/actions/api-system.js @@ -362,7 +362,7 @@ actions.defineHttp({ actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -611,7 +611,7 @@ actions.defineHttp({ actions.resultOk(req, res, actions.HTTP_OK, result); } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/api-user.js b/js/actions/api-user.js index f3c95309df..7a17399f1d 100644 --- a/js/actions/api-user.js +++ b/js/actions/api-user.js @@ -456,7 +456,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/actions/key-value.js b/js/actions/key-value.js index d0e157af46..23cefe4d75 100644 --- a/js/actions/key-value.js +++ b/js/actions/key-value.js @@ -341,7 +341,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); @@ -428,7 +428,7 @@ actions.defineHttp({ } } catch (err) { - actions.resultException(req, res, err); + actions.resultException(req, res, err, undefined, false); } } }); diff --git a/js/server/modules/org/arangodb/actions.js b/js/server/modules/org/arangodb/actions.js index c08e27eede..b9ff4b53f6 100644 --- a/js/server/modules/org/arangodb/actions.js +++ b/js/server/modules/org/arangodb/actions.js @@ -1198,7 +1198,7 @@ function resultError (req, res, httpReturnCode, errorNum, errorMessage, headers, res.body = JSON.stringify(result); - if (headers !== undefined) { + if (headers !== undefined && headers !== null) { res.headers = headers; } } @@ -1806,36 +1806,42 @@ function indexNotFound (req, res, collection, index, headers) { //////////////////////////////////////////////////////////////////////////////// /// @brief generates an error for an exception /// -/// @FUN{actions.resultException(@FA{req}, @FA{res}, @FA{err}, @FA{headers})} +/// @FUN{actions.resultException(@FA{req}, @FA{res}, @FA{err}, @FA{headers}, @FA{verbose})} /// -/// The function generates an error response. +/// The function generates an error response. If @FA{verbose} is set to +/// @LIT{true} or not specified (the default), then the error stack trace will +/// be included in the error message if available. //////////////////////////////////////////////////////////////////////////////// -function resultException (req, res, err, headers) { +function resultException (req, res, err, headers, verbose) { 'use strict'; var code; var msg; var num; + if (verbose || verbose === undefined) { + msg = String(err.stack || err); + } + else { + msg = String(err); + } + if (err instanceof internal.ArangoError) { num = err.errorNum; - msg = err.errorMessage; code = exports.HTTP_BAD; if (num === 0) { num = arangodb.ERROR_INTERNAL; } - if (msg === "") { - msg = String(err.stack || err); + if (err.errorMessage !== "" && ! verbose) { + msg = err.errorMessage; } - else { - msg += ": " + String(err.stack || err); - } - + switch (num) { case arangodb.ERROR_INTERNAL: + case arangodb.ERROR_OUT_OF_MEMORY: code = exports.HTTP_SERVER_ERROR; break; @@ -1844,23 +1850,17 @@ function resultException (req, res, err, headers) { code = exports.HTTP_CONFLICT; break; } - - resultError(req, res, code, num, msg, headers); } else if (err instanceof TypeError) { num = arangodb.ERROR_TYPE_ERROR; code = exports.HTTP_BAD; - msg = String(err.stack || err); - - resultError(req, res, code, num, msg, headers); } - else { - resultError(req, res, - exports.HTTP_SERVER_ERROR, arangodb.ERROR_HTTP_SERVER_ERROR, - String(err.stack || err), - headers); + num = arangodb.ERROR_HTTP_SERVER_ERROR; + code = exports.HTTP_SERVER_ERROR; } + + resultError(req, res, code, num, msg, headers); } //////////////////////////////////////////////////////////////////////////////// From c435a5f7060df0db28035cbc78ffb59b4d7729b8 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Thu, 23 May 2013 13:31:14 +0200 Subject: [PATCH 34/35] removed links to non-existing images in documentation --- Documentation/Manual/NewFeatures11.md | 3 +- Documentation/UserManual/WebInterface.md | 73 +++++++++------------ Documentation/UserManual/WebInterfaceTOC.md | 1 - 3 files changed, 33 insertions(+), 44 deletions(-) diff --git a/Documentation/Manual/NewFeatures11.md b/Documentation/Manual/NewFeatures11.md index 27bf661f31..89643a3b31 100644 --- a/Documentation/Manual/NewFeatures11.md +++ b/Documentation/Manual/NewFeatures11.md @@ -209,8 +209,7 @@ Server Statistics {#NewFeatures11ServerStatistics} -------------------------------------------------- ArangoDB 1.1 allows querying the server status via the administration -front-end (see @ref UserManualWebInterfaceStatistics) or via REST API -methods. +front-end or via REST API methods. The following methods are available: - `GET /_admin/connection-statistics`: provides connection statistics diff --git a/Documentation/UserManual/WebInterface.md b/Documentation/UserManual/WebInterface.md index 506836f142..1b36bd1a86 100644 --- a/Documentation/UserManual/WebInterface.md +++ b/Documentation/UserManual/WebInterface.md @@ -7,7 +7,7 @@ ArangoDB's Web-Interface {#UserManualWebInterface} Accessing the Web-Interface {#UserManualWebInterfaceAccess} =========================================================== -The web interfaced can be access as +The web interface can be accessed via the URL http://localhost:8529 @@ -20,64 +20,55 @@ application instead. In this case use Collections Tab {#UserManualWebInterfaceCollections} ---------------------------------------------------- -The collection tabs shows an overview about the loaded and unloaded -collections of the database. +The *Collections* tab shows an overview of the loaded and unloaded +collections present in ArangoDB. System collections (i.e. collections +whose names start with an underscore) are not shown by default. -@htmlonly ArangoDB Front-End@endhtmlonly -@latexonly\includegraphics[width=12cm]{images/fe-collections.png}@endlatexonly +The list of collections can be restricted using the search bar, or by +using the filtering at the top. The filter can also be used to show or +hide system collections. -You can load, unloaded, delete, or inspect the collections. Please -note that you should not delete or change system collections, i. e., -collections starting with an underscore. +Clicking on a collection will show the documents contained in it. +Clicking the small icon on a collection's badge will bring up a dialog +that allows loading/unloading, renaming and deleting the collection. -If you click on the magnifying glass, you will get a list of all documents -in the collection. +Please note that you should not change or delete system collections. -@htmlonly ArangoDB Front-End@endhtmlonly -@latexonly\includegraphics[width=12cm]{images/fe-documents.png}@endlatexonly +In the list of documents of a collection, you can click on the *Add document* +line to add a new document to the collection. The document will be created +instantly, with a system-defined key. The key and all other attributes of the +document can be adjusted in the following view. -Using the pencil you can edit the document. -Query Tab {#UserManualWebInterfaceQuery} ----------------------------------------- +AQL Editor Tab {#UserManualWebInterfaceQuery} +--------------------------------------------- -The query tabs allows you to execute AQL queries. +The *AQL Editor* tab allow to execute AQL queries. -@htmlonly ArangoDB Front-End@endhtmlonly -@latexonly\includegraphics[width=12cm]{images/fe-query.png}@endlatexonly +Type in a query in the bottom box and execute it by pressing the *Submit* button. +The query result will be shown in the box at the top. -Type in a query and execute it. -Shell Tab {#UserManualWebInterfaceShell} ----------------------------------------- +JS Shell Tab {#UserManualWebInterfaceShell} +------------------------------------------- -The shell tabs give you access to a JavaScript shell connection to the +The *JS Shell* tab provides access to a JavaScript shell connection to the database server. -@htmlonly ArangoDB Front-End@endhtmlonly -@latexonly\includegraphics[width=12cm]{images/fe-shell.png}@endlatexonly +Any valid JavaScript code can be executed inside the shell. The code will be +executed inside your browser. To contact the ArangoDB server, you can use the +`db` object, for example as follows: + + JSH> db._create("mycollection"); + JSH> db.mycollection.save({ _key: "test", value: "something" }); -Use the OK button or return to execute a command. Logs Tab {#UserManualWebInterfaceLogs} -------------------------------------- -You can browse the log files. - -@htmlonly ArangoDB Front-End@endhtmlonly -@latexonly\includegraphics[width=12cm]{images/fe-logs.png}@endlatexonly +You can use the *Logs* tab to browse the most recent log entries provided by the +ArangoDB database server. Note that the server only keeps a limited number of log entries. For real log analyses write the logs to disk using syslog or a similar -mechanism. - -Statistics Tab {#UserManualWebInterfaceStatistics} --------------------------------------------------- - -Use the statistics tab to display information about the server. - -@htmlonly ArangoDB Front-End@endhtmlonly -@latexonly\includegraphics[width=12cm]{images/fe-statistics.png}@endlatexonly - -Initially no statistics will be display. You must use the add button -to configure what type of information should be displayed. +mechanism. ArangoDB provides several startup options for this. diff --git a/Documentation/UserManual/WebInterfaceTOC.md b/Documentation/UserManual/WebInterfaceTOC.md index 4a29ec7410..a17c13ad43 100644 --- a/Documentation/UserManual/WebInterfaceTOC.md +++ b/Documentation/UserManual/WebInterfaceTOC.md @@ -6,4 +6,3 @@ TOC {#UserManualWebInterfaceTOC} - @ref UserManualWebInterfaceQuery - @ref UserManualWebInterfaceShell - @ref UserManualWebInterfaceLogs - - @ref UserManualWebInterfaceStatistics From cece6d5b4bd1b505b0d373e8b8ca14729cc3a8c6 Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Thu, 23 May 2013 14:08:37 +0200 Subject: [PATCH 35/35] GraphViewer: Added option to switch between directed and undirected traversals --- .../js/graphViewer/graph/arangoAdapter.js | 27 +++++++-- .../specAdapter/arangoAdapterSpec.js | 58 +++++++++++++++++-- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index b85c52e635..ddd2959431 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -61,6 +61,7 @@ function ArangoAdapter(nodes, edges, config) { arangodb, width, height, + direction, setWidth = function(w) { initialX.range = w / 2; @@ -94,6 +95,15 @@ function ArangoAdapter(nodes, edges, config) { if (config.height !== undefined) { setHeight(config.height); } + if (config.undirected !== undefined) { + if (config.undirected === true) { + direction = "any"; + } else { + direction = "outbound"; + } + } else { + direction = "outbound"; + } }, findNode = function(id) { @@ -302,6 +312,9 @@ function ArangoAdapter(nodes, edges, config) { if (query !== queries.connectedEdges) { bindVars["@nodes"] = nodeCollection; } + if (query !== queries.childrenCentrality) { + bindVars["@dir"] = direction; + } bindVars["@edges"] = edgeCollection; var data = { query: query, @@ -477,7 +490,7 @@ function ArangoAdapter(nodes, edges, config) { + "@@nodes, " + "@@edges, " + "@id, " - + "\"outbound\", {" + + "@dir, {" + "strategy: \"depthfirst\"," + "maxDepth: 1," + "paths: true" @@ -490,7 +503,7 @@ function ArangoAdapter(nodes, edges, config) { + "@@nodes, " + "@@edges, " + "n._id, " - + "\"outbound\", {" + + "@dir, {" + "strategy: \"depthfirst\"," + "maxDepth: 1," + "paths: true" @@ -510,7 +523,6 @@ function ArangoAdapter(nodes, edges, config) { reducer = new NodeReducer(nodes, edges); - self.oldLoadNodeFromTreeById = function(nodeId, callback) { sendQuery(queries.nodeById, { id: nodeId @@ -669,9 +681,16 @@ function ArangoAdapter(nodes, edges, config) { }); }; - self.changeTo = function (nodesCol, edgesCol ) { + self.changeTo = function (nodesCol, edgesCol, dir) { nodeCollection = nodesCol; edgeCollection = edgesCol; + if (dir !== undefined) { + if (dir === true) { + direction = "any"; + } else { + direction = "outbound"; + } + } api.node = api.base + "document?collection=" + nodeCollection; api.edge = api.base + "edge?collection=" + edgeCollection; }; diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index 3385c59ed4..c721531ab2 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -306,26 +306,40 @@ height: 40 } ); - traversalQuery = function(id, nods, edgs) { + traversalQuery = function(id, nods, edgs, undirected) { + var dir; + if (undirected === true) { + dir = "any"; + } else { + dir = "outbound"; + } return JSON.stringify({ - query: "RETURN TRAVERSAL(@@nodes, @@edges, @id, \"outbound\"," + query: "RETURN TRAVERSAL(@@nodes, @@edges, @id, @dir," + " {strategy: \"depthfirst\",maxDepth: 1,paths: true})", bindVars: { id: id, "@nodes": nods, + "@dir": dir, "@edges": edgs } }); }; - filterQuery = function(v, nods, edgs) { + filterQuery = function(v, nods, edgs, undirected) { + var dir; + if (undirected === true) { + dir = "any"; + } else { + dir = "outbound"; + } return JSON.stringify({ query: "FOR n IN @@nodes FILTER n.id == @value" - + " RETURN TRAVERSAL(@@nodes, @@edges, n._id, \"outbound\"," + + " RETURN TRAVERSAL(@@nodes, @@edges, n._id, @dir," + " {strategy: \"depthfirst\",maxDepth: 1,paths: true})", bindVars: { value: v, "@nodes": nods, - "@edges": edgs + "@dir": dir, + "@edges": edgs } }); }; @@ -655,6 +669,40 @@ }); + it('should be able to switch to different collections and change to directed', function() { + + runs(function() { + + spyOn($, "ajax"); + + adapter.changeTo(altNodesCollection, altEdgesCollection, false); + + adapter.loadNode("42"); + + expect($.ajax).toHaveBeenCalledWith( + requests.cursor(traversalQuery("42", altNodesCollection, altEdgesCollection, false)) + ); + + }); + }); + + it('should be able to switch to different collections' + + ' and change to undirected', function() { + + runs(function() { + + spyOn($, "ajax"); + + adapter.changeTo(altNodesCollection, altEdgesCollection, true); + + adapter.loadNode("42"); + + expect($.ajax).toHaveBeenCalledWith( + requests.cursor(traversalQuery("42", altNodesCollection, altEdgesCollection, true)) + ); + + }); + }); describe('that has already loaded one graph', function() { var c0, c1, c2, c3, c4, c5, c6, c7,