summaryrefslogtreecommitdiff
path: root/src/couchdb/couch_httpd_db.erl
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2008-10-05 16:00:15 +0000
committerJohn Christopher Anderson <jchris@apache.org>2008-10-05 16:00:15 +0000
commitcf69d22a07e9c8687dda93c830f5ff01f99be829 (patch)
tree9755172da93b34e574e51b20b62b44b384897c41 /src/couchdb/couch_httpd_db.erl
parent023179170f616f574fb65db8c5e6bf65cfc5bebf (diff)
added multi-key requests to _view, _temp_view, and _all_docs (with help from davisp)
git-svn-id: https://svn.apache.org/repos/asf/incubator/couchdb/trunk@701814 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/couchdb/couch_httpd_db.erl')
-rw-r--r--src/couchdb/couch_httpd_db.erl101
1 files changed, 73 insertions, 28 deletions
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index ff3d8125..20805c85 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -156,38 +156,17 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_purge">>]}=Req, Db) ->
db_req(#httpd{path_parts=[_,<<"_purge">>]}=Req, _Db) ->
send_method_not_allowed(Req, "POST");
-
+
db_req(#httpd{method='GET',path_parts=[_,<<"_all_docs">>]}=Req, Db) ->
- #view_query_args{
- start_key = StartKey,
- start_docid = StartDocId,
- count = Count,
- skip = SkipCount,
- direction = Dir
- } = QueryArgs = couch_httpd_view:parse_view_query(Req),
- {ok, Info} = couch_db:get_db_info(Db),
- TotalRowCount = proplists:get_value(doc_count, Info),
+ all_docs_view(Req, Db, nil);
- StartId = if is_binary(StartKey) -> StartKey;
- true -> StartDocId
- end,
-
- FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, TotalRowCount,
- fun couch_db:enum_docs_reduce_to_count/1),
- AdapterFun = fun(#full_doc_info{id=Id}=FullDocInfo, Offset, Acc) ->
- case couch_doc:to_doc_info(FullDocInfo) of
- #doc_info{deleted=false, rev=Rev} ->
- FoldlFun({{Id, Id}, {[{rev, Rev}]}}, Offset, Acc);
- #doc_info{deleted=true} ->
- {ok, Acc}
- end
- end,
- {ok, FoldResult} = couch_db:enum_docs(Db, StartId, Dir, AdapterFun,
- {Count, SkipCount, undefined, []}),
- couch_httpd_view:finish_view_fold(Req, TotalRowCount, {ok, FoldResult});
+db_req(#httpd{method='POST',path_parts=[_,<<"_all_docs">>]}=Req, Db) ->
+ {Props} = couch_httpd:json_body(Req),
+ Keys = proplists:get_value(<<"keys">>, Props, nil),
+ all_docs_view(Req, Db, Keys);
db_req(#httpd{path_parts=[_,<<"_all_docs">>]}=Req, _Db) ->
- send_method_not_allowed(Req, "GET,HEAD");
+ send_method_not_allowed(Req, "GET,HEAD,POST");
db_req(#httpd{method='GET',path_parts=[_,<<"_all_docs_by_seq">>]}=Req, Db) ->
#view_query_args{
@@ -261,6 +240,72 @@ db_req(#httpd{path_parts=[_, DocId]}=Req, Db) ->
db_req(#httpd{path_parts=[_, DocId, FileName]}=Req, Db) ->
db_attachment_req(Req, Db, DocId, FileName).
+all_docs_view(Req, Db, Keys) ->
+ #view_query_args{
+ start_key = StartKey,
+ start_docid = StartDocId,
+ count = Count,
+ skip = SkipCount,
+ direction = Dir
+ } = QueryArgs = couch_httpd_view:parse_view_query(Req, Keys),
+ {ok, Info} = couch_db:get_db_info(Db),
+ TotalRowCount = proplists:get_value(doc_count, Info),
+ StartId = if is_binary(StartKey) -> StartKey;
+ true -> StartDocId
+ end,
+ FoldAccInit = {Count, SkipCount, undefined, []},
+
+ case Keys of
+ nil ->
+ FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs,
+ TotalRowCount, fun couch_db:enum_docs_reduce_to_count/1),
+ AdapterFun = fun(#full_doc_info{id=Id}=FullDocInfo, Offset, Acc) ->
+ case couch_doc:to_doc_info(FullDocInfo) of
+ #doc_info{deleted=false, rev=Rev} ->
+ FoldlFun({{Id, Id}, {[{rev, Rev}]}}, Offset, Acc);
+ #doc_info{deleted=true} ->
+ {ok, Acc}
+ end
+ end,
+ {ok, FoldResult} = couch_db:enum_docs(Db, StartId, Dir,
+ AdapterFun, FoldAccInit),
+ couch_httpd_view:finish_view_fold(Req, TotalRowCount, {ok, FoldResult});
+ _ ->
+ FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs,
+ TotalRowCount, fun(Offset) -> Offset end),
+ KeyFoldFun = case Dir of
+ fwd ->
+ fun lists:foldl/3;
+ rev ->
+ fun lists:foldr/3
+ end,
+ {ok, FoldResult} = KeyFoldFun(
+ fun(Key, {ok, FoldAcc}) ->
+ DocInfo = (catch couch_db:get_doc_info(Db, Key)),
+ Doc = case DocInfo of
+ {ok, #doc_info{id=Id, rev=Rev, deleted=false}} = DocInfo ->
+ {{Id, Id}, {[{rev, Rev}]}};
+ {ok, #doc_info{id=Id, rev=Rev, deleted=true}} = DocInfo ->
+ {{Id, Id}, {[{rev, Rev}, {deleted, true}]}};
+ not_found ->
+ {{Key, error}, not_found};
+ _ ->
+ ?LOG_ERROR("Invalid DocInfo: ~p", [DocInfo]),
+ throw({error, invalid_doc_info})
+ end,
+ Acc = (catch FoldlFun(Doc, 0, FoldAcc)),
+ case Acc of
+ {stop, Acc2} ->
+ {ok, Acc2};
+ _ ->
+ Acc
+ end
+ end, {ok, FoldAccInit}, Keys),
+ couch_httpd_view:finish_view_fold(Req, TotalRowCount, {ok, FoldResult})
+ end.
+
+
+
db_doc_req(#httpd{method='DELETE'}=Req, Db, DocId) ->