Till Westmann has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/1097
Change subject: some WebUI hackery
......................................................................
some WebUI hackery
- use query/service endpoint (and SQL++)
- add option to display JSON
- some code simplification
Change-Id: I32361a523e656c62a6bc878b1eed9750579097f9
---
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java
M asterixdb/asterix-app/src/main/resources/queryui/css/master.css
M asterixdb/asterix-app/src/main/resources/queryui/js/main.js
M asterixdb/asterix-app/src/main/resources/queryui/queryui.html
4 files changed, 134 insertions(+), 123 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/97/1097/1
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java
index 5b91f2f..45267ac 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/QueryServiceServlet.java
@@ -397,6 +397,8 @@
SessionConfig sessionConfig = createSessionConfig(request,
resultWriter);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.JSON.str());
+ response.addHeader("Access-Control-Allow-Origin", "*");
+ response.addHeader("Access-Control-Allow-Headers", "Origin,
X-Requested-With, Content-Type, Accept");
int respCode = HttpServletResponse.SC_OK;
Stats stats = new Stats();
diff --git a/asterixdb/asterix-app/src/main/resources/queryui/css/master.css
b/asterixdb/asterix-app/src/main/resources/queryui/css/master.css
index b44169c..44778a7 100644
--- a/asterixdb/asterix-app/src/main/resources/queryui/css/master.css
+++ b/asterixdb/asterix-app/src/main/resources/queryui/css/master.css
@@ -162,6 +162,13 @@
color: #000;
}
+.asterix-inline-json{
+ padding: 0px;
+ margin: 0px;
+ text-decoration: none;
+ color: #2d60e0;
+}
+
.asterix-list-view{
background-color: #FFF;
}
diff --git a/asterixdb/asterix-app/src/main/resources/queryui/js/main.js
b/asterixdb/asterix-app/src/main/resources/queryui/js/main.js
index 991e624..6fd66aa 100644
--- a/asterixdb/asterix-app/src/main/resources/queryui/js/main.js
+++ b/asterixdb/asterix-app/src/main/resources/queryui/js/main.js
@@ -21,72 +21,65 @@
var DATE_TIME_REGEX = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z)$/;
var DATE_REGEX = /^(\d{4}-\d{2}-\d{2})$/;
-var app = angular.module('queryui', ['jsonFormatter','ui.codemirror']);
+var app = angular.module('queryui', ['jsonFormatter', 'ui.codemirror']);
app.service('recordFunctions', function(){
this.ObjectKeys = function(obj){
var typeStr = Object.prototype.toString.call(obj);
var res = [];
if (typeStr === "[object Object]"){
- for (var key in obj) {
- if (obj.hasOwnProperty(key) && !(key === "$$hashKey")) {
- res.push(key)
- }
- }
- }else{
- res = [-1];
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key) && !(key === "$$hashKey")){
+ res.push(key)
+ }
+ }
+ } else {
+ res = [-1];
}
return res;
}
this.isObject = function(obj){
- var typeStr = Object.prototype.toString.call(obj);
- if (typeStr === "[object Object]"){
- return true;
- }else{
- return false;
- }
+ return Object.prototype.toString.call(obj) === "[object Object]";
}
this.isArray = function(obj){
- var typeStr = Object.prototype.toString.call(obj);
- if ((typeStr === "[object Array]" )){
- return true;
- }else{
- return false;
- }
+ return Object.prototype.toString.call(obj) === "[object Array]";
}
this.isNested = function(obj){
- return this.isObject(obj) || this.isArray(obj);
+ return this.isObject(obj) || this.isArray(obj);
}
- this.ObjectValue = function(obj,key){
+ this.ObjectValue = function(obj, key){
var typeStr;
var value;
if (key == -1){
- typeStr = Object.prototype.toString.call(obj);
- value = obj;
- }else{
- typeStr = Object.prototype.toString.call(obj[key]);
- value = obj[key];
+ typeStr = Object.prototype.toString.call(obj);
+ value = obj;
+ } else {
+ typeStr = Object.prototype.toString.call(obj[key]);
+ value = obj[key];
}
if (typeStr === "[object Array]"){
return "List +";
- }else if (typeStr === "[object Object]"){
+ } else if (typeStr === "[object Object]"){
return "Record +";
- }else if (typeStr == "[object Null]"){
+ } else if (typeStr == "[object Null]"){
return "NULL";
- }else if(DATE_REGEX.exec(value) != null){
+ } else if (DATE_REGEX.exec(value) != null){
var dat = new Date(value);
- return dat.getUTCFullYear()+"/"+dat.getUTCMonth()+"/"+dat.getUTCDay();
- }else if(DATE_TIME_REGEX.exec(value) != null){
+ return dat.getUTCFullYear() + "/" + dat.getUTCMonth() + "/" +
dat.getUTCDay();
+ } else if (DATE_TIME_REGEX.exec(value) != null){
var dat = new Date(value);
- return dat.getUTCFullYear()+"/"+dat.getUTCMonth()+"/"+dat.getUTCDay()
- +" "+dat.getUTCHours()+":"+dat.getUTCMinutes()+":"+dat.getUTCSeconds();
- }else{
+ return dat.getUTCFullYear() + "/" + dat.getUTCMonth() + "/" +
dat.getUTCDay()
+ + " " + dat.getUTCHours() + ":" + dat.getUTCMinutes() + ":" +
dat.getUTCSeconds();
+ } else {
return value;
}
}
+ this.ObjectValueJson = function(obj){
+ return JSON.stringify(obj);
+ }
});
-app.controller('queryCtrl', function($rootScope, $scope, $http,
recordFunctions) {
+app.controller('queryCtrl', function($rootScope, $scope, $http,
recordFunctions){
$scope.recordFunctions = recordFunctions;
$scope.current_tab = 0;
@@ -101,71 +94,79 @@
$scope.selected_dataverse = "";
$scope.errorText = null;
$scope.statusText = "Wait...";
- $scope.query_input = "";
+ $scope.query_input = "";
$scope.uiReady = false;
- $scope.queryCmOptions ={
- lineNumbers: true,
- indentWithTabs: true,
- lineWrapping: false,
- mode: 'aql'
+ $scope.queryCmOptions = {
+ lineNumbers: true,
+ indentWithTabs: true,
+ lineWrapping: false,
+ mode: 'aql'
}
- $scope.queryPreviewOptions ={
- indentWithTabs: true,
- lineWrapping: true,
- mode: 'javascript',
- readOnly : true
+ $scope.queryPreviewOptions = {
+ indentWithTabs: true,
+ lineWrapping: true,
+ mode: 'javascript',
+ readOnly: true
}
-$scope.init= function(){
+ $scope.init = function(){
$http.post("/").then(function(response){
- SERVER_HOST = location.protocol + "//" + location.hostname + ":" +
response.data.api_port;
- $scope.initDataverses();
- },function(response){
- $scope.statusText = "Unable to get Asterix HTTP API Port";
+ SERVER_HOST = location.protocol + "//" + location.hostname + ":" +
response.data.api_port;
+ $scope.initDataverses();
+ }, function(response){
+ $scope.statusText = "Unable to get Asterix HTTP API Port";
});
-}
+ }
$scope.initDataverses = function(){
-
$http.get(SERVER_HOST+"/query?query="+encodeURI(DATAVERSE_QUERY)).then(function(response){
- for (i in response.data){
- $scope.dataverses.push(response.data[i].DataverseName);
- $scope.selected_dataverse = $scope.dataverses[0];
- $scope.statusText = "Web UI Ready";
- $scope.uiReady = true;
- }
- },
- function(response){
- $scope.statusText = "Error Occurred Executing Query";
- $scope.errorText = response.data.summary;
- $scope.maximized = false;
- });
+ $http.get(SERVER_HOST + "/query?query=" +
encodeURIComponent(DATAVERSE_QUERY)).then(function(response){
+ for (i in response.data) {
+ $scope.dataverses.push(response.data[i].DataverseName);
+ $scope.selected_dataverse = $scope.dataverses[0];
+ $scope.statusText = "Web UI Ready";
+ $scope.uiReady = true;
+ }
+ },
+ function(response){
+ $scope.statusText = "Error Occurred Executing Query";
+ $scope.errorText = response.data.summary;
+ $scope.maximized = false;
+ });
$scope.load();
}
$scope.query = function(){
var timer = new Date().getTime();
- $scope.save($scope.query_input,$scope.selected_dataverse);
- $http.get(SERVER_HOST+"/query?query="+encodeURI("use dataverse
"+$scope.selected_dataverse+";"+$scope.query_input)).then(function(response){
- $scope.results = response.data;
- console.log(response);
- timer = new Date().getTime() - timer;
- $scope.statusText = "Query returned " + $scope.results.length + "
records in " + timer + "ms";
- $scope.errorText = null;
- $scope.maximized = false;
- },
- function(response){
- $scope.statusText = "Error Occurred Executing Query";
- $scope.errorText = response.data.summary;
- $scope.maximized = false;
- $scope.results = [];
- });
+ $scope.save($scope.query_input, $scope.selected_dataverse);
+ $http.post(SERVER_HOST + "/query/service?statement=" +
encodeURIComponent("use " + $scope.selected_dataverse + ";" + $scope
+ .query_input)).then(function(response){
+ console.log(response);
+ if (response.data.status === "success"){
+ $scope.results = response.data.results;
+ timer = new Date().getTime() - timer;
+ $scope.statusText = "Query returned " + $scope.results.length + "
records in " + timer + "ms";
+ $scope.errorText = null;
+ $scope.maximized = false;
+ } else {
+ $scope.statusText = "Error Occurred Executing Query";
+ $scope.errorText = response.data.errors[0].msg;
+ $scope.maximized = false;
+ $scope.results = response.data.errors;
+ }
+ },
+ function(response){
+ $scope.statusText = "Error Occurred Executing Query";
+ $scope.errorText = response.data.summary;
+ $scope.maximized = false;
+ $scope.results = [];
+ });
}
$scope.isNested = function(obj){
for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
+ if (obj.hasOwnProperty(key)){
var typeStr = Object.prototype.toString.call(obj[key]);
if (typeStr === "[object Array]" || typeStr === "[object Object]")
return true;
}
@@ -173,14 +174,9 @@
return false;
}
- $scope.isRecordPlus = function(obj,key){
- var value;
- if (key == -1){
- value = obj;
- }else{
- value = obj[key];
- }
- return $scope.recordFunctions.isNested(value) ? "asterix-nested" : "";
+ $scope.isRecordPlus = function(obj, key){
+ var value = (key == -1) ? obj : obj[key];
+ return $scope.recordFunctions.isNested(value) ? "asterix-nested" : "";
}
$scope.viewRecord = function(obj){
@@ -190,56 +186,48 @@
}
$scope.previewJSON = function(obj){
- return JSON.stringify(obj,null,4);
+ return JSON.stringify(obj, null, 4);
}
$scope.save = function(query, database){
var toSave = [query, database];
if ($scope.history.length >= 1){
- var i = $scope.history.length - 1;
- if (new String(query).valueOf() === new
String($scope.history[i][0]).valueOf()){
- if (new String(database).valueOf() === new
String($scope.history[i][1]).valueOf()) return;
- }
+ var i = $scope.history.length - 1;
+ if (new String(query).valueOf() === new
String($scope.history[i][0]).valueOf()){
+ if (new String(database).valueOf() === new
String($scope.history[i][1]).valueOf()) return;
+ }
}
- if($scope.history.push(toSave) == 11){
+ if ($scope.history.push(toSave) == 11){
$scope.history.shift();
}
- localStorage.setItem("history",JSON.stringify($scope.history));
+ localStorage.setItem("history", JSON.stringify($scope.history));
}
$scope.load = function(){
- var history = JSON.parse(localStorage.getItem("history"));
- if (history != null) $scope.history = history;
+ var history = JSON.parse(localStorage.getItem("history"));
+ if (history != null) $scope.history = history;
}
$scope.previewHistory = function(entry){
- $scope.current_tab = 0;
- $scope.query_input = entry[0];
- $scope.selected_dataverse = entry[1];
+ $scope.current_tab = 0;
+ $scope.query_input = entry[0];
+ $scope.selected_dataverse = entry[1];
}
- $scope.leftContainerClass =function(){
- if ($scope.maximized){
- return 'col-md-12';
- }else{
- if($scope.collapsed){
- return 'col-md-1';
- }else{
- return 'col-md-4'
- }
- }
+ $scope.leftContainerClass = function(){
+ if ($scope.maximized){
+ return 'col-md-12';
+ } else {
+ return $scope.collapsed ? 'col-md-1' : 'col-md-4';
+ }
}
- $scope.rightContainerClass =function(){
- if ($scope.maximized){
- return 'col-md-0';
- }else{
- if($scope.collapsed){
- return 'col-md-11';
- }else{
- return 'col-md-8'
- }
- }
+ $scope.rightContainerClass = function(){
+ if ($scope.maximized){
+ return 'col-md-0';
+ } else {
+ return $scope.collapsed ? 'col-md-11' : 'col-md-8';
+ }
}
});
diff --git a/asterixdb/asterix-app/src/main/resources/queryui/queryui.html
b/asterixdb/asterix-app/src/main/resources/queryui/queryui.html
index 3c640fb..8785c84 100644
--- a/asterixdb/asterix-app/src/main/resources/queryui/queryui.html
+++ b/asterixdb/asterix-app/src/main/resources/queryui/queryui.html
@@ -103,12 +103,15 @@
<p class="asterix-status">{{statusText}}</p>
<div class="alert alert-danger" role="alert" ng-if="errorText !=
null">{{errorText}}</div>
<div class="right-toolbar">
- <span class="glyphicon glyphicon-align-justify asterix-button"
aria-hidden="true"
+ <span class="glyphicon glyphicon-list asterix-button"
aria-hidden="true"
ng-class="current_list == 0 ? 'asterix-button-selected' : '' "
ng-click="current_list = 0"></span>
<span class="glyphicon glyphicon-th-large asterix-button"
aria-hidden="true"
ng-class="current_list == 1 ? 'asterix-button-selected' : '' "
ng-click="current_list = 1"></span>
+ <span class="glyphicon glyphicon-align-justify asterix-button"
aria-hidden="true"
+ ng-class="current_list == 2 ? 'asterix-button-selected' : '' "
+ ng-click="current_list = 2"></span>
</div>
<div class="asterix-list-view" ng-if="current_list == 0 &&
results.length != 0">
<table class="table table-hover asterix-table">
@@ -134,6 +137,17 @@
</div>
</div>
</div>
+ <div class="asterix-list-json" ng-if="current_list == 2 &&
results.length != 0">
+ <table class="table table-hover asterix-table">
+ <tbody>
+ <tr ng-repeat="record in $parent.results track by $index">
+ <td class="asterix-inline-json"
ng-class="isRecordPlus(record,key)" ng-click="viewRecord(record)">
+ {{recordFunctions.ObjectValueJson(record)}}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
<div class="modal fade" id="recordModel" role="dialog">
<div class="modal-dialog">
<div id="input-tab">
--
To view, visit https://asterix-gerrit.ics.uci.edu/1097
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I32361a523e656c62a6bc878b1eed9750579097f9
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Till Westmann <[email protected]>