summaryrefslogtreecommitdiff
path: root/src/couch/src/couch_query_servers.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couch/src/couch_query_servers.erl')
-rw-r--r--src/couch/src/couch_query_servers.erl93
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]).