summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2018-07-04 17:27:10 +0100
committerRobert Newson <rnewson@apache.org>2018-07-10 15:30:14 +0100
commit38245dd55c830c7a436a1b6abad4e1d2d27f69d8 (patch)
tree25cacd085079859495a6b2ea998b150645bce6dd
parent2b63513f50a364a196e3e5ba9ceb8b325cfd4517 (diff)
downloadcouchdb-38245dd55c830c7a436a1b6abad4e1d2d27f69d8.tar.gz
Extract side-effect free part of validate_args
validate_args/1 also modified the arguments. By separating the validation from the update we are able to add updates that are not idempotent.
-rw-r--r--src/chttpd/src/chttpd_db.erl4
-rw-r--r--src/chttpd/src/chttpd_view.erl2
-rw-r--r--src/couch_mrview/src/couch_mrview.erl2
-rw-r--r--src/couch_mrview/src/couch_mrview_http.erl2
-rw-r--r--src/couch_mrview/src/couch_mrview_util.erl25
-rw-r--r--src/couch_mrview/test/couch_mrview_util_tests.erl2
-rw-r--r--src/couch_replicator/src/couch_replicator_httpd.erl2
-rw-r--r--src/fabric/src/fabric.erl2
8 files changed, 26 insertions, 15 deletions
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index ed0adead9..bf1fe8c3b 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -663,7 +663,7 @@ multi_all_docs_view(Req, Db, OP, Queries) ->
ArgQueries = lists:map(fun({Query}) ->
QueryArg1 = couch_mrview_http:parse_params(Query, undefined,
Args1, [decoded]),
- QueryArgs2 = couch_mrview_util:validate_args(QueryArg1),
+ QueryArgs2 = couch_mrview_util:validate_and_update_args(QueryArg1),
set_namespace(OP, QueryArgs2)
end, Queries),
Options = [{user_ctx, Req#httpd.user_ctx}],
@@ -683,7 +683,7 @@ multi_all_docs_view(Req, Db, OP, Queries) ->
all_docs_view(Req, Db, Keys, OP) ->
Args0 = couch_mrview_http:parse_params(Req, Keys),
Args1 = Args0#mrargs{view_type=map},
- Args2 = couch_mrview_util:validate_args(Args1),
+ Args2 = couch_mrview_util:validate_and_update_args(Args1),
Args3 = set_namespace(OP, Args2),
Options = [{user_ctx, Req#httpd.user_ctx}],
Max = chttpd:chunked_response_buffer_size(),
diff --git a/src/chttpd/src/chttpd_view.erl b/src/chttpd/src/chttpd_view.erl
index 3c05c64ca..799df61b4 100644
--- a/src/chttpd/src/chttpd_view.erl
+++ b/src/chttpd/src/chttpd_view.erl
@@ -24,7 +24,7 @@ multi_query_view(Req, Db, DDoc, ViewName, Queries) ->
QueryArg = couch_mrview_http:parse_params(Query, undefined,
Args1, [decoded]),
QueryArg1 = couch_mrview_util:set_view_type(QueryArg, ViewName, Views),
- couch_mrview_util:validate_args(QueryArg1)
+ couch_mrview_util:validate_and_update_args(QueryArg1)
end, Queries),
Options = [{user_ctx, Req#httpd.user_ctx}],
VAcc0 = #vacc{db=Db, req=Req, prepend="\r\n"},
diff --git a/src/couch_mrview/src/couch_mrview.erl b/src/couch_mrview/src/couch_mrview.erl
index 82bbd7928..a9d5d0ad1 100644
--- a/src/couch_mrview/src/couch_mrview.erl
+++ b/src/couch_mrview/src/couch_mrview.erl
@@ -223,7 +223,7 @@ query_all_docs(Db, Args0, Callback, Acc) ->
couch_index_util:hexsig(crypto:hash(md5, term_to_binary(Info)))
end),
Args1 = Args0#mrargs{view_type=map},
- Args2 = couch_mrview_util:validate_args(Args1),
+ Args2 = couch_mrview_util:validate_and_update_args(Args1),
{ok, Acc1} = case Args2#mrargs.preflight_fun of
PFFun when is_function(PFFun, 2) -> PFFun(Sig, Acc);
_ -> {ok, Acc}
diff --git a/src/couch_mrview/src/couch_mrview_http.erl b/src/couch_mrview/src/couch_mrview_http.erl
index 004caef09..9dae1d86c 100644
--- a/src/couch_mrview/src/couch_mrview_http.erl
+++ b/src/couch_mrview/src/couch_mrview_http.erl
@@ -296,7 +296,7 @@ multi_query_view(Req, Db, DDoc, ViewName, Queries) ->
{ok, _, _, Args1} = couch_mrview_util:get_view(Db, DDoc, ViewName, Args0),
ArgQueries = lists:map(fun({Query}) ->
QueryArg = parse_params(Query, undefined, Args1),
- couch_mrview_util:validate_args(QueryArg)
+ couch_mrview_util:validate_and_update_args(QueryArg)
end, Queries),
{ok, Resp2} = couch_httpd:etag_maybe(Req, fun() ->
Max = chttpd:chunked_response_buffer_size(),
diff --git a/src/couch_mrview/src/couch_mrview_util.erl b/src/couch_mrview/src/couch_mrview_util.erl
index eb461d017..086bf9bbf 100644
--- a/src/couch_mrview/src/couch_mrview_util.erl
+++ b/src/couch_mrview/src/couch_mrview_util.erl
@@ -24,7 +24,7 @@
-export([temp_view_to_ddoc/1]).
-export([calculate_external_size/1]).
-export([calculate_active_size/1]).
--export([validate_args/1]).
+-export([validate_and_update_args/1]).
-export([maybe_load_doc/3, maybe_load_doc/4]).
-export([maybe_update_index_file/1]).
-export([extract_view/4, extract_view_reduce/1]).
@@ -59,7 +59,7 @@ get_view(Db, DDoc, ViewName, Args0) ->
get_view_index_pid(Db, DDoc, ViewName, Args0) ->
ArgCheck = fun(InitState) ->
Args1 = set_view_type(Args0, ViewName, InitState#mrst.views),
- {ok, validate_args(Args1)}
+ {ok, validate_and_update_args(Args1)}
end,
couch_index_server:get_index(?MOD, Db, DDoc, ArgCheck).
@@ -546,6 +546,17 @@ validate_args(Args) ->
{red, _} -> mrverror(<<"`conflicts` is invalid for reduce views.">>)
end,
+ case is_boolean(Args#mrargs.sorted) of
+ true -> ok;
+ _ -> mrverror(<<"Invalid value for `sorted`.">>)
+ end,
+
+ true.
+
+
+update_args(#mrargs{} = Args) ->
+ GroupLevel = determine_group_level(Args),
+
SKDocId = case {Args#mrargs.direction, Args#mrargs.start_key_docid} of
{fwd, undefined} -> <<>>;
{rev, undefined} -> <<255>>;
@@ -558,11 +569,6 @@ validate_args(Args) ->
{_, EKDocId1} -> EKDocId1
end,
- case is_boolean(Args#mrargs.sorted) of
- true -> ok;
- _ -> mrverror(<<"Invalid value for `sorted`.">>)
- end,
-
Args#mrargs{
start_key_docid=SKDocId,
end_key_docid=EKDocId,
@@ -570,6 +576,11 @@ validate_args(Args) ->
}.
+validate_and_update_args(#mrargs{} = Args) ->
+ true = validate_args(Args),
+ update_args(Args).
+
+
determine_group_level(#mrargs{group=undefined, group_level=undefined}) ->
0;
determine_group_level(#mrargs{group=false, group_level=undefined}) ->
diff --git a/src/couch_mrview/test/couch_mrview_util_tests.erl b/src/couch_mrview/test/couch_mrview_util_tests.erl
index 7046c9bb2..df50187fc 100644
--- a/src/couch_mrview/test/couch_mrview_util_tests.erl
+++ b/src/couch_mrview/test/couch_mrview_util_tests.erl
@@ -34,6 +34,6 @@ couch_mrview_util_test_() ->
validate_group_level(Group, GroupLevel) ->
Args0 = #mrargs{group=Group, group_level=GroupLevel, view_type=red},
- Args1 = couch_mrview_util:validate_args(Args0),
+ Args1 = couch_mrview_util:validate_and_update_args(Args0),
Args1#mrargs.group_level.
diff --git a/src/couch_replicator/src/couch_replicator_httpd.erl b/src/couch_replicator/src/couch_replicator_httpd.erl
index abd9f7fd0..f37d4364d 100644
--- a/src/couch_replicator/src/couch_replicator_httpd.erl
+++ b/src/couch_replicator/src/couch_replicator_httpd.erl
@@ -124,7 +124,7 @@ handle_scheduler_docs(Db, Req) when is_binary(Db) ->
reduce = false,
extra = [{filter_states, States}]
},
- VArgs2 = couch_mrview_util:validate_args(VArgs1),
+ VArgs2 = couch_mrview_util:validate_and_update_args(VArgs1),
Opts = [{user_ctx, Req#httpd.user_ctx}],
Max = chttpd:chunked_response_buffer_size(),
Acc = couch_replicator_httpd_util:docs_acc_new(Req, Db, Max),
diff --git a/src/fabric/src/fabric.erl b/src/fabric/src/fabric.erl
index 4a0727131..1b761abf3 100644
--- a/src/fabric/src/fabric.erl
+++ b/src/fabric/src/fabric.erl
@@ -355,7 +355,7 @@ query_view(DbName, Options, DDoc, ViewName, Callback, Acc0, QueryArgs0) ->
{ok, #mrst{views=Views, language=Lang}} =
couch_mrview_util:ddoc_to_mrst(Db, DDoc),
QueryArgs1 = couch_mrview_util:set_view_type(QueryArgs0, View, Views),
- QueryArgs2 = couch_mrview_util:validate_args(QueryArgs1),
+ QueryArgs2 = couch_mrview_util:validate_and_update_args(QueryArgs1),
VInfo = couch_mrview_util:extract_view(Lang, QueryArgs2, View, Views),
case is_reduce_view(QueryArgs2) of
true ->