summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2010-07-07 10:28:31 -0400
committerAdam Kocoloski <adam@cloudant.com>2010-08-12 11:18:48 -0400
commit1a2e1790388e21174ac431a223147eb2ea4949be (patch)
tree6e20ab1e5d6e3cf009470d5cf5af830b66ca0ec3
parent02767bad6e66b88ebf3e74fbd70ca49a4fbfae5a (diff)
remove unused view code
-rw-r--r--src/chttpd_view.erl399
1 files 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) ->