mirror of https://github.com/apache/lucene.git
SOLR-8138: Simple UI for issuing SQL queries (#2381)
* Updated SOLR-8138 files for Solr 9. This code was mostly written by Michael Suzuki, i just tweaked it to load, and updated the version of ui-grid to the 4.10 version. * unused file, we use the .min version. * add an entry for the ui-grid project to license file. Co-authored-by: epugh@opensourceconnections.com <>
This commit is contained in:
parent
5e834b39eb
commit
f70a518f1b
|
@ -207,6 +207,8 @@ class RatTask extends DefaultTask {
|
|||
substringMatcher(licenseFamilyCategory: "MIT ", licenseFamilyName:"Modified BSD License") {
|
||||
// ICU license
|
||||
pattern(substring: "Permission is hereby granted, free of charge, to any person obtaining a copy")
|
||||
// ui-grid
|
||||
pattern(substring: " ; License: MIT")
|
||||
}
|
||||
|
||||
// Apache
|
||||
|
|
|
@ -223,6 +223,7 @@ New Features
|
|||
|
||||
* SOLR-15150: New update.partial.requireInPlace=true option to prevent any partial document updates that can't be done In-Place (hossman)
|
||||
|
||||
* SOLR-8138: Simple UI for issuing SQL queries (Michael Suzuki via Eric Pugh)
|
||||
|
||||
Improvements
|
||||
---------------------
|
||||
|
|
|
@ -596,3 +596,10 @@ Noggit is a fast streaming JSON parser for java. The code is included
|
|||
into Solr codebase.
|
||||
|
||||
https://github.com/yonik/noggit
|
||||
|
||||
=========================================================================
|
||||
== ui-grid notice ==
|
||||
=========================================================================
|
||||
|
||||
This product includes the Angular UI UI Grid JavaScript library.
|
||||
Copyright (c) 2015 the AngularUI Team, http://angular-ui.github.com
|
||||
|
|
|
@ -692,6 +692,7 @@ pre.syntax .tex .formula
|
|||
#content .address-bar
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
background-image: url( ../../img/ico/ui-address-bar.png );
|
||||
background-position: 5px 50%;
|
||||
border: 1px solid #f0f0f0;
|
||||
|
|
|
@ -282,6 +282,7 @@ limitations under the License.
|
|||
|
||||
.sub-menu .overview a { background-image: url( ../../img/ico/home.png ); }
|
||||
.sub-menu .query a { background-image: url( ../../img/ico/magnifier.png ); }
|
||||
.sub-menu .sqlquery a { background-image: url( ../../img/ico/sql.png ); }
|
||||
.sub-menu .stream a { background-image: url( ../../img/ico/node.png ); }
|
||||
.sub-menu .analysis a { background-image: url( ../../img/ico/funnel.png ); }
|
||||
.sub-menu .documents a { background-image: url( ../../img/ico/documents-stack.png ); }
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#content #sqlquery
|
||||
{
|
||||
}
|
||||
|
||||
#content #sqlquery #form
|
||||
{
|
||||
float: top;
|
||||
}
|
||||
|
||||
#content #sqlquery #form label
|
||||
{
|
||||
cursor: pointer;
|
||||
display: inline;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#content #sqlquery #form input,
|
||||
#content #sqlquery #form select,
|
||||
#content #sqlquery #form textarea
|
||||
{
|
||||
margin-bottom: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#content #sqlquery #form textarea
|
||||
{
|
||||
height: 125px;
|
||||
}
|
||||
|
||||
#content #sqlquery #form #start
|
||||
{
|
||||
float: left;
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
#content #sqlquery #form #rows
|
||||
{
|
||||
float: right;
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
#content #sqlquery #form input[type=checkbox]
|
||||
{
|
||||
margin-bottom: 0;
|
||||
margin-left: 5px;
|
||||
margin-right: 0px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#content #sqlquery #form fieldset
|
||||
{
|
||||
border: 1px solid #fff;
|
||||
border-top: 1px solid #c0c0c0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#content #sqlquery #form fieldset.common
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#content #sqlquery #form fieldset legend
|
||||
{
|
||||
display: block;
|
||||
margin-left: 10px;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
#content #sqlquery #form fieldset legend label
|
||||
{
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#content #sqlquery #form button
|
||||
{
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#content #sqlquery #form fieldset .fieldset
|
||||
{
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-bottom: 5px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#content #sqlquery #result
|
||||
{
|
||||
float: bottom;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #response
|
||||
{
|
||||
}
|
||||
|
||||
/************************/
|
||||
|
||||
#content #sqlquery #sql-response
|
||||
{
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-top:8px;
|
||||
}
|
||||
|
||||
#content #sqlquery #result .loader
|
||||
{
|
||||
background-position: 0 50%;
|
||||
padding-left: 21px;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #error
|
||||
{
|
||||
background-color: #f00;
|
||||
background-image: url( ../../img/ico/construction.png );
|
||||
background-position: 10px 12px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
padding-left: 35px;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #error .msg
|
||||
{
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#content #sqlquery #result .content
|
||||
{
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
#content #sqlquery #result .content.show
|
||||
{
|
||||
background-image: url( ../../img/div.gif );
|
||||
background-repeat: repeat-y;
|
||||
background-position: 31% 0;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #legend
|
||||
{
|
||||
border: 1px solid #f0f0f0;
|
||||
padding: 10px;
|
||||
/*position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;*/
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #legend li
|
||||
{
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
-webkit-box-sizing: border-box;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #legend li svg
|
||||
{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #explanation-content
|
||||
{
|
||||
min-height: 50px;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #explanation-content .node circle
|
||||
{
|
||||
color: #c48f00;
|
||||
stroke: #c48f00;
|
||||
fill: #c48f00;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #explanation-content .link
|
||||
{
|
||||
fill: none;
|
||||
stroke: #e0e0e0;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #legend .datastore circle,
|
||||
#content #sqlquery #result #explanation #explanation-content .node.datastore circle
|
||||
{
|
||||
stroke: #3800c4;
|
||||
fill: #3800c4;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #legend .sqlquery-source circle,
|
||||
#content #sqlquery #result #explanation #explanation-content .node.sqlquery-source circle
|
||||
{
|
||||
stroke: #21a9ec;
|
||||
fill: #21a9ec;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #legend .sqlquery-decorator circle,
|
||||
#content #sqlquery #result #explanation #explanation-content .node.sqlquery-decorator circle
|
||||
{
|
||||
stroke: #cb21ec;
|
||||
fill: #cb21ec;
|
||||
}
|
||||
|
||||
#content #sqlquery #result #explanation #legend .graph-source circle,
|
||||
#content #sqlquery #result #explanation #explanation-content .node.graph-source circle
|
||||
{
|
||||
stroke: #21eca9;
|
||||
fill: #21eca9;
|
||||
}
|
||||
.gridStyle {
|
||||
border: 1px solid rgb(212,212,212);
|
||||
width: 400px;
|
||||
height: 300px
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 442 B |
|
@ -46,6 +46,8 @@ limitations under the License.
|
|||
<link rel="stylesheet" type="text/css" href="css/angular/threads.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/chosen.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/overview.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/sqlquery.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/ui-grid.min.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/jquery-ui.min.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/jquery-ui.structure.min.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/jstree.style.min.css?_=${version}">
|
||||
|
@ -62,6 +64,7 @@ limitations under the License.
|
|||
<script src="libs/ngtimeago.js"></script>
|
||||
<script src="libs/highlight.js"></script>
|
||||
<script src="libs/d3.js"></script>
|
||||
<script src="libs/ui-grid.min.js"></script>
|
||||
<script src="libs/jquery-ui.min.js"></script>
|
||||
<script src="libs/angular-utf8-base64.min.js"></script>
|
||||
<script src="js/angular/app.js"></script>
|
||||
|
@ -87,6 +90,7 @@ limitations under the License.
|
|||
<script src="js/angular/controllers/schema.js"></script>
|
||||
<script src="js/angular/controllers/segments.js"></script>
|
||||
<script src="js/angular/controllers/unknown.js"></script>
|
||||
<script src="js/angular/controllers/sqlquery.js"></script>
|
||||
|
||||
|
||||
</head>
|
||||
|
@ -195,6 +199,7 @@ limitations under the License.
|
|||
<li class="files" ng-show="!isMultiDestAlias(currentCollection)" ng-class="{active:page=='files'}"><a href="#/{{currentCollection.name}}/files"><span>Files</span></a></li>
|
||||
<li class="query" ng-class="{active:page=='query'}"><a href="#/{{currentCollection.name}}/query"><span>Query</span></a></li>
|
||||
<li class="stream" ng-class="{active:page=='stream'}"><a href="#/{{currentCollection.name}}/stream"><span>Stream</span></a></li>
|
||||
<li class="sqlquery" ng-class="{active:page=='sqlquery'}"><a href="#/{{currentCollection.name}}/sqlquery"><span>SQL</span></a></li>
|
||||
<li class="schema" ng-show="!isMultiDestAlias(currentCollection)" ng-class="{active:page=='schema'}"><a href="#/{{currentCollection.name}}/schema"><span>Schema</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -20,7 +20,7 @@ if (!String.prototype.includes) {
|
|||
String.prototype.includes = function(search, start) { 'use strict';
|
||||
if (search instanceof RegExp) {
|
||||
throw TypeError('first argument must not be a RegExp');
|
||||
}
|
||||
}
|
||||
if (start === undefined) { start = 0; }
|
||||
return this.indexOf(search, start) !== -1;
|
||||
};
|
||||
|
@ -52,7 +52,8 @@ var solrAdminApp = angular.module("solrAdminApp", [
|
|||
"ngtimeago",
|
||||
"solrAdminServices",
|
||||
"localytics.directives",
|
||||
"ab-base64"
|
||||
"ab-base64",
|
||||
"ui.grid"
|
||||
]);
|
||||
|
||||
solrAdminApp.config([
|
||||
|
@ -156,6 +157,10 @@ solrAdminApp.config([
|
|||
templateUrl: 'partials/stream.html',
|
||||
controller: 'StreamController'
|
||||
}).
|
||||
when('/:core/sqlquery', {
|
||||
templateUrl: 'partials/sqlquery.html',
|
||||
controller: 'SQLQueryController'
|
||||
}).
|
||||
when('/:core/replication', {
|
||||
templateUrl: 'partials/replication.html',
|
||||
controller: 'ReplicationController'
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
solrAdminApp.controller('SQLQueryController',
|
||||
function($scope, $routeParams, $location, Query, Constants) {
|
||||
|
||||
$scope.resetMenu("sqlquery", Constants.IS_COLLECTION_PAGE);
|
||||
$scope.qt = "sql";
|
||||
$scope.doExplanation = false
|
||||
$scope.gridOptions = {
|
||||
enableSorting: false,
|
||||
enableRowHashing:false,
|
||||
enableColumnMenus:false,
|
||||
columnDefs:[],
|
||||
data:[],
|
||||
onRegisterApi: function(gridApi) {
|
||||
$scope.gridApi = gridApi;
|
||||
}
|
||||
};
|
||||
$scope.hostPortContext = $location.absUrl().substr(0,$location.absUrl().indexOf("#")); // For display only
|
||||
$scope.doQuery = function() {
|
||||
|
||||
var params = {};
|
||||
params.core = $routeParams.core;
|
||||
params.handler = $scope.qt;
|
||||
params.stmt = [$scope.stmt]
|
||||
|
||||
$scope.lang = "json";
|
||||
$scope.response = null;
|
||||
$scope.url = "";
|
||||
$scope.gridOptions.data =[]
|
||||
$scope.gridOptions.columnDefs = []
|
||||
|
||||
var url = Query.url(params);
|
||||
Query.query(params, function(data) {
|
||||
|
||||
var jsonData = JSON.parse(data.toJSON().data);
|
||||
$scope.lang = "json";
|
||||
$scope.url = url;
|
||||
$scope.sqlError = null;
|
||||
$scope.sqlData = [];
|
||||
if(jsonData != undefined){
|
||||
var docs = jsonData['result-set'].docs
|
||||
//get all docs
|
||||
for (var i = 0; i < docs.length; i++) {
|
||||
var doc = docs[i]
|
||||
//get all the properties
|
||||
if(doc.hasOwnProperty("EOF")){
|
||||
if(doc.hasOwnProperty("EXCEPTION")){
|
||||
$scope.sqlError = doc.EXCEPTION
|
||||
}
|
||||
} else {
|
||||
$scope.gridOptions.data.push(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Build the columnFields from data
|
||||
var fields = $scope.gridOptions.data[1];
|
||||
for (var property in fields) {
|
||||
if (fields.hasOwnProperty(property)) {
|
||||
$scope.gridOptions.columnDefs.push({"name":property, "type":{}})
|
||||
}
|
||||
}
|
||||
$scope.gridApi.core.notifyDataChange
|
||||
});
|
||||
};
|
||||
}
|
||||
);
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,35 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<div id="sqlquery" class="clearfix">
|
||||
<div id="form">
|
||||
<form>
|
||||
<label for="sqlexpr" title="The SQL Query">
|
||||
SQL Query Statement
|
||||
</label>
|
||||
<textarea name="stmt" ng-model="stmt" id="sqlexp"></textarea>
|
||||
<button type="submit" ng-click="doQuery()">Execute</button>
|
||||
<span><a href="https://lucene.apache.org/solr/guide/8_8/parallel-sql-interface.html" target="_out">syntax help</a></span>
|
||||
</form>
|
||||
</div>
|
||||
<div id="sql-response">
|
||||
<a ng-show="sqlData" id="url" class="address-bar" ng-href="{{url}}">{{hostPortContext}}{{url}}</a>
|
||||
<div ng-show="sqlError"> {{sqlError}}</div>
|
||||
<div ng-show="!sqlError" class="grid" ui-grid="gridOptions" id="sql-response"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue