Repository: couchdb-mango Updated Branches: refs/heads/2652-index-pagination 137ad3abe -> a0cac182c (forced update)
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/2652-index-pagination Commit: a0cac182c9b4a3eb8b9a985245126d6150f0df61 Parents: fa557b7 Author: Tony Sun <[email protected]> Authored: Sun Apr 19 17:47:10 2015 -0700 Committer: Tony Sun <[email protected]> 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"]
