You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2015/08/21 13:05:47 UTC
[6/7] incubator-ignite git commit: # GG-843 Merged with ignite-961.
# GG-843 Merged with ignite-961.
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/17a681c7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/17a681c7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/17a681c7
Branch: refs/heads/ignite-843
Commit: 17a681c78d87101c328ce2a139662600beb204ae
Parents: 494f978
Author: Andrey <an...@gridgain.com>
Authored: Fri Aug 21 18:03:04 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Fri Aug 21 18:03:04 2015 +0700
----------------------------------------------------------------------
examples/pom.xml | 8 +
.../ignite/examples/NodeJsExamplesSelfTest.java | 94 ++++++++++
.../JettyRestProcessorAbstractSelfTest.java | 59 ++++++-
.../src/main/js/controllers/sql-controller.js | 141 ++++++++-------
.../src/main/js/public/stylesheets/style.scss | 69 +++++++-
.../src/main/js/routes/agent.js | 21 +++
.../src/main/js/views/sql/sql.jade | 149 ++++++----------
.../processors/rest/GridRestCommand.java | 3 +
.../processors/rest/GridRestProcessor.java | 3 +-
.../handlers/query/QueryCommandHandler.java | 100 +++++++++--
.../rest/request/RestQueryRequest.java | 175 +++++++++++++++++++
.../rest/request/RestSqlQueryRequest.java | 125 -------------
modules/nodejs/src/main/js/apache-ignite.js | 5 +-
modules/nodejs/src/main/js/cache.js | 32 +++-
modules/nodejs/src/main/js/query.js | 52 ++++++
modules/nodejs/src/main/js/scan-query.js | 52 ++++++
modules/nodejs/src/main/js/server.js | 4 +-
modules/nodejs/src/main/js/sql-fields-query.js | 70 +-------
modules/nodejs/src/test/js/test-query.js | 51 +++++-
modules/nodejs/src/test/js/test-runner.js | 4 +-
.../nodejs/src/test/js/test-script-runner.js | 39 +++++
.../http/jetty/GridJettyRestHandler.java | 35 +++-
22 files changed, 888 insertions(+), 403 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index 8204a36..54dc2ea 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -63,6 +63,14 @@
<dependency>
<groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-nodejs</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/examples/src/test/java/org/apache/ignite/examples/NodeJsExamplesSelfTest.java
----------------------------------------------------------------------
diff --git a/examples/src/test/java/org/apache/ignite/examples/NodeJsExamplesSelfTest.java b/examples/src/test/java/org/apache/ignite/examples/NodeJsExamplesSelfTest.java
new file mode 100644
index 0000000..53f194f
--- /dev/null
+++ b/examples/src/test/java/org/apache/ignite/examples/NodeJsExamplesSelfTest.java
@@ -0,0 +1,94 @@
+/*
+ *
+ * * 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.
+ *
+ */
+
+package org.apache.ignite.examples;
+
+import org.apache.ignite.configuration.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+
+/**
+ * Test for nodejs examples.
+ */
+public class NodeJsExamplesSelfTest extends NodeJsAbstractTest {
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ return loadConfiguration("examples/config/js/example-query.xml");
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ startGrid(0);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ stopAllGrids();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testCacheApiExample() throws Exception {
+ run("cache-api-example.js");
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testCachePutGetExample() throws Exception {
+ run("cache-put-get-example.js");
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testQueryExample() throws Exception {
+ run("cache-query-example.js");
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testFieldsQueryExample() throws Exception {
+ run("cache-sql-fields-query-example.js");
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testComputeRunExample() throws Exception {
+ run("compute-run-example.js");
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testComputeMapReduceExample() throws Exception {
+ run("map-reduce-example.js");
+ }
+
+ /**
+ * @param fileName Example file name.
+ * @throws Exception If failed.
+ */
+ private void run(String fileName) throws Exception {
+ runJsScript(null, U.getIgniteHome() + "/examples/src/main/js/" + fileName, ">>> end");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
index 26c22af..4dc3bdc 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/JettyRestProcessorAbstractSelfTest.java
@@ -27,6 +27,7 @@ import org.apache.ignite.configuration.*;
import org.apache.ignite.internal.processors.json.*;
import org.apache.ignite.internal.processors.rest.handlers.*;
import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.lang.*;
import org.apache.ignite.testframework.*;
import java.io.*;
@@ -1333,6 +1334,52 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
/**
* @throws Exception If failed.
*/
+ public void testQueryScan() throws Exception {
+ Map<String, String> params = new HashMap<>();
+ params.put("cmd", GridRestCommand.EXECUTE_SCAN_QUERY.key());
+ params.put("pageSize", "10");
+ params.put("cacheName", "person");
+ params.put("classname", ScanFilter.class.getName());
+
+ String ret = content(params);
+
+ assertNotNull(ret);
+ assertTrue(!ret.isEmpty());
+
+ JSONObject json = JSONObject.fromObject(ret);
+
+ List items = (List)((Map)json.get("response")).get("items");
+
+ assertEquals(2, items.size());
+
+ assertFalse(queryCursorFound());
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testIncorrectQueryScan() throws Exception {
+ Map<String, String> params = new HashMap<>();
+ params.put("cmd", GridRestCommand.EXECUTE_SCAN_QUERY.key());
+ params.put("pageSize", "10");
+ params.put("cacheName", "person");
+ params.put("classname", ScanFilter.class.getName() + 1);
+
+ String ret = content(params);
+
+ assertNotNull(ret);
+ assertTrue(!ret.isEmpty());
+
+ JSONObject json = JSONObject.fromObject(ret);
+
+ String err = (String)json.get("error");
+
+ assertTrue(err.contains("Failed to find target class"));
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
public void testQuery() throws Exception {
grid(0).cache(null).put("1", "1");
grid(0).cache(null).put("2", "2");
@@ -1648,7 +1695,7 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
String qry = "salary > ? and salary <= ?";
String ret = makePostRequest(F.asMap("cmd", GridRestCommand.EXECUTE_SQL_QUERY.key(),
- "type", "Person", "psz", "10", "cacheName", "person",
+ "type", "Person", "pageSize", "10", "cacheName", "person",
"qry", URLEncoder.encode(qry)), "{\"arg\": [1000, 2000]}");
assertNotNull(ret);
@@ -1775,4 +1822,14 @@ public abstract class JettyRestProcessorAbstractSelfTest extends AbstractRestPro
return id;
}
}
+
+ /**
+ * Test filter for scan query.
+ */
+ public static class ScanFilter implements IgniteBiPredicate<Integer, Person> {
+ /** {@inheritDoc} */
+ @Override public boolean apply(Integer integer, Person person) {
+ return person.salary > 1000;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/control-center-web/src/main/js/controllers/sql-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/sql-controller.js b/modules/control-center-web/src/main/js/controllers/sql-controller.js
index d02dec0..7a1eb49 100644
--- a/modules/control-center-web/src/main/js/controllers/sql-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/sql-controller.js
@@ -38,9 +38,6 @@ controlCenterModule.controller('sqlController', ['$scope', '$controller', '$http
$scope.notebook = notebook;
$scope.notebook_name = notebook.name;
-
- if (notebook.paragraphs)
- notebook.paragraphs = [{name: 'Query'}];
})
.error(function (errMsg) {
$common.showError(errMsg);
@@ -50,50 +47,63 @@ controlCenterModule.controller('sqlController', ['$scope', '$controller', '$http
loadNotebook();
$scope.renameNotebook = function(name) {
- $scope.notebook_edit = false;
+ if ($scope.notebook.name != name) {
+ $scope.notebook.name = name;
- $scope.notebook.name = name;
+ $http.post('/notebooks/save', $scope.notebook)
+ .success(function () {
+ var idx = _.findIndex($scope.$root.notebooks, function (item) {
+ return item._id == $scope.notebook._id;
+ });
- $http.post('/notebooks/save', $scope.notebook)
- .success(function () {
- var idx = _.findIndex($scope.$root.notebooks, function (item) {
- return item._id == $scope.notebook._id;
- });
+ if (idx >= 0) {
+ $scope.$root.notebooks[idx].name = name;
- if (idx >= 0) {
- $scope.$root.notebooks[idx].name = name;
+ $scope.$root.rebuildDropdown();
+ }
- $scope.$root.rebuildDropdown();
- }
- })
- .error(function (errMsg) {
- $common.showError(errMsg);
- });
+ $scope.notebook.edit = false;
+ })
+ .error(function (errMsg) {
+ $common.showError(errMsg);
+ });
+ }
+ else
+ $scope.notebook.edit = false
};
- $scope.resetNotebookName = function() {
- $scope.notebook_edit = false;
+ $scope.renameParagraph = function(paragraph, newName) {
+ if (paragraph.name != newName) {
+ paragraph.name = newName;
- $scope.notebook_name = $scope.notebook.name;
+ $http.post('/notebooks/save', $scope.notebook)
+ .success(function () {
+ paragraph.edit = false;
+ })
+ .error(function (errMsg) {
+ $common.showError(errMsg);
+ });
+ }
+ else
+ paragraph.edit = false
};
- $scope.addParagraph = function(notebook) {
- notebook.paragraphs.push({});
- };
+ $scope.addParagraph = function() {
+ if (!$scope.notebook.paragraphs)
+ $scope.notebook.paragraphs = [];
- $scope.tabs = [];
+ var sz = $scope.notebook.paragraphs.length;
- $scope.addTab = function() {
- var tab = {query: "", pageSize: $scope.pageSizes[0]};
+ var paragraph = {name: 'Query' + (sz ==0 ? '' : sz), editor: true, query: '', pageSize: $scope.pageSizes[0]};
if ($scope.caches.length > 0)
- tab.selectedItem = $scope.caches[0];
+ paragraph.cache = $scope.caches[0];
- $scope.tabs.push(tab);
+ $scope.notebook.paragraphs.push(paragraph);
};
- $scope.removeTab = function(idx) {
- $scope.tabs.splice(idx, 1);
+ $scope.removeParagraph = function(idx) {
+ $scope.notebook.splice(idx, 1);
};
$http.get('/models/sql.json')
@@ -113,8 +123,8 @@ controlCenterModule.controller('sqlController', ['$scope', '$controller', '$http
$scope.caches = node.caches;
- if ($scope.tabs.length == 0)
- $scope.addTab();
+ $scope.addParagraph();
+ $scope.addParagraph();
})
.error(function (err, status) {
$scope.caches = undefined;
@@ -125,59 +135,60 @@ controlCenterModule.controller('sqlController', ['$scope', '$controller', '$http
$common.showError('Receive agent error: ' + err);
});
- $scope.execute = function(tab) {
- $http.post('/agent/query', {query: tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
- .success(function (res) {
- tab.meta = [];
+ var _processQueryResult = function(item) {
+ return function(res) {
+ item.meta = [];
- if (res.meta)
- tab.meta = res.meta;
+ if (res.meta)
+ item.meta = res.meta;
- tab.page = 1;
+ item.page = 1;
- tab.total = 0;
+ item.total = 0;
- tab.queryId = res.queryId;
+ item.queryId = res.queryId;
- tab.rows = res.rows;
- })
+ item.rows = res.rows;
+
+ item.result = 'table';
+ }
+ };
+
+ $scope.execute = function(item) {
+ $http.post('/agent/query', {query: item.query, pageSize: item.pageSize, cacheName: item.cache.name})
+ .success(_processQueryResult(item))
.error(function (errMsg) {
$common.showError(errMsg);
});
};
- $scope.explain = function(tab) {
- $http.post('/agent/query', {query: 'EXPLAIN ' + tab.query, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
- .success(function (res) {
- tab.meta = [];
-
- if (res.meta)
- tab.meta = res.meta;
-
- tab.page = 1;
-
- tab.total = 0;
-
- tab.queryId = res.queryId;
+ $scope.explain = function(item) {
+ $http.post('/agent/query', {query: 'EXPLAIN ' + item.query, pageSize: item.pageSize, cacheName: item.cache.name})
+ .success(_processQueryResult)
+ .error(function (errMsg) {
+ $common.showError(errMsg);
+ });
+ };
- tab.rows = res.rows;
- })
+ $scope.scan = function(item) {
+ $http.post('/agent/scan', {pageSize: item.pageSize, cacheName: item.cache.name})
+ .success(_processQueryResult(item))
.error(function (errMsg) {
$common.showError(errMsg);
});
};
- $scope.nextPage = function(tab) {
- $http.post('/agent/query/fetch', {queryId: tab.queryId, pageSize: tab.pageSize, cacheName: tab.selectedItem.name})
+ $scope.nextPage = function(item) {
+ $http.post('/agent/query/fetch', {queryId: item.queryId, pageSize: item.pageSize, cacheName: item.cache.name})
.success(function (res) {
- tab.page++;
+ item.page++;
- tab.total += tab.rows.length;
+ item.total += item.rows.length;
- tab.rows = res.rows;
+ item.rows = res.rows;
if (res.last)
- delete tab.queryId;
+ delete item.queryId;
})
.error(function (errMsg) {
$common.showError(errMsg);
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/control-center-web/src/main/js/public/stylesheets/style.scss
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/public/stylesheets/style.scss b/modules/control-center-web/src/main/js/public/stylesheets/style.scss
index e42e91f..1ebb373 100644
--- a/modules/control-center-web/src/main/js/public/stylesheets/style.scss
+++ b/modules/control-center-web/src/main/js/public/stylesheets/style.scss
@@ -15,6 +15,8 @@
* limitations under the License.
*/
+@import "../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";
+
$logo-path: "https://www.filepicker.io/api/file/QagunjDGRFul2JgNCAli";
$input-height: 28px;
$ignite-red: #ec1c24;
@@ -675,6 +677,12 @@ button .caret, .btn .caret {
height: $input-height;
}
+.sql-name-input {
+ @extend .form-control;
+
+ width: auto;
+}
+
.form-control {
@extend .base-control;
@@ -685,12 +693,36 @@ button .caret, .btn .caret {
}
}
-.form-control-h1 {
- @extend .form-control;
+.theme-line .notebook-header {
+ color: black;
+ border-color: #eee;
- width: auto;
font-size: 22px;
+ line-height: 44px;
height: 44px;
+
+ h1 {
+ padding: 0;
+ line-height: 44px;
+ height: 44px;
+ margin: 0;
+ }
+
+ i {
+ line-height: 44px;
+ height: 44px;
+ font-size: 14px;
+ }
+
+ input {
+ font-size: 22px;
+ line-height: 44px;
+ height: 44px;
+ }
+}
+
+.theme-line .paragraph-header {
+
}
.line-control {
@@ -703,11 +735,25 @@ button .caret, .btn .caret {
h3 {
margin-bottom: 0;
+
+ .result {
+ float: right;
+ i {
+ font-size: 14px;
+ line-height: 14px;
+ }
+ }
}
h3 > a {
color: black;
}
+
+ i {
+ font-size: 14px;
+ }
+
+
}
.theme-line .panel-body {
@@ -859,6 +905,23 @@ button .caret, .btn .caret {
line-height: $input-height;
}
+
+ tfoot > tr > td {
+ padding: 0;
+
+ .pagination {
+ margin: 10px 0 0 0;
+
+ > .active > a {
+ color: $ignite-red;
+ font-weight: bold;
+ border-color: #ddd;
+ background-color: #eee;
+ }
+ }
+ }
+
+ margin: 0;
}
.panel-title a {
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/control-center-web/src/main/js/routes/agent.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/routes/agent.js b/modules/control-center-web/src/main/js/routes/agent.js
index d0fba45..4b23b2e 100644
--- a/modules/control-center-web/src/main/js/routes/agent.js
+++ b/modules/control-center-web/src/main/js/routes/agent.js
@@ -20,6 +20,7 @@ var agentManager = require('../agents/agent-manager');
var apacheIgnite = require('apache-ignite');
var SqlFieldsQuery = apacheIgnite.SqlFieldsQuery;
+var ScanQuery = apacheIgnite.ScanQuery;
function _client(req, res) {
var client = agentManager.getAgentManager().findClient(req.currentUserId());
@@ -77,6 +78,26 @@ router.post('/query', function (req, res) {
}
});
+/* Execute query. */
+router.post('/scan', function (req, res) {
+ var client = _client(req, res);
+
+ if (client) {
+ // Create sql query.
+ var qry = new ScanQuery();
+
+ // Set page size for query.
+ qry.setPageSize(req.body.pageSize);
+
+ // Get query cursor.
+ client.ignite().cache(req.body.cacheName).query(qry).nextPage().then(function (cursor) {
+ res.json({meta: cursor.fieldsMetadata(), rows: cursor.page(), queryId: cursor.queryId()});
+ }, function (err) {
+ res.status(500).send(err);
+ });
+ }
+});
+
/* Get next query page. */
router.post('/query/fetch', function (req, res) {
var client = _client(req, res);
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/control-center-web/src/main/js/views/sql/sql.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/sql/sql.jade b/modules/control-center-web/src/main/js/views/sql/sql.jade
index aa770ae..e49e3ad 100644
--- a/modules/control-center-web/src/main/js/views/sql/sql.jade
+++ b/modules/control-center-web/src/main/js/views/sql/sql.jade
@@ -25,34 +25,46 @@ block container
.row
.col-sm-12(ng-init='noteId = "#{noteId}";')
.docs-content(ng-controller='sqlController' )
- .docs-header
- h1
- a(ng-hide='notebook_edit' ng-click='notebook_edit = true;' style='line-height: 44px;') {{notebook.name}}
- div(ng-show='notebook_edit')
- input.form-control-h1(ng-model='notebook_name' on-enter='renameNotebook(notebook_name)' on-escape='resetNotebookName()')
+ .docs-header.notebook-header
+ h1.col-sm-6(ng-hide='notebook.edit')
+ a {{notebook.name}}
+ i.fa.fa-pencil.tipLabel(ng-click='notebook.edit = true;notebook.edit_name = notebook.name' bs-tooltip data-title='Rename notebook' data-trigger='hover')
+ h1.col-sm-6(ng-show='notebook.edit')
+ input.sql-name-input(ng-model='notebook.edit_name' on-enter='renameNotebook(notebook.edit_name)' on-escape='notebook.edit = false;')
+ i.tipLabel.fa.fa-floppy-o(ng-click='renameNotebook(notebook.edit_name)' bs-tooltip data-title='Save notebook name' data-trigger='hover')
+ h1.col-sm-6
+ i.tipField.fa.fa-plus(ng-click='addParagraph()' bs-tooltip data-title='Add new paragraph' data-trigger='hover')
+ .docs-body(style='margin-top: 20px;')
hr
- .docs-body
- .panel-group(bs-collapse ng-model='notebook.activeIdx')
+ .panel-group(bs-collapse ng-model='notebook.activeIdx' data-allow-multiple='true' data-start-collapsed='false')
.panel.panel-default(ng-repeat='paragraph in notebook.paragraphs')
.panel-heading
- h3
+ h3(ng-hide='paragraph.edit')
a(bs-collapse-toggle ng-click='hidePopover()') {{paragraph.name}}
+ i.fa.fa-pencil.tipLabel(ng-click='paragraph.edit = true; paragraph.edit_name = paragraph.name;' bs-tooltip data-title='Rename paragraph' data-trigger='hover')
+ .result.btn-group(ng-model='paragraph.result')
+ i.btn.btn-default.fa.fa-table(ng-click='paragraph.result="table"' bs-tooltip data-title='Show table' data-trigger='hover')
+ i.btn.btn-default.fa.fa-bar-chart(ng-click='paragraph.result="bar"' bs-tooltip data-title='Show bar chart' data-trigger='hover')
+ h3(ng-show='paragraph.edit')
+ input.sql-name-input(ng-model='paragraph.edit_name' on-enter='renameParagraph(paragraph, paragraph.edit_name)' on-escape='paragraph.edit = false;')
+ i.tipLabel.fa.fa-floppy-o(ng-click='renameParagraph(paragraph, paragraph.edit_name)' bs-tooltip data-title='Save paragraph name' data-trigger='hover')
.panel-collapse(role='tabpanel' bs-collapse-target)
- .panel-body
+ .panel-body(ng-show='paragraph.editor')
.row
.col-xs-8.col-sm-9(style='border-right: 1px solid #eee')
div(style='height: 200px' ui-ace='{ theme: "chrome", mode: "sql",' +
'require: ["ace/ext/language_tools"],' +
'rendererOptions: {showPrintMargin: false, highlightGutterLine: false, fontSize: 14},' +
- 'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' ng-model='paragraph.query')
+ 'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' ng-model='paragraph.query'
+ ng-class='{"disable": paragraph.status == "RUNNING" || paragraph.status == "PENDING" }')
.col-xs-4.col-sm-3
div(ng-hide='caches.length == 0' style='margin-top: 0.65em')
lable.labelHeader Caches:
table.links(st-table='caches')
tbody
tr(ng-repeat='cache in caches track by cache.name')
- td.col-sm-6(ng-class='{active: cache.name == paragraph.activeCache.name}')
- a(ng-click='paragraph.activeCache = row') {{$index + 1}}) {{::cache.name}}, {{::cache.mode}}
+ td.col-sm-6(ng-class='{active: cache.name == paragraph.cache.name}')
+ a(ng-click='paragraph.cache = cache') {{$index + 1}}) {{::cache.name}}, {{::cache.mode}}
hr(style='margin: 0')
.settings-row
label Page Size:
@@ -61,90 +73,29 @@ block container
button.btn.btn-primary(ng-click='explain(paragraph)') Explain
button.btn.btn-primary(ng-click='execute(paragraph)') Execute
button.btn.btn-primary(ng-click='scan(paragraph)') Scan
-
- // div(ng-show='#{tab}.rows.length > 0' style='margin-top: 0.65em')
- // hr
- // div
- // table.table.table-striped.col-sm-12.sql-results(st-table='displayedCollection' st-safe-src='#{tab}.rows')
- // thead
- // tr(style='border-size: 0')
- // td(colspan='{{#{tab}.meta.length}}')
- // .col-sm-8
- // lable Page #:
- // b {{#{tab}.page}}
- // | Results:
- // b {{#{tab}.rows.length + #{tab}.total}}
- // .col-sm-4
- // button.btn.btn-primary.fieldButton(ng-click='nextPage(#{tab})' ng-disabled='!#{tab}.queryId') Next page
- // //.input-tip
- // // input.form-control(st-search placeholder='Filter...' type='search')
- // tr
- // th(ng-repeat='col in #{tab}.meta track by $index' st-sort='getter' data-ng-bind='::col.fieldName' bs-tooltip='col.schemaName + "." + col.typeName + "." + col.fieldName')
- // tbody
- // //tr
- // // td(colspan='{{#{tab}.cols.length}}')
- // // .loading-indicator
- // tr(ng-repeat='row in displayedCollection track by $index')
- // td(ng-repeat='val in row track by $index') {{ val }}
- //
- //
- //
- //div(ng-if='!caches')
- // .block-callout-right.margin-bottom-dflt(style='width: 100%')
- // p(ng-bind-html='joinTip(missingClientTip)')
- //div(ng-if='caches')
- // .block-callout-parent.block-callout-border.margin-bottom-dflt
- // .block-callout
- // p(ng-bind-html='joinTip(screenTip)')
- //
- // - var tab = 'tabs[tabs.activeIdx]'
- //
- // .tabs-below(bs-tabs bs-active-pane='tabs.activeIdx' data-template='/tab')
- // div(ng-repeat='tab in tabs' title='Query' bs-pane)
- // .row
- // .col-xs-8.col-sm-9(style='border-right: 1px solid #eee')
- // div(style='height: 200px' ui-ace='{ theme: "chrome", mode: "sql",' +
- // 'require: ["ace/ext/language_tools"],' +
- // 'rendererOptions: {showPrintMargin: false, highlightGutterLine: false, fontSize: 14},' +
- // 'advanced: {enableSnippets: false, enableBasicAutocompletion: true, enableLiveAutocompletion: true}}' ng-model='#{tab}.query')
- // .col-xs-4.col-sm-3
- // div(ng-hide='caches.length == 0' style='margin-top: 0.65em')
- // lable.labelHeader Caches:
- // table.links(st-table='caches')
- // tbody
- // tr(ng-repeat='row in caches track by row.name')
- // td.col-sm-6(ng-class='{active: row.name == #{tab}.selectedItem.name}')
- // a(ng-click='#{tab}.selectedItem = row') {{$index + 1}}) {{::row.name}}, {{::row.mode}}
- // hr(style='margin: 0')
- // .settings-row
- // label Page Size:
- // button.btn.btn-default.base-control(ng-model='#{tab}.pageSize' bs-options='item for item in pageSizes' bs-select)
- // .settings-row
- // button.btn.btn-primary(ng-click='explain(#{tab})') Explain
- // button.btn.btn-primary(ng-click='execute(#{tab})') Execute
- // button.btn.btn-primary(ng-click='scan(#{tab})' disabled) Scan
- //
- // div(ng-show='#{tab}.rows.length > 0' style='margin-top: 0.65em')
- // hr
- // div
- // table.table.table-striped.col-sm-12.sql-results(st-table='displayedCollection' st-safe-src='#{tab}.rows')
- // thead
- // tr(style='border-size: 0')
- // td(colspan='{{#{tab}.meta.length}}')
- // .col-sm-8
- // lable Page #:
- // b {{#{tab}.page}}
- // | Results:
- // b {{#{tab}.rows.length + #{tab}.total}}
- // .col-sm-4
- // button.btn.btn-primary.fieldButton(ng-click='nextPage(#{tab})' ng-disabled='!#{tab}.queryId') Next page
- // //.input-tip
- // // input.form-control(st-search placeholder='Filter...' type='search')
- // tr
- // th(ng-repeat='col in #{tab}.meta track by $index' st-sort='getter' data-ng-bind='::col.fieldName' bs-tooltip='col.schemaName + "." + col.typeName + "." + col.fieldName')
- // tbody
- // //tr
- // // td(colspan='{{#{tab}.cols.length}}')
- // // .loading-indicator
- // tr(ng-repeat='row in displayedCollection track by $index')
- // td(ng-repeat='val in row track by $index') {{ val }}
+ .panel-body(ng-show='paragraph.result == "table')
+ table.table.table-striped.col-sm-12.sql-results(st-table='displayedCollection' st-safe-src='paragraph.rows')
+ thead
+ tr(style='border-size: 0')
+ td(colspan='{{paragraph.meta.length}}')
+ .col-sm-8
+ lable Page #:
+ b {{paragraph.page}}
+ | Results:
+ b {{paragraph.rows.length + paragraph.total}}
+ .col-sm-4
+ button.btn.btn-primary.fieldButton(ng-click='nextPage(paragraph)' ng-disabled='!paragraph.queryId') Next page
+ //.input-tip
+ // input.form-control(st-search placeholder='Filter...' type='search')
+ tr
+ th(ng-repeat='col in paragraph.meta track by $index' st-sort='getter' data-ng-bind='::col.fieldName' bs-tooltip='col.schemaName + "." + col.typeName + "." + col.fieldName')
+ tbody
+ //tr
+ // td(colspan='{{#{tab}.cols.length}}')
+ // .loading-indicator
+ tr(ng-repeat='row in displayedCollection track by $index')
+ td(ng-repeat='val in row track by $index') {{ val }}
+ tfoot
+ tr
+ td.text-right(colspan='{{paragraph.meta.length}}')
+ div(st-pagination st-items-by-page='10' st-displayed-pages='5')
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
index d28119a..cabe5fd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
@@ -153,6 +153,9 @@ public enum GridRestCommand {
/** Execute sql fields query. */
EXECUTE_SQL_FIELDS_QUERY("qryfldexe"),
+ /** Execute scan query. */
+ EXECUTE_SCAN_QUERY("qryscanexe"),
+
/** Fetch query results. */
FETCH_SQL_QUERY("qryfetch"),
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
index 5937c14..ccf4d47 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java
@@ -540,10 +540,11 @@ public class GridRestProcessor extends GridProcessorAdapter {
case EXECUTE_SQL_QUERY:
case EXECUTE_SQL_FIELDS_QUERY:
+ case EXECUTE_SCAN_QUERY:
case CLOSE_SQL_QUERY:
case FETCH_SQL_QUERY:
perm = SecurityPermission.CACHE_READ;
- name = ((RestSqlQueryRequest)req).cacheName();
+ name = ((RestQueryRequest)req).cacheName();
break;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
index 43ecc0c..e121b23 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/query/QueryCommandHandler.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.util.future.*;
import org.apache.ignite.internal.util.typedef.internal.*;
import org.apache.ignite.lang.*;
+import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
@@ -42,6 +43,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
/** Supported commands. */
private static final Collection<GridRestCommand> SUPPORTED_COMMANDS = U.sealList(EXECUTE_SQL_QUERY,
EXECUTE_SQL_FIELDS_QUERY,
+ EXECUTE_SCAN_QUERY,
FETCH_SQL_QUERY,
CLOSE_SQL_QUERY);
@@ -68,23 +70,24 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
assert req != null;
assert SUPPORTED_COMMANDS.contains(req.command());
- assert req instanceof RestSqlQueryRequest : "Invalid type of query request.";
+ assert req instanceof RestQueryRequest : "Invalid type of query request.";
switch (req.command()) {
case EXECUTE_SQL_QUERY:
- case EXECUTE_SQL_FIELDS_QUERY: {
+ case EXECUTE_SQL_FIELDS_QUERY:
+ case EXECUTE_SCAN_QUERY: {
return ctx.closure().callLocalSafe(
- new ExecuteQueryCallable(ctx, (RestSqlQueryRequest)req, qryCurs), false);
+ new ExecuteQueryCallable(ctx, (RestQueryRequest)req, qryCurs), false);
}
case FETCH_SQL_QUERY: {
return ctx.closure().callLocalSafe(
- new FetchQueryCallable(ctx, (RestSqlQueryRequest)req, qryCurs), false);
+ new FetchQueryCallable(ctx, (RestQueryRequest)req, qryCurs), false);
}
case CLOSE_SQL_QUERY: {
return ctx.closure().callLocalSafe(
- new CloseQueryCallable((RestSqlQueryRequest)req, qryCurs), false);
+ new CloseQueryCallable((RestQueryRequest)req, qryCurs), false);
}
}
@@ -99,7 +102,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
private GridKernalContext ctx;
/** Execute query request. */
- private RestSqlQueryRequest req;
+ private RestQueryRequest req;
/** Queries cursors. */
private ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs;
@@ -109,7 +112,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
* @param req Execute query request.
* @param qryCurs Queries cursors.
*/
- public ExecuteQueryCallable(GridKernalContext ctx, RestSqlQueryRequest req,
+ public ExecuteQueryCallable(GridKernalContext ctx, RestQueryRequest req,
ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) {
this.ctx = ctx;
this.req = req;
@@ -123,15 +126,33 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
try {
Query qry;
- if (req.typeName() != null) {
- qry = new SqlQuery(req.typeName(), req.sqlQuery());
+ switch (req.queryType()) {
+ case SQL:
+ qry = new SqlQuery(req.typeName(), req.sqlQuery());
- ((SqlQuery)qry).setArgs(req.arguments());
- }
- else {
- qry = new SqlFieldsQuery(req.sqlQuery());
+ ((SqlQuery)qry).setArgs(req.arguments());
+
+ break;
+
+ case SQL_FIELDS:
+ qry = new SqlFieldsQuery(req.sqlQuery());
+
+ ((SqlFieldsQuery)qry).setArgs(req.arguments());
+
+ break;
+
+ case SCAN:
+ IgniteBiPredicate pred = null;
- ((SqlFieldsQuery)qry).setArgs(req.arguments());
+ if (req.className() != null)
+ pred = instance(IgniteBiPredicate.class, req.className());
+
+ qry = new ScanQuery(pred);
+
+ break;
+
+ default:
+ throw new IgniteException("Incorrect query type [type=" + req.queryType() + "]");
}
IgniteCache<Object, Object> cache = ctx.grid().cache(req.cacheName());
@@ -182,7 +203,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
*/
private static class CloseQueryCallable implements Callable<GridRestResponse> {
/** Execute query request. */
- private RestSqlQueryRequest req;
+ private RestQueryRequest req;
/** Queries cursors. */
private final ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs;
@@ -191,7 +212,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
* @param req Execute query request.
* @param qryCurs Queries cursors.
*/
- public CloseQueryCallable(RestSqlQueryRequest req,
+ public CloseQueryCallable(RestQueryRequest req,
ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) {
this.req = req;
this.qryCurs = qryCurs;
@@ -225,7 +246,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
*/
private static class FetchQueryCallable implements Callable<GridRestResponse> {
/** Execute query request. */
- private RestSqlQueryRequest req;
+ private RestQueryRequest req;
/** Queries cursors. */
private final ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs;
@@ -238,7 +259,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
* @param req Execute query request.
* @param qryCurs Queries cursors.
*/
- public FetchQueryCallable(GridKernalContext ctx, RestSqlQueryRequest req,
+ public FetchQueryCallable(GridKernalContext ctx, RestQueryRequest req,
ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs) {
this.ctx = ctx;
this.req = req;
@@ -276,7 +297,7 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
*/
private static CacheQueryResult createQueryResult(
ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCurs,
- Iterator cur, RestSqlQueryRequest req, Long qryId, GridKernalContext ctx) {
+ Iterator cur, RestQueryRequest req, Long qryId, GridKernalContext ctx) {
CacheQueryResult res = new CacheQueryResult();
List<Object> items = new ArrayList<>();
@@ -295,4 +316,45 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
return res;
}
+
+ /**
+ * Creates class instance.
+ *
+ * @param cls Target class.
+ * @param clsName Implementing class name.
+ * @return Class instance.
+ * @throws IgniteException If failed.
+ */
+ private static <T> T instance(Class<? extends T> cls, String clsName) throws IgniteException {
+ try {
+ Class<?> implCls = Class.forName(clsName);
+
+ if (!cls.isAssignableFrom(implCls))
+ throw new IgniteException("Failed to create instance (target class does not extend or implement " +
+ "required class or interface) [cls=" + cls.getName() + ", clsName=" + clsName + ']');
+
+ Constructor<?> ctor = implCls.getConstructor();
+
+ return (T)ctor.newInstance();
+ }
+ catch (ClassNotFoundException e) {
+ throw new IgniteException("Failed to find target class: " + clsName, e);
+ }
+ catch (NoSuchMethodException e) {
+ throw new IgniteException("Failed to find constructor for provided arguments " +
+ "[clsName=" + clsName + ']', e);
+ }
+ catch (InstantiationException e) {
+ throw new IgniteException("Failed to instantiate target class " +
+ "[clsName=" + clsName + ']', e);
+ }
+ catch (IllegalAccessException e) {
+ throw new IgniteException("Failed to instantiate class (constructor is not available) " +
+ "[clsName=" + clsName + ']', e);
+ }
+ catch (InvocationTargetException e) {
+ throw new IgniteException("Failed to instantiate class (constructor threw an exception) " +
+ "[clsName=" + clsName + ']', e.getCause());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestQueryRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestQueryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestQueryRequest.java
new file mode 100644
index 0000000..a719776
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestQueryRequest.java
@@ -0,0 +1,175 @@
+/*
+ *
+ * * 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.
+ *
+ */
+
+package org.apache.ignite.internal.processors.rest.request;
+
+/**
+ * Sql query request.
+ */
+public class RestQueryRequest extends GridRestRequest {
+ /** Sql query. */
+ private String sqlQry;
+
+ /** Sql query arguments. */
+ private Object[] args;
+
+ /** Page size. */
+ private Integer pageSize;
+
+ /** Cache name. */
+ private String cacheName;
+
+ /** Query id. */
+ private Long qryId;
+
+ /** Query type name. */
+ private String typeName;
+
+ /** Predicate class name for scan query. */
+ private String className;
+
+ /** Query type. */
+ private QueryType type;
+
+ /**
+ * @param sqlQry Sql query.
+ */
+ public void sqlQuery(String sqlQry) {
+ this.sqlQry = sqlQry;
+ }
+
+ /**
+ * @return Sql query.
+ */
+ public String sqlQuery() {
+ return sqlQry;
+ }
+
+ /**
+ * @param args Sql query arguments.
+ */
+ public void arguments(Object[] args) {
+ this.args = args;
+ }
+
+ /**
+ * @return Sql query arguments.
+ */
+ public Object[] arguments() {
+ return args;
+ }
+
+ /**
+ * @param pageSize Page size.
+ */
+ public void pageSize(Integer pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ /**
+ * @return Page size.
+ */
+ public int pageSize() {
+ return pageSize;
+ }
+
+ /**
+ * @param cacheName Cache name.
+ */
+ public void cacheName(String cacheName) {
+ this.cacheName = cacheName;
+ }
+
+ /**
+ * @return Cache name.
+ */
+ public String cacheName() {
+ return cacheName;
+ }
+
+ /**
+ * @param id Query id.
+ */
+ public void queryId(Long id) {
+ this.qryId = id;
+ }
+
+ /**
+ * @return Query id.
+ */
+ public Long queryId() {
+ return qryId;
+ }
+
+ /**
+ * @param typeName Query type name.
+ */
+ public void typeName(String typeName) {
+ this.typeName = typeName;
+ }
+
+ /**
+ * @return Query type name.
+ */
+ public String typeName() {
+ return typeName;
+ }
+
+ /**
+ * @return Predicate class name for scan query.
+ */
+ public String className() {
+ return className;
+ }
+
+ /**
+ * @param className Predicate class name for scan query.
+ */
+ public void className(String className) {
+ this.className = className;
+ }
+
+ /**
+ * @param type Query type.
+ */
+ public void queryType(QueryType type) {
+ this.type = type;
+ }
+
+ /**
+ * @return Query type.
+ */
+ public QueryType queryType() {
+ return type;
+ }
+
+ /**
+ * Supported query types.
+ */
+ public enum QueryType {
+ /** Sql query. */
+ SQL,
+
+ /** Sql fields query. */
+ SQL_FIELDS,
+
+ /** Scan query. */
+ SCAN
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestSqlQueryRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestSqlQueryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestSqlQueryRequest.java
deleted file mode 100644
index 5ba3a50..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/request/RestSqlQueryRequest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.ignite.internal.processors.rest.request;
-
-/**
- * Sql query request.
- */
-public class RestSqlQueryRequest extends GridRestRequest {
- /** Sql query. */
- private String sqlQry;
-
- /** Sql query arguments. */
- private Object[] args;
-
- /** Page size. */
- private Integer pageSize;
-
- /** Cache name. */
- private String cacheName;
-
- /** Query id. */
- private Long qryId;
-
- /** Query type name. */
- private String typeName;
-
- /**
- * @param sqlQry Sql query.
- */
- public void sqlQuery(String sqlQry) {
- this.sqlQry = sqlQry;
- }
-
- /**
- * @return Sql query.
- */
- public String sqlQuery() {
- return sqlQry;
- }
-
- /**
- * @param args Sql query arguments.
- */
- public void arguments(Object[] args) {
- this.args = args;
- }
-
- /**
- * @return Sql query arguments.
- */
- public Object[] arguments() {
- return args;
- }
-
- /**
- * @param pageSize Page size.
- */
- public void pageSize(Integer pageSize) {
- this.pageSize = pageSize;
- }
-
- /**
- * @return Page size.
- */
- public int pageSize() {
- return pageSize;
- }
-
- /**
- * @param cacheName Cache name.
- */
- public void cacheName(String cacheName) {
- this.cacheName = cacheName;
- }
-
- /**
- * @return Cache name.
- */
- public String cacheName() {
- return cacheName;
- }
-
- /**
- * @param id Query id.
- */
- public void queryId(Long id) {
- this.qryId = id;
- }
-
- /**
- * @return Query id.
- */
- public Long queryId() {
- return qryId;
- }
-
- /**
- * @param typeName Query type name.
- */
- public void typeName(String typeName) {
- this.typeName = typeName;
- }
-
- /**
- * @return Query type name.
- */
- public String typeName() {
- return typeName;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/main/js/apache-ignite.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/apache-ignite.js b/modules/nodejs/src/main/js/apache-ignite.js
index 053b88a..5c54c33 100644
--- a/modules/nodejs/src/main/js/apache-ignite.js
+++ b/modules/nodejs/src/main/js/apache-ignite.js
@@ -22,5 +22,6 @@ module.exports = {
Ignite : require('./ignite.js').Ignite,
Compute : require('./compute.js').Compute,
SqlQuery : require('./sql-query.js').SqlQuery,
- SqlFieldsQuery : require('./sql-fields-query.js').SqlFieldsQuery
-}
\ No newline at end of file
+ SqlFieldsQuery : require('./sql-fields-query.js').SqlFieldsQuery,
+ ScanQuery : require('./scan-query.js').ScanQuery
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/main/js/cache.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/cache.js b/modules/nodejs/src/main/js/cache.js
index 7c04843..0a6dae2 100644
--- a/modules/nodejs/src/main/js/cache.js
+++ b/modules/nodejs/src/main/js/cache.js
@@ -274,7 +274,7 @@ Cache.prototype.metadata = function(callback) {
/**
* Execute sql query
*
- * @param {SqlQuery|SqlFieldsQuery} qry Query
+ * @param {SqlQuery|SqlFieldsQuery|ScanQuery} qry Query
* @returns {QueryCursor} Cursor for current query.
*/
Cache.prototype.query = function(qry) {
@@ -308,7 +308,7 @@ Cache.prototype._createCommand = function(name) {
* @constructor
* @this {QueryCursor}
* @param {Cache} cache Cache that runs query
- * @param {SqlQuery|SqlFieldsQuery} qry Sql query
+ * @param {SqlQuery|SqlFieldsQuery|ScanQuery} qry Sql query
* @param {boolean} init True if query is not started
* @param {Object[]} res Current page result
* @param fieldsMeta Fields metadata.
@@ -485,17 +485,23 @@ QueryCursor.prototype.isFinished = function() {
QueryCursor.prototype._getQueryCommand = function() {
if (this._init) {
+ this._init = false;
+
if (this._qry.type() === "Sql") {
return this._sqlQuery(this._qry);
}
+ else if (this._qry.type() == "SqlFields") {
+ return this._sqlFieldsQuery(this._qry);
+ }
+ else if (this._qry.type() == "Scan") {
+ return this._scanQuery(this._qry);
+ }
- this._init = false;
-
- return this._sqlFieldsQuery(this._qry);
+ return null;
}
return this._cache._createCommand("qryfetch").addParam("qryId", this._res.queryId).
- addParam("psz", this._qry.pageSize());
+ addParam("pageSize", this._qry.pageSize());
}
QueryCursor.prototype._sqlFieldsQuery = function(qry) {
@@ -508,9 +514,19 @@ QueryCursor.prototype._sqlQuery = function(qry) {
setPostData(JSON.stringify({"arg" : qry.arguments()}));
}
+QueryCursor.prototype._scanQuery = function(qry) {
+ var cmd = new Command("qryscanexe").addParam("cacheName", this._cache._cacheName).
+ addParam("pageSize", qry.pageSize());
+
+ if (qry.filterClassName() != null)
+ cmd.addParam("classname", qry.filterClassName());
+
+ return cmd;
+}
+
QueryCursor.prototype._createQueryCommand = function(name, qry) {
return new Command(name).addParam("cacheName", this._cache._cacheName).
- addParam("qry", qry.query()).addParam("psz", qry.pageSize());
+ addParam("qry", qry.query()).addParam("pageSize", qry.pageSize());
}
/**
@@ -524,4 +540,4 @@ function CacheEntry(key0, val0) {
}
exports.Cache = Cache
-exports.CacheEntry = CacheEntry
\ No newline at end of file
+exports.CacheEntry = CacheEntry
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/main/js/query.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/query.js b/modules/nodejs/src/main/js/query.js
new file mode 100644
index 0000000..221dd76
--- /dev/null
+++ b/modules/nodejs/src/main/js/query.js
@@ -0,0 +1,52 @@
+/*
+ *
+ * * 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.
+ *
+ */
+
+/**
+ * @this {Query}
+ */
+function Query() {
+ this._qryType = "";
+ this._pageSz = 1;
+}
+
+/**
+ * @this {Query}
+ * @param {int} pageSz Page size.
+ */
+Query.prototype.setPageSize = function(pageSz) {
+ this._pageSz = pageSz;
+}
+
+/**
+ * @this {Query}
+ * @returns pageSize
+ */
+Query.prototype.pageSize = function() {
+ return this._pageSz;
+}
+
+/**
+ * @this {Query}
+ * @returns "SqlFields"
+ */
+Query.prototype.type = function() {
+ return this._qryType;
+}
+
+exports.Query = Query;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/main/js/scan-query.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/scan-query.js b/modules/nodejs/src/main/js/scan-query.js
new file mode 100644
index 0000000..1e211c2
--- /dev/null
+++ b/modules/nodejs/src/main/js/scan-query.js
@@ -0,0 +1,52 @@
+/*
+ *
+ * * 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.
+ *
+ */
+
+var Query = require("./query").Query
+
+/**
+ * @this {ScanQuery}
+ */
+function ScanQuery() {
+ Query.apply(this, arguments);
+ this._className = null;
+ this._qryType = "Scan";
+}
+
+ScanQuery.prototype = Query.prototype;
+
+ScanQuery.prototype.constructor = ScanQuery;
+
+
+/**
+ * @this {ScanQuery}
+ * @param type Filter class name
+ */
+ScanQuery.prototype.setFilterClassName = function(className) {
+ this._className = className;
+}
+
+/**
+ * @this {ScanQuery}
+ * @returns Filter class name
+ */
+ScanQuery.prototype.filterClassName = function() {
+ return this._className;
+}
+
+exports.ScanQuery = ScanQuery;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/main/js/server.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/server.js b/modules/nodejs/src/main/js/server.js
index 7fa22b1..b81073c 100644
--- a/modules/nodejs/src/main/js/server.js
+++ b/modules/nodejs/src/main/js/server.js
@@ -86,8 +86,6 @@ Server.prototype.runCommand = function(cmd, callback) {
});
response.on('end', function () {
- //console.log("Full response:" + fullResponseString);
-
if (response.statusCode !== 200) {
if (response.statusCode === 401) {
callback.call(null, "Authentication failed. Status code 401.");
@@ -250,4 +248,4 @@ Command.prototype._isPost = function() {
}
exports.Server = Server;
-exports.Command = Command;
\ No newline at end of file
+exports.Command = Command;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/main/js/sql-fields-query.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/main/js/sql-fields-query.js b/modules/nodejs/src/main/js/sql-fields-query.js
index edc9f4c..36615a1 100644
--- a/modules/nodejs/src/main/js/sql-fields-query.js
+++ b/modules/nodejs/src/main/js/sql-fields-query.js
@@ -15,65 +15,23 @@
* limitations under the License.
*/
+var Query = require("./query").Query
+
/**
* @this {SqlFieldsQuery}
* @param {string} Sql query
*/
function SqlFieldsQuery(sql) {
+ Query.apply(this, arguments);
this._qryType = "SqlFields";
this._sql = sql;
this._arg = [];
this._pageSz = 1;
- this._type = null;
- this._endFunc = function(err) {console.log("Empty end function is called [err=" + err + "]")};
- this._pageFunc = function(res) {console.log("Empty page function is called [res=" + res + "]")}
-}
-
-/**
- * Set the callbacks for query events.
- *
- * @this {SqlFieldsQuery}
- * @param {string} code Function code could be "end", "page"
- * @param function Functions "end" and "page" are one argument functions.
- */
-SqlFieldsQuery.prototype.on = function(code, f) {
- switch(code) {
- case "end":
- this._endFunc = f;
-
- break;
- case "page":
- this._pageFunc = f;
-
- break;
- default :
- throw "Sql do not have method " + code;
- }
-}
-
-/**
- * @this {SqlFieldsQuery}
- * @param res Query result
- */
-SqlFieldsQuery.prototype.end = function(err) {
- this._endFunc(err);
}
-/**
- * @this {SqlFieldsQuery}
- * @param res Query data
- */
-SqlFieldsQuery.prototype.page = function(res) {
- this._pageFunc(res);
-}
+SqlFieldsQuery.prototype = Query.prototype;
-/**
- * @this {SqlFieldsQuery}
- * @param {int} pageSz Page size.
- */
-SqlFieldsQuery.prototype.setPageSize = function(pageSz) {
- this._pageSz = pageSz;
-}
+SqlFieldsQuery.prototype.constructor = SqlFieldsQuery;
/**
* @this {SqlFieldsQuery}
@@ -99,20 +57,4 @@ SqlFieldsQuery.prototype.arguments = function() {
return this._arg;
}
-/**
- * @this {SqlFieldsQuery}
- * @returns pageSize
- */
-SqlFieldsQuery.prototype.pageSize = function() {
- return this._pageSz;
-}
-
-/**
- * @this {SqlFieldsQuery}
- * @returns "SqlFields"
- */
-SqlFieldsQuery.prototype.type = function() {
- return this._qryType;
-}
-
-exports.SqlFieldsQuery = SqlFieldsQuery;
\ No newline at end of file
+exports.SqlFieldsQuery = SqlFieldsQuery;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/test/js/test-query.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/test/js/test-query.js b/modules/nodejs/src/test/js/test-query.js
index 3d55886..293b2ea 100644
--- a/modules/nodejs/src/test/js/test-query.js
+++ b/modules/nodejs/src/test/js/test-query.js
@@ -22,6 +22,7 @@ var assert = require("assert");
var Ignite = require(TestUtils.scriptPath());
var SqlQuery = Ignite.SqlQuery;
var SqlFieldsQuery = Ignite.SqlFieldsQuery;
+var ScanQuery = Ignite.ScanQuery;
testSqlQuery = function() {
TestUtils.startIgniteNode().then(function(ignite) {
@@ -59,10 +60,46 @@ testSqlQuery = function() {
cursor.nextPage().then(onQuery);
}).catch(function(err) {
- assert(err === null, err);
+ TestUtils.testFails(err);
})
}).catch(function(err) {
- assert(err === null, err);
+ TestUtils.testFails(err);
+ });
+}
+
+testScanQuery = function() {
+ TestUtils.startIgniteNode().then(function(ignite) {
+ var qry = new ScanQuery();
+
+ var fullRes = [];
+
+ function onQuery(cursor) {
+ var page = cursor.page();
+
+ fullRes = fullRes.concat(page);
+
+ if (cursor.isFinished()) {
+ console.log("Full result=" + JSON.stringify(fullRes));
+
+ assert(fullRes.length === 4, "Result length is not correct" +
+ "[expected=1, val = " + fullRes.length + "]");
+
+ fullRes.sort();
+
+ assert(fullRes[0]["key"] >= 0,
+ "Result has incorrect index [res=" + fullRes[0]["key"] + "]");
+
+ return ignite.cache("person").get("key");
+ }
+
+ return cursor.nextPage().then(onQuery);
+ }
+
+ ignite.cache("person").query(qry).nextPage().then(onQuery).then(function(){
+ TestUtils.testDone();
+ })
+ }).catch(function(err) {
+ TestUtils.testFails(err);
});
}
@@ -98,7 +135,7 @@ testSqlFieldsQuery = function() {
TestUtils.testDone();
})
}).catch(function(err) {
- assert(err === null, err);
+ TestUtils.testFails(err);
});
}
@@ -148,7 +185,7 @@ testSqlFieldsGetAllQuery = function() {
TestUtils.testDone();
})
}).catch(function(err) {
- assert(err === null, err);
+ TestUtils.testFails(err);
});
}
@@ -193,7 +230,7 @@ testSqlFieldsMeta = function() {
ignite.cache("person").query(qry).nextPage().then(onQuery);
}).catch(function(err) {
- assert(err === null, err);
+ TestUtils.testFails(err);
});
}
@@ -232,6 +269,6 @@ testSqlQueryWithParams = function() {
ignite.cache("person").query(qry).nextPage().then(onQuery);
}).catch(function(err) {
- assert(err === null, err);
+ TestUtils.testFails(err);
});
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/test/js/test-runner.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/test/js/test-runner.js b/modules/nodejs/src/test/js/test-runner.js
index 9ee1092..adbad85 100644
--- a/modules/nodejs/src/test/js/test-runner.js
+++ b/modules/nodejs/src/test/js/test-runner.js
@@ -31,7 +31,7 @@ TestRunner.runTest = function() {
console.log("FileName " + fileName);
- require("./" + fileName);
+ require(fileName);
var functionName = process.argv[3].toString().trim();
@@ -43,4 +43,4 @@ TestRunner.runTest = function() {
global[functionName]();
}
-TestRunner.runTest();
\ No newline at end of file
+TestRunner.runTest();
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/nodejs/src/test/js/test-script-runner.js
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/test/js/test-script-runner.js b/modules/nodejs/src/test/js/test-script-runner.js
new file mode 100644
index 0000000..7223d51
--- /dev/null
+++ b/modules/nodejs/src/test/js/test-script-runner.js
@@ -0,0 +1,39 @@
+/*
+ *
+ * * 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.
+ *
+ */
+
+/**
+ * Create instance of ScriptTestRunner
+ *
+ * @constructor
+ */
+function ScriptTestRunner() {
+}
+
+/**
+ * Test routine
+ */
+ScriptTestRunner.runTest = function() {
+ var fileName = process.argv[2].toString().trim();
+
+ console.log("FileName " + fileName);
+
+ require(fileName);
+}
+
+ScriptTestRunner.runTest();
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/17a681c7/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
index edd1745..59b22d4 100644
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
@@ -24,6 +24,7 @@ import org.apache.ignite.internal.*;
import org.apache.ignite.internal.processors.rest.*;
import org.apache.ignite.internal.processors.rest.client.message.*;
import org.apache.ignite.internal.processors.rest.request.*;
+import org.apache.ignite.internal.processors.rest.request.RestQueryRequest.*;
import org.apache.ignite.internal.util.typedef.*;
import org.apache.ignite.internal.util.typedef.internal.*;
import org.apache.ignite.lang.*;
@@ -640,7 +641,7 @@ public class GridJettyRestHandler extends AbstractHandler {
case EXECUTE_SQL_QUERY:
case EXECUTE_SQL_FIELDS_QUERY: {
- RestSqlQueryRequest restReq0 = new RestSqlQueryRequest();
+ RestQueryRequest restReq0 = new RestQueryRequest();
restReq0.sqlQuery((String) params.get("qry"));
@@ -661,20 +662,46 @@ public class GridJettyRestHandler extends AbstractHandler {
restReq0.cacheName((String)params.get("cacheName"));
+ if (cmd.equals(EXECUTE_SQL_QUERY))
+ restReq0.queryType(QueryType.SQL);
+ else
+ restReq0.queryType(QueryType.SQL_FIELDS);
+
+ restReq = restReq0;
+
+ break;
+ }
+
+ case EXECUTE_SCAN_QUERY: {
+ RestQueryRequest restReq0 = new RestQueryRequest();
+
+ restReq0.sqlQuery((String)params.get("qry"));
+
+ String pageSize = (String)params.get("pageSize");
+
+ if (pageSize != null)
+ restReq0.pageSize(Integer.parseInt(pageSize));
+
+ restReq0.cacheName((String)params.get("cacheName"));
+
+ restReq0.className((String)params.get("classname"));
+
+ restReq0.queryType(QueryType.SCAN);
+
restReq = restReq0;
break;
}
case FETCH_SQL_QUERY: {
- RestSqlQueryRequest restReq0 = new RestSqlQueryRequest();
+ RestQueryRequest restReq0 = new RestQueryRequest();
String qryId = (String) params.get("qryId");
if (qryId != null)
restReq0.queryId(Long.parseLong(qryId));
- String pageSize = (String) params.get("pageSize");
+ String pageSize = (String)params.get("pageSize");
if (pageSize != null)
restReq0.pageSize(Integer.parseInt(pageSize));
@@ -687,7 +714,7 @@ public class GridJettyRestHandler extends AbstractHandler {
}
case CLOSE_SQL_QUERY: {
- RestSqlQueryRequest restReq0 = new RestSqlQueryRequest();
+ RestQueryRequest restReq0 = new RestQueryRequest();
String qryId = (String) params.get("qryId");