couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tonysu...@apache.org
Subject couchdb-mango git commit: Add support for index pagination
Date Mon, 20 Apr 2015 18:49:04 GMT
Repository: couchdb-mango
Updated Branches:
  refs/heads/master fa557b728 -> a0cac182c


Add support for index pagination

We add limit and skip parameters to GET so that the dashboard
can utilize these parameters for pagination.

Fixes:COUCHDB-2652


Project: http://git-wip-us.apache.org/repos/asf/couchdb-mango/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mango/commit/a0cac182
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mango/tree/a0cac182
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mango/diff/a0cac182

Branch: refs/heads/master
Commit: a0cac182c9b4a3eb8b9a985245126d6150f0df61
Parents: fa557b7
Author: Tony Sun <tony.sun@cloudant.com>
Authored: Sun Apr 19 17:47:10 2015 -0700
Committer: Tony Sun <tony.sun@cloudant.com>
Committed: Mon Apr 20 11:46:08 2015 -0700

----------------------------------------------------------------------
 src/mango_error.erl        |  6 ++++++
 src/mango_httpd.erl        | 38 ++++++++++++++++++++++++++++++++++++--
 test/01-index-crud-test.py | 30 ++++++++++++++++++++++++++++++
 test/mango.py              |  8 ++++++--
 4 files changed, 78 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/a0cac182/src/mango_error.erl
----------------------------------------------------------------------
diff --git a/src/mango_error.erl b/src/mango_error.erl
index 6dcf7c8..dfd4bd7 100644
--- a/src/mango_error.erl
+++ b/src/mango_error.erl
@@ -77,6 +77,12 @@ info(mango_httpd, {error_saving_ddoc, Reason}) ->
         <<"error_saving_ddoc">>,
         fmt("Unknown error while saving the design document: ~s", [Reason])
     };
+info(mango_httpd, invalid_list_index_params) ->
+    {
+        500,
+        <<"invalid_list_index_params">>,
+        <<"Index parameter ranges: limit > 1, skip > 0" >>
+    };
 
 info(mango_idx, {invalid_index_type, BadType}) ->
     {

http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/a0cac182/src/mango_httpd.erl
----------------------------------------------------------------------
diff --git a/src/mango_httpd.erl b/src/mango_httpd.erl
index 671ffd2..d3fde9c 100644
--- a/src/mango_httpd.erl
+++ b/src/mango_httpd.erl
@@ -50,9 +50,27 @@ handle_req_int(_, _) ->
 
 
 handle_index_req(#httpd{method='GET', path_parts=[_, _]}=Req, Db) ->
+    Params = lists:flatmap(fun({K, V}) -> parse_index_param(K, V) end,
+        chttpd:qs(Req)),
     Idxs = lists:sort(mango_idx:list(Db)),
-    JsonIdxs = lists:map(fun mango_idx:to_json/1, Idxs),
-	chttpd:send_json(Req, {[{indexes, JsonIdxs}]});
+    JsonIdxs0 = lists:map(fun mango_idx:to_json/1, Idxs),
+    TotalRows = length(JsonIdxs0),
+    Limit = case couch_util:get_value(limit, Params, TotalRows) of
+        Limit0 when Limit0 < 1 ->
+            ?MANGO_ERROR(invalid_list_index_params);
+        Limit0 ->
+            Limit0
+    end,
+    Skip = case couch_util:get_value(skip, Params, 0) of
+        Skip0 when Skip0 < 0 ->
+            ?MANGO_ERROR(invalid_list_index_params);
+        Skip0 when Skip0 > TotalRows ->
+            TotalRows;
+        Skip0 ->
+            Skip0
+    end,
+    JsonIdxs = lists:sublist(JsonIdxs0, Skip+1, Limit),
+	chttpd:send_json(Req, {[{total_rows, TotalRows}, {indexes, JsonIdxs}]});
 
 handle_index_req(#httpd{method='POST', path_parts=[_, _]}=Req, Db) ->
     {ok, Opts} = mango_opts:validate_idx_create(chttpd:json_body_obj(Req)),
@@ -217,3 +235,19 @@ handle_doc({row, Doc}, {Resp0, Prepend, KVs}) ->
     Chunk = [Prepend, ?JSON_ENCODE(Doc)],
     {ok, Resp1} = chttpd:send_delayed_chunk(Resp0, Chunk),
     {ok, {Resp1, ",\r\n", KVs}}.
+
+
+parse_index_param("limit", Value) ->
+    [{limit, parse_val(Value)}];
+parse_index_param("skip", Value) ->
+    [{skip, parse_val(Value)}];
+parse_index_param(_Key, _Value) ->
+     [].
+
+parse_val(Value) ->
+    case (catch list_to_integer(Value)) of
+    IntVal when is_integer(IntVal) ->
+        IntVal;
+    _ ->
+        ?MANGO_ERROR(invalid_list_index_params)
+    end.

http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/a0cac182/test/01-index-crud-test.py
----------------------------------------------------------------------
diff --git a/test/01-index-crud-test.py b/test/01-index-crud-test.py
index a44376c..d83e97f 100644
--- a/test/01-index-crud-test.py
+++ b/test/01-index-crud-test.py
@@ -222,3 +222,33 @@ class IndexCrudTests(mango.DbPerClass):
             assert e.response.status_code == 404
         else:
             raise AssertionError("bad index delete")
+
+    def test_limit_skip_index(self):
+        fields = ["field1"]
+        ret = self.db.create_index(fields, name="idx_01")
+        assert ret is True
+
+        fields = ["field2"]
+        ret = self.db.create_index(fields, name="idx_02")
+        assert ret is True
+
+        fields = ["field3"]
+        ret = self.db.create_index(fields, name="idx_03")
+        assert ret is True
+
+        assert len(self.db.list_indexes(limit=2)) == 2
+        assert len(self.db.list_indexes(limit=5,skip=4)) == 2
+        assert len(self.db.list_indexes(skip=5)) == 1
+        assert len(self.db.list_indexes(skip=6)) == 0
+        assert len(self.db.list_indexes(skip=100)) == 0
+        assert len(self.db.list_indexes(limit=10000000)) == 6
+
+        try:
+            self.db.list_indexes(skip=-1)
+        except Exception, e:
+            assert e.response.status_code == 500
+
+        try:
+            self.db.list_indexes(limit=0)
+        except Exception, e:
+            assert e.response.status_code == 500

http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/a0cac182/test/mango.py
----------------------------------------------------------------------
diff --git a/test/mango.py b/test/mango.py
index b39c916..bde9323 100644
--- a/test/mango.py
+++ b/test/mango.py
@@ -125,8 +125,12 @@ class Database(object):
         r.raise_for_status()
         return r.json()["result"] == "created"
 
-    def list_indexes(self):
-        r = self.sess.get(self.path("_index"))
+    def list_indexes(self, limit="", skip=""):
+        if limit != "":
+            limit = "limit=" + str(limit)
+        if skip != "":
+            skip = "skip=" + str(skip)
+        r = self.sess.get(self.path("_index?"+limit+";"+skip))
         r.raise_for_status()
         return r.json()["indexes"]
 


Mime
View raw message