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]>

Reply via email to