Skip to content

Commit eb94cb3

Browse files
committed
Merge pull request #91 from eliranmoyal/master
Join limited support and more features
2 parents 8841a76 + d8f1e0e commit eb94cb3

File tree

341 files changed

+3637
-35655
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

341 files changed

+3637
-35655
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Elasticsearch-SQL
44
Query elasticsearch using familiar SQL syntax.
55
You can also use ES functions in SQL.
66

7+
**Check out our [wiki!](https://github.com/NLPchina/elasticsearch-sql/wiki)**
78

89

910
## Web frontend overview
@@ -17,7 +18,7 @@ Install as plugin:
1718

1819
### Elasticsearch 1.6.X
1920
````
20-
./bin/plugin -u https://github.com/NLPchina/elasticsearch-sql/releases/download/1.3.5/elasticsearch-sql-1.3.5.zip --install sql
21+
./bin/plugin -u https://github.com/NLPchina/elasticsearch-sql/releases/download/1.4/elasticsearch-sql-1.4.zip --install sql
2122
````
2223

2324
After doing this, you need to restart the Elasticsearch server. Otherwise you may get errors like `Invalid index name [sql], must not start with '']; ","status":400}`.

pom.xml

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>org.nlpcn</groupId>
55
<artifactId>elasticsearch-sql</artifactId>
6-
<version>1.3.5</version>
6+
<version>1.4</version>
77
<packaging>jar</packaging>
88
<description>Query elasticsearch using SQL</description>
99
<name>elasticsearch-sql</name>
@@ -66,13 +66,6 @@
6666
<scope>provided</scope>
6767
</dependency>
6868

69-
<dependency>
70-
<groupId>com.alibaba</groupId>
71-
<artifactId>fastjson</artifactId>
72-
<version>1.1.41</version>
73-
<scope>test</scope>
74-
</dependency>
75-
7669
<dependency>
7770
<groupId>org.hamcrest</groupId>
7871
<artifactId>hamcrest-all</artifactId>
@@ -87,6 +80,20 @@
8780
<scope>test</scope>
8881
</dependency>
8982

83+
<dependency>
84+
<groupId>com.alibaba</groupId>
85+
<artifactId>fastjson</artifactId>
86+
<version>1.1.41</version>
87+
<scope>test</scope>
88+
</dependency>
89+
90+
<dependency>
91+
<groupId>com.alibaba</groupId>
92+
<artifactId>druid</artifactId>
93+
<version>1.0.15</version>
94+
</dependency>
95+
96+
9097
<dependency>
9198
<groupId>com.google.guava</groupId>
9299
<artifactId>guava</artifactId>
@@ -124,7 +131,34 @@
124131
</execution>
125132
</executions>
126133
</plugin>
127-
134+
<plugin>
135+
<groupId>org.apache.maven.plugins</groupId>
136+
<artifactId>maven-dependency-plugin</artifactId>
137+
<version>2.10</version>
138+
<executions>
139+
<execution>
140+
<id>copy</id>
141+
<phase>package</phase>
142+
<goals>
143+
<goal>copy</goal>
144+
</goals>
145+
<configuration>
146+
<artifactItems>
147+
<artifactItem>
148+
<groupId>com.alibaba</groupId>
149+
<artifactId>druid</artifactId>
150+
<overWrite>false</overWrite>
151+
<outputDirectory>${project.build.directory}</outputDirectory>
152+
<destFileName>druid.jar</destFileName>
153+
</artifactItem>
154+
</artifactItems>
155+
<outputDirectory>${project.build.directory}</outputDirectory>
156+
<overWriteReleases>false</overWriteReleases>
157+
<overWriteSnapshots>true</overWriteSnapshots>
158+
</configuration>
159+
</execution>
160+
</executions>
161+
</plugin>
128162

129163
<plugin>
130164
<artifactId>maven-assembly-plugin</artifactId>

src/_site/controllers.js

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
var elasticsearchSqlApp = angular.module('elasticsearchSqlApp', ["ngAnimate", "ngSanitize"]);
23

34
elasticsearchSqlApp.controller('MainController', function ($scope, $http, $sce) {
@@ -7,9 +8,61 @@ elasticsearchSqlApp.controller('MainController', function ($scope, $http, $sce)
78
$scope.resultsRows = [];
89
$scope.searchLoading = false;
910
$scope.explainLoading = false;
11+
$scope.nextLoading = false;
1012
$scope.resultExplan = false;
11-
13+
$scope.scrollId = null;
14+
$scope.gotNext = false;
15+
16+
$scope.nextSearch = function(){
17+
$scope.error = "";
18+
$scope.nextLoading = true;
19+
$scope.$apply();
20+
21+
22+
if($scope.scrollId == null || $scope.scrollId == "" ){
23+
$scope.error = "tryed scrolling with empty scrollId";
24+
return;
25+
}
26+
27+
$http.get($scope.url + "_search/scroll?scroll=1m&scroll_id=" + $scope.scrollId)
28+
.success(function(data, status, headers, config) {
29+
var handler = ResultHandlerFactory.create(data);
30+
var body = handler.getBody()
31+
32+
if(body.length ==null || body.length == 0){
33+
$scope.gotNext=false;
34+
}
35+
else
36+
{
37+
$scope.scrollId = handler.getScrollId();
38+
}
39+
40+
if($scope.resultsRows.length > 0){
41+
$scope.resultsRows = $scope.resultsRows.concat(handler.getBody());
42+
}
43+
else {
44+
$scope.resultsColumns = handler.getHead();
45+
$scope.resultsRows = handler.getBody();
46+
47+
}
48+
49+
50+
})
51+
.error(function(data, status, headers, config) {
52+
if(data == "") {
53+
$scope.error = "Error occured! response is not avalible.";
54+
}
55+
else {
56+
$scope.error = JSON.stringify(data);
57+
$scope.scrollId = null;
58+
}
59+
})
60+
.finally(function() {
61+
$scope.nextLoading = false;
62+
$scope.$apply()
63+
});
1264

65+
}
1366

1467
$scope.search = function() {
1568
// Reset results and error box
@@ -27,6 +80,10 @@ elasticsearchSqlApp.controller('MainController', function ($scope, $http, $sce)
2780
$http.post($scope.url + "_sql", query)
2881
.success(function(data, status, headers, config) {
2982
var handler = ResultHandlerFactory.create(data);
83+
if(handler.isScroll){
84+
$scope.gotNext=true;
85+
$scope.scrollId = handler.getScrollId();
86+
}
3087
$scope.resultsColumns = handler.getHead();
3188
$scope.resultsRows = handler.getBody();
3289

@@ -88,7 +145,8 @@ elasticsearchSqlApp.controller('MainController', function ($scope, $http, $sce)
88145
data += map2csvStr(columns,rows[i],',') ;
89146

90147
}
91-
window.location='data:text/csv;charset=utf8,' + encodeURIComponent(data);
148+
var plain = 'data:text/csv;charset=utf8,' + encodeURIComponent(data);
149+
download(plain, "query_result.csv", "text/plain");
92150
return true;
93151
}
94152

@@ -109,10 +167,10 @@ elasticsearchSqlApp.controller('MainController', function ($scope, $http, $sce)
109167
}
110168

111169
function map2csvStr(columns,arr,op){
112-
var data = arr[columns[0]];
170+
var data = JSON.stringify(arr[columns[0]]);
113171
for(var i=1; i<columns.length ; i++){
114172
data += op;
115-
data += arr[columns[i]] ;
173+
data += JSON.stringify(arr[columns[i]]) ;
116174
}
117175
return data ;
118176
}

src/_site/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ <h1 class="page-header">SQL Query</h1>
105105
</button>
106106

107107
<button type="button" ng-click="explain()" id="explainButton" class="btn btn-info explain-button" ng-bind-html="getButtonContent(explainLoading,'Explain')" ng-cloak>
108+
</button>
109+
110+
<button type="next" ng-click="nextSearch()" id="nextButton" class="btn btn-warning next-button" ng-show="gotNext" ng-bind-html="getButtonContent(nextLoading,'Next')" ng-cloak>
108111
</button>
109112
</div>
110113

@@ -172,10 +175,12 @@ <h2 class="sub-header">Results</h2>
172175
<script src="vendor/codemirror/addon/hint/sql-hint.js"></script>
173176

174177
<!-- AngularJS -->
178+
<script src="vendor/download/download.min.js"></script>
175179
<script src="vendor/angularjs/angular.min.js"></script>
176180
<script src="vendor/angularjs/angular-animate.min.js"></script>
177181
<script src="vendor/angularjs/angular-sanitize.min.js"></script>
178182

183+
179184
<script src="editor.js"></script>
180185
<script src="query.js"></script>
181186
<script src="controllers.js"></script>

src/_site/query.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,19 @@ var DefaultQueryResultHandler = function(data) {
4242

4343
this.data = data
4444
this.head = createScheme()
45+
this.scrollId = data["_scroll_id"]
46+
this.isScroll = this.scrollId!=null && this.scrollId!="";
4547
};
4648

49+
DefaultQueryResultHandler.prototype.isScroll = function() {
50+
return this.isScroll;
51+
};
52+
53+
DefaultQueryResultHandler.prototype.getScrollId = function() {
54+
return this.scrollId;
55+
};
56+
57+
4758
DefaultQueryResultHandler.prototype.getHead = function() {
4859
return this.head
4960
};

src/_site/style.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ body {
123123
}
124124

125125

126+
.next-button {
127+
float:left;
128+
margin-top: 10px;
129+
}
130+
131+
126132
.keyboardSection {
127133
margin-top:35px;
128134
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//download.js v4.0, by dandavis; 2008-2015. [CCBY2] see http://danml.com/download.html for tests/usage
2+
// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
3+
// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
4+
// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.
5+
// v4 adds AMD/UMD, commonJS, and plain browser support
6+
// https://github.com/rndme/download
7+
8+
(function (root, factory) {
9+
if (typeof define === 'function' && define.amd) {
10+
// AMD. Register as an anonymous module.
11+
define([], factory);
12+
} else if (typeof exports === 'object') {
13+
// Node. Does not work with strict CommonJS, but
14+
// only CommonJS-like environments that support module.exports,
15+
// like Node.
16+
module.exports = factory();
17+
} else {
18+
// Browser globals (root is window)
19+
root.download = factory();
20+
}
21+
}(this, function () {
22+
23+
return function download(data, strFileName, strMimeType) {
24+
25+
var self = window, // this script is only for browsers anyway...
26+
u = "application/octet-stream", // this default mime also triggers iframe downloads
27+
m = strMimeType || u,
28+
x = data,
29+
D = document,
30+
a = D.createElement("a"),
31+
z = function(a){return String(a);},
32+
B = (self.Blob || self.MozBlob || self.WebKitBlob || z);
33+
B=B.call ? B.bind(self) : Blob ;
34+
var fn = strFileName || "download",
35+
blob,
36+
fr;
37+
38+
39+
if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
40+
x=[x, m];
41+
m=x[0];
42+
x=x[1];
43+
}
44+
45+
46+
47+
48+
//go ahead and download dataURLs right away
49+
if(String(x).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/)){
50+
return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs:
51+
navigator.msSaveBlob(d2b(x), fn) :
52+
saver(x) ; // everyone else can save dataURLs un-processed
53+
}//end if dataURL passed?
54+
55+
blob = x instanceof B ?
56+
x :
57+
new B([x], {type: m}) ;
58+
59+
60+
function d2b(u) {
61+
var p= u.split(/[:;,]/),
62+
t= p[1],
63+
dec= p[2] == "base64" ? atob : decodeURIComponent,
64+
bin= dec(p.pop()),
65+
mx= bin.length,
66+
i= 0,
67+
uia= new Uint8Array(mx);
68+
69+
for(i;i<mx;++i) uia[i]= bin.charCodeAt(i);
70+
71+
return new B([uia], {type: t});
72+
}
73+
74+
function saver(url, winMode){
75+
76+
if ('download' in a) { //html5 A[download]
77+
a.href = url;
78+
a.setAttribute("download", fn);
79+
a.innerHTML = "downloading...";
80+
D.body.appendChild(a);
81+
setTimeout(function() {
82+
a.click();
83+
D.body.removeChild(a);
84+
if(winMode===true){setTimeout(function(){ self.URL.revokeObjectURL(a.href);}, 250 );}
85+
}, 66);
86+
return true;
87+
}
88+
89+
if(typeof safari !=="undefined" ){ // handle non-a[download] safari as best we can:
90+
url="data:"+url.replace(/^data:([\w\/\-\+]+)/, u);
91+
if(!window.open(url)){ // popup blocked, offer direct download:
92+
if(confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")){ location.href=url; }
93+
}
94+
return true;
95+
}
96+
97+
//do iframe dataURL download (old ch+FF):
98+
var f = D.createElement("iframe");
99+
D.body.appendChild(f);
100+
101+
if(!winMode){ // force a mime that will download:
102+
url="data:"+url.replace(/^data:([\w\/\-\+]+)/, u);
103+
}
104+
f.src=url;
105+
setTimeout(function(){ D.body.removeChild(f); }, 333);
106+
107+
}//end saver
108+
109+
110+
111+
112+
if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
113+
return navigator.msSaveBlob(blob, fn);
114+
}
115+
116+
if(self.URL){ // simple fast and modern way using Blob and URL:
117+
saver(self.URL.createObjectURL(blob), true);
118+
}else{
119+
// handle non-Blob()+non-URL browsers:
120+
if(typeof blob === "string" || blob.constructor===z ){
121+
try{
122+
return saver( "data:" + m + ";base64," + self.btoa(blob) );
123+
}catch(y){
124+
return saver( "data:" + m + "," + encodeURIComponent(blob) );
125+
}
126+
}
127+
128+
// Blob but not URL:
129+
fr=new FileReader();
130+
fr.onload=function(e){
131+
saver(this.result);
132+
};
133+
fr.readAsDataURL(blob);
134+
}
135+
return true;
136+
}; /* end download() */
137+
}));

src/_site/vendor/download/download.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)