diff options
Diffstat (limited to 'src/couch/src/couch_query_servers.erl')
-rw-r--r-- | src/couch/src/couch_query_servers.erl | 93 |
1 files changed, 13 insertions, 80 deletions
diff --git a/src/couch/src/couch_query_servers.erl b/src/couch/src/couch_query_servers.erl index 8eb07abbf..d2523826b 100644 --- a/src/couch/src/couch_query_servers.erl +++ b/src/couch/src/couch_query_servers.erl @@ -18,7 +18,6 @@ -export([filter_docs/5]). -export([filter_view/3]). -export([finalize/2]). --export([rewrite/3]). -export([with_ddoc_proc/2, proc_prompt/2, ddoc_prompt/3, ddoc_proc_prompt/3, json_doc/1]). @@ -392,84 +391,6 @@ validate_doc_update(DDoc, EditDoc, DiskDoc, Ctx, SecObj) -> end. -rewrite(Req, Db, DDoc) -> - Fields = [F || F <- chttpd_external:json_req_obj_fields(), - F =/= <<"info">>, F =/= <<"form">>, - F =/= <<"uuid">>, F =/= <<"id">>], - JsonReq = chttpd_external:json_req_obj(Req, Db, null, Fields), - case couch_query_servers:ddoc_prompt(DDoc, [<<"rewrites">>], [JsonReq]) of - {[{<<"forbidden">>, Message}]} -> - throw({forbidden, Message}); - {[{<<"unauthorized">>, Message}]} -> - throw({unauthorized, Message}); - [<<"no_dispatch_rule">>] -> - undefined; - [<<"ok">>, {V}=Rewrite] when is_list(V) -> - ok = validate_rewrite_response(Rewrite), - Rewrite; - [<<"ok">>, _] -> - throw_rewrite_error(<<"bad rewrite">>); - V -> - couch_log:error("bad rewrite return ~p", [V]), - throw({unknown_error, V}) - end. - -validate_rewrite_response({Fields}) when is_list(Fields) -> - validate_rewrite_response_fields(Fields). - -validate_rewrite_response_fields([{Key, Value} | Rest]) -> - validate_rewrite_response_field(Key, Value), - validate_rewrite_response_fields(Rest); -validate_rewrite_response_fields([]) -> - ok. - -validate_rewrite_response_field(<<"method">>, Method) when is_binary(Method) -> - ok; -validate_rewrite_response_field(<<"method">>, _) -> - throw_rewrite_error(<<"bad method">>); -validate_rewrite_response_field(<<"path">>, Path) when is_binary(Path) -> - ok; -validate_rewrite_response_field(<<"path">>, _) -> - throw_rewrite_error(<<"bad path">>); -validate_rewrite_response_field(<<"body">>, Body) when is_binary(Body) -> - ok; -validate_rewrite_response_field(<<"body">>, _) -> - throw_rewrite_error(<<"bad body">>); -validate_rewrite_response_field(<<"headers">>, {Props}=Headers) when is_list(Props) -> - validate_object_fields(Headers); -validate_rewrite_response_field(<<"headers">>, _) -> - throw_rewrite_error(<<"bad headers">>); -validate_rewrite_response_field(<<"query">>, {Props}=Query) when is_list(Props) -> - validate_object_fields(Query); -validate_rewrite_response_field(<<"query">>, _) -> - throw_rewrite_error(<<"bad query">>); -validate_rewrite_response_field(<<"code">>, Code) when is_integer(Code) andalso Code >= 200 andalso Code < 600 -> - ok; -validate_rewrite_response_field(<<"code">>, _) -> - throw_rewrite_error(<<"bad code">>); -validate_rewrite_response_field(K, V) -> - couch_log:debug("unknown rewrite field ~p=~p", [K, V]), - ok. - -validate_object_fields({Props}) when is_list(Props) -> - lists:foreach(fun - ({Key, Value}) when is_binary(Key) andalso is_binary(Value) -> - ok; - ({Key, Value}) -> - Reason = io_lib:format( - "object key/value must be strings ~p=~p", [Key, Value]), - throw_rewrite_error(Reason); - (Value) -> - throw_rewrite_error(io_lib:format("bad value ~p", [Value])) - end, Props). - - -throw_rewrite_error(Reason) when is_list(Reason)-> - throw_rewrite_error(iolist_to_binary(Reason)); -throw_rewrite_error(Reason) when is_binary(Reason) -> - throw({rewrite_error, Reason}). - - json_doc_options() -> json_doc_options([]). @@ -500,9 +421,21 @@ filter_docs(Req, Db, DDoc, FName, Docs) -> end, Options = json_doc_options(), JsonDocs = [json_doc(Doc, Options) || Doc <- Docs], + try + {ok, filter_docs_int(DDoc, FName, JsonReq, JsonDocs)} + catch + throw:{os_process_error,{exit_status,1}} -> + %% batch used too much memory, retry sequentially. + Fun = fun(JsonDoc) -> + filter_docs_int(DDoc, FName, JsonReq, [JsonDoc]) + end, + {ok, lists:flatmap(Fun, JsonDocs)} + end. + +filter_docs_int(DDoc, FName, JsonReq, JsonDocs) -> [true, Passes] = ddoc_prompt(DDoc, [<<"filters">>, FName], [JsonDocs, JsonReq]), - {ok, Passes}. + Passes. ddoc_proc_prompt({Proc, DDocId}, FunPath, Args) -> proc_prompt(Proc, [<<"ddoc">>, DDocId, FunPath, Args]). |