blob: 31448ee48c8d6c1a7cc5f4489eb2af227a9950fa [file] [log] [blame]
<!--
! Licensed to the Apache Software Foundation (ASF) under one
! or more contributor license agreements. See the NOTICE file
! distributed with this work for additional information
! regarding copyright ownership. The ASF licenses this file
! to you 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.
!-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="description" content="ASTERIX WEB PAGE" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link
href='http://fonts.googleapis.com/css?family=Bitter|PT+Sans+Caption|Open+Sans'
rel='stylesheet' type='text/css'>
<script src="/webui/static/js/jquery.min.js"></script>
<link href="/webui/static/css/bootstrap.min.css" rel="stylesheet"
type="text/css" />
<link href="/webui/static/css/bootstrap-responsive.min.css"
rel="stylesheet" type="text/css" />
<script src="/webui/static/js/bootstrap.min.js"></script>
<link href="/webui/static/css/style.css" rel="stylesheet"
type="text/css" />
<script src="/webui/static/js/jquery.json-viewer.js"></script>
<link href="/webui/static/css/jquery.json-viewer.css" type="text/css" rel="stylesheet" />
<script type="text/javascript">
$(document).ready(function() {
var optionButtonSize = $('#checkboxes-on').width();
$('#clear-query-button, #run-btn').width(optionButtonSize);
$('#checkboxes-on').click(function() {
/* Displays a checkmark to indicate selection/clearing */
if ($('#opts').is(":visible")) {
$('#opts').hide();
$('#queryform :input').prop('checked', false);
} else {
$('#opts').show();
$('#queryform :input').prop('checked', true);
}
return false;
});
$('#clear-query-button').click(function() {
$("#qry").val('');
return false;
});
$('form#queryform :input').click(function() {
/* Hides selection check on uncheck, shows when all 5 selected */
if ($(this).val()) {
if ($(this).is(':checked') && $('input[type=checkbox]').filter(':checked').length == 5) {
$('#opts').show();
} else {
$('#opts').hide();
}
}
});
$('#output-format').on('change', function() {
var resultFormat = $('#output-format option:checked').text();
if (resultFormat == 'JSON (formatted)' || resultFormat == 'CSV (no header)' || resultFormat == 'CSV (with header)') {
$('input[name=wrapper-array]').attr('disabled', true);
$('input[name=wrapper-array]').prop('checked', false);
$('input[name=wrapper-array]').parent().css('color', 'grey');
} else {
$('input[name=wrapper-array]').attr("disabled", false);
$('input[name=wrapper-array]').parent().css('color', '');
}
});
$("form#queryform").submit(function() {
$('#output-message').html("");
$.post("/", $("form#queryform").serialize(), function(data) {
var durPattern = '<PRE>Duration';
var errorPattern = /<div class="accordion" id="errorblock">/g;
var sectionsSeparator = '<h4>';
var resultPat = 'Results:</h4>';
if (errorPattern.test(data)) {
$('#output-heading').html('Error');
$('#output-heading').addClass('error');
} else {
$('#output-heading').html('Output');
$('#output-heading').removeClass('error');
}
var executedStatements = data.split('<!-- BEGIN -->');
var executedStatementsWithResultsCount = 0;
for (var i = 0; i < executedStatements.length; i++) {
if (executedStatements[i].toString().trim().length > 0) {
/* check how many statements have returned data*/
executedStatementsWithResultsCount++;
}
}
/* only a single statement returned results and/or duration message*/
if (executedStatementsWithResultsCount <= 2) {
/* print statement results and duration*/
$('#output-message').html(data);
} else {
var resultsCount = 1;
/* need to create collapse button and div per statement*/
for (var i = 0; i < executedStatements.length; i++) {
/* last statement is always the duration message*/
if (i == (executedStatements.length - 1)) {
/* print duration message*/
$('#output-message').append(executedStatements[i]);
break;
}
if (executedStatements[i].toString().trim().length > 0) {
var sections = executedStatements[i].toString().split(sectionsSeparator);
/* remove the first section since it is always empty due to splitng on sectionsSeparator */
sections.splice(0, 1);
/* if there is a results section, we need to put it before the collapsible section*/
for (var j = 0; j < sections.length; j++) {
/* print results section and remove it*/
if (sections[j].indexOf(resultPat) >= 0) {
var resultsSection = sections.splice(j, 1);
$('#output-message').append(sectionsSeparator + resultsSection.toString());
}
}
if (sections.length > 0) {
/* generate the collapsible section for this statement*/
$('<button/>')
.attr("class", "btn")
.attr("data-toggle", "collapse")
.attr("data-target", "#collapse" + i)
.css("margin-bottom", "1em")
.html('Result Plan #' + resultsCount + '<i id="ibtn' + resultsCount + '" class="icon-plus extarget"></i>')
.appendTo('#output-message');
$('<div/>')
.attr("id", "collapse" + i)
.attr("class", "collapse in")
.appendTo('#output-message');
/* put the rest of the sections in the collapsible section*/
for (var k = 0; k < sections.length; k++) {
$('#collapse' + i).append(sectionsSeparator + sections[k].toString());
}
}
$('#output-message').append("<hr/>");
resultsCount++;
/* Placeholder for future on show/hide result plan behavior
$('#collapse' + resSet).on('show', function() {
}).on('hide', function() {
});
*/
}
}
}
/* Handling Pretty JSON-query result */
var resultFormat = $('#output-format option:checked').text();
if ( resultFormat == 'JSON (formatted)') {
$('.result-content').each(
function(idx) {
var results = $(this).text().split('\n');
$(this).css('padding-left', '20px');
$(this).text('');
for (var iter1 = 0; iter1 < results.length - 1; iter1++) {
if (results[iter1].length < 1) {
continue;
}
var str_obj = results[iter1].replace(/:\s*(\d+)([\s,])/g, ': "#bigint#$1#bigint#"$2');
resultJSON = JSON.parse(str_obj, (key, value) => {
if (/^#bigint#\d+#bigint#/g.test(value)) {
value = value.substring(8, value.length - 8);
return BigInt(value);
}
return value;
});
$(this).append($('<div/>').attr("id", "json-record"+idx+"-"+iter1));
$('#json-record'+idx+"-"+iter1).jsonViewer(resultJSON, {collapsed: true, level: 10});
}
}
);
}
/* Handling Pretty JSON-logical plan */
var planFormat = $('#plan-format option:checked').text();
$('.query-plan').addClass("outer");
$('.query-optimized-plan').addClass("outer");
if ( planFormat == 'JSON (formatted)') {
$('.query-plan').each(
function() {
var planSt = $(this).text();
$(this).text('');
var planJSON = $.parseJSON(planSt);
$(this).append($('<div/>').attr("id", "json-queryPlan"));
$('#json-queryPlan').jsonViewer(planJSON, {collapsed: false, level: 10});
}
);
$('.query-optimized-plan').each(
function() {
var opPlanSt = $(this).text();
$(this).text('');
var opPlanJSON = $.parseJSON(opPlanSt);
$(this).append($('<div/>').attr("id", "json-queryOptimizedPlan").attr("class","inner"));
$('#json-queryOptimizedPlan').jsonViewer(opPlanJSON, {collapsed: false, level: 10});
}
);
}
var contentString = data.toString();
if (contentString.indexOf(durPattern) != -1) {
$('<div/>')
.addClass("alert alert-success")
.html("Success: Query Complete")
.appendTo('#output-message');
}
});
return false;
});
});
</script>
<meta charset=utf-8 />
<title>AsterixDB Web Interface</title>
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<!-- Temporary logo placeholder -->
<a class="brand" href="#"><img src="/webui/static/img/finalasterixlogo.png"></a>
<div class="nav-collapse collapse">
<ul class="nav">
<li><a href="https://asterixdb.apache.org/" target="_blank">
Open source<img class="extarget" src="/webui/static/img/targetlink.png"/></a></li>
<li><a href="https://issues.apache.org/jira/browse/ASTERIXDB" target="_blank">
File issues<img class="extarget" src="/webui/static/img/targetlink.png"/></a></li>
<li><a href="https://ci.apache.org/projects/asterixdb/index.html" target="_blank">
Documentation<img class="extarget" src="/webui/static/img/targetlink.png"/></a></li>
<li><a href="https://asterixdb.apache.org/community.html" target="_blank">
Contact<img class="extarget" src="/webui/static/img/targetlink.png"/></a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="content">
<div class="container">
<div class="row-fluid">
<div class="span6">
<form id="queryform" class="form-horizontal" method="post">
<div style="margin-bottom: 1em;">
<label class="query">Query</label>
<textarea rows="10" id="qry" name="query" class="query" value="%s"
placeholder="Type your query ..."></textarea>
</div>
<div class="btn-group">
<button id="checkboxes-on" class="btn">
<i id="opts" class="icon-ok" style="display:none;"></i>Select Options
</button>
<button id="clear-query-button" class="btn">Clear Query</button>
<!-- <button id="checkboxes-off" class="btn">Clear All Options</button> -->
<button type="submit" id="run-btn" class="btn btn-custom-darken">Run</button>
</div>
<div>
<label id="query-language" class="optlabel"> Query Language:<br/>
<select name="query-language" class="btn btn-width">
<option selected value="SQLPP">SQL++</option>
<option value="AQL">AQL</option>
</select>
</label>
<label id="output-format" class="optlabel"> Output Format:<br/>
<select name="output-format" class="btn btn-width">
<option selected value="CLEAN_JSON">JSON</option>
<option value="CLEAN_JSON">JSON (formatted)</option>
<option value="ADM">ADM</option>
<option value="CSV">CSV (no header)</option>
<option value="CSV-Header">CSV (with header)</option>
<option value="LOSSLESS_JSON">JSON (lossless)</option>
</select>
</label>
<label id="plan-format" class="optlabel"> Plan Format:<br/>
<select name="plan-format" class="btn btn-width">
<option selected value="JSON">JSON</option>
<option value="CLEAN_JSON">JSON (formatted)</option>
<option value="STRING">String</option>
</select>
</label>
<label class="optlabel"><input type="checkbox" name="wrapper-array" value="true"/> Wrap results
in outer array</label>
<label class="checkbox optlabel"><input type="checkbox" name="print-expr-tree" value="true"/>
Print parsed expressions</label>
<label class="checkbox optlabel"><input type="checkbox" name="print-rewritten-expr-tree"
value="true"/> Print rewritten expressions</label>
<div><label class="checkbox optlabel"><input type="checkbox"
name="print-logical-plan"
value="true"/> Print logical
plan</label></div>
<div><label class="checkbox optlabel"><input type="checkbox"
name="print-optimized-logical-plan"
value="true"/> Print optimized
logical plan</label></div>
<label class="checkbox optlabel"><input type="checkbox" name="print-job" value="true"/> Print
Hyracks job</label>
<label class="optlabel"><input type="checkbox" name="execute-query" value="true" checked/>
Execute query</label>
</div>
</form>
</div>
<div class="span6">
<div class="output">
<label id="output-heading" class="heading">Output</label>
<div id="output-message" class="message">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="footer">
<section class="line">
<hr>
</section>
<section class="content">
<section class="left">
</section>
<section class="right">
</section>
</section>
</div>
</body>
</html>