mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:arangodb/arangodb into solaris
This commit is contained in:
commit
32685a1c69
|
@ -1,4 +1,3 @@
|
|||
js-*.h
|
||||
.deps
|
||||
.dirstamp
|
||||
*.o
|
||||
|
@ -18,11 +17,6 @@ js-*.h
|
|||
*.patch
|
||||
*.lnk
|
||||
|
||||
.idea
|
||||
.setup-mr-directories
|
||||
.setup-js-directories
|
||||
.file-list-js
|
||||
|
||||
testresult.json
|
||||
|
||||
build*/
|
||||
|
@ -60,12 +54,10 @@ Documentation/Books/Users/manual.mobi
|
|||
Documentation/Books/Users/manual.pdf
|
||||
Documentation/Books/Makefile
|
||||
Documentation/Books/Users/node_modules/
|
||||
Documentation/Examples/*.generated
|
||||
Documentation/Books/ppbooks/
|
||||
Documentation/Books/allComments.txt
|
||||
|
||||
UnitTests/HttpInterface/logs/
|
||||
UnitTests/basics_suite
|
||||
UnitTests/geo_suite
|
||||
|
||||
arangod/Aql/grammar.c
|
||||
arangod/Aql/grammar.cpp
|
||||
|
@ -88,12 +80,11 @@ lib/JsonParser/json-parser.c
|
|||
lib/JsonParser/json-parser.cpp
|
||||
lib/V8/v8-json.cpp
|
||||
|
||||
cppcheck.log
|
||||
cppcheck.tmp
|
||||
|
||||
Installation/epm/arangodb.sublist
|
||||
Installation/MacOSX/Bundle/Info.plist
|
||||
|
||||
nbproject/
|
||||
.idea
|
||||
|
||||
test.cpp.txt
|
||||
|
||||
|
@ -112,7 +103,6 @@ js/apps/*
|
|||
js/apps/system/_admin/aardvark/APP/node_modules/*
|
||||
|
||||
3rdParty/etcd/src/
|
||||
Documentation/Books/allComments.txt
|
||||
|
||||
.gdb-history
|
||||
npm-debug.log
|
||||
|
|
|
@ -40,6 +40,7 @@ HttpHandler::status_t RestEdgesHandler::execute() {
|
|||
HttpRequest::HttpRequestType type = _request->requestType();
|
||||
|
||||
// execute one of the CRUD methods
|
||||
try {
|
||||
switch (type) {
|
||||
case HttpRequest::HTTP_REQUEST_GET: {
|
||||
std::vector<traverser::TraverserExpression*> empty;
|
||||
|
@ -60,6 +61,15 @@ HttpHandler::status_t RestEdgesHandler::execute() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
generateError(HttpResponse::responseCode(ex.code()), ex.code(), ex.what());
|
||||
}
|
||||
catch (std::exception const& ex) {
|
||||
generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_INTERNAL, ex.what());
|
||||
}
|
||||
catch (...) {
|
||||
generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
// this handler is done
|
||||
return status_t(HANDLER_DONE);
|
||||
|
@ -80,6 +90,10 @@ bool RestEdgesHandler::getEdgesForVertex(
|
|||
TRI_document_collection_t* docCol =
|
||||
trx.trxCollection()->_collection->_collection;
|
||||
|
||||
if (trx.orderDitch(trx.trxCollection()) == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
std::vector<TRI_doc_mptr_copy_t>&& edges = TRI_LookupEdgesDocumentCollection(
|
||||
&trx, docCol, direction, start.cid, const_cast<char*>(start.key));
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"frontend/js/lib/jquery.textfill.min.js",
|
||||
"frontend/js/lib/jquery.noty.packaged.min.js",
|
||||
"frontend/js/lib/select2.min.js",
|
||||
"frontend/js/lib/typeahead.bundle.min.js",
|
||||
"frontend/js/lib/numeral.min.js",
|
||||
"frontend/js/lib/sigma.min.js",
|
||||
"frontend/js/lib/jsoneditor-min.js",
|
||||
|
|
|
@ -796,4 +796,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div></script></head><body><nav class="navbar"><div class="resizecontainer"><div class="navlogo"><a class="logo" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a></div><div id="progressPlaceholderIcon"></div><div class="statmenu" id="statisticBar"></div><div class="usermenu" id="userBar" style="float:right"></div><div class="notificationmenu" id="notificationBar" style="float:right"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="centralRow resizecontainer"><div id="content" class="centralContent"></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><footer class="footer"><div class="resizecontainer" id="footerBar"></div></footer><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js"></script><script src="cluster.js"></script></body></html>
|
||||
</div></script></head><body><nav class="navbar"><div class="resizecontainer"><div class="navlogo"><a class="logo" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a></div><div id="progressPlaceholderIcon"></div><div class="statmenu" id="statisticBar"></div><div class="usermenu" id="userBar" style="float:right"></div><div class="notificationmenu" id="notificationBar" style="float:right"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="centralRow resizecontainer"><div id="content" class="centralContent"></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><footer class="footer"><div class="resizecontainer" id="footerBar"></div></footer><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js"></script><script src="cluster.js"></script></body></html>
|
Binary file not shown.
|
@ -913,6 +913,9 @@
|
|||
<div id="progressPlaceholder" style="display:none">
|
||||
</div>
|
||||
|
||||
<div id="spotlightPlaceholder" style="display:none">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
|
|
|
@ -257,6 +257,11 @@
|
|||
window.App.notificationList.add({title:title, content: content, info: info, type: 'error'});
|
||||
},
|
||||
|
||||
hideArangoNotifications: function() {
|
||||
$.noty.clearQueue();
|
||||
$.noty.closeAll();
|
||||
},
|
||||
|
||||
openDocEditor: function (id, type, callback) {
|
||||
var ids = id.split("/"),
|
||||
self = this;
|
||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -2077,7 +2077,7 @@ textarea,
|
|||
height: 0;
|
||||
visibility: hidden; }
|
||||
|
||||
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .scenarioImage {
|
||||
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton i, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .scenarioImage {
|
||||
cursor: pointer; }
|
||||
|
||||
.navbar, footer.footer {
|
||||
|
@ -2095,10 +2095,10 @@ textarea,
|
|||
.button-danger:focus {
|
||||
background-color: #be342e; }
|
||||
|
||||
.deleteButton, a.danger.coordinator, a.danger.dbserver {
|
||||
.deleteButton i, a.danger.coordinator, a.danger.dbserver {
|
||||
color: #da4f49; }
|
||||
.deleteButton:hover,
|
||||
a.danger.coordinator:hover, a.danger.dbserver:hover, .deleteButton:focus, a.danger.coordinator:focus, a.danger.dbserver:focus {
|
||||
.deleteButton i:hover,
|
||||
a.danger.coordinator:hover, a.danger.dbserver:hover, .deleteButton i:focus, a.danger.coordinator:focus, a.danger.dbserver:focus {
|
||||
color: #be342e; }
|
||||
|
||||
a.danger.coordinator, a.danger.dbserver {
|
||||
|
@ -2597,13 +2597,13 @@ button.disabled,
|
|||
cursor: not-allowed; }
|
||||
|
||||
.addButton {
|
||||
font-size: 22px;
|
||||
font-size: 16pt;
|
||||
margin-right: 7px;
|
||||
margin-top: 2px;
|
||||
position: relative; }
|
||||
|
||||
.deleteButton {
|
||||
font-size: 22px;
|
||||
.deleteButton i {
|
||||
font-size: 16pt;
|
||||
padding-right: 3px;
|
||||
position: relative;
|
||||
top: 3px; }
|
||||
|
|
Binary file not shown.
|
@ -10607,6 +10607,11 @@ function GraphViewer(svg, width, height, adapterConfig, config) {
|
|||
window.App.notificationList.add({title:title, content: content, info: info, type: 'error'});
|
||||
},
|
||||
|
||||
hideArangoNotifications: function() {
|
||||
$.noty.clearQueue();
|
||||
$.noty.closeAll();
|
||||
},
|
||||
|
||||
openDocEditor: function (id, type, callback) {
|
||||
var ids = id.split("/"),
|
||||
self = this;
|
||||
|
@ -25884,6 +25889,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
$('.' + menuItem).addClass('active');
|
||||
}
|
||||
}
|
||||
arangoHelper.hideArangoNotifications();
|
||||
},
|
||||
|
||||
showDropdown: function (e) {
|
||||
|
@ -27625,7 +27631,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
currentQuery: {},
|
||||
initDone: false,
|
||||
|
||||
bindParamRegExp: /@(@?)(\w+(\d*))/,
|
||||
bindParamRegExp: /@(@?\w+\d*)/,
|
||||
bindParamTableObj: {},
|
||||
|
||||
bindParamTableDesc: {
|
||||
|
@ -27636,7 +27642,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
|
||||
myQueriesTableDesc: {
|
||||
id: "arangoMyQueriesTable",
|
||||
titles: ["Name", "Actions"],
|
||||
titles: ["Name", "Query", "Actions"],
|
||||
rows: []
|
||||
},
|
||||
|
||||
|
@ -27649,6 +27655,8 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
this.refreshAQL();
|
||||
},
|
||||
|
||||
allowParamToggle: true,
|
||||
|
||||
events: {
|
||||
"click #executeQuery": "executeQuery",
|
||||
"click #explainQuery": "explainQuery",
|
||||
|
@ -27662,6 +27670,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
"click #exportQuery": "exportCustomQueries",
|
||||
"click #importQuery": "openImportDialog",
|
||||
"click #removeResults": "removeResults",
|
||||
"click #querySpotlight": "showSpotlight",
|
||||
"click #deleteQuery": "selectAndDeleteQueryFromTable",
|
||||
"click #explQuery": "selectAndExplainQueryFromTable",
|
||||
"keyup #arangoBindParamTable input": "updateBindParams",
|
||||
|
@ -27671,6 +27680,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
"click #arangoMyQueriesTable #copyQuery" : "selectQueryFromTable",
|
||||
'click #closeQueryModal': 'closeExportDialog',
|
||||
'click #confirmQueryImport': 'importCustomQueries',
|
||||
'click #switchTypes': 'toggleBindParams',
|
||||
"click #arangoMyQueriesTable #runQuery" : "selectAndRunQueryFromTable"
|
||||
},
|
||||
|
||||
|
@ -27678,6 +27688,38 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
this.aqlEditor.setValue('');
|
||||
},
|
||||
|
||||
toggleBindParams: function() {
|
||||
|
||||
if (this.allowParamToggle) {
|
||||
$('#bindParamEditor').toggle();
|
||||
$('#bindParamAceEditor').toggle();
|
||||
|
||||
if ($('#switchTypes').text() === 'JSON') {
|
||||
$('#switchTypes').text('Table');
|
||||
this.updateQueryTable();
|
||||
this.bindParamAceEditor.setValue(JSON.stringify(this.bindParamTableObj, null, "\t"));
|
||||
this.deselect(this.bindParamAceEditor);
|
||||
}
|
||||
else {
|
||||
$('#switchTypes').text('JSON');
|
||||
this.renderBindParamTable();
|
||||
}
|
||||
}
|
||||
else {
|
||||
arangoHelper.arangoError("Bind parameter", "Could not parse bind parameter");
|
||||
}
|
||||
this.resize();
|
||||
|
||||
},
|
||||
|
||||
openExportDialog: function() {
|
||||
$('#queryImportDialog').modal('show');
|
||||
},
|
||||
|
||||
closeExportDialo: function() {
|
||||
$('#queryImportDialog').modal('hide');
|
||||
},
|
||||
|
||||
initQueryImport: function () {
|
||||
var self = this;
|
||||
self.allowUpload = false;
|
||||
|
@ -27726,9 +27768,22 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
},
|
||||
|
||||
getCustomQueryValueByName: function (qName) {
|
||||
var obj;
|
||||
|
||||
if (qName) {
|
||||
return this.collection.findWhere({name: qName}).get("value");
|
||||
obj = this.collection.findWhere({name: qName});
|
||||
}
|
||||
if (obj) {
|
||||
obj = obj.get("value");
|
||||
}
|
||||
else {
|
||||
_.each(this.queries, function(query) {
|
||||
if (query.name === qName) {
|
||||
obj = query.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
openImportDialog: function() {
|
||||
|
@ -27757,13 +27812,16 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
if (e) {
|
||||
if (e.currentTarget.id === "toggleQueries1") {
|
||||
this.updateQueryTable();
|
||||
$('#bindParamAceEditor').hide();
|
||||
$('#bindParamEditor').show();
|
||||
$('#switchTypes').text('JSON');
|
||||
}
|
||||
}
|
||||
|
||||
var divs = [
|
||||
"aqlEditor", "queryTable", "previewWrapper",
|
||||
"aqlEditor", "queryTable", "previewWrapper", "querySpotlight",
|
||||
"bindParamEditor", "toggleQueries1", "toggleQueries2",
|
||||
"saveCurrentQuery", "querySize", "executeQuery",
|
||||
"saveCurrentQuery", "querySize", "executeQuery", "switchTypes",
|
||||
"explainQuery", "clearQuery", "importQuery", "exportQuery"
|
||||
];
|
||||
_.each(divs, function(div) {
|
||||
|
@ -27787,7 +27845,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
name = $(e.currentTarget).children().first().text();
|
||||
}
|
||||
else if ($(e.currentTarget).is('span')) {
|
||||
name = $(e.currentTarget).parent().parent().prev().text();
|
||||
name = $(e.currentTarget).parent().parent().prev().prev().text();
|
||||
}
|
||||
return name;
|
||||
},
|
||||
|
@ -27914,8 +27972,8 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
},
|
||||
|
||||
explainQuery: function() {
|
||||
if (this.aqlEditor.getValue().length === 0) {
|
||||
arangoHelper.arangoError("Query", "Your query is empty");
|
||||
|
||||
if (this.verifyQueryAndParams()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27929,6 +27987,8 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
sentQueryEditor = ace.edit("sentQueryEditor" + counter);
|
||||
sentQueryEditor.getSession().setMode("ace/mode/aql");
|
||||
outputEditor.getSession().setMode("ace/mode/json");
|
||||
outputEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
sentQueryEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
outputEditor.setReadOnly(true);
|
||||
sentQueryEditor.setReadOnly(true);
|
||||
|
||||
|
@ -27959,6 +28019,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
if (data.msg.includes('errorMessage')) {
|
||||
self.removeOutputEditor(counter);
|
||||
arangoHelper.arangoError("Explain error", data.msg);
|
||||
window.progressView.hide();
|
||||
}
|
||||
else {
|
||||
outputEditor.setValue(data.msg);
|
||||
|
@ -27969,7 +28030,6 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
}
|
||||
},
|
||||
error: function (data) {
|
||||
window.progressView.hide();
|
||||
try {
|
||||
var temp = JSON.parse(data.responseText);
|
||||
arangoHelper.arangoError("Explain error", temp.errorMessage);
|
||||
|
@ -27977,6 +28037,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
catch (e) {
|
||||
arangoHelper.arangoError("Explain error", "ERROR");
|
||||
}
|
||||
window.progressView.hide();
|
||||
self.handleResult(counter);
|
||||
this.removeOutputEditor(counter);
|
||||
}
|
||||
|
@ -27987,6 +28048,9 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
removeOutputEditor: function(counter) {
|
||||
$('#outputEditorWrapper' + counter).hide();
|
||||
$('#outputEditorWrapper' + counter).remove();
|
||||
if ($('.outputEditorWrapper').length === 0) {
|
||||
$('#removeResults').hide();
|
||||
}
|
||||
},
|
||||
|
||||
getCachedQueryAfterRender: function() {
|
||||
|
@ -28074,13 +28138,27 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
this.initQueryImport();
|
||||
|
||||
//set height of editor wrapper
|
||||
$('.inputEditorWrapper').height($(window).height() / 10 * 3);
|
||||
$('.inputEditorWrapper').height($(window).height() / 10 * 5 + 25);
|
||||
window.setTimeout(function() {
|
||||
self.resize();
|
||||
}, 10);
|
||||
self.deselect(self.aqlEditor);
|
||||
},
|
||||
|
||||
showSpotlight: function() {
|
||||
|
||||
var callback = function(string) {
|
||||
this.aqlEditor.insert(string);
|
||||
$('#aqlEditor .ace_text-input').focus();
|
||||
}.bind(this);
|
||||
|
||||
var cancelCallback = function() {
|
||||
$('#aqlEditor .ace_text-input').focus();
|
||||
};
|
||||
|
||||
window.spotlightView.show(callback, cancelCallback);
|
||||
},
|
||||
|
||||
resize: function() {
|
||||
this.resizeFunction();
|
||||
},
|
||||
|
@ -28101,12 +28179,13 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
this.queryPreview.resize();
|
||||
//fix my queries preview table resizing issues TODO
|
||||
$('#arangoMyQueriesTable thead').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable thead th').css('width', $('#queryTable').width() / 2);
|
||||
$('#arangoMyQueriesTable thead th').css('width', $('#queryTable').width() / 3);
|
||||
$('#arangoMyQueriesTable tr').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable tbody').css('height', $('#queryTable').height() - 18);
|
||||
$('#arangoMyQueriesTable tbody').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable tbody tr').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable tbody td').css('width', $('#queryTable').width() / 2);
|
||||
$('#arangoMyQueriesTable tbody td').css('width', $('#queryTable').width() / 3);
|
||||
$('#arangoMyQueriesTable tbody td .truncate').css('width', $('#queryTable').width() / 3);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -28193,19 +28272,26 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
});
|
||||
});
|
||||
|
||||
_.each(words, function(word) {
|
||||
word = word.split(",");
|
||||
_.each(word, function(x) {
|
||||
words1.push(x);
|
||||
});
|
||||
});
|
||||
|
||||
_.each(words1, function(word) {
|
||||
// remove newlines and whitespaces
|
||||
words[pos] = word.replace(/(\r\n|\n|\r)/gm,"");
|
||||
pos++;
|
||||
});
|
||||
words1.sort();
|
||||
|
||||
var newObject = {};
|
||||
_.each(words1, function(word) {
|
||||
//found a valid bind param expression
|
||||
if (self.bindParamRegExp.test(word)) {
|
||||
var match = word.match(self.bindParamRegExp);
|
||||
if (match) {
|
||||
//if property is not available
|
||||
word = word.substr(1, word.length);
|
||||
word = match[1];
|
||||
newObject[word] = '';
|
||||
}
|
||||
});
|
||||
|
@ -28228,6 +28314,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
}
|
||||
|
||||
var counter = 0;
|
||||
|
||||
_.each(this.bindParamTableObj, function(val, key) {
|
||||
$('#arangoBindParamTable tbody').append(
|
||||
"<tr>" +
|
||||
|
@ -28278,12 +28365,30 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
this.aqlEditor = ace.edit("aqlEditor");
|
||||
this.aqlEditor.getSession().setMode("ace/mode/aql");
|
||||
this.aqlEditor.setFontSize("13px");
|
||||
|
||||
this.bindParamAceEditor = ace.edit("bindParamAceEditor");
|
||||
this.bindParamAceEditor.getSession().setMode("ace/mode/json");
|
||||
this.bindParamAceEditor.setFontSize("13px");
|
||||
|
||||
this.bindParamAceEditor.getSession().on('change', function() {
|
||||
try {
|
||||
self.bindParamTableObj = JSON.parse(self.bindParamAceEditor.getValue());
|
||||
self.allowParamToggle = true;
|
||||
}
|
||||
catch (e) {
|
||||
self.allowParamToggle = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.aqlEditor.getSession().on('change', function() {
|
||||
self.checkForNewBindParams();
|
||||
self.renderBindParamTable();
|
||||
if (self.initDone) {
|
||||
self.setCachedQuery(self.aqlEditor.getValue(), JSON.stringify(self.bindParamTableObj));
|
||||
}
|
||||
self.bindParamAceEditor.setValue(JSON.stringify(self.bindParamTableObj, null, "\t"));
|
||||
$('#aqlEditor .ace_text-input').focus();
|
||||
|
||||
self.resize();
|
||||
});
|
||||
|
||||
|
@ -28314,12 +28419,21 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
|
||||
this.aqlEditor.commands.addCommand({
|
||||
name: "explainQuery",
|
||||
bindKey: {win: "Ctrl-Shift-E", mac: "Command-Shift-E", linux: "Ctrl-Shift-E"},
|
||||
bindKey: {win: "Ctrl-Shift-Return", mac: "Command-Shift-Return", linux: "Ctrl-Shift-Return"},
|
||||
exec: function() {
|
||||
self.explainQuery();
|
||||
}
|
||||
});
|
||||
|
||||
this.aqlEditor.commands.addCommand({
|
||||
name: "showSpotlight",
|
||||
bindKey: {win: "Ctrl-Space", mac: "Ctrl-Space", linux: "Ctrl-Space"},
|
||||
exec: function() {
|
||||
|
||||
self.showSpotlight();
|
||||
}
|
||||
});
|
||||
|
||||
this.queryPreview = ace.edit("queryPreview");
|
||||
this.queryPreview.getSession().setMode("ace/mode/aql");
|
||||
this.queryPreview.setReadOnly(true);
|
||||
|
@ -28330,9 +28444,15 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
},
|
||||
|
||||
updateQueryTable: function () {
|
||||
this.myQueriesTableDesc.rows = this.customQueries;
|
||||
var self = this;
|
||||
this.updateLocalQueries();
|
||||
|
||||
this.myQueriesTableDesc.rows = this.customQueries;
|
||||
_.each(this.myQueriesTableDesc.rows, function(k) {
|
||||
k.secondRow = '<div class="truncate">' +
|
||||
JSON.stringify(self.collection.findWhere({name: k.name}).get('value')) +
|
||||
'</div>';
|
||||
|
||||
k.thirdRow = '<span class="spanWrapper">' +
|
||||
'<span id="copyQuery" title="Copy query"><i class="fa fa-copy"></i></span>' +
|
||||
'<span id="explQuery" title="Explain query"><i class="fa fa-comments"></i></i></span>' +
|
||||
|
@ -28345,8 +28465,35 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
delete k.value;
|
||||
});
|
||||
|
||||
function compare(a,b) {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
}
|
||||
else if (a.name > b.name) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.myQueriesTableDesc.rows.sort(compare);
|
||||
|
||||
_.each(this.queries, function(val) {
|
||||
if (val.hasOwnProperty('parameter')) {
|
||||
delete val.parameter;
|
||||
}
|
||||
self.myQueriesTableDesc.rows.push({
|
||||
name: val.name,
|
||||
secondRow: '<div class="truncate">' + val.value + '</div>',
|
||||
thirdRow: '<span class="spanWrapper">' +
|
||||
'<span id="copyQuery" title="Copy query"><i class="fa fa-copy"></i></span></span>'
|
||||
});
|
||||
});
|
||||
|
||||
// escape all columns but the third (which contains HTML)
|
||||
this.myQueriesTableDesc.unescaped = [ false, true ];
|
||||
this.myQueriesTableDesc.unescaped = [ false, true, true ];
|
||||
|
||||
|
||||
this.$(this.myQueriesId).html(this.table.render({content: this.myQueriesTableDesc}));
|
||||
},
|
||||
|
@ -28489,9 +28636,31 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
window.modalView.hide();
|
||||
},
|
||||
|
||||
executeQuery: function () {
|
||||
verifyQueryAndParams: function() {
|
||||
var quit = false;
|
||||
|
||||
if (this.aqlEditor.getValue().length === 0) {
|
||||
arangoHelper.arangoError("Query", "Your query is empty");
|
||||
quit = true;
|
||||
}
|
||||
|
||||
var keys = [];
|
||||
_.each(this.bindParamTableObj, function(val, key) {
|
||||
if (val === '') {
|
||||
quit = true;
|
||||
keys.push(key);
|
||||
}
|
||||
});
|
||||
if (keys.length > 0) {
|
||||
arangoHelper.arangoError("Bind Parameter", JSON.stringify(keys) + " not defined.");
|
||||
}
|
||||
|
||||
return quit;
|
||||
},
|
||||
|
||||
executeQuery: function () {
|
||||
|
||||
if (this.verifyQueryAndParams()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -28509,6 +28678,8 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
sentQueryEditor.getSession().setMode("ace/mode/aql");
|
||||
outputEditor.getSession().setMode("ace/mode/json");
|
||||
outputEditor.setReadOnly(true);
|
||||
outputEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
sentQueryEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
outputEditor.setFontSize("13px");
|
||||
sentQueryEditor.setFontSize("13px");
|
||||
sentQueryEditor.setReadOnly(true);
|
||||
|
@ -28572,10 +28743,9 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
error: function (data) {
|
||||
try {
|
||||
var temp = JSON.parse(data.responseText);
|
||||
outputEditor.setValue('[' + temp.errorNum + '] ' + temp.errorMessage);
|
||||
arangoHelper.arangoError('[' + temp.errorNum + ']', temp.errorMessage);
|
||||
}
|
||||
catch (e) {
|
||||
outputEditor.setValue('ERROR');
|
||||
arangoHelper.arangoError("Query error", "ERROR");
|
||||
}
|
||||
self.handleResult(counter);
|
||||
|
@ -28700,18 +28870,19 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
error.errorMessage.match(/'.*'/g)[0],
|
||||
error.errorMessage.match(/\d+:\d+/g)[0]
|
||||
);
|
||||
arangoHelper.arangoError("Query", error.errorMessage);
|
||||
}
|
||||
else {
|
||||
console.log(resp);
|
||||
self.markPositionError(
|
||||
error.errorMessage.match(/\(\w+\)/g)[0]
|
||||
);
|
||||
}
|
||||
arangoHelper.arangoError("Query", error.errorMessage);
|
||||
self.removeOutputEditor(counter);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
arangoHelper.arangoError("Query", "Something went wrong.");
|
||||
self.removeOutputEditor(counter);
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
window.progressView.hide();
|
||||
|
@ -28722,16 +28893,22 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
},
|
||||
|
||||
markPositionError: function(text, pos) {
|
||||
var row = pos.split(":")[0],
|
||||
line = pos.split(":")[1];
|
||||
var row;
|
||||
|
||||
if (pos) {
|
||||
row = pos.split(":")[0];
|
||||
text = text.substr(1, text.length - 2);
|
||||
}
|
||||
|
||||
this.aqlEditor.find(text);
|
||||
var found = this.aqlEditor.find(text);
|
||||
|
||||
if (!found && pos) {
|
||||
this.aqlEditor.selection.moveCursorToPosition({row: row, column: 0});
|
||||
this.aqlEditor.selection.selectLine();
|
||||
}
|
||||
window.setTimeout(function() {
|
||||
$('.ace_start').first().css('background', 'rgba(255, 129, 129, 0.7)');
|
||||
}, 100);
|
||||
|
||||
},
|
||||
|
||||
refreshAQL: function() {
|
||||
|
@ -28966,6 +29143,199 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
});
|
||||
}());
|
||||
|
||||
/*jshint browser: true */
|
||||
/*jshint unused: false */
|
||||
/*global Backbone, $, window, setTimeout, Joi, _ */
|
||||
/*global templateEngine*/
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
window.SpotlightView = Backbone.View.extend({
|
||||
|
||||
template: templateEngine.createTemplate("spotlightView.ejs"),
|
||||
|
||||
el: "#spotlightPlaceholder",
|
||||
|
||||
displayLimit: 8,
|
||||
typeahead: null,
|
||||
callbackSuccess: null,
|
||||
callbackCancel: null,
|
||||
|
||||
collections: {
|
||||
system: [],
|
||||
doc: [],
|
||||
edge: [],
|
||||
},
|
||||
|
||||
events: {
|
||||
"focusout #spotlight .tt-input" : "hide",
|
||||
"keyup #spotlight .typeahead" : "listenKey"
|
||||
},
|
||||
|
||||
aqlKeywords:
|
||||
"for|return|filter|sort|limit|let|collect|asc|desc|in|into|" +
|
||||
"insert|update|remove|replace|upsert|options|with|and|or|not|" +
|
||||
"distinct|graph|outbound|inbound|any|all|none|aggregate",
|
||||
|
||||
aqlBuiltinFunctions:
|
||||
"to_bool|to_number|to_string|to_list|is_null|is_bool|is_number|is_string|is_list|is_document|" +
|
||||
"concat|concat_separator|char_length|lower|upper|substring|left|right|trim|reverse|contains|" +
|
||||
"like|floor|ceil|round|abs|rand|sqrt|pow|length|min|max|average|sum|median|variance_population|" +
|
||||
"variance_sample|first|last|unique|matches|merge|merge_recursive|has|attributes|values|unset|unset_recursive|keep|" +
|
||||
"near|within|within_rectangle|is_in_polygon|fulltext|paths|traversal|traversal_tree|edges|stddev_sample|" +
|
||||
"stddev_population|slice|nth|position|translate|zip|call|apply|push|append|pop|shift|unshift|remove_value" +
|
||||
"remove_nth|graph_paths|shortest_path|graph_shortest_path|graph_distance_to|graph_traversal|graph_traversal_tree|" +
|
||||
"graph_edges|graph_vertices|neighbors|graph_neighbors|graph_common_neighbors|graph_common_properties|" +
|
||||
"graph_eccentricity|graph_betweenness|graph_closeness|graph_absolute_eccentricity|remove_values|" +
|
||||
"graph_absolute_betweenness|graph_absolute_closeness|graph_diameter|graph_radius|date_now|" +
|
||||
"date_timestamp|date_iso8601|date_dayofweek|date_year|date_month|date_day|date_hour|" +
|
||||
"date_minute|date_second|date_millisecond|date_dayofyear|date_isoweek|date_leapyear|date_quarter|date_days_in_month|" +
|
||||
"date_add|date_subtract|date_diff|date_compare|date_format|fail|passthru|sleep|not_null|" +
|
||||
"first_list|first_document|parse_identifier|current_user|current_database|" +
|
||||
"collections|document|union|union_distinct|intersection|flatten|" +
|
||||
"ltrim|rtrim|find_first|find_last|split|substitute|md5|sha1|random_token|AQL_LAST_ENTRY",
|
||||
|
||||
listenKey: function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
if (this.callbackSuccess) {
|
||||
this.callbackCancel();
|
||||
}
|
||||
this.hide();
|
||||
}
|
||||
else if (e.keyCode === 13) {
|
||||
if (this.callbackSuccess) {
|
||||
this.callbackSuccess($(this.typeahead).val());
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
substringMatcher: function(strs) {
|
||||
return function findMatches(q, cb) {
|
||||
var matches, substrRegex;
|
||||
|
||||
matches = [];
|
||||
|
||||
substrRegex = new RegExp(q, 'i');
|
||||
|
||||
_.each(strs, function(str) {
|
||||
if (substrRegex.test(str)) {
|
||||
matches.push(str);
|
||||
}
|
||||
});
|
||||
|
||||
cb(matches);
|
||||
};
|
||||
},
|
||||
|
||||
updateDatasets: function() {
|
||||
var self = this;
|
||||
this.collections = {
|
||||
system: [],
|
||||
doc: [],
|
||||
edge: [],
|
||||
};
|
||||
|
||||
window.App.arangoCollectionsStore.each(function(collection) {
|
||||
if (collection.get("isSystem")) {
|
||||
self.collections.system.push(collection.get("name"));
|
||||
}
|
||||
else if (collection.get("type") === 'document') {
|
||||
self.collections.doc.push(collection.get("name"));
|
||||
}
|
||||
else {
|
||||
self.collections.edge.push(collection.get("name"));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
stringToArray: function() {
|
||||
this.aqlKeywordsArray = this.aqlKeywords.split('|');
|
||||
this.aqlBuiltinFunctionsArray = this.aqlBuiltinFunctions.split('|');
|
||||
},
|
||||
|
||||
show: function(callbackSuccess, callbackCancel) {
|
||||
|
||||
this.callbackSuccess = callbackSuccess;
|
||||
this.callbackCancel = callbackCancel;
|
||||
this.stringToArray();
|
||||
this.updateDatasets();
|
||||
|
||||
var genHeader = function(name, icon, type) {
|
||||
var string = '<div class="header-type"><h4>' + name + '</h4>';
|
||||
if (icon) {
|
||||
string += '<span><i class="fa ' + icon + '"></i></span>';
|
||||
}
|
||||
if (type) {
|
||||
string += '<span class="type">' + type.toUpperCase() + '</span>';
|
||||
}
|
||||
string += '</div>';
|
||||
|
||||
return string;
|
||||
};
|
||||
|
||||
$(this.el).html(this.template.render({}));
|
||||
$(this.el).show();
|
||||
|
||||
this.typeahead = $('#spotlight .typeahead').typeahead(
|
||||
{
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
},
|
||||
{
|
||||
name: 'Functions',
|
||||
source: this.substringMatcher(this.aqlBuiltinFunctionsArray),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Functions", "fa-code", "aql")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Keywords',
|
||||
source: this.substringMatcher(this.aqlKeywordsArray),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Keywords", "fa-code", "aql")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Documents',
|
||||
source: this.substringMatcher(this.collections.doc),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Documents", "fa-file-text-o", "Collection")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Edges',
|
||||
source: this.substringMatcher(this.collections.edge),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Edges", "fa-share-alt", "Collection")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'System',
|
||||
limit: this.displayLimit,
|
||||
source: this.substringMatcher(this.collections.system),
|
||||
templates: {
|
||||
header: genHeader("System", "fa-cogs", "Collection")
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('#spotlight .typeahead').focus();
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
$(this.el).hide();
|
||||
}
|
||||
|
||||
});
|
||||
}());
|
||||
|
||||
/*jshint browser: true */
|
||||
/*jshint unused: false */
|
||||
/*global Backbone, templateEngine, $, window*/
|
||||
|
@ -30662,8 +31032,8 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
"collection/:colid/documents/:pageid": "documents",
|
||||
"collection/:colid/:docid": "document",
|
||||
"shell": "shell",
|
||||
"query": "query",
|
||||
"query2": "query2",
|
||||
"query": "query2",
|
||||
"query2": "query",
|
||||
"queryManagement": "queryManagement",
|
||||
"workMonitor": "workMonitor",
|
||||
"databases": "databases",
|
||||
|
@ -30727,6 +31097,7 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
collection: this.foxxList
|
||||
});
|
||||
window.progressView = new window.ProgressView();
|
||||
|
||||
var self = this;
|
||||
|
||||
this.userCollection = new window.ArangoUsers();
|
||||
|
@ -30743,6 +31114,10 @@ window.ArangoUsers = Backbone.Collection.extend({
|
|||
|
||||
this.arangoCollectionsStore.fetch();
|
||||
|
||||
window.spotlightView = new window.SpotlightView({
|
||||
collection: this.arangoCollectionsStore
|
||||
});
|
||||
|
||||
this.footerView = new window.FooterView();
|
||||
this.notificationList = new window.NotificationCollection();
|
||||
|
||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -1,3 +1,3 @@
|
|||
<script src="sharedLibs.js?version=1456340072524"></script>
|
||||
<script src="libs.js?version=1456340072524"></script>
|
||||
<script src="app.js?version=1456340072524"></script>
|
||||
<script src="sharedLibs.js?version=1456760585446"></script>
|
||||
<script src="libs.js?version=1456760585446"></script>
|
||||
<script src="app.js?version=1456760585446"></script>
|
||||
|
|
|
@ -2498,6 +2498,7 @@ if (list.length > 0) {
|
|||
</div>
|
||||
|
||||
<div class="pull-right">
|
||||
<span id="querySpotlight"><i class="fa fa-search"></i></span>
|
||||
<div class="styled-select">
|
||||
<select id="querySize" class="query-size"/>
|
||||
</div>
|
||||
|
@ -2510,14 +2511,19 @@ if (list.length > 0) {
|
|||
<div id="aqlEditor"></div>
|
||||
<div id="queryTable" style="display: none"></div>
|
||||
</div>
|
||||
|
||||
<div class="bindParamEditorWrapper" class="arangoEditor">
|
||||
<span id="switchTypes" class="aceAction type">JSON</span>
|
||||
<div id="bindParamEditor"></div>
|
||||
<div id="bindParamAceEditor" style="display: none"></div>
|
||||
|
||||
<div id="previewWrapper" class="previewWrapper" style="display: none">
|
||||
<div id="previewBar" class="previewBar">
|
||||
<span>Preview</span>
|
||||
</div>
|
||||
<div id="queryPreview"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2606,6 +2612,10 @@ if (list.length > 0) {
|
|||
<div id="shell_workspace_header"/>
|
||||
<div id="shell_workspace" class="shell_workspace">
|
||||
<div id="replShell" class="replShell"/>
|
||||
</div></script><script id="spotlightView.ejs" type="text/template"><div class="spotlightWrapper">
|
||||
<div id="spotlight">
|
||||
<input class="typeahead" type="text" placeholder="Search... ">
|
||||
</div>
|
||||
</div></script><script id="statisticBarView.ejs" type="text/template"><div class="navlogo display-none">
|
||||
<a href="#dashboard" style="padding-left: 15px;">
|
||||
<img class="svg stat_cpu"
|
||||
|
@ -2669,7 +2679,7 @@ var cutByResolution = function (str) {
|
|||
</td>
|
||||
<td class="docsThirdCol">
|
||||
<a class="deleteButton">
|
||||
<span class="icon_arangodb_roundminus" data-original-title="Delete document" title="Delete document"></span></a>
|
||||
<span data-original-title="Delete document" title="Delete document"><i class="fa fa-minus-circle"></i></i></span></a>
|
||||
</td>
|
||||
</tr>
|
||||
<%
|
||||
|
@ -2832,4 +2842,4 @@ var cutByResolution = function (str) {
|
|||
</div>
|
||||
|
||||
<div id="workMonitorContent" class="innerContent">
|
||||
</div></script></head><body><nav class="navbar"><div class="resizecontainer"><div class="navlogo"><a class="logo" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a></div><div id="progressPlaceholderIcon"></div><div class="statmenu" id="statisticBar"></div><div class="usermenu" id="userBar" style="float:right"></div><div class="notificationmenu" id="notificationBar" style="float:right"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="centralRow resizecontainer"><div id="content" class="centralContent"></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><footer class="footer"><div class="resizecontainer" id="footerBar"></div></footer><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js?version=1456340072524"></script><script src="libs.js?version=1456340072524"></script><script src="app.js?version=1456340072524"></script></body></html>
|
||||
</div></script></head><body><nav class="navbar"><div class="resizecontainer"><div class="navlogo"><a class="logo" href="#"><img class="arangodbLogo" src="img/arangodb_logo_small.png"></a></div><div id="progressPlaceholderIcon"></div><div class="statmenu" id="statisticBar"></div><div class="usermenu" id="userBar" style="float:right"></div><div class="notificationmenu" id="notificationBar" style="float:right"></div><div class="navmenu" id="navigationBar"></div></div></nav><div class="centralRow resizecontainer"><div id="content" class="centralContent"></div></div><div id="modalPlaceholder"></div><div id="progressPlaceholder" style="display:none"></div><div id="spotlightPlaceholder" style="display:none"></div><footer class="footer"><div class="resizecontainer" id="footerBar"></div></footer><div class="arangoFrame" style=""><div class="outerDiv"><div class="innerDiv"></div></div></div><script src="sharedLibs.js?version=1456760585446"></script><script src="libs.js?version=1456760585446"></script><script src="app.js?version=1456760585446"></script></body></html>
|
Binary file not shown.
|
@ -2690,6 +2690,7 @@ if (list.length > 0) {
|
|||
</div>
|
||||
|
||||
<div class="pull-right">
|
||||
<span id="querySpotlight"><i class="fa fa-search"></i></span>
|
||||
<div class="styled-select">
|
||||
<select id="querySize" class="query-size"/>
|
||||
</div>
|
||||
|
@ -2702,14 +2703,19 @@ if (list.length > 0) {
|
|||
<div id="aqlEditor"></div>
|
||||
<div id="queryTable" style="display: none"></div>
|
||||
</div>
|
||||
|
||||
<div class="bindParamEditorWrapper" class="arangoEditor">
|
||||
<span id="switchTypes" class="aceAction type">JSON</span>
|
||||
<div id="bindParamEditor"></div>
|
||||
<div id="bindParamAceEditor" style="display: none"></div>
|
||||
|
||||
<div id="previewWrapper" class="previewWrapper" style="display: none">
|
||||
<div id="previewBar" class="previewBar">
|
||||
<span>Preview</span>
|
||||
</div>
|
||||
<div id="queryPreview"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2812,6 +2818,14 @@ if (list.length > 0) {
|
|||
</div>
|
||||
</script>
|
||||
|
||||
<script id="spotlightView.ejs" type="text/template">
|
||||
<div class="spotlightWrapper">
|
||||
<div id="spotlight">
|
||||
<input class="typeahead" type="text" placeholder="Search... ">
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="statisticBarView.ejs" type="text/template">
|
||||
<div class="navlogo display-none">
|
||||
<a href="#dashboard" style="padding-left: 15px;">
|
||||
|
@ -2880,7 +2894,7 @@ var cutByResolution = function (str) {
|
|||
</td>
|
||||
<td class="docsThirdCol">
|
||||
<a class="deleteButton">
|
||||
<span class="icon_arangodb_roundminus" data-original-title="Delete document" title="Delete document"></span></a>
|
||||
<span data-original-title="Delete document" title="Delete document"><i class="fa fa-minus-circle"></i></i></span></a>
|
||||
</td>
|
||||
</tr>
|
||||
<%
|
||||
|
@ -3096,6 +3110,9 @@ var cutByResolution = function (str) {
|
|||
<div id="progressPlaceholder" style="display:none">
|
||||
</div>
|
||||
|
||||
<div id="spotlightPlaceholder" style="display:none">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
|
@ -3109,9 +3126,9 @@ var cutByResolution = function (str) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script src="sharedLibs.js?version=1456340072524"></script>
|
||||
<script src="libs.js?version=1456340072524"></script>
|
||||
<script src="app.js?version=1456340072524"></script>
|
||||
<script src="sharedLibs.js?version=1456760585446"></script>
|
||||
<script src="libs.js?version=1456760585446"></script>
|
||||
<script src="app.js?version=1456760585446"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -2087,7 +2087,7 @@ textarea,
|
|||
height: 0;
|
||||
visibility: hidden; }
|
||||
|
||||
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .fixedDropdown .notificationItem i, .fullNotification:hover, .contentTables tr.contentRowInactive a, .arango-tab a, .arango-tab li, .pagination-line li a, .link > line, .node, .edit-index-table .icon_arangodb_roundminus {
|
||||
.script-dropdown-menu .dropdown-item, .addButton, .deleteButton i, a.headerButton, a.button-gui, div.toolbox div.gv_action_button, .clusterDownBtn button, div .tile a span.icon, div .bigtile a span.icon, div .tile a svg, div .bigtile a svg, div .tile .iconSet span, div .bigtile .iconSet span, div .bigtile, .contentDiv .icon, .icon-info-sign, .arangoicon, div.headerDropdown.headerDropdown input[type=checkbox].css-checkbox label.css-label, .search-submit-icon, .gv-search-submit-icon, .fixedDropdown .notificationItem i, .fullNotification:hover, .contentTables tr.contentRowInactive a, .arango-tab a, .arango-tab li, .pagination-line li a, .link > line, .node, .edit-index-table .icon_arangodb_roundminus {
|
||||
cursor: pointer; }
|
||||
|
||||
.navbar, footer.footer {
|
||||
|
@ -2106,12 +2106,12 @@ textarea,
|
|||
.button-danger:focus, .ajax-file-upload-red:focus {
|
||||
background-color: #be342e; }
|
||||
|
||||
.deleteButton, .contentTables td span, .edit-index-table .icon_arangodb_roundminus {
|
||||
.deleteButton i, .contentTables td span, .edit-index-table .icon_arangodb_roundminus {
|
||||
color: #da4f49; }
|
||||
.deleteButton:hover,
|
||||
.deleteButton i:hover,
|
||||
.contentTables td span:hover,
|
||||
.edit-index-table .icon_arangodb_roundminus:hover,
|
||||
.deleteButton:focus, .contentTables td span:focus, .edit-index-table .icon_arangodb_roundminus:focus {
|
||||
.deleteButton i:focus, .contentTables td span:focus, .edit-index-table .icon_arangodb_roundminus:focus {
|
||||
color: #be342e; }
|
||||
|
||||
.button-success, .ajax-file-upload {
|
||||
|
@ -2589,13 +2589,13 @@ button.disabled,
|
|||
cursor: not-allowed; }
|
||||
|
||||
.addButton {
|
||||
font-size: 22px;
|
||||
font-size: 16pt;
|
||||
margin-right: 7px;
|
||||
margin-top: 2px;
|
||||
position: relative; }
|
||||
|
||||
.deleteButton {
|
||||
font-size: 22px;
|
||||
.deleteButton i {
|
||||
font-size: 16pt;
|
||||
padding-right: 3px;
|
||||
position: relative;
|
||||
top: 3px; }
|
||||
|
@ -6043,9 +6043,14 @@ div.headerBar {
|
|||
width: 10%; }
|
||||
|
||||
.arangoToolbar span {
|
||||
padding: 1px 4px 3px;
|
||||
padding: 5px 8px;
|
||||
position: relative;
|
||||
top: 4px; }
|
||||
top: 5px; }
|
||||
.arangoToolbar span:hover {
|
||||
background-color: #8aa051;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
cursor: pointer; }
|
||||
|
||||
.arangoToolbar {
|
||||
background-color: #fff;
|
||||
|
@ -6065,6 +6070,8 @@ div.headerBar {
|
|||
font-weight: 100;
|
||||
margin-left: 10px; }
|
||||
.arangoToolbar i {
|
||||
cursor: pointer;
|
||||
font-size: 11pt;
|
||||
font-style: normal; }
|
||||
.arangoToolbar i.fa {
|
||||
margin-right: 5px; }
|
||||
|
@ -6780,7 +6787,6 @@ toolbar {
|
|||
min-height: 300px;
|
||||
width: 100%; }
|
||||
.inputEditorWrapper .aqlEditorWrapper {
|
||||
background: #f6f6f6;
|
||||
border: 0 !important;
|
||||
border-right: 3px solid rgba(140, 138, 137, 0.25) !important;
|
||||
float: left;
|
||||
|
@ -6792,23 +6798,22 @@ toolbar {
|
|||
cursor: copy; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper,
|
||||
.inputEditorWrapper .aqlEditorWrapper {
|
||||
background: #eee;
|
||||
overflow: hidden; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper .stringtype,
|
||||
.inputEditorWrapper .aqlEditorWrapper .stringtype {
|
||||
color: black; }
|
||||
color: #ce2f30; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper .objecttype,
|
||||
.inputEditorWrapper .aqlEditorWrapper .objecttype {
|
||||
color: blue; }
|
||||
color: #00f; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper .arraytype,
|
||||
.inputEditorWrapper .aqlEditorWrapper .arraytype {
|
||||
color: green; }
|
||||
color: #00f; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper .numbertype,
|
||||
.inputEditorWrapper .aqlEditorWrapper .numbertype {
|
||||
color: red; }
|
||||
color: #044; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper .booleantype,
|
||||
.inputEditorWrapper .aqlEditorWrapper .booleantype {
|
||||
color: lightgreen; }
|
||||
color: #c12dad; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper table,
|
||||
.inputEditorWrapper .aqlEditorWrapper table {
|
||||
border-top: 0;
|
||||
|
@ -6817,6 +6822,13 @@ toolbar {
|
|||
.inputEditorWrapper .aqlEditorWrapper table tbody {
|
||||
display: block;
|
||||
overflow-y: auto; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper table .truncate,
|
||||
.inputEditorWrapper .aqlEditorWrapper table .truncate {
|
||||
opacity: .8;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 30%; }
|
||||
.inputEditorWrapper .bindParamEditorWrapper table tr.noBgColor,
|
||||
.inputEditorWrapper .aqlEditorWrapper table tr.noBgColor {
|
||||
background-color: transparent !important; }
|
||||
|
@ -6872,7 +6884,7 @@ toolbar {
|
|||
.inputEditorWrapper .bindParamEditorWrapper table th,
|
||||
.inputEditorWrapper .aqlEditorWrapper table th {
|
||||
font: 13px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
height: 17px;
|
||||
height: 34px;
|
||||
padding: 0;
|
||||
width: 50%; }
|
||||
.inputEditorWrapper .aqlEditorWrapper,
|
||||
|
@ -6883,18 +6895,23 @@ toolbar {
|
|||
background: #da4f49; }
|
||||
.inputEditorWrapper .aqlEditorWrapper .aceAction,
|
||||
.inputEditorWrapper .bindParamEditorWrapper .aceAction {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
background-color: #858585;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
font-size: 13pt;
|
||||
height: 23px;
|
||||
line-height: 22px;
|
||||
opacity: .8;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
right: 5px;
|
||||
text-align: center;
|
||||
top: 10px;
|
||||
top: 5px;
|
||||
width: 33px;
|
||||
z-index: 10; }
|
||||
.inputEditorWrapper .aqlEditorWrapper .aceAction.type,
|
||||
.inputEditorWrapper .bindParamEditorWrapper .aceAction.type {
|
||||
font-size: 8pt; }
|
||||
.inputEditorWrapper .aqlEditorWrapper .aceAction i,
|
||||
.inputEditorWrapper .bindParamEditorWrapper .aceAction i {
|
||||
margin-bottom: 3px; }
|
||||
|
@ -6910,10 +6927,12 @@ toolbar {
|
|||
background-color: #fff;
|
||||
border-bottom: 1px solid rgba(140, 138, 137, 0.25);
|
||||
font: 13px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
height: 17px; }
|
||||
height: 34px; }
|
||||
.inputEditorWrapper .aqlEditorWrapper .previewWrapper .previewBar span,
|
||||
.inputEditorWrapper .bindParamEditorWrapper .previewWrapper .previewBar span {
|
||||
margin-left: 5px; }
|
||||
margin-left: 5px;
|
||||
padding-top: 8px;
|
||||
position: absolute; }
|
||||
.inputEditorWrapper .aqlEditorWrapper .previewWrapper #queryPreview,
|
||||
.inputEditorWrapper .bindParamEditorWrapper .previewWrapper #queryPreview {
|
||||
height: 100%; }
|
||||
|
@ -6944,7 +6963,7 @@ toolbar {
|
|||
color: #fff;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
right: -27px;
|
||||
right: -24px;
|
||||
top: 45px;
|
||||
z-index: 10; }
|
||||
.outputEditorWrapper .ace_editor {
|
||||
|
@ -7859,6 +7878,82 @@ input.gv-radio-button {
|
|||
left: 5px;
|
||||
top: 20px; } }
|
||||
|
||||
#spotlightPlaceholder {
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 2000; }
|
||||
|
||||
.spotlightWrapper {
|
||||
height: 50px;
|
||||
left: 25%;
|
||||
position: absolute;
|
||||
top: 115px;
|
||||
width: 50%; }
|
||||
.spotlightWrapper .twitter-typeahead {
|
||||
width: 100%; }
|
||||
.spotlightWrapper .tt-highlight {
|
||||
color: #5bc0de;
|
||||
font-weight: 400; }
|
||||
.spotlightWrapper input {
|
||||
box-sizing: border-box;
|
||||
height: 40px !important; }
|
||||
.spotlightWrapper .tt-dataset {
|
||||
clear: both; }
|
||||
.spotlightWrapper .tt-menu {
|
||||
background: #3d4246;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
width: 100%; }
|
||||
.spotlightWrapper .tt-menu .header-type {
|
||||
background: #32373b;
|
||||
clear: both;
|
||||
color: #fff;
|
||||
height: 30px;
|
||||
padding-left: 5px; }
|
||||
.spotlightWrapper .tt-menu .header-type h4 {
|
||||
float: left;
|
||||
margin: 4px 0 0;
|
||||
padding: 0; }
|
||||
.spotlightWrapper .tt-menu .header-type .fa {
|
||||
font-size: 12pt;
|
||||
margin-left: 6px;
|
||||
margin-top: 6px; }
|
||||
.spotlightWrapper .tt-menu .header-type .type {
|
||||
background-color: #5bc0de;
|
||||
border-radius: 3px;
|
||||
float: right;
|
||||
margin: 4px;
|
||||
padding: 0 5px; }
|
||||
.spotlightWrapper .tt-menu .tt-cursor {
|
||||
background-color: #fff;
|
||||
color: #000; }
|
||||
.spotlightWrapper .tt-menu .tt-selectable {
|
||||
padding-left: 10px; }
|
||||
.spotlightWrapper .typeahead {
|
||||
background: #3d4246;
|
||||
background-color: #3d4246;
|
||||
border: 0 solid #3d4246;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
font-size: 22px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
outline: none;
|
||||
outline-color: transparent;
|
||||
outline-style: none;
|
||||
padding: 8px 12px;
|
||||
width: 100%; }
|
||||
.spotlightWrapper .typeahead:focus {
|
||||
outline: none;
|
||||
outline-color: transparent;
|
||||
outline-style: none; }
|
||||
|
||||
.application-detail-view section.info {
|
||||
float: left;
|
||||
padding: 13px 0 0; }
|
||||
|
|
Binary file not shown.
|
@ -27,6 +27,9 @@
|
|||
<div id="progressPlaceholder" style="display:none">
|
||||
</div>
|
||||
|
||||
<div id="spotlightPlaceholder" style="display:none">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
|
|
|
@ -257,6 +257,11 @@
|
|||
window.App.notificationList.add({title:title, content: content, info: info, type: 'error'});
|
||||
},
|
||||
|
||||
hideArangoNotifications: function() {
|
||||
$.noty.clearQueue();
|
||||
$.noty.closeAll();
|
||||
},
|
||||
|
||||
openDocEditor: function (id, type, callback) {
|
||||
var ids = id.split("/"),
|
||||
self = this;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -15,8 +15,8 @@
|
|||
"collection/:colid/documents/:pageid": "documents",
|
||||
"collection/:colid/:docid": "document",
|
||||
"shell": "shell",
|
||||
"query": "query",
|
||||
"query2": "query2",
|
||||
"query": "query2",
|
||||
"query2": "query",
|
||||
"queryManagement": "queryManagement",
|
||||
"workMonitor": "workMonitor",
|
||||
"databases": "databases",
|
||||
|
@ -80,6 +80,7 @@
|
|||
collection: this.foxxList
|
||||
});
|
||||
window.progressView = new window.ProgressView();
|
||||
|
||||
var self = this;
|
||||
|
||||
this.userCollection = new window.ArangoUsers();
|
||||
|
@ -96,6 +97,10 @@
|
|||
|
||||
this.arangoCollectionsStore.fetch();
|
||||
|
||||
window.spotlightView = new window.SpotlightView({
|
||||
collection: this.arangoCollectionsStore
|
||||
});
|
||||
|
||||
this.footerView = new window.FooterView();
|
||||
this.notificationList = new window.NotificationCollection();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
</div>
|
||||
|
||||
<div class="pull-right">
|
||||
<span id="querySpotlight"><i class="fa fa-search"></i></span>
|
||||
<div class="styled-select">
|
||||
<select id="querySize" class="query-size"/>
|
||||
</div>
|
||||
|
@ -27,14 +28,19 @@
|
|||
<div id="aqlEditor"></div>
|
||||
<div id="queryTable" style="display: none"></div>
|
||||
</div>
|
||||
|
||||
<div class="bindParamEditorWrapper" class="arangoEditor">
|
||||
<span id="switchTypes" class="aceAction type">JSON</span>
|
||||
<div id="bindParamEditor"></div>
|
||||
<div id="bindParamAceEditor" style="display: none"></div>
|
||||
|
||||
<div id="previewWrapper" class="previewWrapper" style="display: none">
|
||||
<div id="previewBar" class="previewBar">
|
||||
<span>Preview</span>
|
||||
</div>
|
||||
<div id="queryPreview"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<script id="spotlightView.ejs" type="text/template">
|
||||
<div class="spotlightWrapper">
|
||||
<div id="spotlight">
|
||||
<input class="typeahead" type="text" placeholder="Search... ">
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
|
@ -48,7 +48,7 @@ var cutByResolution = function (str) {
|
|||
</td>
|
||||
<td class="docsThirdCol">
|
||||
<a class="deleteButton">
|
||||
<span class="icon_arangodb_roundminus" data-original-title="Delete document" title="Delete document"></span></a>
|
||||
<span data-original-title="Delete document" title="Delete document"><i class="fa fa-minus-circle"></i></i></span></a>
|
||||
</td>
|
||||
</tr>
|
||||
<%
|
||||
|
|
|
@ -143,6 +143,7 @@
|
|||
$('.' + menuItem).addClass('active');
|
||||
}
|
||||
}
|
||||
arangoHelper.hideArangoNotifications();
|
||||
},
|
||||
|
||||
showDropdown: function (e) {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
currentQuery: {},
|
||||
initDone: false,
|
||||
|
||||
bindParamRegExp: /@(@?)(\w+(\d*))/,
|
||||
bindParamRegExp: /@(@?\w+\d*)/,
|
||||
bindParamTableObj: {},
|
||||
|
||||
bindParamTableDesc: {
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
myQueriesTableDesc: {
|
||||
id: "arangoMyQueriesTable",
|
||||
titles: ["Name", "Actions"],
|
||||
titles: ["Name", "Query", "Actions"],
|
||||
rows: []
|
||||
},
|
||||
|
||||
|
@ -48,6 +48,8 @@
|
|||
this.refreshAQL();
|
||||
},
|
||||
|
||||
allowParamToggle: true,
|
||||
|
||||
events: {
|
||||
"click #executeQuery": "executeQuery",
|
||||
"click #explainQuery": "explainQuery",
|
||||
|
@ -61,6 +63,7 @@
|
|||
"click #exportQuery": "exportCustomQueries",
|
||||
"click #importQuery": "openImportDialog",
|
||||
"click #removeResults": "removeResults",
|
||||
"click #querySpotlight": "showSpotlight",
|
||||
"click #deleteQuery": "selectAndDeleteQueryFromTable",
|
||||
"click #explQuery": "selectAndExplainQueryFromTable",
|
||||
"keyup #arangoBindParamTable input": "updateBindParams",
|
||||
|
@ -70,6 +73,7 @@
|
|||
"click #arangoMyQueriesTable #copyQuery" : "selectQueryFromTable",
|
||||
'click #closeQueryModal': 'closeExportDialog',
|
||||
'click #confirmQueryImport': 'importCustomQueries',
|
||||
'click #switchTypes': 'toggleBindParams',
|
||||
"click #arangoMyQueriesTable #runQuery" : "selectAndRunQueryFromTable"
|
||||
},
|
||||
|
||||
|
@ -77,6 +81,38 @@
|
|||
this.aqlEditor.setValue('');
|
||||
},
|
||||
|
||||
toggleBindParams: function() {
|
||||
|
||||
if (this.allowParamToggle) {
|
||||
$('#bindParamEditor').toggle();
|
||||
$('#bindParamAceEditor').toggle();
|
||||
|
||||
if ($('#switchTypes').text() === 'JSON') {
|
||||
$('#switchTypes').text('Table');
|
||||
this.updateQueryTable();
|
||||
this.bindParamAceEditor.setValue(JSON.stringify(this.bindParamTableObj, null, "\t"));
|
||||
this.deselect(this.bindParamAceEditor);
|
||||
}
|
||||
else {
|
||||
$('#switchTypes').text('JSON');
|
||||
this.renderBindParamTable();
|
||||
}
|
||||
}
|
||||
else {
|
||||
arangoHelper.arangoError("Bind parameter", "Could not parse bind parameter");
|
||||
}
|
||||
this.resize();
|
||||
|
||||
},
|
||||
|
||||
openExportDialog: function() {
|
||||
$('#queryImportDialog').modal('show');
|
||||
},
|
||||
|
||||
closeExportDialo: function() {
|
||||
$('#queryImportDialog').modal('hide');
|
||||
},
|
||||
|
||||
initQueryImport: function () {
|
||||
var self = this;
|
||||
self.allowUpload = false;
|
||||
|
@ -125,9 +161,22 @@
|
|||
},
|
||||
|
||||
getCustomQueryValueByName: function (qName) {
|
||||
var obj;
|
||||
|
||||
if (qName) {
|
||||
return this.collection.findWhere({name: qName}).get("value");
|
||||
obj = this.collection.findWhere({name: qName});
|
||||
}
|
||||
if (obj) {
|
||||
obj = obj.get("value");
|
||||
}
|
||||
else {
|
||||
_.each(this.queries, function(query) {
|
||||
if (query.name === qName) {
|
||||
obj = query.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
openImportDialog: function() {
|
||||
|
@ -156,13 +205,16 @@
|
|||
if (e) {
|
||||
if (e.currentTarget.id === "toggleQueries1") {
|
||||
this.updateQueryTable();
|
||||
$('#bindParamAceEditor').hide();
|
||||
$('#bindParamEditor').show();
|
||||
$('#switchTypes').text('JSON');
|
||||
}
|
||||
}
|
||||
|
||||
var divs = [
|
||||
"aqlEditor", "queryTable", "previewWrapper",
|
||||
"aqlEditor", "queryTable", "previewWrapper", "querySpotlight",
|
||||
"bindParamEditor", "toggleQueries1", "toggleQueries2",
|
||||
"saveCurrentQuery", "querySize", "executeQuery",
|
||||
"saveCurrentQuery", "querySize", "executeQuery", "switchTypes",
|
||||
"explainQuery", "clearQuery", "importQuery", "exportQuery"
|
||||
];
|
||||
_.each(divs, function(div) {
|
||||
|
@ -186,7 +238,7 @@
|
|||
name = $(e.currentTarget).children().first().text();
|
||||
}
|
||||
else if ($(e.currentTarget).is('span')) {
|
||||
name = $(e.currentTarget).parent().parent().prev().text();
|
||||
name = $(e.currentTarget).parent().parent().prev().prev().text();
|
||||
}
|
||||
return name;
|
||||
},
|
||||
|
@ -313,8 +365,8 @@
|
|||
},
|
||||
|
||||
explainQuery: function() {
|
||||
if (this.aqlEditor.getValue().length === 0) {
|
||||
arangoHelper.arangoError("Query", "Your query is empty");
|
||||
|
||||
if (this.verifyQueryAndParams()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -328,6 +380,8 @@
|
|||
sentQueryEditor = ace.edit("sentQueryEditor" + counter);
|
||||
sentQueryEditor.getSession().setMode("ace/mode/aql");
|
||||
outputEditor.getSession().setMode("ace/mode/json");
|
||||
outputEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
sentQueryEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
outputEditor.setReadOnly(true);
|
||||
sentQueryEditor.setReadOnly(true);
|
||||
|
||||
|
@ -358,6 +412,7 @@
|
|||
if (data.msg.includes('errorMessage')) {
|
||||
self.removeOutputEditor(counter);
|
||||
arangoHelper.arangoError("Explain error", data.msg);
|
||||
window.progressView.hide();
|
||||
}
|
||||
else {
|
||||
outputEditor.setValue(data.msg);
|
||||
|
@ -368,7 +423,6 @@
|
|||
}
|
||||
},
|
||||
error: function (data) {
|
||||
window.progressView.hide();
|
||||
try {
|
||||
var temp = JSON.parse(data.responseText);
|
||||
arangoHelper.arangoError("Explain error", temp.errorMessage);
|
||||
|
@ -376,6 +430,7 @@
|
|||
catch (e) {
|
||||
arangoHelper.arangoError("Explain error", "ERROR");
|
||||
}
|
||||
window.progressView.hide();
|
||||
self.handleResult(counter);
|
||||
this.removeOutputEditor(counter);
|
||||
}
|
||||
|
@ -386,6 +441,9 @@
|
|||
removeOutputEditor: function(counter) {
|
||||
$('#outputEditorWrapper' + counter).hide();
|
||||
$('#outputEditorWrapper' + counter).remove();
|
||||
if ($('.outputEditorWrapper').length === 0) {
|
||||
$('#removeResults').hide();
|
||||
}
|
||||
},
|
||||
|
||||
getCachedQueryAfterRender: function() {
|
||||
|
@ -473,13 +531,27 @@
|
|||
this.initQueryImport();
|
||||
|
||||
//set height of editor wrapper
|
||||
$('.inputEditorWrapper').height($(window).height() / 10 * 3);
|
||||
$('.inputEditorWrapper').height($(window).height() / 10 * 5 + 25);
|
||||
window.setTimeout(function() {
|
||||
self.resize();
|
||||
}, 10);
|
||||
self.deselect(self.aqlEditor);
|
||||
},
|
||||
|
||||
showSpotlight: function() {
|
||||
|
||||
var callback = function(string) {
|
||||
this.aqlEditor.insert(string);
|
||||
$('#aqlEditor .ace_text-input').focus();
|
||||
}.bind(this);
|
||||
|
||||
var cancelCallback = function() {
|
||||
$('#aqlEditor .ace_text-input').focus();
|
||||
};
|
||||
|
||||
window.spotlightView.show(callback, cancelCallback);
|
||||
},
|
||||
|
||||
resize: function() {
|
||||
this.resizeFunction();
|
||||
},
|
||||
|
@ -500,12 +572,13 @@
|
|||
this.queryPreview.resize();
|
||||
//fix my queries preview table resizing issues TODO
|
||||
$('#arangoMyQueriesTable thead').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable thead th').css('width', $('#queryTable').width() / 2);
|
||||
$('#arangoMyQueriesTable thead th').css('width', $('#queryTable').width() / 3);
|
||||
$('#arangoMyQueriesTable tr').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable tbody').css('height', $('#queryTable').height() - 18);
|
||||
$('#arangoMyQueriesTable tbody').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable tbody tr').css('width', $('#queryTable').width());
|
||||
$('#arangoMyQueriesTable tbody td').css('width', $('#queryTable').width() / 2);
|
||||
$('#arangoMyQueriesTable tbody td').css('width', $('#queryTable').width() / 3);
|
||||
$('#arangoMyQueriesTable tbody td .truncate').css('width', $('#queryTable').width() / 3);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -592,19 +665,26 @@
|
|||
});
|
||||
});
|
||||
|
||||
_.each(words, function(word) {
|
||||
word = word.split(",");
|
||||
_.each(word, function(x) {
|
||||
words1.push(x);
|
||||
});
|
||||
});
|
||||
|
||||
_.each(words1, function(word) {
|
||||
// remove newlines and whitespaces
|
||||
words[pos] = word.replace(/(\r\n|\n|\r)/gm,"");
|
||||
pos++;
|
||||
});
|
||||
words1.sort();
|
||||
|
||||
var newObject = {};
|
||||
_.each(words1, function(word) {
|
||||
//found a valid bind param expression
|
||||
if (self.bindParamRegExp.test(word)) {
|
||||
var match = word.match(self.bindParamRegExp);
|
||||
if (match) {
|
||||
//if property is not available
|
||||
word = word.substr(1, word.length);
|
||||
word = match[1];
|
||||
newObject[word] = '';
|
||||
}
|
||||
});
|
||||
|
@ -627,6 +707,7 @@
|
|||
}
|
||||
|
||||
var counter = 0;
|
||||
|
||||
_.each(this.bindParamTableObj, function(val, key) {
|
||||
$('#arangoBindParamTable tbody').append(
|
||||
"<tr>" +
|
||||
|
@ -677,12 +758,30 @@
|
|||
this.aqlEditor = ace.edit("aqlEditor");
|
||||
this.aqlEditor.getSession().setMode("ace/mode/aql");
|
||||
this.aqlEditor.setFontSize("13px");
|
||||
|
||||
this.bindParamAceEditor = ace.edit("bindParamAceEditor");
|
||||
this.bindParamAceEditor.getSession().setMode("ace/mode/json");
|
||||
this.bindParamAceEditor.setFontSize("13px");
|
||||
|
||||
this.bindParamAceEditor.getSession().on('change', function() {
|
||||
try {
|
||||
self.bindParamTableObj = JSON.parse(self.bindParamAceEditor.getValue());
|
||||
self.allowParamToggle = true;
|
||||
}
|
||||
catch (e) {
|
||||
self.allowParamToggle = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.aqlEditor.getSession().on('change', function() {
|
||||
self.checkForNewBindParams();
|
||||
self.renderBindParamTable();
|
||||
if (self.initDone) {
|
||||
self.setCachedQuery(self.aqlEditor.getValue(), JSON.stringify(self.bindParamTableObj));
|
||||
}
|
||||
self.bindParamAceEditor.setValue(JSON.stringify(self.bindParamTableObj, null, "\t"));
|
||||
$('#aqlEditor .ace_text-input').focus();
|
||||
|
||||
self.resize();
|
||||
});
|
||||
|
||||
|
@ -713,12 +812,21 @@
|
|||
|
||||
this.aqlEditor.commands.addCommand({
|
||||
name: "explainQuery",
|
||||
bindKey: {win: "Ctrl-Shift-E", mac: "Command-Shift-E", linux: "Ctrl-Shift-E"},
|
||||
bindKey: {win: "Ctrl-Shift-Return", mac: "Command-Shift-Return", linux: "Ctrl-Shift-Return"},
|
||||
exec: function() {
|
||||
self.explainQuery();
|
||||
}
|
||||
});
|
||||
|
||||
this.aqlEditor.commands.addCommand({
|
||||
name: "showSpotlight",
|
||||
bindKey: {win: "Ctrl-Space", mac: "Ctrl-Space", linux: "Ctrl-Space"},
|
||||
exec: function() {
|
||||
|
||||
self.showSpotlight();
|
||||
}
|
||||
});
|
||||
|
||||
this.queryPreview = ace.edit("queryPreview");
|
||||
this.queryPreview.getSession().setMode("ace/mode/aql");
|
||||
this.queryPreview.setReadOnly(true);
|
||||
|
@ -729,9 +837,15 @@
|
|||
},
|
||||
|
||||
updateQueryTable: function () {
|
||||
this.myQueriesTableDesc.rows = this.customQueries;
|
||||
var self = this;
|
||||
this.updateLocalQueries();
|
||||
|
||||
this.myQueriesTableDesc.rows = this.customQueries;
|
||||
_.each(this.myQueriesTableDesc.rows, function(k) {
|
||||
k.secondRow = '<div class="truncate">' +
|
||||
JSON.stringify(self.collection.findWhere({name: k.name}).get('value')) +
|
||||
'</div>';
|
||||
|
||||
k.thirdRow = '<span class="spanWrapper">' +
|
||||
'<span id="copyQuery" title="Copy query"><i class="fa fa-copy"></i></span>' +
|
||||
'<span id="explQuery" title="Explain query"><i class="fa fa-comments"></i></i></span>' +
|
||||
|
@ -744,8 +858,35 @@
|
|||
delete k.value;
|
||||
});
|
||||
|
||||
function compare(a,b) {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
}
|
||||
else if (a.name > b.name) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.myQueriesTableDesc.rows.sort(compare);
|
||||
|
||||
_.each(this.queries, function(val) {
|
||||
if (val.hasOwnProperty('parameter')) {
|
||||
delete val.parameter;
|
||||
}
|
||||
self.myQueriesTableDesc.rows.push({
|
||||
name: val.name,
|
||||
secondRow: '<div class="truncate">' + val.value + '</div>',
|
||||
thirdRow: '<span class="spanWrapper">' +
|
||||
'<span id="copyQuery" title="Copy query"><i class="fa fa-copy"></i></span></span>'
|
||||
});
|
||||
});
|
||||
|
||||
// escape all columns but the third (which contains HTML)
|
||||
this.myQueriesTableDesc.unescaped = [ false, true ];
|
||||
this.myQueriesTableDesc.unescaped = [ false, true, true ];
|
||||
|
||||
|
||||
this.$(this.myQueriesId).html(this.table.render({content: this.myQueriesTableDesc}));
|
||||
},
|
||||
|
@ -888,9 +1029,31 @@
|
|||
window.modalView.hide();
|
||||
},
|
||||
|
||||
executeQuery: function () {
|
||||
verifyQueryAndParams: function() {
|
||||
var quit = false;
|
||||
|
||||
if (this.aqlEditor.getValue().length === 0) {
|
||||
arangoHelper.arangoError("Query", "Your query is empty");
|
||||
quit = true;
|
||||
}
|
||||
|
||||
var keys = [];
|
||||
_.each(this.bindParamTableObj, function(val, key) {
|
||||
if (val === '') {
|
||||
quit = true;
|
||||
keys.push(key);
|
||||
}
|
||||
});
|
||||
if (keys.length > 0) {
|
||||
arangoHelper.arangoError("Bind Parameter", JSON.stringify(keys) + " not defined.");
|
||||
}
|
||||
|
||||
return quit;
|
||||
},
|
||||
|
||||
executeQuery: function () {
|
||||
|
||||
if (this.verifyQueryAndParams()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -908,6 +1071,8 @@
|
|||
sentQueryEditor.getSession().setMode("ace/mode/aql");
|
||||
outputEditor.getSession().setMode("ace/mode/json");
|
||||
outputEditor.setReadOnly(true);
|
||||
outputEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
sentQueryEditor.setOption("vScrollBarAlwaysVisible", true);
|
||||
outputEditor.setFontSize("13px");
|
||||
sentQueryEditor.setFontSize("13px");
|
||||
sentQueryEditor.setReadOnly(true);
|
||||
|
@ -971,10 +1136,9 @@
|
|||
error: function (data) {
|
||||
try {
|
||||
var temp = JSON.parse(data.responseText);
|
||||
outputEditor.setValue('[' + temp.errorNum + '] ' + temp.errorMessage);
|
||||
arangoHelper.arangoError('[' + temp.errorNum + ']', temp.errorMessage);
|
||||
}
|
||||
catch (e) {
|
||||
outputEditor.setValue('ERROR');
|
||||
arangoHelper.arangoError("Query error", "ERROR");
|
||||
}
|
||||
self.handleResult(counter);
|
||||
|
@ -1099,18 +1263,19 @@
|
|||
error.errorMessage.match(/'.*'/g)[0],
|
||||
error.errorMessage.match(/\d+:\d+/g)[0]
|
||||
);
|
||||
arangoHelper.arangoError("Query", error.errorMessage);
|
||||
}
|
||||
else {
|
||||
console.log(resp);
|
||||
self.markPositionError(
|
||||
error.errorMessage.match(/\(\w+\)/g)[0]
|
||||
);
|
||||
}
|
||||
arangoHelper.arangoError("Query", error.errorMessage);
|
||||
self.removeOutputEditor(counter);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
arangoHelper.arangoError("Query", "Something went wrong.");
|
||||
self.removeOutputEditor(counter);
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
window.progressView.hide();
|
||||
|
@ -1121,16 +1286,22 @@
|
|||
},
|
||||
|
||||
markPositionError: function(text, pos) {
|
||||
var row = pos.split(":")[0],
|
||||
line = pos.split(":")[1];
|
||||
var row;
|
||||
|
||||
if (pos) {
|
||||
row = pos.split(":")[0];
|
||||
text = text.substr(1, text.length - 2);
|
||||
}
|
||||
|
||||
this.aqlEditor.find(text);
|
||||
var found = this.aqlEditor.find(text);
|
||||
|
||||
if (!found && pos) {
|
||||
this.aqlEditor.selection.moveCursorToPosition({row: row, column: 0});
|
||||
this.aqlEditor.selection.selectLine();
|
||||
}
|
||||
window.setTimeout(function() {
|
||||
$('.ace_start').first().css('background', 'rgba(255, 129, 129, 0.7)');
|
||||
}, 100);
|
||||
|
||||
},
|
||||
|
||||
refreshAQL: function() {
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/*jshint browser: true */
|
||||
/*jshint unused: false */
|
||||
/*global Backbone, $, window, setTimeout, Joi, _ */
|
||||
/*global templateEngine*/
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
window.SpotlightView = Backbone.View.extend({
|
||||
|
||||
template: templateEngine.createTemplate("spotlightView.ejs"),
|
||||
|
||||
el: "#spotlightPlaceholder",
|
||||
|
||||
displayLimit: 8,
|
||||
typeahead: null,
|
||||
callbackSuccess: null,
|
||||
callbackCancel: null,
|
||||
|
||||
collections: {
|
||||
system: [],
|
||||
doc: [],
|
||||
edge: [],
|
||||
},
|
||||
|
||||
events: {
|
||||
"focusout #spotlight .tt-input" : "hide",
|
||||
"keyup #spotlight .typeahead" : "listenKey"
|
||||
},
|
||||
|
||||
aqlKeywords:
|
||||
"for|return|filter|sort|limit|let|collect|asc|desc|in|into|" +
|
||||
"insert|update|remove|replace|upsert|options|with|and|or|not|" +
|
||||
"distinct|graph|outbound|inbound|any|all|none|aggregate",
|
||||
|
||||
aqlBuiltinFunctions:
|
||||
"to_bool|to_number|to_string|to_list|is_null|is_bool|is_number|is_string|is_list|is_document|" +
|
||||
"concat|concat_separator|char_length|lower|upper|substring|left|right|trim|reverse|contains|" +
|
||||
"like|floor|ceil|round|abs|rand|sqrt|pow|length|min|max|average|sum|median|variance_population|" +
|
||||
"variance_sample|first|last|unique|matches|merge|merge_recursive|has|attributes|values|unset|unset_recursive|keep|" +
|
||||
"near|within|within_rectangle|is_in_polygon|fulltext|paths|traversal|traversal_tree|edges|stddev_sample|" +
|
||||
"stddev_population|slice|nth|position|translate|zip|call|apply|push|append|pop|shift|unshift|remove_value" +
|
||||
"remove_nth|graph_paths|shortest_path|graph_shortest_path|graph_distance_to|graph_traversal|graph_traversal_tree|" +
|
||||
"graph_edges|graph_vertices|neighbors|graph_neighbors|graph_common_neighbors|graph_common_properties|" +
|
||||
"graph_eccentricity|graph_betweenness|graph_closeness|graph_absolute_eccentricity|remove_values|" +
|
||||
"graph_absolute_betweenness|graph_absolute_closeness|graph_diameter|graph_radius|date_now|" +
|
||||
"date_timestamp|date_iso8601|date_dayofweek|date_year|date_month|date_day|date_hour|" +
|
||||
"date_minute|date_second|date_millisecond|date_dayofyear|date_isoweek|date_leapyear|date_quarter|date_days_in_month|" +
|
||||
"date_add|date_subtract|date_diff|date_compare|date_format|fail|passthru|sleep|not_null|" +
|
||||
"first_list|first_document|parse_identifier|current_user|current_database|" +
|
||||
"collections|document|union|union_distinct|intersection|flatten|" +
|
||||
"ltrim|rtrim|find_first|find_last|split|substitute|md5|sha1|random_token|AQL_LAST_ENTRY",
|
||||
|
||||
listenKey: function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
if (this.callbackSuccess) {
|
||||
this.callbackCancel();
|
||||
}
|
||||
this.hide();
|
||||
}
|
||||
else if (e.keyCode === 13) {
|
||||
if (this.callbackSuccess) {
|
||||
this.callbackSuccess($(this.typeahead).val());
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
substringMatcher: function(strs) {
|
||||
return function findMatches(q, cb) {
|
||||
var matches, substrRegex;
|
||||
|
||||
matches = [];
|
||||
|
||||
substrRegex = new RegExp(q, 'i');
|
||||
|
||||
_.each(strs, function(str) {
|
||||
if (substrRegex.test(str)) {
|
||||
matches.push(str);
|
||||
}
|
||||
});
|
||||
|
||||
cb(matches);
|
||||
};
|
||||
},
|
||||
|
||||
updateDatasets: function() {
|
||||
var self = this;
|
||||
this.collections = {
|
||||
system: [],
|
||||
doc: [],
|
||||
edge: [],
|
||||
};
|
||||
|
||||
window.App.arangoCollectionsStore.each(function(collection) {
|
||||
if (collection.get("isSystem")) {
|
||||
self.collections.system.push(collection.get("name"));
|
||||
}
|
||||
else if (collection.get("type") === 'document') {
|
||||
self.collections.doc.push(collection.get("name"));
|
||||
}
|
||||
else {
|
||||
self.collections.edge.push(collection.get("name"));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
stringToArray: function() {
|
||||
this.aqlKeywordsArray = this.aqlKeywords.split('|');
|
||||
this.aqlBuiltinFunctionsArray = this.aqlBuiltinFunctions.split('|');
|
||||
},
|
||||
|
||||
show: function(callbackSuccess, callbackCancel) {
|
||||
|
||||
this.callbackSuccess = callbackSuccess;
|
||||
this.callbackCancel = callbackCancel;
|
||||
this.stringToArray();
|
||||
this.updateDatasets();
|
||||
|
||||
var genHeader = function(name, icon, type) {
|
||||
var string = '<div class="header-type"><h4>' + name + '</h4>';
|
||||
if (icon) {
|
||||
string += '<span><i class="fa ' + icon + '"></i></span>';
|
||||
}
|
||||
if (type) {
|
||||
string += '<span class="type">' + type.toUpperCase() + '</span>';
|
||||
}
|
||||
string += '</div>';
|
||||
|
||||
return string;
|
||||
};
|
||||
|
||||
$(this.el).html(this.template.render({}));
|
||||
$(this.el).show();
|
||||
|
||||
this.typeahead = $('#spotlight .typeahead').typeahead(
|
||||
{
|
||||
hint: true,
|
||||
highlight: true,
|
||||
minLength: 1
|
||||
},
|
||||
{
|
||||
name: 'Functions',
|
||||
source: this.substringMatcher(this.aqlBuiltinFunctionsArray),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Functions", "fa-code", "aql")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Keywords',
|
||||
source: this.substringMatcher(this.aqlKeywordsArray),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Keywords", "fa-code", "aql")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Documents',
|
||||
source: this.substringMatcher(this.collections.doc),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Documents", "fa-file-text-o", "Collection")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Edges',
|
||||
source: this.substringMatcher(this.collections.edge),
|
||||
limit: this.displayLimit,
|
||||
templates: {
|
||||
header: genHeader("Edges", "fa-share-alt", "Collection")
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'System',
|
||||
limit: this.displayLimit,
|
||||
source: this.substringMatcher(this.collections.system),
|
||||
templates: {
|
||||
header: genHeader("System", "fa-cogs", "Collection")
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('#spotlight .typeahead').focus();
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
$(this.el).hide();
|
||||
}
|
||||
|
||||
});
|
||||
}());
|
|
@ -79,20 +79,23 @@ button.disabled,
|
|||
.addButton {
|
||||
@extend %clickable;
|
||||
@extend %icon-positive;
|
||||
font-size: 22px;
|
||||
font-size: 16pt;
|
||||
margin-right: 7px;
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.deleteButton {
|
||||
|
||||
i {
|
||||
@extend %clickable;
|
||||
@extend %icon-negative;
|
||||
font-size: 22px;
|
||||
font-size: 16pt;
|
||||
padding-right: 3px;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
#closeBtnInfoView {
|
||||
margin-left: 0 !important;
|
||||
|
|
|
@ -149,6 +149,10 @@ $c-sh-string: #ce2f30;
|
|||
$c-sh-object: #00f;
|
||||
$c-sh-array: #00f;
|
||||
|
||||
$c-spotlight-bg: rgb(61, 66, 70);
|
||||
$c-spotlight-header-bg: rgb(50, 55, 59);
|
||||
$c-spotlight-transp-bg: rgba(0, 0, 0, .25);
|
||||
|
||||
$c-progress-bar: #5bc0de;
|
||||
$c-progress-shadow: #353c39;
|
||||
$c-progress-shadow-2: #8cdb8b;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
width: 100%;
|
||||
|
||||
.aqlEditorWrapper {
|
||||
background: #f6f6f6;
|
||||
border: 0 !important;
|
||||
border-right: 3px solid $c-content-border !important;
|
||||
float: left;
|
||||
|
@ -26,27 +25,26 @@
|
|||
|
||||
.bindParamEditorWrapper,
|
||||
.aqlEditorWrapper {
|
||||
background: #eee;
|
||||
overflow: hidden;
|
||||
|
||||
.stringtype {
|
||||
color: black;
|
||||
color: $c-sh-string;
|
||||
}
|
||||
|
||||
.objecttype {
|
||||
color: blue;
|
||||
color: $c-sh-object;
|
||||
}
|
||||
|
||||
.arraytype {
|
||||
color: green;
|
||||
color: $c-sh-array;
|
||||
}
|
||||
|
||||
.numbertype {
|
||||
color: red;
|
||||
color: $c-sh-number;
|
||||
}
|
||||
|
||||
.booleantype {
|
||||
color: lightgreen;
|
||||
color: $c-sh-keyword;
|
||||
}
|
||||
|
||||
table {
|
||||
|
@ -58,6 +56,14 @@
|
|||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.truncate {
|
||||
opacity: .8;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
tr {
|
||||
&.noBgColor {
|
||||
background-color: rgba(0, 0, 0, 0) !important;
|
||||
|
@ -127,7 +133,7 @@
|
|||
|
||||
th {
|
||||
font: 13px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
height: 17px;
|
||||
height: 34px;
|
||||
padding: 0;
|
||||
width: 50%;
|
||||
}
|
||||
|
@ -143,19 +149,25 @@
|
|||
}
|
||||
|
||||
.aceAction {
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
background-color: rgb(133, 133, 133);
|
||||
border-radius: 3px;
|
||||
color: $c-white;
|
||||
cursor: pointer;
|
||||
font-size: 13pt;
|
||||
height: 23px;
|
||||
line-height: 22px;
|
||||
opacity: .8;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
right: 5px;
|
||||
text-align: center;
|
||||
top: 10px;
|
||||
top: 5px;
|
||||
width: 33px;
|
||||
z-index: 10;
|
||||
|
||||
&.type {
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
@ -173,10 +185,12 @@
|
|||
background-color: $c-white;
|
||||
border-bottom: 1px solid $c-content-border;
|
||||
font: 13px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||
height: 17px;
|
||||
height: 34px;
|
||||
|
||||
span {
|
||||
margin-left: 5px;
|
||||
padding-top: 8px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +236,7 @@
|
|||
color: $c-white;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
right: -27px;
|
||||
right: -24px;
|
||||
top: 45px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
#spotlightPlaceholder {
|
||||
background-color: $c-spotlight-transp-bg;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.spotlightWrapper {
|
||||
height: 50px;
|
||||
left: 25%;
|
||||
position: absolute;
|
||||
top: 115px;
|
||||
width: 50%;
|
||||
|
||||
.twitter-typeahead {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tt-highlight {
|
||||
color: $c-progress-bar;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
input {
|
||||
box-sizing: border-box;
|
||||
height: 40px !important;
|
||||
}
|
||||
|
||||
.tt-dataset {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.tt-menu {
|
||||
background: $c-spotlight-bg;
|
||||
border-radius: 3px;
|
||||
color: $c-white;
|
||||
width: 100%;
|
||||
|
||||
.header-type {
|
||||
background: $c-spotlight-header-bg;
|
||||
clear: both;
|
||||
color: $c-white;
|
||||
height: 30px;
|
||||
padding-left: 5px;
|
||||
|
||||
h4 {
|
||||
float: left;
|
||||
margin: 4px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.fa {
|
||||
font-size: 12pt;
|
||||
margin-left: 6px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.type {
|
||||
background-color: $c-progress-bar;
|
||||
border-radius: 3px;
|
||||
float: right;
|
||||
margin: 4px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.tt-cursor {
|
||||
background-color: $c-white;
|
||||
color: $c-black;
|
||||
}
|
||||
|
||||
.tt-selectable {
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.typeahead {
|
||||
background: $c-spotlight-bg;
|
||||
background-color: $c-spotlight-bg;
|
||||
border: 0 solid $c-spotlight-bg;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
color: $c-white;
|
||||
font-size: 22px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
outline: none;
|
||||
outline-color: transparent;
|
||||
outline-style: none;
|
||||
padding: 8px 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.typeahead:focus {
|
||||
outline: none;
|
||||
outline-color: transparent;
|
||||
outline-style: none;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,14 @@
|
|||
%toolbarSpan {
|
||||
padding: 1px 4px 3px;
|
||||
padding: 5px 8px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
top: 5px;
|
||||
|
||||
&:hover {
|
||||
background-color: $c-positive;
|
||||
border-radius: 3px;
|
||||
color: $c-white;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.arangoToolbar {
|
||||
|
@ -36,6 +43,8 @@
|
|||
}
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
font-size: 11pt;
|
||||
font-style: normal;
|
||||
|
||||
&.fa {
|
||||
|
@ -56,6 +65,7 @@
|
|||
background: $c-info-blue;
|
||||
border-radius: 3px;
|
||||
color: $c-white;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.styled-select {
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
@import 'documentView';
|
||||
// progress view
|
||||
@import 'progressView';
|
||||
// spotlight view
|
||||
@import 'spotlightView';
|
||||
// application detail view
|
||||
@import 'applicationDetailView';
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
const functionsDocumentation = {
|
||||
"all": "run all tests (marked with [x])",
|
||||
"agency": "run agency tests",
|
||||
"arangob": "arangob tests",
|
||||
"arangosh": "arangosh exit codes tests",
|
||||
"authentication": "authentication tests",
|
||||
|
@ -91,6 +92,8 @@ const optionsDocumentation = [
|
|||
' - `cluster`: if set to true the tests are run with the coordinator',
|
||||
' of a small local cluster',
|
||||
' - `clusterNodes`: number of DB-Servers to use',
|
||||
' - `agency`: if set to true agency tests are done',
|
||||
' - `agencySize`: number of agents in agency',
|
||||
' - `test`: path to single test to execute for "single" test target',
|
||||
' - `cleanup`: if set to true (the default), the cluster data files',
|
||||
' and logs are removed after termination of the test.',
|
||||
|
@ -495,6 +498,68 @@ function checkInstanceAliveSingleServer(instanceInfo, options) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if an agency instance is still alive
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function checkInstanceAliveAgency(instanceInfo, options) {
|
||||
if (instanceInfo.hasOwnProperty('exitStatus')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < options.agencySize; i++) {
|
||||
const res = statusExternal(instanceInfo.pids[i], false);
|
||||
const ret = res.status === "RUNNING";
|
||||
|
||||
if (!ret) {
|
||||
print("ArangoD with PID " + instanceInfo.pids[i].pid + " gone:");
|
||||
print(instanceInfo);
|
||||
|
||||
if (res.hasOwnProperty('signal') &&
|
||||
((res.signal === 11) ||
|
||||
(res.signal === 6) ||
|
||||
// Windows sometimes has random numbers in signal...
|
||||
(require("internal").platform.substr(0, 3) === 'win')
|
||||
)
|
||||
) {
|
||||
const storeArangodPath = "/var/tmp/arangod_" + instanceInfo.pids[i].pid;
|
||||
|
||||
print("Core dump written; copying arangod to " +
|
||||
instanceInfo.tmpDataDir + " for later analysis.");
|
||||
|
||||
let corePath = (options.coreDirectory === "") ?
|
||||
"core" :
|
||||
options.coreDirectory + "/core*" + instanceInfo.pids[i].pid + "*'";
|
||||
|
||||
res.gdbHint = "Run debugger with 'gdb " +
|
||||
storeArangodPath + " " + corePath;
|
||||
|
||||
if (require("internal").platform.substr(0, 3) === 'win') {
|
||||
// Windows: wait for procdump to do its job...
|
||||
statusExternal(instanceInfo.monitor, true);
|
||||
analyzeCoreDumpWindows(instanceInfo);
|
||||
} else {
|
||||
fs.copyFile("bin/arangod", storeArangodPath);
|
||||
analyzeCoreDump(instanceInfo, options, storeArangodPath, instanceInfo.pids[i].pid);
|
||||
}
|
||||
}
|
||||
|
||||
if (instanceInfo.exitStatus === undefined) {
|
||||
instanceInfo.exitStatus = [];
|
||||
}
|
||||
instanceInfo.exitStatus[i] = res;
|
||||
}
|
||||
}
|
||||
|
||||
if (instanceInfo.exitStatus !== undefined) {
|
||||
print("marking crashy");
|
||||
serverCrashed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkRemoteInstance(pid, wait, options) {
|
||||
const debug = options.debug || false;
|
||||
const p = JSON.stringify(pid);
|
||||
|
@ -556,12 +621,15 @@ function checkInstanceAliveCluster(instanceInfo, options) {
|
|||
}
|
||||
|
||||
function checkInstanceAlive(instanceInfo, options) {
|
||||
if (options.cluster === false) {
|
||||
return checkInstanceAliveSingleServer(instanceInfo, options);
|
||||
}
|
||||
|
||||
if (options.cluster) {
|
||||
return checkInstanceAliveCluster(instanceInfo, options);
|
||||
}
|
||||
if (options.agency) {
|
||||
return checkInstanceAliveAgency(instanceInfo, options);
|
||||
}
|
||||
return checkInstanceAliveSingleServer(instanceInfo, options);
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief waits for garbage collection using /_admin/execute
|
||||
|
@ -972,7 +1040,12 @@ function executeAndWait(cmd, args) {
|
|||
|
||||
function runInArangosh(options, instanceInfo, file, addArgs) {
|
||||
let args = makeArgsArangosh(options);
|
||||
if (instanceInfo.endpoint !== undefined) {
|
||||
args["server.endpoint"] = instanceInfo.endpoint;
|
||||
}
|
||||
if (instanceInfo.urls !== undefined) {
|
||||
args["flatCommands"] = instanceInfo.urls;
|
||||
}
|
||||
args["javascript.unit-tests"] = fs.join(TOP_DIR, file);
|
||||
|
||||
if (addArgs !== undefined) {
|
||||
|
@ -1141,6 +1214,87 @@ function shutdownInstance(instanceInfo, options) {
|
|||
killExternal(instanceInfo.dispatcherPid);
|
||||
}
|
||||
|
||||
// agency mode
|
||||
else if (options.agency) {
|
||||
if (instanceInfo.exitStatus === undefined) {
|
||||
instanceInfo.exitStatus = [];
|
||||
}
|
||||
for (let i = 0; i < options.agencySize; i++) {
|
||||
if (instanceInfo.exitStatus[i] === undefined) {
|
||||
download(instanceInfo.urls[i] + "/_admin/shutdown", "",
|
||||
makeAuthorizationHeaders(options));
|
||||
|
||||
print("Waiting for server shut down");
|
||||
|
||||
let count = 0;
|
||||
let bar = "[";
|
||||
|
||||
let timeout = 600;
|
||||
|
||||
if (options.sanitizer) {
|
||||
timeout *= 2;
|
||||
}
|
||||
|
||||
if (instanceInfo.exitStatus === undefined) {
|
||||
instanceInfo.exitStatus = [];
|
||||
}
|
||||
while (true) {
|
||||
instanceInfo.exitStatus[i] = statusExternal(instanceInfo.pids[i], false);
|
||||
|
||||
if (instanceInfo.exitStatus[i].status === "RUNNING") {
|
||||
++count;
|
||||
|
||||
if (options.valgrind) {
|
||||
wait(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count % 10 === 0) {
|
||||
bar = bar + "#";
|
||||
}
|
||||
|
||||
if (count > 600) {
|
||||
print("forcefully terminating " + yaml.safeDump(instanceInfo.pids[i]) +
|
||||
" after " + timeout + "s grace period; marking crashy.");
|
||||
serverCrashed = true;
|
||||
killExternal(instanceInfo.pids[i]);
|
||||
break;
|
||||
} else {
|
||||
wait(1);
|
||||
}
|
||||
} else if (instanceInfo.exitStatus[i].status !== "TERMINATED") {
|
||||
if (instanceInfo.exitStatus[i].hasOwnProperty('signal')) {
|
||||
print("Server shut down with : " +
|
||||
yaml.safeDump(instanceInfo.exitStatus[i]) +
|
||||
" marking build as crashy.");
|
||||
|
||||
serverCrashed = true;
|
||||
break;
|
||||
}
|
||||
if (require("internal").platform.substr(0, 3) === 'win') {
|
||||
// Windows: wait for procdump to do its job...
|
||||
statusExternal(instanceInfo.monitor, true);
|
||||
}
|
||||
} else {
|
||||
print("Server shutdown: Success.");
|
||||
break; // Success.
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 10) {
|
||||
print("long Server shutdown: " + bar + ']');
|
||||
}
|
||||
} else {
|
||||
print("Server already dead, doing nothing.");
|
||||
}
|
||||
|
||||
if (!options.skipLogAnalysis) {
|
||||
instanceInfo.importantLogLines =
|
||||
readImportantLogLines(instanceInfo.tmpDataDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// single server
|
||||
else {
|
||||
if (typeof(instanceInfo.exitStatus) === 'undefined') {
|
||||
|
@ -1397,6 +1551,72 @@ function valgrindArgsSingleServer(options, testname, run) {
|
|||
return toArgv(valgrindOpts, true).concat([run]);
|
||||
}
|
||||
|
||||
function startInstanceAgency(instanceInfo, protocol, options,
|
||||
addArgs, testname, appDir, tmpDataDir) {
|
||||
const N = options.agencySize;
|
||||
const ports = [];
|
||||
for (let i = 0; i < N; i++) {
|
||||
ports.push(findFreePort());
|
||||
}
|
||||
instanceInfo.ports = ports;
|
||||
|
||||
const endpoints = ports.map(function(port) {
|
||||
return protocol + "://127.0.0.1:" + port;
|
||||
});
|
||||
instanceInfo.endpoints = endpoints;
|
||||
|
||||
let td = ports.map(function(port) {
|
||||
return fs.join(tmpDataDir, "data" + port);
|
||||
});
|
||||
for (let i = 0; i < N; i++) {
|
||||
fs.makeDirectoryRecursive(td[i]);
|
||||
}
|
||||
|
||||
let argss = [];
|
||||
for (let i = 0; i < N; i++) {
|
||||
let args = makeArgsArangod(options, appDir);
|
||||
args["server.endpoint"] = endpoints[i];
|
||||
args["database.directory"] = td[i];
|
||||
args["log.file"] = fs.join(tmpDataDir, "log" + ports[i]);
|
||||
//args["agency.id"] = String(i);
|
||||
//args["agency.size"] = String(N);
|
||||
|
||||
if (protocol === "ssl") {
|
||||
args["server.keyfile"] = fs.join("UnitTests", "server.pem");
|
||||
}
|
||||
|
||||
args = _.extend(args, options.extraArgs);
|
||||
|
||||
if (addArgs !== undefined) {
|
||||
args = _.extend(args, addArgs);
|
||||
}
|
||||
|
||||
if (i === N-1) {
|
||||
let l = [];
|
||||
for (let j = 0; j < N; j++) {
|
||||
l.push("--agency.endpoint");
|
||||
l.push(endpoints[j]);
|
||||
}
|
||||
//args["flatCommands"] = l;
|
||||
}
|
||||
argss.push(args);
|
||||
}
|
||||
|
||||
instanceInfo.pids = [];
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (options.valgrind) {
|
||||
const valgrindArgs = valgrindArgsSingleServer(options, testname, ARANGOD_BIN);
|
||||
const newargs = valgrindArgs.concat(toArgv(argss[i]));
|
||||
|
||||
instanceInfo.pids[i] = executeExternal(options.valgrind, newargs);
|
||||
} else {
|
||||
instanceInfo.pids[i] = executeExternal(ARANGOD_BIN, toArgv(argss[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function startInstanceSingleServer(instanceInfo, protocol, options,
|
||||
addArgs, testname, appDir, tmpDataDir) {
|
||||
const port = findFreePort();
|
||||
|
@ -1458,6 +1678,12 @@ function startInstance(protocol, options, addArgs, testname, tmpDir) {
|
|||
addArgs, testname, appDir, tmpDataDir);
|
||||
}
|
||||
|
||||
// agency testing mode
|
||||
else if (options.agency) {
|
||||
res = startInstanceAgency(instanceInfo, protocol, options,
|
||||
addArgs, testname, appDir, tmpDataDir);
|
||||
}
|
||||
|
||||
// single instance mode
|
||||
else {
|
||||
res = startInstanceSingleServer(instanceInfo, protocol, options,
|
||||
|
@ -1471,8 +1697,15 @@ function startInstance(protocol, options, addArgs, testname, tmpDir) {
|
|||
// wait until the server/coordinator is up:
|
||||
let count = 0;
|
||||
|
||||
const url = endpointToURL(instanceInfo.endpoint);
|
||||
let url;
|
||||
if (instanceInfo.endpoint !== undefined) {
|
||||
url = endpointToURL(instanceInfo.endpoint);
|
||||
instanceInfo.url = url;
|
||||
} else {
|
||||
instanceInfo.urls = instanceInfo.endpoints.map(endpointToURL);
|
||||
url = instanceInfo.urls[0];
|
||||
instanceInfo.url = url;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
wait(0.5, false);
|
||||
|
@ -1755,6 +1988,14 @@ function findTests() {
|
|||
return fs.join(makePathUnix("js/common/tests/replication"), x);
|
||||
}).sort();
|
||||
|
||||
testsCases.agency = _.filter(fs.list(makePathUnix("js/client/tests/agency")),
|
||||
function(p) {
|
||||
return p.substr(-3) === ".js";
|
||||
}).map(
|
||||
function(x) {
|
||||
return fs.join(makePathUnix("js/client/tests/agency"), x);
|
||||
}).sort();
|
||||
|
||||
testsCases.server = testsCases.common.concat(testsCases.server_only);
|
||||
testsCases.client = testsCases.common.concat(testsCases.client_only);
|
||||
|
||||
|
@ -3647,6 +3888,86 @@ testFuncs.stress_locks = function(options) {
|
|||
return runStressTest(options, command, "stress_lock");
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief agency tests
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testFuncs.agency = function(options) {
|
||||
findTests();
|
||||
|
||||
options.agency = true;
|
||||
options.cluster = false;
|
||||
if (options.agencySize === undefined) {
|
||||
options.agencySize = 3;
|
||||
}
|
||||
|
||||
let instanceInfo = startInstance("tcp", options, {}, "agency");
|
||||
|
||||
if (instanceInfo === false) {
|
||||
return {
|
||||
shell_client: {
|
||||
status: false,
|
||||
message: "failed to start agency!"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let results = {};
|
||||
let filtered = {};
|
||||
let continueTesting = true;
|
||||
|
||||
for (let i = 0; i < testsCases.agency.length; i++) {
|
||||
const te = testsCases.agency[i];
|
||||
|
||||
if (filterTestcaseByOptions(te, options, filtered)) {
|
||||
if (!continueTesting) {
|
||||
print("Skipping, " + te + " server is gone.");
|
||||
|
||||
results[te] = {
|
||||
status: false,
|
||||
message: instanceInfo.exitStatus
|
||||
};
|
||||
|
||||
instanceInfo.exitStatus = "server is gone.";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
print("\narangosh: Trying", te, "...");
|
||||
|
||||
const reply = runInArangosh(options, instanceInfo, te);
|
||||
results[te] = reply;
|
||||
|
||||
if (reply.status !== true) {
|
||||
options.cleanup = false;
|
||||
|
||||
if (!options.force) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
continueTesting = checkInstanceAlive(instanceInfo, options);
|
||||
} else {
|
||||
if (options.extremeVerbosity) {
|
||||
print("Skipped " + te + " because of " + filtered.filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print("Shutting down...");
|
||||
shutdownInstance(instanceInfo, options);
|
||||
print("done.");
|
||||
|
||||
if ((!options.skipLogAnalysis) &&
|
||||
instanceInfo.hasOwnProperty('importantLogLines') &&
|
||||
Object.keys(instanceInfo.importantLogLines).length > 0) {
|
||||
print("Found messages in the server logs: \n" +
|
||||
yaml.safeDump(instanceInfo.importantLogLines));
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief pretty prints the result
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
Conventions for testing framework:
|
||||
==================================
|
||||
|
||||
All files in the directory "shell" and ends with ".js" automatically
|
||||
All files in the directory "shell" that end with ".js" automatically
|
||||
take part in client shell tests (target "shell_client").
|
||||
|
||||
All files in the directory "agency" that end with ".js" automatically
|
||||
take part in agency tests (target "agency").
|
||||
|
||||
If the filename contains the string "-cluster", then it is only
|
||||
executed when testing in cluster mode. If the filename contains the
|
||||
string "-noncluster", then it is only executed when testing in single
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/*jshint globalstrict:false, strict:true */
|
||||
/*global assertEqual, ARGUMENTS */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for client-specific functionality
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Max Neunhoeffer
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function agencyTestSuite () {
|
||||
'use strict';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the agency servers
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var agencyServers = ARGUMENTS;
|
||||
var whoseTurn = 0; // used to do round robin on agencyServers
|
||||
|
||||
var request = require("@arangodb/request");
|
||||
|
||||
function readAgency(list) {
|
||||
// We simply try all agency servers in turn until one gives us an HTTP
|
||||
// response:
|
||||
var res = request({url: agencyServers[whoseTurn] + "/read", method: "POST",
|
||||
followRedirects: true, body: JSON.stringify(list),
|
||||
headers: {"Content-Type": "application/json"}});
|
||||
res.bodyParsed = JSON.parse(res.body);
|
||||
return res;
|
||||
}
|
||||
|
||||
function writeAgency(list) {
|
||||
// We simply try all agency servers in turn until one gives us an HTTP
|
||||
// response:
|
||||
var res = request({url: agencyServers[whoseTurn] + "/write", method: "POST",
|
||||
followRedirects: true, body: JSON.stringify(list),
|
||||
headers: {"Content-Type": "application/json"}});
|
||||
res.bodyParsed = JSON.parse(res.body);
|
||||
return res;
|
||||
}
|
||||
|
||||
function readAndCheck(list) {
|
||||
var res = readAgency(list);
|
||||
assertEqual(res.statusCode, 200);
|
||||
return res.bodyParsed;
|
||||
}
|
||||
|
||||
function writeAndCheck(list) {
|
||||
var res = writeAgency(list);
|
||||
assertEqual(res.statusCode, 200);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test to write a single top level key
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSingleTopLevel : function () {
|
||||
assertEqual(readAndCheck([["x"]]), [{}]);
|
||||
writeAndCheck([[{x:12}]]);
|
||||
assertEqual(readAndCheck([["x"]]), [{x:12}]);
|
||||
writeAndCheck([[{x:{"op":"delete"}}]]);
|
||||
assertEqual(readAndCheck([["x"]]), [{}]);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test to write a single non-top level key
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testSingleNonTopLevel : function () {
|
||||
assertEqual(readAndCheck([["x/y"]]), [{}]);
|
||||
writeAndCheck([[{"x/y":12}]]);
|
||||
assertEqual(readAndCheck([["x/y"]]), [{x:{y:12}}]);
|
||||
writeAndCheck([[{"x/y":{"op":"delete"}}]]);
|
||||
assertEqual(readAndCheck([["x"]]), [{x:{}}]);
|
||||
writeAndCheck([[{"x":{"op":"delete"}}]]);
|
||||
assertEqual(readAndCheck([["x"]]), [{}]);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test a precondition
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testPrecondition : function () {
|
||||
writeAndCheck([[{"a":12}]]);
|
||||
assertEqual(readAndCheck([["a"]]), [{a:12}]);
|
||||
writeAndCheck([[{"a":13},{"a":12}]]);
|
||||
assertEqual(readAndCheck([["a"]]), [{a:13}]);
|
||||
var res = writeAgency([[{"a":14},{"a":12}]]);
|
||||
assertEqual(res.statusCode, 412);
|
||||
assertEqual(res.bodyParsed, {error:true, successes:[]});
|
||||
writeAndCheck([[{a:{op:"delete"}}]]);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(agencyTestSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
|
@ -24,11 +24,13 @@
|
|||
#define ARANGODB_PROGRAM_OPTIONS_OPTION_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "ProgramOptions2/Parameters.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "ProgramOptions2/Parameters.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace options {
|
||||
|
||||
|
@ -57,6 +59,10 @@ struct Option {
|
|||
}
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const {
|
||||
parameter->toVPack(builder);
|
||||
}
|
||||
|
||||
// get display name for the option
|
||||
std::string displayName() const { return "--" + fullName(); }
|
||||
|
||||
|
@ -69,8 +75,9 @@ struct Option {
|
|||
}
|
||||
|
||||
// print help for an option
|
||||
void printHelp(size_t tw, size_t ow) const {
|
||||
if (!hidden) {
|
||||
// the special search string "." will show help for all sections, even if hidden
|
||||
void printHelp(std::string const& search, size_t tw, size_t ow) const {
|
||||
if (search == "." || !hidden) {
|
||||
std::cout << " " << pad(nameWithType(), ow) << " ";
|
||||
|
||||
std::string value = description;
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
#include <limits>
|
||||
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include <numeric>
|
||||
#include <type_traits>
|
||||
|
||||
namespace arangodb {
|
||||
namespace options {
|
||||
|
||||
|
@ -58,6 +64,20 @@ double toNumber<double>(std::string const& value) {
|
|||
return std::stod(value);
|
||||
}
|
||||
|
||||
// convert a string into another type, specialized version for numbers
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_arithmetic<T>::value, T>::type fromString(
|
||||
std::string const& value) {
|
||||
return toNumber<T>(value);
|
||||
}
|
||||
|
||||
// convert a string into another type, specialized version for string -> string
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_same<T, std::string>::value, T>::type fromString(
|
||||
std::string const& value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// stringify a value, base version for any type
|
||||
template <typename T>
|
||||
inline std::string stringifyValue(T const& value) {
|
||||
|
@ -92,6 +112,8 @@ struct Parameter {
|
|||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
virtual void toVPack(VPackBuilder&) const = 0;
|
||||
};
|
||||
|
||||
// specialized type for boolean values
|
||||
|
@ -121,6 +143,10 @@ struct BooleanParameter : public Parameter {
|
|||
return "";
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(*ptr));
|
||||
}
|
||||
|
||||
ValueType* ptr;
|
||||
bool required;
|
||||
};
|
||||
|
@ -149,6 +175,10 @@ struct NumericParameter : public Parameter {
|
|||
return "number out of range";
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(*ptr));
|
||||
}
|
||||
|
||||
ValueType* ptr;
|
||||
};
|
||||
|
||||
|
@ -208,29 +238,28 @@ struct UInt64Parameter : public NumericParameter<uint64_t> {
|
|||
|
||||
template <typename T>
|
||||
struct BoundedParameter : public T {
|
||||
BoundedParameter(typename T::ValueType* ptr,
|
||||
typename T::ValueType minimum,
|
||||
typename T::ValueType maximum)
|
||||
: T(ptr), minimum(minimum), maximum(maximum) {}
|
||||
BoundedParameter(typename T::ValueType* ptr, typename T::ValueType minValue,
|
||||
typename T::ValueType maxValue)
|
||||
: T(ptr), minValue(minValue), maxValue(maxValue) {}
|
||||
|
||||
std::string set(std::string const& value) override {
|
||||
try {
|
||||
typename T::ValueType v = toNumber<typename T::ValueType>(value);
|
||||
if (v >= (std::numeric_limits<typename T::ValueType>::min)() &&
|
||||
v <= (std::numeric_limits<typename T::ValueType>::max)() && v >= minimum &&
|
||||
v <= maximum) {
|
||||
v <= (std::numeric_limits<typename T::ValueType>::max)() && v >= minValue &&
|
||||
v <= maxValue) {
|
||||
*this->ptr = v;
|
||||
return "";
|
||||
}
|
||||
} catch (...) {
|
||||
return "invalid numeric value";
|
||||
}
|
||||
return "number out of allowed range (" + std::to_string(minimum) + " - " +
|
||||
std::to_string(maximum) + ")";
|
||||
return "number out of allowed range (" + std::to_string(minValue) + " - " +
|
||||
std::to_string(maxValue) + ")";
|
||||
}
|
||||
|
||||
typename T::ValueType minimum;
|
||||
typename T::ValueType maximum;
|
||||
typename T::ValueType minValue;
|
||||
typename T::ValueType maxValue;
|
||||
};
|
||||
|
||||
// concrete double number value type
|
||||
|
@ -256,9 +285,33 @@ struct StringParameter : public Parameter {
|
|||
return "";
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(*ptr));
|
||||
}
|
||||
|
||||
ValueType* ptr;
|
||||
};
|
||||
|
||||
// specialized type for discrete values (defined in the unordered_set)
|
||||
// this templated type needs a concrete value type
|
||||
template <typename T>
|
||||
struct DiscreteValuesParameter : public T {
|
||||
DiscreteValuesParameter(typename T::ValueType* ptr,
|
||||
std::unordered_set<typename T::ValueType> const& allowed)
|
||||
: T(ptr), allowed(allowed) {}
|
||||
|
||||
std::string set(std::string const& value) override {
|
||||
auto it = allowed.find(fromString<typename T::ValueType>(value));
|
||||
|
||||
if (it == allowed.end()) {
|
||||
return "invalid value " + value;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::unordered_set<typename T::ValueType> allowed;
|
||||
};
|
||||
|
||||
// specialized type for vectors of values
|
||||
// this templated type needs a concrete value type
|
||||
template <typename T>
|
||||
|
@ -293,6 +346,13 @@ struct VectorParameter : public Parameter {
|
|||
return result;
|
||||
}
|
||||
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.openArray();
|
||||
for (size_t i = 0; i < ptr->size(); ++i) {
|
||||
builder.add(VPackValue(ptr->at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<typename T::ValueType>* ptr;
|
||||
};
|
||||
|
||||
|
@ -302,6 +362,9 @@ struct ObsoleteParameter : public Parameter {
|
|||
std::string name() const override { return "obsolete"; }
|
||||
std::string valueString() const override { return "-"; }
|
||||
std::string set(std::string const&) override { return ""; }
|
||||
void toVPack(VPackBuilder& builder) const override {
|
||||
builder.add(VPackValue(VPackValueType::Null));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@
|
|||
#include "ProgramOptions2/Option.h"
|
||||
#include "ProgramOptions2/Section.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/velocypack-aliases.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#define ARANGODB_PROGRAM_OPTIONS_PROGNAME "#progname#"
|
||||
|
||||
namespace arangodb {
|
||||
|
@ -82,7 +87,8 @@ class ProgramOptions {
|
|||
_terminalWidth(terminalWidth),
|
||||
_similarity(similarity),
|
||||
_processingResult(),
|
||||
_sealed(false) {
|
||||
_sealed(false),
|
||||
_overrideOptions(false) {
|
||||
// find progname wildcard in string
|
||||
size_t const pos = _usage.find(ARANGODB_PROGRAM_OPTIONS_PROGNAME);
|
||||
|
||||
|
@ -100,9 +106,19 @@ class ProgramOptions {
|
|||
ProcessingResult& processingResult() { return _processingResult; }
|
||||
|
||||
// seal the options
|
||||
// tryin to add an option or a section after sealing will throw an error
|
||||
// trying to add an option or a section after sealing will throw an error
|
||||
void seal() { _sealed = true; }
|
||||
|
||||
// allow or disallow overriding already set options
|
||||
void allowOverride(bool value) {
|
||||
checkIfSealed();
|
||||
_overrideOptions = value;
|
||||
}
|
||||
|
||||
bool allowOverride() const {
|
||||
return _overrideOptions;
|
||||
}
|
||||
|
||||
// set context for error reporting
|
||||
void setContext(std::string const& value) { _context = value; }
|
||||
|
||||
|
@ -149,21 +165,25 @@ class ProgramOptions {
|
|||
// prints usage information
|
||||
void printUsage() const { std::cout << _usage << std::endl << std::endl; }
|
||||
|
||||
// prints a help for all options
|
||||
void printHelp(std::string const& section) const {
|
||||
// prints a help for all options, or the options of a section
|
||||
// the special search string "*" will show help for all sections
|
||||
// the special search string "." will show help for all sections, even if hidden
|
||||
void printHelp(std::string const& search) const {
|
||||
printUsage();
|
||||
|
||||
size_t const tw = _terminalWidth();
|
||||
size_t const ow = optionsWidth();
|
||||
|
||||
for (auto const& it : _sections) {
|
||||
if (section == "*" || section == it.second.name) {
|
||||
it.second.printHelp(tw, ow);
|
||||
if (search == "*" || search == "." || search == it.second.name) {
|
||||
it.second.printHelp(search, tw, ow);
|
||||
}
|
||||
}
|
||||
|
||||
if (search == "*") {
|
||||
printSectionsHelp();
|
||||
}
|
||||
}
|
||||
|
||||
// prints the names for all section help options
|
||||
void printSectionsHelp() const {
|
||||
|
@ -177,6 +197,28 @@ class ProgramOptions {
|
|||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// returns a VPack representation of the option values
|
||||
VPackBuilder toVPack(bool onlyTouched, std::unordered_set<std::string> const& exclude) const {
|
||||
VPackBuilder builder;
|
||||
builder.openObject();
|
||||
|
||||
walk([&builder, &exclude](Section const&, Option const& option) {
|
||||
std::string full(option.fullName());
|
||||
if (exclude.find(full) != exclude.end()) {
|
||||
// excluded option
|
||||
return;
|
||||
}
|
||||
|
||||
// add key
|
||||
builder.add(VPackValue(full));
|
||||
// add value
|
||||
option.toVPack(builder);
|
||||
}, onlyTouched);
|
||||
|
||||
builder.close();
|
||||
return builder;
|
||||
}
|
||||
|
||||
// translate a shorthand option
|
||||
std::string translateShorthand(std::string const& name) const {
|
||||
auto it = _shorthands.find(name);
|
||||
|
@ -188,7 +230,7 @@ class ProgramOptions {
|
|||
}
|
||||
|
||||
void walk(std::function<void(Section const&, Option const&)> const& callback,
|
||||
bool onlyTouched) {
|
||||
bool onlyTouched) const {
|
||||
for (auto const& it : _sections) {
|
||||
if (it.second.obsolete) {
|
||||
// obsolete section. ignore it
|
||||
|
@ -229,6 +271,11 @@ class ProgramOptions {
|
|||
|
||||
// sets a value for an option
|
||||
bool setValue(std::string const& name, std::string const& value) {
|
||||
if (!_overrideOptions && _processingResult.touched(name)) {
|
||||
// option already set. don't override it
|
||||
return true;
|
||||
}
|
||||
|
||||
auto parts = Option::splitName(name);
|
||||
auto it = _sections.find(parts.first);
|
||||
|
||||
|
@ -432,6 +479,8 @@ class ProgramOptions {
|
|||
ProcessingResult _processingResult;
|
||||
// whether or not the program options setup is still mutable
|
||||
bool _sealed;
|
||||
// allow or disallow overriding already set options
|
||||
bool _overrideOptions;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,9 @@ struct Section {
|
|||
}
|
||||
|
||||
// print help for a section
|
||||
void printHelp(size_t tw, size_t ow) const {
|
||||
if (hidden || !hasOptions()) {
|
||||
// the special search string "." will show help for all sections, even if hidden
|
||||
void printHelp(std::string const& search, size_t tw, size_t ow) const {
|
||||
if (search != "." && (hidden || !hasOptions())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -71,7 +72,7 @@ struct Section {
|
|||
|
||||
// propagate print command to options
|
||||
for (auto const& it : options) {
|
||||
it.second.printHelp(tw, ow);
|
||||
it.second.printHelp(search, tw, ow);
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ "x$@" == "x" ] ; then
|
||||
JAVASCRIPT_JSLINT="\
|
||||
`find ./js/actions -name "*.js"` \
|
||||
`find ./js/common/bootstrap -name "*.js"` \
|
||||
|
@ -37,6 +38,9 @@ JAVASCRIPT_JSLINT="\
|
|||
\
|
||||
./js/apps/system/_admin/aardvark/APP/frontend/js/shell/browser.js \
|
||||
"
|
||||
else
|
||||
JAVASCRIPT_JSLINT="$@"
|
||||
fi
|
||||
|
||||
FILELIST=""
|
||||
|
||||
|
|
Loading…
Reference in New Issue