Repository: couchdb-mango
Updated Branches:
  refs/heads/2652-index-pagination [created] 90652ce11


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/90652ce1
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mango/tree/90652ce1
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mango/diff/90652ce1

Branch: refs/heads/2652-index-pagination
Commit: 90652ce11047ded5ef72da34f7d5cbc8195dc924
Parents: fa557b7
Author: Tony Sun <[email protected]>
Authored: Sun Apr 19 17:47:10 2015 -0700
Committer: Tony Sun <[email protected]>
Committed: Sun Apr 19 17:47:10 2015 -0700

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


http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/90652ce1/src/mango_error.erl
----------------------------------------------------------------------
diff --git a/src/mango_error.erl b/src/mango_error.erl
index 6dcf7c8..7832b82 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, 0 <= skip <= total indexes" >>
+    };
 
 info(mango_idx, {invalid_index_type, BadType}) ->
     {

http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/90652ce1/src/mango_httpd.erl
----------------------------------------------------------------------
diff --git a/src/mango_httpd.erl b/src/mango_httpd.erl
index 671ffd2..4980f10 100644
--- a/src/mango_httpd.erl
+++ b/src/mango_httpd.erl
@@ -50,8 +50,24 @@ 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),
+    JsonIdxs0 = lists:map(fun mango_idx:to_json/1, Idxs),
+    % Set limit default to 200 here since dashboard defaults to 200 per page.
+    Limit = case couch_util:get_value(limit, Params, 200) 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; Skip0 > length(JsonIdxs0) ->
+            ?MANGO_ERROR(invalid_list_index_params);
+        Skip0 ->
+            Skip0
+    end,
+    JsonIdxs = lists:sublist(JsonIdxs0, Skip+1, Limit),
        chttpd:send_json(Req, {[{indexes, JsonIdxs}]});
 
 handle_index_req(#httpd{method='POST', path_parts=[_, _]}=Req, Db) ->
@@ -217,3 +233,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/90652ce1/test/01-index-crud-test.py
----------------------------------------------------------------------
diff --git a/test/01-index-crud-test.py b/test/01-index-crud-test.py
index a44376c..43681dc 100644
--- a/test/01-index-crud-test.py
+++ b/test/01-index-crud-test.py
@@ -222,3 +222,37 @@ 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(limit=10000000)) == 6
+
+        try:
+            self.db.list_indexes(skip=10)
+        except Exception, e:
+            assert e.response.status_code == 500
+
+        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/90652ce1/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"]
 

Reply via email to