1
0
Fork 0

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

This commit is contained in:
Kaveh Vahedipour 2016-09-12 10:38:47 +02:00
commit 7e5bd6f868
26 changed files with 198 additions and 134 deletions

View File

@ -56,6 +56,7 @@ option(USE_ENTERPRISE OFF)
if (USE_ENTERPRISE)
add_definitions("-DUSE_ENTERPRISE=1")
include_directories(${ENTERPRISE_INCLUDE_DIR})
add_subdirectory(enterprise)
endif ()
################################################################################

View File

@ -299,7 +299,7 @@ clean-book-intermediate:
# Check docublocks - checks whether docublock are
# - files in intermediate output directories and temporary
# files are excludes (with # in their names)
# - uniq in the source
# - unique in the source
# - all docublocks are used somewhere in the documentation
#
check-docublocks:

View File

@ -21,4 +21,4 @@ To configure the hashing:
127.0.0.1:8529@_system> db._create("sharded_collection", {"numberOfShards": 4, "shardKeys": ["country"]});
```
This would be useful to keep data of every country in one shard which would result in better performance for queries working on a per country base. You can also specify multiple `shardKeys`. Note however that if you change the shard keys from their defailt `["_key"]`, then finding a document in the collection by its primary key involves a request to every single shard. Furthermore, in this case one can no longer prescribe the primary key value of a new document but must use the automatically generated one. This latter restriction comes from the fact that ensuring uniqueness of the primary key would be very inefficient if the user could specify the primary key.
This would be useful to keep data of every country in one shard which would result in better performance for queries working on a per country base. You can also specify multiple `shardKeys`. Note however that if you change the shard keys from their default `["_key"]`, then finding a document in the collection by its primary key involves a request to every single shard. Furthermore, in this case one can no longer prescribe the primary key value of a new document but must use the automatically generated one. This latter restriction comes from the fact that ensuring uniqueness of the primary key would be very inefficient if the user could specify the primary key.

View File

@ -59,9 +59,10 @@ a collection's primary index. Thus looking up a document by its
key is a fast operation. The _key value of a document is
immutable once the document has been created. By default, ArangoDB will
auto-generate a document key if no _key attribute is specified, and use
the user-specified _key otherwise. The generateed _key is guaranteed to
be unique in the collection it was generated for. It can't be guaranteed
that this _key is uniq across the whole installation.
the user-specified _key otherwise. The generated _key is guaranteed to
be unique in the collection it was generated for. This also applies to
sharded collections in a cluster. It can't be guaranteed that the _key is
unique within a database or across a whole node or instance however.
This behavior can be changed on a per-collection level by creating
collections with the `keyOptions` attribute.

View File

@ -1,6 +1,6 @@
@startDocuBlock JSF_put_api_replication_serverID
@brief fetch this servers uniq identifier
@brief fetch this server's unique identifier
@RESTHEADER{GET /_api/replication/server-id, Return server id}

View File

@ -359,6 +359,7 @@ add_executable(${BIN_ARANGOD}
Wal/Slot.cpp
Wal/Slots.cpp
Wal/SynchronizerThread.cpp
${ADDITIONAL_BIN_ARANGOD_SOURCES}
)
target_link_libraries(${BIN_ARANGOD}

View File

@ -2279,6 +2279,7 @@ std::shared_ptr<std::vector<ShardID>> ClusterInfo::getShardList(
/// `_key` is the one and only sharding attribute.
////////////////////////////////////////////////////////////////////////////////
#ifndef USE_ENTERPRISE
int ClusterInfo::getResponsibleShard(CollectionID const& collectionID,
VPackSlice slice, bool docComplete,
ShardID& shardID,
@ -2339,6 +2340,7 @@ int ClusterInfo::getResponsibleShard(CollectionID const& collectionID,
shardID = shards->at(hash % shards->size());
return error;
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief return the list of coordinator server names

View File

@ -238,7 +238,7 @@ bool VppCommTask::processRead() {
}
// handle request types
if (type == 1000 && _authenticationEnabled) {
if (type == 1000) {
// do authentication
// std::string encryption = header.at(2).copyString();
std::string user = header.at(3).copyString();
@ -247,7 +247,7 @@ bool VppCommTask::processRead() {
AuthResult result = GeneralServerFeature::AUTH_INFO.checkAuthentication(
AuthInfo::AuthType::BASIC, auth);
if (result._authorized) {
if (!_authenticationEnabled || result._authorized) {
_authenticatedUser = std::move(user);
handleSimpleError(rest::ResponseCode::OK, TRI_ERROR_NO_ERROR,
"authentication successful", chunkHeader._messageID);

View File

@ -705,9 +705,20 @@ static void CreateCollectionCoordinator(
v8::Handle<v8::Value> v = k->Get(i);
if (v->IsString()) {
std::string const key = TRI_ObjectToString(v);
// remove : char at the beginning or end (for enterprise)
std::string stripped;
if (!key.empty()) {
if (key.front() == ':') {
stripped = key.substr(1);
} else if (key.back() == ':') {
stripped = key.substr(0, key.size()-1);
} else {
stripped = key;
}
}
// system attributes are not allowed (except _key)
if (!key.empty() && (key[0] != '_' || key == "_key")) {
if (!stripped.empty() && stripped != StaticStrings::IdString &&
stripped != StaticStrings::RevString) {
shardKeys.push_back(key);
}
}

View File

@ -419,14 +419,12 @@ authRouter.get('/graph/:name', function (req, res) {
var tmpObjNodes = {};
_.each(cursor.json, function (obj) {
var edgeLabel;
var edgeLabel = '';
var edgeObj;
_.each(obj.edges, function (edge) {
if (edge._to && edge._from) {
if (config.edgeLabelByCollection === 'true') {
edgeLabel = edge._id.split('/')[0];
} else if (config.edgeLabel) {
if (config.edgeLabel && config.edgeLabel.length > 0) {
// configure edge labels
if (config.edgeLabel.indexOf('.') > -1) {
@ -441,9 +439,12 @@ authRouter.get('/graph/:name', function (req, res) {
if (typeof edgeLabel !== 'string') {
edgeLabel = JSON.stringify(edgeLabel);
}
if (!edgeLabel) {
edgeLabel = 'attribute ' + config.edgeLabel + ' not found';
if (config.edgeLabelByCollection === 'true') {
edgeLabel += ' - ' + edge._id.split('/')[0];
}
} else {
if (config.edgeLabelByCollection === 'true') {
edgeLabel = edge._id.split('/')[0];
}
}
@ -475,6 +476,8 @@ authRouter.get('/graph/:name', function (req, res) {
if (config.edgeEditable === 'true') {
edgeObj.size = 1;
} else {
edgeObj.size = 1;
}
if (config.edgeColorByCollection === 'true') {
@ -506,9 +509,8 @@ authRouter.get('/graph/:name', function (req, res) {
_.each(obj.vertices, function (node) {
if (node !== null) {
nodeNames[node._id] = true;
if (config.nodeLabelByCollection === 'true') {
nodeLabel = node._id.split('/')[0];
} else if (config.nodeLabel) {
if (config.nodeLabel) {
if (config.nodeLabel.indexOf('.') > -1) {
nodeLabel = getAttributeByKey(node, config.nodeLabel);
if (nodeLabel === undefined || nodeLabel === '') {
@ -518,13 +520,15 @@ authRouter.get('/graph/:name', function (req, res) {
nodeLabel = node[config.nodeLabel];
}
} else {
nodeLabel = node._id;
nodeLabel = node._key;
}
if (config.nodeLabelByCollection === 'true') {
nodeLabel += ' - ' + node._id.split('/')[0];
}
if (typeof nodeLabel === 'number') {
nodeLabel = JSON.stringify(nodeLabel);
}
if (config.nodeSize && config.nodeSizeByEdges === 'false') {
nodeSize = node[config.nodeSize];
}

File diff suppressed because one or more lines are too long

View File

@ -258,14 +258,9 @@
</div></script><script id="collectionsItemView.ejs" type="text/template"><div class="paddingBox">
<div class="borderBox"></div>
<!--
<div class="iconSet">
<span id="editCollection_<%=model.get('name')%>" class="icon_arangodb_settings2" alt="Edit collection properties" title="Edit collection properties"></span> <% if(model.get('status') === "loaded") { %> <span id="info_<%=model.get('name')%>" class="spanInfo icon_arangodb_info" title="Show collection properties"></span> <%} else {%> <span class="icon_arangodb_info disabled" alt="disabled"></span> <%}%> </div>
-->
<i class="collection-type-icon fa <%= model.get('picture') %>"></i>
<!--<img src="<%= model.get('picture') %>" height="50" width="50" alt="" class="icon">-->
<div class="tileBadge">
<span> <% if(model.get('desc')) { %> <div class="corneredBadge inProgress"> <%= model.get('desc') %> </div> <% } else if (model.get('status') === "loaded" || model.get('status') === 'unloaded' || model.get('status') === 'loading' || model.get('status') === 'unloading') { %> <% if (!model.get('locked') && model.get("status") !== "loading" && model.get("status") !== "unloading") { %> <div class="corneredBadge <%= model.get('status') %>"> <%= model.get('status') %> </div> <% } else if (model.get('status') === 'loading' || model.get('status') === 'unloading') { %> <div class="corneredBadge inProgress"> <%= model.get('status') %> </div> <% } else { %> <div class="corneredBadge inProgress"> <%= model.get('status') %> </div> <% } %> <% } %> </span>
<span> <% if(model.get('desc')) { %> <div class="corneredBadge inProgress"> <%= model.get('desc') %> </div> <% } else if (model.get('status') === 'corrupted') { %> <div class="corneredBadge <%= model.get('status') %>"> <%= model.get('status') %> </div> <% } else if (model.get('status') === "loaded" || model.get('status') === 'unloaded' || model.get('status') === 'loading' || model.get('status') === 'unloading') { %> <% if (!model.get('locked') && model.get("status") !== "loading" && model.get("status") !== "unloading") { %> <div class="corneredBadge <%= model.get('status') %>"> <%= model.get('status') %> </div> <% } else if (model.get('status') === 'loading' || model.get('status') === 'unloading') { %> <div class="corneredBadge inProgress"> <%= model.get('status') %> </div> <% } else { %> <div class="corneredBadge inProgress"> <%= model.get('status') %> </div> <% } %> <% } %> </span>
</div> <% if(model.get('lockType') === "index") { %> <!-- <progress max="100" value="80"></progress>-->
<h5 class="collectionName"><%= model.get('name') %></h5> <% } else { %> <h5 class="collectionName"><%= model.get('name') %></h5> <% } %> </div></script><script id="collectionsView.ejs" type="text/template"><div class="headerBar">
<div class="search-field">
@ -1028,7 +1023,7 @@ if (list.length > 0) {
<div class="pure-u-1-1 pure-u-md-1-1 pure-u-lg-1-1 pure-u-xl-1-1">
<div class="pure-g pure-table pure-table-body"> <% _.each(general, function(val, key) { %> <% if (val.type === 'divider') { %> <div class="pure-u-1-1 left heading"><%=val.name%></div> <% } else { %> <div class="<%= genClass %> left"> <%=val.name%> </div>
<div class="<%= genClass2 %> left"> <% if (val.type === 'select') { %> <select id="g_<%=key%>"> <% _.each(val, function(option, optKey) { %> <% if (option.name) { %> <option value="<%=option.val%>"> <%=option.name%> </option> <% } %> <% }); %> </select> <% } %> <% if (val.type === 'string') { %> <input id="g_<%=key%>" type="text" placeholder="string"></input> <% } %> <% if (val.type === 'number') { %> <input id="g_<%=key%>" type="text" id="<%=val %>" value="<%=val.value %>" placeholder=""></input> <% } %> <% if (val.type === 'range') { %> <label id="g_<%=key%>_label" class="rangeLabel">1</label>
<div class="<%= genClass2 %> left"> <% if (val.type === 'select') { %> <select id="g_<%=key%>"> <% _.each(val, function(option, optKey) { %> <% if (option.name) { %> <option value="<%=option.val%>"> <%=option.name%> </option> <% } %> <% }); %> </select> <% } %> <% if (val.type === 'string') { %> <input id="g_<%=key%>" type="text" placeholder="attribute"></input> <% } %> <% if (val.type === 'number') { %> <input id="g_<%=key%>" type="text" id="<%=val %>" value="<%=val.value %>" placeholder=""></input> <% } %> <% if (val.type === 'range') { %> <label id="g_<%=key%>_label" class="rangeLabel">1</label>
<input id="g_<%=key%>" type='range' min="0" max="9" val="1"/> <% } %> <% if (val.type === 'color') { %> <input id="g_<%=key%>" type='color' name='color' value="<%=VALUE%>"/> <% } %> <i title="<%=val.desc%>" class="fa fa-info-circle gv-tooltips" aria-hidden="true"></i>
</div> <% } %> <% }); %> </div>
@ -1036,11 +1031,11 @@ if (list.length > 0) {
<div class="pure-u-1-1 pure-u-md-1-1 pure-u-lg-1-1 pure-u-xl-1-1">
<div class="pure-g pure-table pure-table-body"> <% _.each(specific, function(val, key) { %> <% if (val.type === 'divider') { %> <div class="pure-u-1-1 left heading"><%=val.name%></div> <% } else { %> <div class="<%= genClass %> left"> <%=val.name%> </div>
<div class="pure-g pure-table pure-table-body"> <% _.each(specific, function(val, key) { %> <% if (val.hide !== 'true') { %> <% if (val.type === 'divider') { %> <div class="pure-u-1-1 left heading"><%=val.name%></div> <% } else { %> <div class="<%= genClass %> left"> <%=val.name%> </div>
<div class="<%= genClass2 %> left"> <% var VALUE; %> <% if (val.value) { %> <% VALUE = val.value %> <% } else { %> <% VALUE = val.default %> <% } %> <% if (val.type === 'string') { %> <input id="g_<%=key%>" type="text" placeholder="string"></input> <% } %> <% if (val.type === 'number') { %> <input id="g_<%=key%>" type="text" placeholder="number"></input> <% } %> <% if (val.type === 'color') { %> <input id="g_<%=key%>" type='color' name='color' value="<%=VALUE%>"/> <% } %> <% if (val.type === 'range') { %> <label id="g_<%=key%>_label" class="rangeLabel">1</label>
<input id="g_<%=key%>" type='range' min="0" max="9" val="1"/> <% } %> <% if (val.type === 'select') { %> <select id="g_<%=key%>"> <% _.each(val, function(option, optKey) { %> <% if (option.name) { %> <option value="<%=option.val%>"> <%=option.name%> </option> <% } %> <% }); %> </select> <% } %> <i title="<%=val.desc%>" class="fa fa-info-circle gv-tooltips" aria-hidden="true"></i>
</div> <% } %> <% }); %> </div>
<div class="<%= genClass2 %> left"> <% var VALUE; %> <% if (val.value) { %> <% VALUE = val.value %> <% } else { %> <% VALUE = val.default %> <% } %> <% if (val.type === 'string') { %> <input id="g_<%=key%>" type="text" placeholder="attribute"></input> <% } %> <% if (val.type === 'number') { %> <input id="g_<%=key%>" type="text" placeholder="number"></input> <% } %> <% if (val.type === 'color') { %> <input id="g_<%=key%>" type='color' name='color' value="<%=VALUE%>"/> <% } %> <% if (val.type === 'range') { %> <label id="g_<%=key%>_label" class="rangeLabel">1</label>
<input id="g_<%=key%>" type='range' min="0" max="9" val="1"/> <% } %> <% if (val.type === 'select') { %> <select id="g_<%=key%>"> <% _.each(val, function(option, optKey) { %> <% if (option.name) { %> <option value="<%=option.val%>"> <%=option.name%> </option> <% } %> <% }); %> </select> <% } %> <i title="<%=val.desc%>" class="fa fa-info-circle gv-tooltips" aria-hidden="true"></i>
</div> <% } %> <% } %> <% }); %> </div>
<div class="pure-u-1-1">
<button id="saveGraphSettings" style="margin-top: 20px; margin-right: 10px;" class="button-success pull-right">Save</button>
@ -1073,6 +1068,7 @@ if (list.length > 0) {
</span>
</a>
</li>
<!--
<li class="enabled">
<a id="selectNodes" class="headerButton">
<span title="Lasso tool - Select and delete multiple nodes">
@ -1080,6 +1076,7 @@ if (list.length > 0) {
</span>
</a>
</li>
-->
</ul>
</div>
</div>
@ -2739,4 +2736,4 @@ var cutByResolution = function (str) {
</div>
<div id="workMonitorContent" class="innerContent">
</div></script></head><body><nav class="navbar" style="display: none"><div class="primary"><div class="navlogo"><a class="logo big" href="#"><img class="arangodbLogo" src="img/arangodb_logo_big.png"></a><a class="logo small" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a><a class="version"><span>VERSION: </span><span id="currentVersion"></span></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div id="modalPlaceholder"></div><div class="bodyWrapper" style="display: none"><div class="centralRow"><div id="navbar2" class="navbarWrapper secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper"><div id="loadingScreen" class="loadingScreen" style="display: none"><i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw margin-bottom"></i> <span class="sr-only">Loading...</span></div><div id="content" class="centralContent"></div><footer class="footer"><div id="footerBar"></div></footer></div></div></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div id="graphSettingsContent" style="display: none"></div><div id="offlinePlaceholder" style="display:none"><div class="offline-div"><div class="pure-u"><div class="pure-u-1-4"></div><div class="pure-u-1-2 offline-window"><div class="offline-header"><h3>You have been disconnected from the server</h3></div><div class="offline-body"><p>The connection to the server has been lost. The server may be under heavy load.</p><p>Trying to reconnect in <span id="offlineSeconds">10</span> seconds.</p><p class="animation_state"><span><button class="button-success">Reconnect now</button></span></p></div></div><div class="pure-u-1-4"></div></div></div></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="libs.js?version=1472049166163"></script><script src="app.js?version=1472049166163"></script></body></html>
</div></script></head><body><nav class="navbar" style="display: none"><div class="primary"><div class="navlogo"><a class="logo big" href="#"><img class="arangodbLogo" src="img/arangodb_logo_big.png"></a><a class="logo small" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a><a class="version"><span>VERSION: </span><span id="currentVersion"></span></a></div><div class="statmenu" id="statisticBar"></div><div class="navmenu" id="navigationBar"></div></div></nav><div id="modalPlaceholder"></div><div class="bodyWrapper" style="display: none"><div class="centralRow"><div id="navbar2" class="navbarWrapper secondary"><div class="subnavmenu" id="subNavigationBar"></div></div><div class="resizecontainer contentWrapper"><div id="loadingScreen" class="loadingScreen" style="display: none"><i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw margin-bottom"></i> <span class="sr-only">Loading...</span></div><div id="content" class="centralContent"></div><footer class="footer"><div id="footerBar"></div></footer></div></div></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><div id="graphSettingsContent" style="display: none"></div><div id="offlinePlaceholder" style="display:none"><div class="offline-div"><div class="pure-u"><div class="pure-u-1-4"></div><div class="pure-u-1-2 offline-window"><div class="offline-header"><h3>You have been disconnected from the server</h3></div><div class="offline-body"><p>The connection to the server has been lost. The server may be under heavy load.</p><p>Trying to reconnect in <span id="offlineSeconds">10</span> seconds.</p><p class="animation_state"><span><button class="button-success">Reconnect now</button></span></p></div></div><div class="pure-u-1-4"></div></div></div></div><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="libs.js?version=1473434769207"></script><script src="app.js?version=1473434769207"></script></body></html>

File diff suppressed because one or more lines are too long

View File

@ -1,24 +1,17 @@
<script id="collectionsItemView.ejs" type="text/template">
<div class="paddingBox">
<div class="borderBox"></div>
<!--
<div class="iconSet">
<span id="editCollection_<%=model.get('name')%>" class="icon_arangodb_settings2" alt="Edit collection properties" title="Edit collection properties"></span>
<% if(model.get('status') === "loaded") { %>
<span id="info_<%=model.get('name')%>" class="spanInfo icon_arangodb_info" title="Show collection properties"></span>
<%} else {%>
<span class="icon_arangodb_info disabled" alt="disabled"></span>
<%}%>
</div>
-->
<i class="collection-type-icon fa <%= model.get('picture') %>"></i>
<!--<img src="<%= model.get('picture') %>" height="50" width="50" alt="" class="icon">-->
<div class="tileBadge">
<span>
<% if(model.get('desc')) { %>
<div class="corneredBadge inProgress">
<%= model.get('desc') %>
</div>
<% } else if (model.get('status') === 'corrupted') { %>
<div class="corneredBadge <%= model.get('status') %>">
<%= model.get('status') %>
</div>
<% } else if (model.get('status') === "loaded" || model.get('status') === 'unloaded' || model.get('status') === 'loading' || model.get('status') === 'unloading') { %>
<% if (!model.get('locked') && model.get("status") !== "loading" && model.get("status") !== "unloading") { %>
<div class="corneredBadge <%= model.get('status') %>">

View File

@ -35,7 +35,7 @@
<% } %>
<% if (val.type === 'string') { %>
<input id="g_<%=key%>" type="text" placeholder="string"></input>
<input id="g_<%=key%>" type="text" placeholder="attribute"></input>
<% } %>
<% if (val.type === 'number') { %>
@ -65,40 +65,41 @@
<div class="pure-g pure-table pure-table-body">
<% _.each(specific, function(val, key) { %>
<% if (val.type === 'divider') { %>
<div class="pure-u-1-1 left heading"><%=val.name%></div>
<% } else { %>
<div class="<%= genClass %> left">
<%=val.name%>
</div>
<% if (val.hide !== 'true') { %>
<% if (val.type === 'divider') { %>
<div class="pure-u-1-1 left heading"><%=val.name%></div>
<% } else { %>
<div class="<%= genClass %> left">
<%=val.name%>
</div>
<div class="<%= genClass2 %> left">
<div class="<%= genClass2 %> left">
<% var VALUE; %>
<% if (val.value) { %>
<% VALUE = val.value %>
<% } else { %>
<% VALUE = val.default %>
<% } %>
<% var VALUE; %>
<% if (val.value) { %>
<% VALUE = val.value %>
<% } else { %>
<% VALUE = val.default %>
<% } %>
<% if (val.type === 'string') { %>
<input id="g_<%=key%>" type="text" placeholder="string"></input>
<% } %>
<% if (val.type === 'string') { %>
<input id="g_<%=key%>" type="text" placeholder="attribute"></input>
<% } %>
<% if (val.type === 'number') { %>
<input id="g_<%=key%>" type="text" placeholder="number"></input>
<% } %>
<% if (val.type === 'number') { %>
<input id="g_<%=key%>" type="text" placeholder="number"></input>
<% } %>
<% if (val.type === 'color') { %>
<input id="g_<%=key%>" type='color' name='color' value="<%=VALUE%>"/>
<% } %>
<% if (val.type === 'color') { %>
<input id="g_<%=key%>" type='color' name='color' value="<%=VALUE%>"/>
<% } %>
<% if (val.type === 'range') { %>
<label id="g_<%=key%>_label" class="rangeLabel">1</label>
<input id="g_<%=key%>" type='range' min="0" max="9" val="1"/>
<% } %>
<% if (val.type === 'range') { %>
<label id="g_<%=key%>_label" class="rangeLabel">1</label>
<input id="g_<%=key%>" type='range' min="0" max="9" val="1"/>
<% } %>
<% if (val.type === 'select') { %>
<% if (val.type === 'select') { %>
<select id="g_<%=key%>">
<% _.each(val, function(option, optKey) { %>
<% if (option.name) { %>
@ -106,9 +107,10 @@
<% } %>
<% }); %>
</select>
<% } %>
<i title="<%=val.desc%>" class="fa fa-info-circle gv-tooltips" aria-hidden="true"></i>
</div>
<% } %>
<i title="<%=val.desc%>" class="fa fa-info-circle gv-tooltips" aria-hidden="true"></i>
</div>
<% } %>
<% } %>
<% }); %>
</div>

View File

@ -25,6 +25,7 @@
</span>
</a>
</li>
<!--
<li class="enabled">
<a id="selectNodes" class="headerButton">
<span title="Lasso tool - Select and delete multiple nodes">
@ -32,6 +33,7 @@
</span>
</a>
</li>
-->
</ul>
</div>
</div>

View File

@ -23,7 +23,7 @@
},
render: function () {
if (this.model.get('locked')) {
if (this.model.get('locked') || this.model.get('status') === 'corrupted') {
$(this.el).addClass('locked');
$(this.el).addClass(this.model.get('lockType'));
} else {
@ -67,6 +67,9 @@
if (this.model.get('status') === 'loading') {
return 0;
}
if (this.model.get('status') === 'corrupted') {
return 0;
}
if (this.model.get('status') === 'unloaded') {
this.loadCollection();

View File

@ -27,7 +27,7 @@
'layout': {
type: 'select',
name: 'Layout',
desc: 'Different graph algorithms. No overlap is very fast (more than 5000 nodes), force is slower (less than 5000 nodes) and fruchtermann is the slowest (less than 500 nodes). The calculation time strongly depends on your nodes and edges counts.',
desc: 'Different graph algorithms. No overlap is very fast (more than 5000 nodes), force is slower (less than 5000 nodes) and fruchtermann is the slowest (less than 500 nodes).',
noverlap: {
name: 'No overlap',
val: 'noverlap'
@ -81,8 +81,8 @@
},
'nodeLabelByCollection': {
type: 'select',
name: 'Use Collection Name',
desc: 'Set label text by collection. If activated node label attribute will be ignored.',
name: 'Add Collection Name',
desc: 'Append collection name to the label?',
yes: {
name: 'Yes',
val: 'true'
@ -94,7 +94,7 @@
},
'nodeColorByCollection': {
type: 'select',
name: 'Use Collection Color',
name: 'Color By Collections',
no: {
name: 'No',
val: 'false'
@ -118,7 +118,7 @@
},
'nodeSizeByEdges': {
type: 'select',
name: 'Size By Edges',
name: 'Size By Collections',
yes: {
name: 'Yes',
val: 'true'
@ -145,7 +145,7 @@
},
'edgeLabelByCollection': {
type: 'select',
name: 'Use Collection Name',
name: 'Add Collection Name',
desc: 'Set label text by collection. If activated edge label attribute will be ignored.',
yes: {
name: 'Yes',
@ -158,7 +158,7 @@
},
'edgeColorByCollection': {
type: 'select',
name: 'Use Collection Color',
name: 'Color By Collections',
no: {
name: 'No',
val: 'false'
@ -182,6 +182,7 @@
},
'edgeEditable': {
type: 'select',
hide: 'true',
name: 'Editable',
yes: {
name: 'Yes',
@ -314,18 +315,18 @@
}
var callback = function () {
if (window.App.graphViewer2) {
if (window.App.graphViewer) {
if (color !== '' && color !== undefined) {
var nodes = !$('#g_nodeColor').is(':disabled');
var edges = !$('#g_edgeColor').is(':disabled');
window.App.graphViewer2.updateColors(
window.App.graphViewer.updateColors(
nodes,
edges,
$('#g_nodeColor').val(),
$('#g_edgeColor').val()
);
} else {
window.App.graphViewer2.render(self.lastFocussed);
window.App.graphViewer.render(self.lastFocussed);
}
} else {
arangoHelper.arangoNotification('Graph ' + this.name, 'Configuration saved.');
@ -352,7 +353,7 @@
edgeType: 'arrow',
nodeSize: '',
nodeSizeByEdges: 'true',
edgeEditable: 'false',
edgeEditable: 'true',
nodeLabelByCollection: 'false',
edgeLabelByCollection: 'false',
nodeStart: '',
@ -364,7 +365,7 @@
} else {
this.saveGraphSettings(null, null, null, obj);
this.render();
window.App.graphViewer2.render(this.lastFocussed);
window.App.graphViewer.render(this.lastFocussed);
}
},
@ -394,6 +395,7 @@
if ($('#g_nodeSizeByEdges').val() === 'true') {
$('#g_nodeSize').prop('disabled', true);
}
// node color
if ($('#g_nodeColorByCollection').val() === 'true') {
$('#g_nodeColorAttribute').prop('disabled', true);
@ -411,16 +413,6 @@
if ($('#g_edgeColorAttribute').val() !== '') {
$('#g_edgeColor').prop('disabled', true);
}
// node label
if ($('#g_nodeLabelByCollection').val() === 'true') {
$('#g_nodeLabel').prop('disabled', true);
}
// edge label
if ($('#g_edgeLabelByCollection').val() === 'true') {
$('#g_edgeLabel').prop('disabled', true);
}
},
continueRender: function () {

View File

@ -51,7 +51,7 @@
aqlMode: false,
events: {
'click #downloadPNG': 'downloadSVG',
'click #downloadPNG': 'downloadPNG',
'click #reloadGraph': 'reloadGraph',
'click #settingsMenu': 'toggleSettings',
'click #noGraphToggle': 'toggleSettings',
@ -109,11 +109,12 @@
} catch (ignore) {}
},
downloadSVG: function () {
downloadPNG: function () {
var size = parseInt($('#graph-container').width(), 10);
sigma.plugins.image(this.currentGraph, this.currentGraph.renderers[0], {
download: true,
size: size,
labels: true,
background: 'white',
zoom: true
});
@ -139,6 +140,47 @@
this.resize();
this.fetchGraph(toFocus);
this.initFullscreen();
},
initFullscreen: function () {
var self = this;
if (window.App.initializedFullscreen === false || window.App.initializedFullscreen === undefined) {
window.App.initializedFullscreen = true;
this.isFullscreen = false;
var exitHandler = function (a) {
if (document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement !== null) {
if (self.isFullscreen === false) {
self.isFullscreen = true;
// FULLSCREEN STYLING
$('#toggleForce').css('bottom', '10px');
$('#objectCount').css('bottom', '10px');
$('#objectCount').css('left', '25px');
} else {
self.isFullscreen = false;
// NO FULLSCREEN STYLING
$('#toggleForce').css('bottom', '40px');
$('#objectCount').css('bottom', '50px');
$('#objectCount').css('left', '25px');
}
console.log(self.isFullscreen);
}
};
if (document.addEventListener) {
document.addEventListener('webkitfullscreenchange', exitHandler, false);
document.addEventListener('mozfullscreenchange', exitHandler, false);
document.addEventListener('fullscreenchange', exitHandler, false);
document.addEventListener('MSFullscreenChange', exitHandler, false);
}
}
},
renderAQL: function (data) {
@ -1301,10 +1343,11 @@
},
initializeGraph: function (sigmaInstance, graph) {
var self = this;
// var self = this;
// sigmaInstance.graph.read(graph);
sigmaInstance.refresh();
/*
this.Sigma.plugins.Lasso = sigma.plugins.lasso;
var lasso = new this.Sigma.plugins.Lasso(sigmaInstance, sigmaInstance.renderers[0], {
@ -1343,6 +1386,7 @@
});
return lasso;
*/
},
renderGraph: function (graph, toFocus, aqlMode) {
@ -1368,8 +1412,8 @@
style = 'position: absolute; left: 30px; margin-top: -37px;';
}
$(this.el).append(
'<div style="' + style + ' animated fadeIn">' +
$('#graph-container').append(
'<div id="objectCount" style="' + style + ' animated fadeIn">' +
'<span style="margin-right: 10px" class="arangoState"><span id="nodesCount">' + graph.nodes.length + '</span> nodes</span>' +
'<span class="arangoState"><span id="edgesCount">' + graph.edges.length + '</span> edges</span>' +
'</div>'
@ -1406,13 +1450,13 @@
labelThreshold: 10,
maxNodeSize: 15,
batchEdgesDrawing: true,
minEdgeSize: 10,
maxEdgeSize: 20,
minEdgeSize: 1,
maxEdgeSize: 1,
enableEdgeHovering: true,
edgeHoverColor: '#8c8c8c',
defaultEdgeHoverColor: '#8c8c8c',
defaultEdgeType: 'arrow',
edgeHoverSizeRatio: 2,
edgeHoverSizeRatio: 2.5,
edgeHoverExtremities: true,
nodesPowRatio: 0.5,
// edgesPowRatio: 1.5,
@ -1540,7 +1584,7 @@
var attributes = '';
attributes += '<span>ID </span> <span class="nodeId">' + data._id + '</span>';
if (Object.keys(data).length > 3) {
attributes += '<span>KEYS </span>';
attributes += '<span>ATTRIBUTES </span>';
}
_.each(data, function (value, key) {
if (key !== '_key' && key !== '_id' && key !== '_rev' && key !== '_from' && key !== '_to') {
@ -1549,7 +1593,7 @@
});
var string = '<div id="nodeInfoDiv" class="nodeInfoDiv" style="display: none;">' + attributes + '</div>';
$(self.el).append(string);
$('#graph-container').append(string);
$('#nodeInfoDiv').fadeIn('slow');
}
};
@ -1737,7 +1781,7 @@
style2 = 'color: rgb(64, 74, 83); cursor: pointer; position: absolute; right: 30px; margin-top: -30px;';
}
$(this.el).append(
$('#graph-container').append(
'<div id="toggleForce" style="' + style2 + '">' +
'<i style="margin-right: 5px;" class="fa fa-pause"></i><span> Stop layout</span>' +
'</div>'
@ -1787,6 +1831,7 @@
}, 2000);
}
/*
var enableLasso = function () {
self.graphLasso = self.initializeGraph(s, graph);
self.graphLasso.activate();
@ -1807,12 +1852,14 @@
$('#selectNodes').parent().hide();
}
}
*/
if (self.graphLasso) {
/* if (self.graphLasso) {
// add lasso event
// Toggle lasso activation on Alt + l
window.App.listenerFunctions['graphViewer'] = this.keyUpFunction.bind(this);
}
} */
// clear up info div
$('#calculatingGraph').fadeOut('slow');
@ -1860,6 +1907,7 @@
}
},
/*
toggleLasso: function () {
var self = this;
@ -1888,6 +1936,7 @@
x.addEventListener('mouseup', self.nodesContextMenuCheck.bind(this), false);
}
},
*/
startLayout: function (kill, origin) {
var self = this;
@ -1925,7 +1974,7 @@
stopLayout: function () {
$('#toggleForce .fa').removeClass('fa-pause').addClass('fa-play');
$('#toggleForce span').html('Start layout');
$('#toggleForce span').html('Resume layout');
this.layouting = false;
this.currentGraph.stopForceAtlas2();
sigma.plugins.dragNodes(this.currentGraph, this.currentGraph.renderers[0]);

View File

@ -1942,7 +1942,7 @@
},
renderOutputGraph: function (data, counter) {
this.graphViewer2 = new window.GraphViewer2({
this.graphViewer = new window.GraphViewer({
name: undefined,
documentStore: window.App.arangoDocumentStore,
collection: new window.GraphCollection(),
@ -1950,7 +1950,7 @@
id: '#outputGraph' + counter,
data: data
});
this.graphViewer2.renderAQL();
this.graphViewer.renderAQL();
},
getAQL: function (originCallback) {

View File

@ -366,6 +366,10 @@ $iconsize: 50px;
border-bottom-color: $c-positive;
}
&.corrupted {
border-bottom-color: $c-negative;
}
&.inProgress {
border-bottom-color: $c-progress-bar;
}

View File

@ -821,6 +821,7 @@ double VelocyPackHelper::toDouble(VPackSlice const& slice, bool& failed) {
return 0.0;
}
#ifndef USE_ENTERPRISE
uint64_t VelocyPackHelper::hashByAttributes(
VPackSlice slice, std::vector<std::string> const& attributes,
bool docComplete, int& error, std::string const& key) {
@ -830,24 +831,25 @@ uint64_t VelocyPackHelper::hashByAttributes(
if (slice.isObject()) {
for (auto const& attr : attributes) {
VPackSlice sub = slice.get(attr).resolveExternal();
VPackBuilder temporaryBuilder;
if (sub.isNone()) {
if (attr == StaticStrings::KeyString && !key.empty()) {
VPackBuilder temporaryBuilder;
temporaryBuilder.add(VPackValue(key));
hash = temporaryBuilder.slice().normalizedHash(hash);
continue;
sub = temporaryBuilder.slice();
} else {
if (!docComplete) {
error = TRI_ERROR_CLUSTER_NOT_ALL_SHARDING_ATTRIBUTES_GIVEN;
}
// Null is equal to None/not present
sub = VPackSlice::nullSlice();
}
if (!docComplete) {
error = TRI_ERROR_CLUSTER_NOT_ALL_SHARDING_ATTRIBUTES_GIVEN;
}
// Null is equal to None/not present
sub = VPackSlice::nullSlice();
}
hash = sub.normalizedHash(hash);
}
}
return hash;
}
#endif
void VelocyPackHelper::SanitizeExternals(VPackSlice const input,
VPackBuilder& output) {