You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2013/12/14 16:11:33 UTC

git commit: updated refs/heads/1960-paginate-all_dbs to e1ea767

Updated Branches:
  refs/heads/1960-paginate-all_dbs [created] e1ea76789


paginate all_dbs

simple way to paginate results by skipping first results and limit the
number of results returned.

fix #COUCHDB-1960


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

Branch: refs/heads/1960-paginate-all_dbs
Commit: e1ea767895705dae55b0586e4f5758bbe578c43b
Parents: 7c23a6e
Author: Benoit Chesneau <bc...@gmail.com>
Authored: Sat Dec 14 16:08:13 2013 +0100
Committer: Benoit Chesneau <bc...@gmail.com>
Committed: Sat Dec 14 16:08:13 2013 +0100

----------------------------------------------------------------------
 src/couchdb/couch_httpd_misc_handlers.erl | 21 +++++-
 test/etap/071-all_dbs.t                   | 94 ++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e1ea7678/src/couchdb/couch_httpd_misc_handlers.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl
index 96a05c6..0d7fb2b 100644
--- a/src/couchdb/couch_httpd_misc_handlers.erl
+++ b/src/couchdb/couch_httpd_misc_handlers.erl
@@ -27,6 +27,9 @@
     start_json_response/2,send_chunk/2,last_chunk/1,end_json_response/1,
     start_chunked_response/3, send_error/4]).
 
+
+-define(DEFAULT_LIMIT, 16#10000000).
+
 % httpd global handlers
 
 handle_welcome_req(#httpd{method='GET'}=Req, WelcomeMessage) ->
@@ -80,12 +83,26 @@ handle_utils_dir_req(Req, _) ->
     send_method_not_allowed(Req, "GET,HEAD").
 
 handle_all_dbs_req(#httpd{method='GET'}=Req) ->
-    {ok, DbNames} = couch_server:all_databases(),
-    send_json(Req, DbNames);
+    Limit0 = couch_util:to_integer(couch_httpd:qs_value(Req, "limit",
+                                                        ?DEFAULT_LIMIT)),
+    Skip0 = couch_util:to_integer(couch_httpd:qs_value(Req, "skip", -1)),
+    {ok, {DbNames, _, _}} = couch_server:all_databases(fun all_dbs_fun/2,
+                                                       {[], Skip0, Limit0}),
+    send_json(Req, lists:usort(DbNames));
 handle_all_dbs_req(Req) ->
     send_method_not_allowed(Req, "GET,HEAD").
 
 
+all_dbs_fun(DbName, {Acc, Skip, 0}) ->
+    {stop, {Acc, Skip, 0}};
+all_dbs_fun(DbName, {Acc, 0, Limit}) ->
+    {ok, {[DbName | Acc], 0, Limit - 1}};
+all_dbs_fun(_DbName, {Acc, Skip, Limit}) when Skip > 0 ->
+    {ok, {Acc, Skip - 1, Limit}};
+all_dbs_fun (DbName, {Acc, Skip, Limit}) ->
+    {ok, {[DbName | Acc], Skip, Limit - 1}}.
+
+
 handle_task_status_req(#httpd{method='GET'}=Req) ->
     ok = couch_httpd:verify_is_server_admin(Req),
     % convert the list of prop lists to a list of json objects

http://git-wip-us.apache.org/repos/asf/couchdb/blob/e1ea7678/test/etap/071-all_dbs.t
----------------------------------------------------------------------
diff --git a/test/etap/071-all_dbs.t b/test/etap/071-all_dbs.t
new file mode 100644
index 0000000..d98aeff
--- /dev/null
+++ b/test/etap/071-all_dbs.t
@@ -0,0 +1,94 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+
+% Licensed 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.
+
+main(_) ->
+    test_util:init_code_path(),
+
+    couch_server_sup:start_link(test_util:config_files()),
+
+    delete_dbs(),
+    init_dbs(),
+
+    etap:plan(8),
+    case (catch test()) of
+        ok ->
+            etap:end_tests();
+        Other ->
+            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
+            etap:bail(Other)
+    end,
+
+    delete_dbs(),
+
+    ok.
+
+init_dbs() ->
+    %% init databases
+    [couch_db:create(iolist_to_binary([<<"etap-test-db">>,
+                                       integer_to_list(I)]), [])
+     || I <- lists:seq(0, 10)].
+
+
+delete_dbs() ->
+    {ok, AllDbs} = couch_server:all_databases(),
+    %% delete all created dbs
+    lists:foreach(fun(DbName) ->
+                couch_server:delete(DbName, [])
+            end, AllDbs).
+
+
+server() ->
+    lists:concat([
+        "http://127.0.0.1:",
+        mochiweb_socket_server:get(couch_httpd, port),
+        "/"
+    ]).
+
+
+test() ->
+    {ok, AllDbs} = couch_server:all_databases(),
+    etap:is(12, length(AllDbs), "11 databases was created."),
+
+    Url = server() ++ "_all_dbs",
+    {ok, _, _, Body} = ibrowse:send_req(Url, [], get, []),
+    AllDbs1 = ejson:decode(Body),
+    etap:is(12, length(AllDbs1), "11 databases listed"),
+
+
+    Url1 = server() ++ "_all_dbs?limit=4",
+    {ok, _, _, Body1} = ibrowse:send_req(Url1, [], get, []),
+    AllDbs2 = ejson:decode(Body1),
+    etap:is(4, length(AllDbs2), "4 databases listed"),
+
+    Url2 = server() ++ "_all_dbs?skip=4&limit=4",
+    {ok, _, _, Body2} = ibrowse:send_req(Url2, [], get, []),
+    AllDbs3 = ejson:decode(Body2),
+    etap:is(4, length(AllDbs3), "4 databases listed"),
+
+    etap:is(true, lists:member(<<"etap-test-db2">>, AllDbs3),
+            "etap-test-db2 in list"),
+
+    etap:is(true, lists:member(<<"etap-test-db5">>, AllDbs3),
+            "etap-test-db5 in list"),
+
+
+    etap:is(false, lists:member(<<"etap-test-db10">>, AllDbs3),
+            "etap-test-db10 in list"),
+
+    etap:is(false, lists:member(<<"etap-test-db6">>, AllDbs3),
+            "etap-test-db6 in list"),
+
+
+    ok.