From 1a2e1790388e21174ac431a223147eb2ea4949be Mon Sep 17 00:00:00 2001 From: Adam Kocoloski Date: Wed, 7 Jul 2010 10:28:31 -0400 Subject: remove unused view code --- src/chttpd_view.erl | 399 +--------------------------------------------------- 1 file changed, 5 insertions(+), 394 deletions(-) diff --git a/src/chttpd_view.erl b/src/chttpd_view.erl index 6d29101a..42972870 100644 --- a/src/chttpd_view.erl +++ b/src/chttpd_view.erl @@ -13,12 +13,9 @@ -module(chttpd_view). -include_lib("couch/include/couch_db.hrl"). --export([handle_view_req/3,handle_temp_view_req/2]). - --export([get_stale_type/1, get_reduce_type/1, parse_view_params/3]). --export([make_view_fold_fun/6, finish_view_fold/3, view_row_obj/3]). --export([view_group_etag/2, view_group_etag/3, make_reduce_fold_funs/5]). --export([design_doc_view/5, parse_bool_param/1, extract_view_type/3]). +-export([handle_view_req/3, handle_temp_view_req/2, get_reduce_type/1, + parse_view_params/3, view_group_etag/2, view_group_etag/3, + parse_bool_param/1, extract_view_type/3]). -import(chttpd, [send_json/2,send_json/3,send_json/4,send_method_not_allowed/2,send_chunk/2, @@ -91,127 +88,14 @@ handle_view_req(#httpd{method='POST', handle_view_req(Req, _Db, _DDoc) -> send_method_not_allowed(Req, "GET,POST,HEAD"). -handle_temp_view_req(#httpd{method='POST'}=Req, Db) -> - throw(not_implemented), - couch_stats_collector:increment({httpd, temporary_view_reads}), - {Props} = chttpd:json_body_obj(Req), - Language = couch_util:get_value(<<"language">>, Props, <<"javascript">>), - {DesignOptions} = couch_util:get_value(<<"options">>, Props, {[]}), - MapSrc = couch_util:get_value(<<"map">>, Props), - Keys = couch_util:get_value(<<"keys">>, Props, nil), - case couch_util:get_value(<<"reduce">>, Props, null) of - null -> - QueryArgs = parse_view_params(Req, Keys, map), - {ok, View, Group} = ?COUCH:get_temp_map_view(Db, Language, - DesignOptions, MapSrc), - output_map_view(Req, View, Group, Db, QueryArgs, Keys); - RedSrc -> - QueryArgs = parse_view_params(Req, Keys, reduce), - {ok, View, Group} = ?COUCH:get_temp_reduce_view(Db, Language, - DesignOptions, MapSrc, RedSrc), - output_reduce_view(Req, Db, View, Group, QueryArgs, Keys) - end; - handle_temp_view_req(Req, _Db) -> - send_method_not_allowed(Req, "POST"). - -output_map_view(Req, View, Group, Db, QueryArgs, nil) -> - #view_query_args{ - limit = Limit, - direction = Dir, - skip = SkipCount, - start_key = StartKey, - start_docid = StartDocId - } = QueryArgs, - CurrentEtag = view_group_etag(Group, Db), - chttpd:etag_respond(Req, CurrentEtag, fun() -> - {ok, RowCount} = ?COUCH:get_row_count(View), - Start = {StartKey, StartDocId}, - FoldlFun = make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db, RowCount, #view_fold_helper_funs{reduce_count=fun ?COUCH:reduce_to_count/1}), - FoldAccInit = {Limit, SkipCount, undefined, [], nil}, - FoldResult = ?COUCH:view_fold(View, Start, Dir, FoldlFun, FoldAccInit), - finish_view_fold(Req, RowCount, FoldResult) - end); - -output_map_view(Req, View, Group, Db, QueryArgs, Keys) -> - #view_query_args{ - limit = Limit, - direction = Dir, - skip = SkipCount, - start_docid = StartDocId - } = QueryArgs, - CurrentEtag = view_group_etag(Group, Db, Keys), - chttpd:etag_respond(Req, CurrentEtag, fun() -> - {ok, RowCount} = ?COUCH:get_row_count(View), - FoldAccInit = {Limit, SkipCount, undefined, [], nil}, - FoldResult = lists:foldl( - fun(Key, {ok, FoldAcc}) -> - Start = {Key, StartDocId}, - FoldlFun = make_view_fold_fun(Req, - QueryArgs#view_query_args{ - start_key = Key, - end_key = Key - }, CurrentEtag, Db, RowCount, - #view_fold_helper_funs{ - reduce_count = fun ?COUCH:reduce_to_count/1 - }), - ?COUCH:view_fold(View, Start, Dir, FoldlFun, FoldAcc) - end, {ok, FoldAccInit}, Keys), - finish_view_fold(Req, RowCount, FoldResult) - end). - -output_reduce_view(Req, Db, View, Group, QueryArgs, nil) -> - #view_query_args{ - start_key = StartKey, - end_key = EndKey, - limit = Limit, - skip = Skip, - direction = Dir, - start_docid = StartDocId, - end_docid = EndDocId, - group_level = GroupLevel - } = QueryArgs, - CurrentEtag = view_group_etag(Group, Db), - chttpd:etag_respond(Req, CurrentEtag, fun() -> - {ok, GroupRowsFun, RespFun} = make_reduce_fold_funs(Req, GroupLevel, QueryArgs, CurrentEtag, #reduce_fold_helper_funs{}), - FoldAccInit = {Limit, Skip, undefined, []}, - {ok, {_, _, Resp, _}} = ?COUCH:view_fold_reduce(View, Dir, {StartKey, StartDocId}, - {EndKey, EndDocId}, GroupRowsFun, RespFun, FoldAccInit), - finish_reduce_fold(Req, Resp) - end); - -output_reduce_view(Req, Db, View, Group, QueryArgs, Keys) -> - #view_query_args{ - limit = Limit, - skip = Skip, - direction = Dir, - start_docid = StartDocId, - end_docid = EndDocId, - group_level = GroupLevel - } = QueryArgs, - CurrentEtag = view_group_etag(Group, Db), - chttpd:etag_respond(Req, CurrentEtag, fun() -> - {ok, GroupRowsFun, RespFun} = make_reduce_fold_funs(Req, GroupLevel, QueryArgs, CurrentEtag, #reduce_fold_helper_funs{}), - {Resp, _RedAcc3} = lists:foldl( - fun(Key, {Resp, RedAcc}) -> - % run the reduce once for each key in keys, with limit etc reapplied for each key - FoldAccInit = {Limit, Skip, Resp, RedAcc}, - {_, {_, _, Resp2, RedAcc2}} = ?COUCH:view_fold_reduce(View, Dir, {Key, StartDocId}, - {Key, EndDocId}, GroupRowsFun, RespFun, FoldAccInit), - % Switch to comma - {Resp2, RedAcc2} - end, - {undefined, []}, Keys), % Start with no comma - finish_reduce_fold(Req, Resp) - end). + Msg = <<"Temporary views are not supported by Cloudant">>, + chttpd:send_error(Req, 403, Msg). reverse_key_default(?MIN_STR) -> ?MAX_STR; reverse_key_default(?MAX_STR) -> ?MIN_STR; reverse_key_default(Key) -> Key. -get_stale_type(Req) -> - list_to_atom(chttpd:qs_value(Req, "stale", "nil")). - get_reduce_type(Req) -> list_to_atom(chttpd:qs_value(Req, "reduce", "true")). @@ -385,214 +269,6 @@ validate_view_query(sorted, _Value, Args) -> validate_view_query(extra, _Value, Args) -> Args. -make_view_fold_fun(Req, QueryArgs, Etag, Db, TotalViewCount, HelperFuns) -> - #view_query_args{ - end_key = EndKey, - end_docid = EndDocId, - inclusive_end = InclusiveEnd, - direction = Dir - } = QueryArgs, - - #view_fold_helper_funs{ - passed_end = PassedEndFun, - start_response = StartRespFun, - send_row = SendRowFun, - reduce_count = ReduceCountFun - } = apply_default_helper_funs(HelperFuns, - {Dir, EndKey, EndDocId, InclusiveEnd}), - - #view_query_args{ - include_docs = IncludeDocs - } = QueryArgs, - - fun({{Key, DocId}, Value}, OffsetReds, {AccLimit, AccSkip, Resp, RowFunAcc, - OffsetAcc}) -> - PassedEnd = PassedEndFun(Key, DocId), - case {PassedEnd, AccLimit, AccSkip, Resp} of - {true, _, _, _} -> - % The stop key has been passed, stop looping. - % We may need offset so calcluate it here. - % Checking Resp is an optimization that tells - % us its already been calculated (and sent). - NewOffset = case Resp of - undefined -> ReduceCountFun(OffsetReds); - _ -> nil - end, - {stop, {AccLimit, AccSkip, Resp, RowFunAcc, NewOffset}}; - {_, 0, _, _} -> - % we've done "limit" rows, stop foldling - {stop, {0, 0, Resp, RowFunAcc, OffsetAcc}}; - {_, _, AccSkip, _} when AccSkip > 0 -> - % just keep skipping - {ok, {AccLimit, AccSkip - 1, Resp, RowFunAcc, OffsetAcc}}; - {_, _, _, undefined} -> - % rendering the first row, first we start the response - Offset = ReduceCountFun(OffsetReds), - {ok, Resp2, RowFunAcc0} = StartRespFun(Req, Etag, - TotalViewCount, Offset, RowFunAcc), - {Go, RowFunAcc2} = SendRowFun(Resp2, Db, {{Key, DocId}, Value}, - IncludeDocs, RowFunAcc0), - {Go, {AccLimit - 1, 0, Resp2, RowFunAcc2, Offset}}; - {_, AccLimit, _, Resp} when (AccLimit > 0) -> - % rendering all other rows - {Go, RowFunAcc2} = SendRowFun(Resp, Db, {{Key, DocId}, Value}, - IncludeDocs, RowFunAcc), - {Go, {AccLimit - 1, 0, Resp, RowFunAcc2, OffsetAcc}} - end - end. - -make_reduce_fold_funs(Req, GroupLevel, _QueryArgs, Etag, HelperFuns) -> - #reduce_fold_helper_funs{ - start_response = StartRespFun, - send_row = SendRowFun - } = apply_default_helper_funs(HelperFuns), - - GroupRowsFun = - fun({_Key1,_}, {_Key2,_}) when GroupLevel == 0 -> - true; - ({Key1,_}, {Key2,_}) - when is_integer(GroupLevel) and is_list(Key1) and is_list(Key2) -> - lists:sublist(Key1, GroupLevel) == lists:sublist(Key2, GroupLevel); - ({Key1,_}, {Key2,_}) -> - Key1 == Key2 - end, - - RespFun = fun - (_Key, _Red, {AccLimit, AccSkip, Resp, RowAcc}) when AccSkip > 0 -> - % keep skipping - {ok, {AccLimit, AccSkip - 1, Resp, RowAcc}}; - (_Key, _Red, {0, _AccSkip, Resp, RowAcc}) -> - % we've exhausted limit rows, stop - {stop, {0, _AccSkip, Resp, RowAcc}}; - - (_Key, Red, {AccLimit, 0, undefined, RowAcc0}) when GroupLevel == 0 -> - % we haven't started responding yet and group=false - {ok, Resp2, RowAcc} = StartRespFun(Req, Etag, RowAcc0), - {Go, RowAcc2} = SendRowFun(Resp2, {null, Red}, RowAcc), - {Go, {AccLimit - 1, 0, Resp2, RowAcc2}}; - (_Key, Red, {AccLimit, 0, Resp, RowAcc}) when GroupLevel == 0 -> - % group=false but we've already started the response - {Go, RowAcc2} = SendRowFun(Resp, {null, Red}, RowAcc), - {Go, {AccLimit - 1, 0, Resp, RowAcc2}}; - - (Key, Red, {AccLimit, 0, undefined, RowAcc0}) - when is_integer(GroupLevel), is_list(Key) -> - % group_level and we haven't responded yet - {ok, Resp2, RowAcc} = StartRespFun(Req, Etag, RowAcc0), - {Go, RowAcc2} = SendRowFun(Resp2, {lists:sublist(Key, GroupLevel), Red}, RowAcc), - {Go, {AccLimit - 1, 0, Resp2, RowAcc2}}; - (Key, Red, {AccLimit, 0, Resp, RowAcc}) - when is_integer(GroupLevel), is_list(Key) -> - % group_level and we've already started the response - {Go, RowAcc2} = SendRowFun(Resp, {lists:sublist(Key, GroupLevel), Red}, RowAcc), - {Go, {AccLimit - 1, 0, Resp, RowAcc2}}; - - (Key, Red, {AccLimit, 0, undefined, RowAcc0}) -> - % group=true and we haven't responded yet - {ok, Resp2, RowAcc} = StartRespFun(Req, Etag, RowAcc0), - {Go, RowAcc2} = SendRowFun(Resp2, {Key, Red}, RowAcc), - {Go, {AccLimit - 1, 0, Resp2, RowAcc2}}; - (Key, Red, {AccLimit, 0, Resp, RowAcc}) -> - % group=true and we've already started the response - {Go, RowAcc2} = SendRowFun(Resp, {Key, Red}, RowAcc), - {Go, {AccLimit - 1, 0, Resp, RowAcc2}} - end, - {ok, GroupRowsFun, RespFun}. - -apply_default_helper_funs(#view_fold_helper_funs{ - passed_end = PassedEnd, - start_response = StartResp, - send_row = SendRow -}=Helpers, {Dir, EndKey, EndDocId, InclusiveEnd}) -> - PassedEnd2 = case PassedEnd of - undefined -> make_passed_end_fun(Dir, EndKey, EndDocId, InclusiveEnd); - _ -> PassedEnd - end, - - StartResp2 = case StartResp of - undefined -> fun json_view_start_resp/5; - _ -> StartResp - end, - - SendRow2 = case SendRow of - undefined -> fun send_json_view_row/5; - _ -> SendRow - end, - - Helpers#view_fold_helper_funs{ - passed_end = PassedEnd2, - start_response = StartResp2, - send_row = SendRow2 - }. - -apply_default_helper_funs(#reduce_fold_helper_funs{ - start_response = StartResp, - send_row = SendRow -}=Helpers) -> - StartResp2 = case StartResp of - undefined -> fun json_reduce_start_resp/3; - _ -> StartResp - end, - - SendRow2 = case SendRow of - undefined -> fun send_json_reduce_row/3; - _ -> SendRow - end, - - Helpers#reduce_fold_helper_funs{ - start_response = StartResp2, - send_row = SendRow2 - }. - -make_passed_end_fun(fwd, EndKey, EndDocId, InclusiveEnd) -> - case InclusiveEnd of - true -> - fun(ViewKey, ViewId) -> - couch_view:less_json([EndKey, EndDocId], [ViewKey, ViewId]) - end; - false -> - fun - (ViewKey, _ViewId) when ViewKey == EndKey -> - true; - (ViewKey, ViewId) -> - couch_view:less_json([EndKey, EndDocId], [ViewKey, ViewId]) - end - end; - -make_passed_end_fun(rev, EndKey, EndDocId, InclusiveEnd) -> - case InclusiveEnd of - true -> - fun(ViewKey, ViewId) -> - couch_view:less_json([ViewKey, ViewId], [EndKey, EndDocId]) - end; - false-> - fun - (ViewKey, _ViewId) when ViewKey == EndKey -> - true; - (ViewKey, ViewId) -> - couch_view:less_json([ViewKey, ViewId], [EndKey, EndDocId]) - end - end. - -json_view_start_resp(Req, Etag, TotalViewCount, Offset, _Acc) -> - {ok, Resp} = start_json_response(Req, 200, [{"Etag", Etag}]), - BeginBody = io_lib:format("{\"total_rows\":~w,\"offset\":~w,\"rows\":[\r\n", - [TotalViewCount, Offset]), - {ok, Resp, BeginBody}. - -send_json_view_row(Resp, Db, {{Key, DocId}, Value}, IncludeDocs, RowFront) -> - JsonObj = view_row_obj(Db, {{Key, DocId}, Value}, IncludeDocs), - send_chunk(Resp, RowFront ++ ?JSON_ENCODE(JsonObj)), - {ok, ",\r\n"}. - -json_reduce_start_resp(Req, Etag, _Acc0) -> - {ok, Resp} = start_json_response(Req, 200, [{"Etag", Etag}]), - {ok, Resp, "{\"rows\":[\r\n"}. - -send_json_reduce_row(Resp, {Key, Value}, RowFront) -> - send_chunk(Resp, RowFront ++ ?JSON_ENCODE({[{key, Key}, {value, Value}]})), - {ok, ",\r\n"}. - view_group_etag(Group, Db) -> view_group_etag(Group, Db, nil). @@ -604,71 +280,6 @@ view_group_etag(#group{sig=Sig,current_seq=CurrentSeq}, _Db, Extra) -> % track of the last Db seq that caused an index change. chttpd:make_etag({Sig, CurrentSeq, Extra}). -% the view row has an error -view_row_obj(_Db, {{Key, error}, Value}, _IncludeDocs) -> - {[{key, Key}, {error, Value}]}; -% include docs in the view output -view_row_obj(Db, {{Key, DocId}, {Props}}, true) -> - Rev = case couch_util:get_value(<<"_rev">>, Props) of - undefined -> - nil; - Rev0 -> - couch_doc:parse_rev(Rev0) - end, - view_row_with_doc(Db, {{Key, DocId}, {Props}}, Rev); -view_row_obj(Db, {{Key, DocId}, Value}, true) -> - view_row_with_doc(Db, {{Key, DocId}, Value}, nil); -% the normal case for rendering a view row -view_row_obj(_Db, {{Key, DocId}, Value}, _IncludeDocs) -> - {[{id, DocId}, {key, Key}, {value, Value}]}. - -view_row_with_doc(Db, {{Key, DocId}, Value}, Rev) -> - ?LOG_DEBUG("Include Doc: ~p ~p", [DocId, Rev]), - case (catch chttpd_db:couch_doc_open(Db, DocId, Rev, [])) of - {{not_found, missing}, _RevId} -> - {[{id, DocId}, {key, Key}, {value, Value}, {error, missing}]}; - {not_found, missing} -> - {[{id, DocId}, {key, Key}, {value, Value}, {error, missing}]}; - {not_found, deleted} -> - {[{id, DocId}, {key, Key}, {value, Value}]}; - Doc -> - JsonDoc = couch_doc:to_json_obj(Doc, []), - {[{id, DocId}, {key, Key}, {value, Value}, {doc, JsonDoc}]} - end. - -finish_view_fold(Req, TotalRows, FoldResult) -> - case FoldResult of - {ok, {_, _, undefined, _, Offset}} -> - % nothing found in the view, nothing has been returned - % send empty view - NewOffset = case Offset of - nil -> TotalRows; - _ -> Offset - end, - send_json(Req, 200, {[ - {total_rows, TotalRows}, - {offset, NewOffset}, - {rows, []} - ]}); - {ok, {_, _, Resp, _, _}} -> - % end the view - send_chunk(Resp, "\r\n]}"), - end_json_response(Resp); - Error -> - throw(Error) - end. - -finish_reduce_fold(Req, Resp) -> - case Resp of - undefined -> - send_json(Req, 200, {[ - {rows, []} - ]}); - Resp -> - send_chunk(Resp, "\r\n]}"), - end_json_response(Resp) - end. - parse_bool_param("true") -> true; parse_bool_param("false") -> false; parse_bool_param(Val) -> -- cgit v1.2.3