diff options
Diffstat (limited to 'src/chttpd/src/chttpd_view.erl')
-rw-r--r-- | src/chttpd/src/chttpd_view.erl | 186 |
1 files changed, 0 insertions, 186 deletions
diff --git a/src/chttpd/src/chttpd_view.erl b/src/chttpd/src/chttpd_view.erl deleted file mode 100644 index f73a8b7b1..000000000 --- a/src/chttpd/src/chttpd_view.erl +++ /dev/null @@ -1,186 +0,0 @@ -% 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. - --module(chttpd_view). --include_lib("couch/include/couch_db.hrl"). --include_lib("couch_mrview/include/couch_mrview.hrl"). - --export([handle_view_req/3, handle_temp_view_req/2]). - -multi_query_view(Req, Db, DDoc, ViewName, Queries) -> - Args0 = couch_mrview_http:parse_params(Req, undefined), - {ok, #mrst{views=Views}} = couch_mrview_util:ddoc_to_mrst(Db, DDoc), - Args1 = couch_mrview_util:set_view_type(Args0, ViewName, Views), - ArgQueries = lists:map(fun({Query}) -> - QueryArg = couch_mrview_http:parse_params(Query, undefined, - Args1, [decoded]), - QueryArg1 = couch_mrview_util:set_view_type(QueryArg, ViewName, Views), - fabric_util:validate_args(Db, DDoc, QueryArg1) - end, Queries), - Options = [{user_ctx, Req#httpd.user_ctx}], - VAcc0 = #vacc{db=Db, req=Req, prepend="\r\n"}, - FirstChunk = "{\"results\":[", - {ok, Resp0} = chttpd:start_delayed_json_response(VAcc0#vacc.req, 200, [], FirstChunk), - VAcc1 = VAcc0#vacc{resp=Resp0}, - VAcc2 = lists:foldl(fun(Args, Acc0) -> - {ok, Acc1} = fabric:query_view(Db, Options, DDoc, ViewName, - fun view_cb/2, Acc0, Args), - Acc1 - end, VAcc1, ArgQueries), - {ok, Resp1} = chttpd:send_delayed_chunk(VAcc2#vacc.resp, "\r\n]}"), - chttpd:end_delayed_json_response(Resp1). - -design_doc_post_view(Req, Props, Db, DDoc, ViewName, Keys) -> - Args = couch_mrview_http:parse_body_and_query(Req, Props, Keys), - fabric_query_view(Db, Req, DDoc, ViewName, Args). - -design_doc_view(Req, Db, DDoc, ViewName, Keys) -> - Args = couch_mrview_http:parse_params(Req, Keys), - fabric_query_view(Db, Req, DDoc, ViewName, Args). - -fabric_query_view(Db, Req, DDoc, ViewName, Args) -> - Max = chttpd:chunked_response_buffer_size(), - VAcc = #vacc{db=Db, req=Req, threshold=Max}, - Options = [{user_ctx, Req#httpd.user_ctx}], - {ok, Resp} = fabric:query_view(Db, Options, DDoc, ViewName, - fun view_cb/2, VAcc, Args), - {ok, Resp#vacc.resp}. - - -view_cb({row, Row} = Msg, Acc) -> - case lists:keymember(doc, 1, Row) of - true -> chttpd_stats:incr_reads(); - false -> ok - end, - chttpd_stats:incr_rows(), - couch_mrview_http:view_cb(Msg, Acc); - -view_cb(Msg, Acc) -> - couch_mrview_http:view_cb(Msg, Acc). - - -handle_view_req(#httpd{method='POST', - path_parts=[_, _, _, _, ViewName, <<"queries">>]}=Req, Db, DDoc) -> - chttpd:validate_ctype(Req, "application/json"), - Props = couch_httpd:json_body_obj(Req), - case couch_mrview_util:get_view_queries(Props) of - undefined -> - throw({bad_request, - <<"POST body must include `queries` parameter.">>}); - Queries -> - multi_query_view(Req, Db, DDoc, ViewName, Queries) - end; - -handle_view_req(#httpd{path_parts=[_, _, _, _, _, <<"queries">>]}=Req, - _Db, _DDoc) -> - chttpd:send_method_not_allowed(Req, "POST"); - -handle_view_req(#httpd{method='GET', - path_parts=[_, _, _, _, ViewName]}=Req, Db, DDoc) -> - couch_stats:increment_counter([couchdb, httpd, view_reads]), - Keys = chttpd:qs_json_value(Req, "keys", undefined), - design_doc_view(Req, Db, DDoc, ViewName, Keys); - -handle_view_req(#httpd{method='POST', - path_parts=[_, _, _, _, ViewName]}=Req, Db, DDoc) -> - chttpd:validate_ctype(Req, "application/json"), - Props = couch_httpd:json_body_obj(Req), - assert_no_queries_param(couch_mrview_util:get_view_queries(Props)), - Keys = couch_mrview_util:get_view_keys(Props), - couch_stats:increment_counter([couchdb, httpd, view_reads]), - design_doc_post_view(Req, Props, Db, DDoc, ViewName, Keys); - -handle_view_req(Req, _Db, _DDoc) -> - chttpd:send_method_not_allowed(Req, "GET,POST,HEAD"). - -handle_temp_view_req(Req, _Db) -> - Msg = <<"Temporary views are not supported in CouchDB">>, - chttpd:send_error(Req, 410, gone, Msg). - -% See https://github.com/apache/couchdb/issues/2168 -assert_no_queries_param(undefined) -> - ok; -assert_no_queries_param(_) -> - throw({ - bad_request, - "The `queries` parameter is no longer supported at this endpoint" - }). - - --ifdef(TEST). - --include_lib("eunit/include/eunit.hrl"). - - -check_multi_query_reduce_view_overrides_test_() -> - { - setup, - fun setup_all/0, - fun teardown_all/1, - { - foreach, - fun setup/0, - fun teardown/1, - [ - t_check_include_docs_throw_validation_error(), - t_check_user_can_override_individual_query_type() - ] - } - }. - - -t_check_include_docs_throw_validation_error() -> - ?_test(begin - Req = #httpd{qs = []}, - Db = test_util:fake_db([{name, <<"foo">>}]), - Query = {[{<<"include_docs">>, true}]}, - Throw = {query_parse_error, <<"`include_docs` is invalid for reduce">>}, - ?assertThrow(Throw, multi_query_view(Req, Db, ddoc, <<"v">>, [Query])) - end). - - -t_check_user_can_override_individual_query_type() -> - ?_test(begin - Req = #httpd{qs = []}, - Db = test_util:fake_db([{name, <<"foo">>}]), - Query = {[{<<"include_docs">>, true}, {<<"reduce">>, false}]}, - multi_query_view(Req, Db, ddoc, <<"v">>, [Query]), - ?assertEqual(1, meck:num_calls(chttpd, start_delayed_json_response, '_')) - end). - - -setup_all() -> - Views = [#mrview{reduce_funs = [{<<"v">>, <<"_count">>}]}], - meck:expect(couch_mrview_util, ddoc_to_mrst, 2, {ok, #mrst{views = Views}}), - meck:expect(chttpd, start_delayed_json_response, 4, {ok, resp}), - meck:expect(fabric, query_view, 7, {ok, #vacc{}}), - meck:expect(chttpd, send_delayed_chunk, 2, {ok, resp}), - meck:expect(chttpd, end_delayed_json_response, 1, ok). - - -teardown_all(_) -> - meck:unload(). - - -setup() -> - meck:reset([ - chttpd, - couch_mrview_util, - fabric - ]). - - -teardown(_) -> - ok. - - --endif. |