You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by iv...@apache.org on 2015/07/14 16:19:38 UTC

incubator-ignite git commit: #ignite-961-promise: add close method for query.

Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-961-promise 912bdab91 -> 7d489c169


#ignite-961-promise: add close method for query.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/7d489c16
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/7d489c16
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/7d489c16

Branch: refs/heads/ignite-961-promise
Commit: 7d489c169e17396c709f045768a338e90d484360
Parents: 912bdab
Author: ivasilinets <iv...@gridgain.com>
Authored: Tue Jul 14 17:19:28 2015 +0300
Committer: ivasilinets <iv...@gridgain.com>
Committed: Tue Jul 14 17:19:28 2015 +0300

----------------------------------------------------------------------
 examples/src/main/js/cache-query-example.js     |  21 +--
 .../main/js/cache-sql-fields-query-example.js   |  27 +---
 .../processors/rest/GridRestCommand.java        |   5 +-
 .../handlers/query/QueryCommandHandler.java     | 110 +++++++++++--
 modules/nodejs/src/main/js/cache.js             | 158 ++++++++++++-------
 modules/nodejs/src/main/js/server.js            |   2 +
 .../ignite/internal/NodeJsSqlQuerySelfTest.java |  18 +++
 modules/nodejs/src/test/js/test-query.js        |  65 ++++++--
 .../http/jetty/GridJettyRestHandler.java        |  11 ++
 9 files changed, 306 insertions(+), 111 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/examples/src/main/js/cache-query-example.js
----------------------------------------------------------------------
diff --git a/examples/src/main/js/cache-query-example.js b/examples/src/main/js/cache-query-example.js
index a83b577..5edf118 100644
--- a/examples/src/main/js/cache-query-example.js
+++ b/examples/src/main/js/cache-query-example.js
@@ -68,11 +68,11 @@ main = function() {
 
             var fullRes = [];
 
-            function onQuery(cursor) {
-                console.log(">>> Get result on page: " + JSON.stringify(res));
+            function onPage(page, cursor) {
+                console.log(">>> Get result on page: " + JSON.stringify(page));
 
                 //Concat query page results.
-                fullRes.concat(cursor.page());
+                fullRes.concat(page);
 
                 // IsFinished return true if it is the last page.
                 if (cursor.isFinished()) {
@@ -85,14 +85,17 @@ main = function() {
                 //Get Promise for next page.
             	var nextPromise = cursor.next();
 
-            	nextPromise.then(onQuery);
+            	return nextPromise.then(onQuery);
             }
 
-            // Run query.
-            ignite.cache(cacheName).query(qry).then(onQuery);
-        }).then(function(){
-            console.log(">>> End of sql query example.");
-        });
+            // Get query cursor.
+            var cursor = ignite.cache(cacheName).query(qry);
+
+            // Get query's page.
+            return cursor.nextPage().then(onQuery).then(function(){
+                console.log(">>> End of sql query example.");
+            });
+        })
     }
 
     // Initialize cache for people.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/examples/src/main/js/cache-sql-fields-query-example.js
----------------------------------------------------------------------
diff --git a/examples/src/main/js/cache-sql-fields-query-example.js b/examples/src/main/js/cache-sql-fields-query-example.js
index fed91e4..936dd4a 100644
--- a/examples/src/main/js/cache-sql-fields-query-example.js
+++ b/examples/src/main/js/cache-sql-fields-query-example.js
@@ -65,31 +65,16 @@ main = function() {
             //Set salary range.
             qry.setArguments([0, 2000]);
 
-            var fullRes = [];
-
-            function onQuery(cursor) {
-                console.log(">>> Get result on page: " + JSON.stringify(res));
-
-                //Concat query page results.
-                fullRes.concat(cursor.page());
-
-                // IsFinished return true if it is the last page.
-                if (cursor.isFinished()) {
-                    console.log(">>> Names of all employees: " + JSON.stringify(fullRes));
-
-                    return ignite.destroyCache(cacheName);
-                }
-
-                //Get Promise for next page.
-            	var nextPromise = cursor.next();
+            function onQuery(fullRes) {
+                console.log(">>> Names of all employees: " + JSON.stringify(fullRes));
 
-            	nextPromise.then(onQuery);
+                return ignite.destroyCache(cacheName);
             }
 
             // Run query.
-            ignite.cache(cacheName).query(qry).then(onQuery);
-        }).then(function(){
-            console.log(">>> End of sql fields query example.");
+            ignite.cache(cacheName).query(qry).getAll(onQuery).then(function(){
+                console.log(">>> End of sql fields query example.");
+            });
         });
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/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 45e86e0..f5c2546 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
@@ -151,7 +151,10 @@ public enum GridRestCommand {
     EXECUTE_SQL_FIELDS_QUERY("qryfieldsexecute"),
 
     /** Fetch query results. */
-    FETCH_SQL_QUERY("qryfetch");
+    FETCH_SQL_QUERY("qryfetch"),
+
+    /** Close query. */
+    CLOSE_SQL_QUERY("qryclose");
 
     /** Enum values. */
     private static final GridRestCommand[] VALS = values();

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/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 ec9575c..e2118b6 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
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.rest.handlers.query;
 
+import org.apache.ignite.*;
 import org.apache.ignite.cache.query.*;
 import org.apache.ignite.internal.*;
 import org.apache.ignite.internal.processors.rest.*;
@@ -38,7 +39,8 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
     /** Supported commands. */
     private static final Collection<GridRestCommand> SUPPORTED_COMMANDS = U.sealList(EXECUTE_SQL_QUERY,
         EXECUTE_SQL_FIELDS_QUERY,
-        FETCH_SQL_QUERY);
+        FETCH_SQL_QUERY,
+        CLOSE_SQL_QUERY);
 
     /** Query ID sequence. */
     private static final AtomicLong qryIdGen = new AtomicLong();
@@ -46,6 +48,9 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
     /** Current queries. */
     private final ConcurrentHashMap<Long, Iterator> curs = new ConcurrentHashMap<>();
 
+    /** Current queries cursors. */
+    private final ConcurrentHashMap<Long, QueryCursor> qryCurs = new ConcurrentHashMap<>();
+
     /**
      * @param ctx Context.
      */
@@ -63,21 +68,23 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
         assert req != null;
 
         assert SUPPORTED_COMMANDS.contains(req.command());
+        assert req instanceof RestSqlQueryRequest : "Invalid type of query request.";
 
         switch (req.command()) {
             case EXECUTE_SQL_QUERY:
             case EXECUTE_SQL_FIELDS_QUERY: {
-                assert req instanceof RestSqlQueryRequest : "Invalid type of query request.";
-
                 return ctx.closure().callLocalSafe(
-                    new ExecuteQueryCallable(ctx, (RestSqlQueryRequest)req, curs), false);
+                    new ExecuteQueryCallable(ctx, (RestSqlQueryRequest)req, curs, qryCurs), false);
             }
 
             case FETCH_SQL_QUERY: {
-                assert req instanceof RestSqlQueryRequest : "Invalid type of query request.";
+                return ctx.closure().callLocalSafe(
+                    new FetchQueryCallable((RestSqlQueryRequest)req, curs, qryCurs), false);
+            }
 
+            case CLOSE_SQL_QUERY: {
                 return ctx.closure().callLocalSafe(
-                    new FetchQueryCallable((RestSqlQueryRequest)req, curs), false);
+                    new CloseQueryCallable((RestSqlQueryRequest)req, curs, qryCurs), false);
             }
         }
 
@@ -94,19 +101,23 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
         /** Execute query request. */
         private RestSqlQueryRequest req;
 
-        /** Queries cursors. */
+        /** Queries iterators. */
         private ConcurrentHashMap<Long, Iterator> curs;
 
+        /** Queries cursors. */
+        private ConcurrentHashMap<Long, QueryCursor> qryCurs;
+
         /**
          * @param ctx Kernal context.
          * @param req Execute query request.
          * @param curs Queries cursors.
          */
         public ExecuteQueryCallable(GridKernalContext ctx, RestSqlQueryRequest req,
-            ConcurrentHashMap<Long, Iterator> curs) {
+            ConcurrentHashMap<Long, Iterator> curs, ConcurrentHashMap<Long, QueryCursor> qryCurs) {
             this.ctx = ctx;
             this.req = req;
             this.curs = curs;
+            this.qryCurs = qryCurs;
         }
 
         /** {@inheritDoc} */
@@ -125,13 +136,22 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
                     ((SqlFieldsQuery)qry).setArgs(req.arguments());
                 }
 
-                Iterator cur = ctx.grid().cache(req.cacheName()).query(qry).iterator();
+                IgniteCache<Object, Object> cache = ctx.grid().cache(req.cacheName());
+
+                if (cache == null)
+                    return new GridRestResponse(GridRestResponse.STATUS_FAILED,
+                        "No cache with name. [cacheName=" + req.cacheName() + "]");
+
+                QueryCursor qryCur = cache.query(qry);
+
+                Iterator cur = qryCur.iterator();
 
                 long qryId = qryIdGen.getAndIncrement();
 
+                qryCurs.put(qryId, qryCur);
                 curs.put(qryId, cur);
 
-                CacheQueryResult res = createQueryResult(curs, cur, req, qryId);
+                CacheQueryResult res = createQueryResult(qryCurs, curs, cur, req, qryId);
 
                 return new GridRestResponse(res);
             }
@@ -142,23 +162,74 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
     }
 
     /**
+     * Close query callable.
+     */
+    private static class CloseQueryCallable implements Callable<GridRestResponse> {
+        /** Execute query request. */
+        private RestSqlQueryRequest req;
+
+        /** Queries iterators. */
+        private ConcurrentHashMap<Long, Iterator> curs;
+
+        /** Queries cursors. */
+        private ConcurrentHashMap<Long, QueryCursor> qryCurs;
+
+        /**
+         * @param req Execute query request.
+         * @param curs Queries cursors.
+         */
+        public CloseQueryCallable(RestSqlQueryRequest req,
+            ConcurrentHashMap<Long, Iterator> curs,
+            ConcurrentHashMap<Long, QueryCursor> qryCurs) {
+            this.req = req;
+            this.curs = curs;
+            this.qryCurs = qryCurs;
+        }
+
+        /** {@inheritDoc} */
+        @Override public GridRestResponse call() throws Exception {
+            try {
+                QueryCursor cur = qryCurs.get(req.queryId());
+
+                if (cur == null)
+                    return new GridRestResponse(GridRestResponse.STATUS_FAILED,
+                        "Cannot find query [qryId=" + req.queryId() + "]");
+
+                cur.close();
+
+                return new GridRestResponse(true);
+            }
+            catch (Exception e) {
+                qryCurs.remove(req.queryId());
+                curs.remove(req.queryId());
+
+                return new GridRestResponse(GridRestResponse.STATUS_FAILED, e.getMessage());
+            }
+        }
+    }
+
+    /**
      * Fetch query callable.
      */
     private static class FetchQueryCallable implements Callable<GridRestResponse> {
         /** Execute query request. */
         private RestSqlQueryRequest req;
 
-        /** Queries cursors. */
+        /** Queries iterators. */
         private ConcurrentHashMap<Long, Iterator> curs;
 
+        /** Queries cursors. */
+        private ConcurrentHashMap<Long, QueryCursor> qryCurs;
+
         /**
          * @param req Execute query request.
          * @param curs Queries cursors.
          */
-        public FetchQueryCallable(RestSqlQueryRequest req,
-            ConcurrentHashMap<Long, Iterator> curs) {
+        public FetchQueryCallable(RestSqlQueryRequest req, ConcurrentHashMap<Long, Iterator> curs,
+            ConcurrentHashMap<Long, QueryCursor> qryCurs) {
             this.req = req;
             this.curs = curs;
+            this.qryCurs = qryCurs;
         }
 
         /** {@inheritDoc} */
@@ -170,12 +241,13 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
                     return new GridRestResponse(GridRestResponse.STATUS_FAILED,
                         "Cannot find query [qryId=" + req.queryId() + "]");
 
-                CacheQueryResult res = createQueryResult(curs, cur, req, req.queryId());
+                CacheQueryResult res = createQueryResult(qryCurs, curs, cur, req, req.queryId());
 
                 return new GridRestResponse(res);
             }
             catch (Exception e) {
                 curs.remove(req.queryId());
+                qryCurs.remove(req.queryId());
 
                 return new GridRestResponse(GridRestResponse.STATUS_FAILED, e.getMessage());
             }
@@ -183,13 +255,15 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
     }
 
     /**
-     * @param curs Queries cursors.
+     * @param qryCurs Query cursors.
+     * @param curs Queries iterators.
      * @param cur Current cursor.
      * @param req Sql request.
      * @param qryId Query id.
      * @return Query result with items.
      */
-    private static CacheQueryResult createQueryResult(ConcurrentHashMap<Long, Iterator> curs, Iterator cur,
+    private static CacheQueryResult createQueryResult(ConcurrentHashMap<Long, QueryCursor> qryCurs,
+        ConcurrentHashMap<Long, Iterator> curs, Iterator cur,
         RestSqlQueryRequest req, Long qryId) {
         CacheQueryResult res = new CacheQueryResult();
 
@@ -204,8 +278,10 @@ public class QueryCommandHandler extends GridRestCommandHandlerAdapter {
 
         res.setQueryId(qryId);
 
-        if (!cur.hasNext())
+        if (!cur.hasNext()) {
+            qryCurs.remove(qryId);
             curs.remove(qryId);
+        }
 
         return res;
     }

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/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 f1396e3..3850cb5 100644
--- a/modules/nodejs/src/main/js/cache.js
+++ b/modules/nodejs/src/main/js/cache.js
@@ -268,44 +268,7 @@ Cache.prototype.size = function(callback) {
  * @param {SqlQuery|SqlFieldsQuery} qry Query
  */
 Cache.prototype.query = function(qry) {
-    var cmd;
-
-    if (qry.type() === "Sql") {
-        if (qry.returnType() == null) {
-            return new Promise(function(resolve, reject) {
-                reject("No type for sql query.");
-            });
-        }
-
-        cmd = this._sqlQuery(qry);
-    }
-    else {
-        cmd = this._sqlFieldsQuery(qry);
-    }
-
-    var server = this._server;
-    var cache = this;
-
-    return new Promise(function(resolve, reject) {
-        server.runCommand(cmd, function(err, res){
-            if(err != null) {
-                reject(err);
-            }
-            else {
-                resolve(new Cursor(qry, res, cache));
-            }
-        });
-    });
-}
-
-Cache.prototype._sqlFieldsQuery = function(qry) {
-    return this._createQueryCommand("qryfieldsexecute", qry).
-        setPostData(JSON.stringify({"arg" : qry.arguments()}));
-}
-
-Cache.prototype._sqlQuery = function(qry) {
-    return this._createQueryCommand("qryexecute", qry).addParam("type", qry.returnType()).
-        setPostData(JSON.stringify({"arg" : qry.arguments()}));
+    return new Cursor(this, qry, true, null);
 }
 
 Cache.prototype.__createPromise = function(cmd) {
@@ -329,52 +292,139 @@ Cache.prototype._createCommand = function(name) {
     return command.addParam("cacheName", this._cacheName);
 }
 
-Cache.prototype._createQueryCommand = function(name, qry) {
-    var command = this._createCommand(name);
+Cursor = function(cache, qry, first, res) {
+    this._qry = qry;
+    this._cache = cache;
+    this._init = first;
+    this._res = res;
+}
 
-    command.addParam("qry", qry.query());
+Cursor.prototype.getAll = function() {
+    if (!this._init) {
+        return new Promise(function(resolve, reject){
+            reject("GetAll is called after nextPage.");
+        });
+    }
 
-    return command.addParam("psz", qry.pageSize());
-}
+    var cmd = this._getQueryCommand();
+    var server = this._cache._server;
+    var cursor = this;
 
-Cursor = function(qry, res, cache) {
-    this._qry = qry;
-    this._res = res;
-    this._cache = cache;
+    return new Promise(function(resolve, reject) {
+        var fullRes = [];
+
+        onResult = function (err, res){
+            if (err !== null) {
+                reject(err);
+            }
+            else {
+                cursor._res = res;
+
+                fullRes = fullRes.concat(res["items"]);
+
+                if (res["last"]) {
+                    resolve(fullRes);
+                }
+                else {
+                    server.runCommand(cursor._getQueryCommand(), onResult);
+                }
+            }
+        }
+
+        server.runCommand(cmd, onResult);
+    });
 }
 
-Cursor.prototype.next = function() {
-    if (this._res["last"]) {
+
+Cursor.prototype.nextPage = function() {
+    if (this._res !== null && this._res["last"]) {
         throw "All pages are returned.";
     }
 
-    var cmd = this._cache._createCommand("qryfetch").addParam("qryId", this._res.queryId).
-        addParam("psz", this._qry.pageSize());
-
+    var cmd = this._getQueryCommand();
     var server = this._cache._server;
     var qry = this._qry;
     var cache = this._cache;
 
     return new Promise(function(resolve, reject) {
        server.runCommand(cmd, function(err, res) {
-           if(err != null) {
+           if(err !== null) {
+               console.log("ERR=" + err)
                reject(err);
            }
            else {
-               resolve(new Cursor(qry, res, cache));
+               resolve(new Cursor(cache, qry, false, res));
            }
        });
     });
 }
 
 Cursor.prototype.page = function() {
+    if (this._res === null)
+        return null;
+
     return this._res["items"];
 }
 
+Cursor.prototype.close = function() {
+    if (this._init) {
+        return new Promise(function(resolve, reject) {
+            return resolve(true);
+        });
+    }
+
+    var server = this._cache._server;
+    var cmd = this._createQueryCommand("qryclose", this._qry).addParam("qryId", this._res.queryId);
+
+    return new Promise(function(resolve, reject) {
+       server.runCommand(cmd, function(err, res) {
+           if(err != null) {
+               reject(err);
+           }
+           else {
+               resolve(true);
+           }
+       });
+    });
+}
+
 Cursor.prototype.isFinished = function() {
+    if (this._res === null)
+        return false;
+
     return this._res["last"];
 }
 
+Cursor.prototype._getQueryCommand = function() {
+    if (this._init) {
+        if (this._qry.type() === "Sql") {
+            return this._sqlQuery(this._qry);
+        }
+
+        this._init = false;
+
+        return this._sqlFieldsQuery(this._qry);
+    }
+
+    return this._cache._createCommand("qryfetch").addParam("qryId", this._res.queryId).
+        addParam("psz", this._qry.pageSize());
+}
+
+Cursor.prototype._sqlFieldsQuery = function(qry) {
+    return this._createQueryCommand("qryfieldsexecute", qry).
+        setPostData(JSON.stringify({"arg" : qry.arguments()}));
+}
+
+Cursor.prototype._sqlQuery = function(qry) {
+    return this._createQueryCommand("qryexecute", qry).addParam("type", qry.returnType()).
+        setPostData(JSON.stringify({"arg" : qry.arguments()}));
+}
+
+Cursor.prototype._createQueryCommand = function(name, qry) {
+    return new Command(name).addParam("cacheName", this._cache._cacheName).
+        addParam("qry", qry.query()).addParam("psz", qry.pageSize());
+}
+
 /**
  * @this{CacheEntry}
  * @param key Key

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/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 5d7430a..f8a98ab 100644
--- a/modules/nodejs/src/main/js/server.js
+++ b/modules/nodejs/src/main/js/server.js
@@ -86,6 +86,8 @@ 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.");

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsSqlQuerySelfTest.java b/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsSqlQuerySelfTest.java
index 9024b93..9a29f52 100644
--- a/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsSqlQuerySelfTest.java
+++ b/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsSqlQuerySelfTest.java
@@ -64,6 +64,24 @@ public class NodeJsSqlQuerySelfTest extends NodeJsAbstractTest {
     /**
      * @throws Exception If failed.
      */
+    public void testCloseQuery() throws Exception {
+        initCache();
+
+        runJsScript("testCloseQuery");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSqlFieldsGetAllQuery() throws Exception {
+        initCache();
+
+        runJsScript("testSqlFieldsGetAllQuery");
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
     public void testSqlQueryWithParams() throws Exception {
         initCache();
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/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 cbdb643..573c4ad 100644
--- a/modules/nodejs/src/test/js/test-query.js
+++ b/modules/nodejs/src/test/js/test-query.js
@@ -33,6 +33,7 @@ testSqlQuery = function() {
             var fullRes = [];
 
             function onQuery(cursor) {
+                console.log("PGE=" + cursor.page());
                 var page = cursor.page();
 
                 fullRes = fullRes.concat(page);
@@ -52,10 +53,12 @@ testSqlQuery = function() {
                     return;
                 }
 
-                cursor.next().then(onQuery);
+                cursor.nextPage().then(onQuery);
             }
 
-            ignite.cache("mycache").query(qry).then(onQuery);
+            var cursor = ignite.cache("mycache").query(qry);
+
+            cursor.nextPage().then(onQuery);
         }).catch(function(err) {
             assert(err === null, err);
         })
@@ -86,15 +89,59 @@ testSqlFieldsQuery = function() {
 
                 console.log("Result: " + JSON.stringify(fullRes));
 
-                TestUtils.testDone();
-
-                return;
+                return ignite.cache("mycache").get("key");
             }
 
-            cursor.next().then(onQuery);
+            return cursor.nextPage().then(onQuery);
         }
 
-        ignite.cache("person").query(qry).then(onQuery);
+        ignite.cache("person").query(qry).nextPage().then(onQuery).then(function(){
+            TestUtils.testDone();
+        })
+    }).catch(function(err) {
+        assert(err === null, err);
+    });
+}
+
+testCloseQuery = function() {
+    TestUtils.startIgniteNode().then(function(ignite) {
+        var qry = new SqlFieldsQuery("select concat(firstName, ' ', lastName) from Person");
+
+        function onQuery(cursor) {
+            return cursor.close();
+        }
+
+        ignite.cache("person").query(qry).nextPage().then(onQuery).then(function(res){
+            TestUtils.testDone();
+        }).catch(function(err){
+            assert(err === null, err);
+        })
+    }).catch(function(err) {
+        assert(err === null, err);
+    });
+}
+
+testSqlFieldsGetAllQuery = function() {
+    TestUtils.startIgniteNode().then(function(ignite) {
+        var qry = new SqlFieldsQuery("select concat(firstName, ' ', lastName) from Person");
+
+        function onQuery(fullRes) {
+            assert(fullRes.length === 4, "Result length is not correct" +
+                "[expected=1, val = " + fullRes.length + "]");
+
+            fullRes.sort();
+
+            assert(fullRes[0].indexOf("Jane Doe") > -1,
+                "Result does not contain Jane Doe [res=" + fullRes[0] + "]");
+
+            console.log("Result: " + JSON.stringify(fullRes));
+
+            return ignite.cache("mycache").get("key");
+        }
+
+        return ignite.cache("person").query(qry).getAll().then(onQuery).then(function(){
+            TestUtils.testDone();
+        })
     }).catch(function(err) {
         assert(err === null, err);
     });
@@ -130,10 +177,10 @@ testSqlQueryWithParams = function() {
                 return;
             }
 
-            cursor.next().then(onQuery);
+            cursor.nextPage().then(onQuery);
         }
 
-        ignite.cache("person").query(qry).then(onQuery);
+        ignite.cache("person").query(qry).nextPage().then(onQuery);
     }).catch(function(err) {
         assert(err === null, err);
     });

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7d489c16/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 20f0a88..69108a4 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
@@ -650,6 +650,17 @@ public class GridJettyRestHandler extends AbstractHandler {
                 break;
             }
 
+            case CLOSE_SQL_QUERY: {
+                RestSqlQueryRequest restReq0 = new RestSqlQueryRequest();
+
+                restReq0.queryId(Long.parseLong((String)params.get("qryId")));
+                restReq0.cacheName((String)params.get("cacheName"));
+
+                restReq = restReq0;
+
+                break;
+            }
+
             default:
                 throw new IgniteCheckedException("Invalid command: " + cmd);
         }