summaryrefslogtreecommitdiff
path: root/src/couchdb/couch_httpd_show.erl
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2009-05-10 09:12:01 +0000
committerJohn Christopher Anderson <jchris@apache.org>2009-05-10 09:12:01 +0000
commit2c8bc8ed6a2dc4ecdde08e779e4882f189485271 (patch)
tree98e826d28806b4fa96d273768719d78aa1355593 /src/couchdb/couch_httpd_show.erl
parentd748a328aec166047c81bcaf3dec6b0a885a2088 (diff)
Refactor the make_view_fold_function stuff. Added a proper Acc to both map and reduce view folds. Cleaned up some pattern matchers.
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@773319 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/couchdb/couch_httpd_show.erl')
-rw-r--r--src/couchdb/couch_httpd_show.erl89
1 files changed, 41 insertions, 48 deletions
diff --git a/src/couchdb/couch_httpd_show.erl b/src/couchdb/couch_httpd_show.erl
index c38522df..49dd88bc 100644
--- a/src/couchdb/couch_httpd_show.erl
+++ b/src/couchdb/couch_httpd_show.erl
@@ -117,10 +117,10 @@ send_view_list_response(Lang, ListSrc, ViewName, DesignId, Req, Db, Keys) ->
end
end.
-make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag) ->
- fun(Req2, _Etag, TotalViewCount, Offset) ->
+make_map_start_resp_fun(QueryServer, Db) ->
+ fun(Req, CurrentEtag, TotalViewCount, Offset, _Acc) ->
ExternalResp = couch_query_servers:render_list_head(QueryServer,
- Req2, Db, TotalViewCount, Offset),
+ Req, Db, TotalViewCount, Offset),
JsonResp = apply_etag(ExternalResp, CurrentEtag),
#extern_resp_args{
code = Code,
@@ -134,8 +134,7 @@ make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag) ->
end.
make_map_send_row_fun(QueryServer, Req) ->
- fun(Resp, Db2, {{Key, DocId}, Value},
- RowFront, _IncludeDocs) ->
+ fun(Resp, Db2, {{Key, DocId}, Value}, _IncludeDocs, RowFront) ->
try
JsonResp = couch_query_servers:render_list_row(QueryServer,
Req, Db2, {{Key, DocId}, Value}),
@@ -144,17 +143,14 @@ make_map_send_row_fun(QueryServer, Req) ->
data = RowBody
} = couch_httpd_external:parse_external_response(JsonResp),
case StopIter of
- true -> stop;
+ true -> {stop, ""};
_ ->
- RowFront2 = case RowFront of
- nil -> [];
- _ -> RowFront
- end,
- Chunk = RowFront2 ++ binary_to_list(RowBody),
+ Chunk = RowFront ++ binary_to_list(RowBody),
case Chunk of
- [] -> {ok, Resp};
+ [] -> ok;
_ -> send_chunk(Resp, Chunk)
- end
+ end,
+ {ok, ""}
end
catch
throw:Error ->
@@ -182,7 +178,7 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer
% pass it into the view fold with closures
{ok, QueryServer} = couch_query_servers:start_view_list(Lang, ListSrc),
- StartListRespFun = make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag),
+ StartListRespFun = make_map_start_resp_fun(QueryServer, Db),
SendListRowFun = make_map_send_row_fun(QueryServer, Req),
FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db, RowCount,
@@ -192,7 +188,7 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer
send_row = SendListRowFun
}),
FoldAccInit = {Limit, SkipCount, undefined, []},
- FoldResult = couch_view:fold(View, Start, Dir, FoldlFun, FoldAccInit),
+ {ok, FoldResult} = couch_view:fold(View, Start, Dir, FoldlFun, FoldAccInit),
finish_list(Req, Db, QueryServer, CurrentEtag, FoldResult, StartListRespFun, RowCount)
end);
@@ -213,11 +209,11 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer
% pass it into the view fold with closures
{ok, QueryServer} = couch_query_servers:start_view_list(Lang, ListSrc),
- StartListRespFun = make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag),
+ StartListRespFun = make_map_start_resp_fun(QueryServer, Db),
SendListRowFun = make_map_send_row_fun(QueryServer, Req),
FoldAccInit = {Limit, SkipCount, undefined, []},
- FoldResult = lists:foldl(
+ {ok, FoldResult} = lists:foldl(
fun(Key, {ok, FoldAcc}) ->
FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs#view_query_args{
start_key = Key,
@@ -234,7 +230,7 @@ output_map_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Quer
end).
make_reduce_start_resp_fun(QueryServer, Req, Db, CurrentEtag) ->
- fun(Req2, _Etag, _, _) ->
+ fun(Req2, _Etag, _Acc) ->
JsonResp = couch_query_servers:render_reduce_head(QueryServer,
Req2, Db),
JsonResp2 = apply_etag(JsonResp, CurrentEtag),
@@ -258,18 +254,15 @@ make_reduce_send_row_fun(QueryServer, Req, Db) ->
stop = StopIter,
data = RowBody
} = couch_httpd_external:parse_external_response(JsonResp),
- RowFront2 = case RowFront of
- nil -> [];
- _ -> RowFront
- end,
case StopIter of
- true -> stop;
+ true -> {stop, ""};
_ ->
- Chunk = RowFront2 ++ binary_to_list(RowBody),
+ Chunk = RowFront ++ binary_to_list(RowBody),
case Chunk of
- [] -> {ok, Resp};
+ [] -> ok;
_ -> send_chunk(Resp, Chunk)
- end
+ end,
+ {ok, ""}
end
catch
throw:Error ->
@@ -307,7 +300,7 @@ output_reduce_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Q
send_row = SendListRowFun
}),
FoldAccInit = {Limit, SkipCount, undefined, []},
- FoldResult = couch_view:fold_reduce(View, Dir, {StartKey, StartDocId},
+ {ok, FoldResult} = couch_view:fold_reduce(View, Dir, {StartKey, StartDocId},
{EndKey, EndDocId}, GroupRowsFun, RespFun,
FoldAccInit),
finish_list(Req, Db, QueryServer, CurrentEtag, FoldResult, StartListRespFun, null)
@@ -341,7 +334,7 @@ output_reduce_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Q
send_row = SendListRowFun
}),
FoldAccInit = {Limit, SkipCount, undefined, []},
- FoldResult = lists:foldl(
+ {ok, FoldResult} = lists:foldl(
fun(Key, {ok, FoldAcc}) ->
couch_view:fold_reduce(View, Dir, {Key, StartDocId},
{Key, EndDocId}, GroupRowsFun, RespFun, FoldAcc)
@@ -350,29 +343,29 @@ output_reduce_list(#httpd{mochi_req=MReq}=Req, Lang, ListSrc, View, Group, Db, Q
end).
finish_list(Req, Db, QueryServer, Etag, FoldResult, StartListRespFun, TotalRows) ->
- case FoldResult of
- {ok, Acc} ->
- JsonTail = couch_query_servers:render_list_tail(QueryServer, Req, Db),
- #extern_resp_args{
- data = Tail
- } = couch_httpd_external:parse_external_response(JsonTail),
- {Resp, BeginBody} = case Acc of
+ {Resp, BeginBody} = case FoldResult of
{_, _, undefined, _} ->
- {ok, Resp2, BeginBody2} = StartListRespFun(Req, Etag, TotalRows, null),
+ {ok, Resp2, BeginBody2} = render_head_for_empty_list(StartListRespFun, Req, Etag, TotalRows),
{Resp2, BeginBody2};
- {_, _, Resp2, _} ->
- {Resp2, ""}
- end,
- Chunk = BeginBody ++ binary_to_list(Tail),
- case Chunk of
- [] -> ok;
- _ -> send_chunk(Resp, Chunk)
- end,
- send_chunk(Resp, []);
- Error ->
- throw(Error)
- end.
+ {_, _, Resp0, _} ->
+ {Resp0, ""}
+ end,
+ JsonTail = couch_query_servers:render_list_tail(QueryServer, Req, Db),
+ #extern_resp_args{
+ data = Tail
+ } = couch_httpd_external:parse_external_response(JsonTail),
+ Chunk = BeginBody ++ binary_to_list(Tail),
+ case Chunk of
+ [] -> ok;
+ _ -> send_chunk(Resp, Chunk)
+ end,
+ send_chunk(Resp, []).
+render_head_for_empty_list(StartListRespFun, Req, Etag, null) ->
+ StartListRespFun(Req, Etag, []);
+render_head_for_empty_list(StartListRespFun, Req, Etag, TotalRows) ->
+ StartListRespFun(Req, Etag, TotalRows, null, []).
+
send_doc_show_response(Lang, ShowSrc, DocId, nil, #httpd{mochi_req=MReq}=Req, Db) ->
% compute etag with no doc
Headers = MReq:get(headers),