You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2018/07/10 15:06:33 UTC

[couchdb] 02/10: Extract side-effect free part of validate_args

This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch user-partitioned-dbs-wip
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 38245dd55c830c7a436a1b6abad4e1d2d27f69d8
Author: Robert Newson <rn...@apache.org>
AuthorDate: Wed Jul 4 17:27:10 2018 +0100

    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.
---
 src/chttpd/src/chttpd_db.erl                       |  4 ++--
 src/chttpd/src/chttpd_view.erl                     |  2 +-
 src/couch_mrview/src/couch_mrview.erl              |  2 +-
 src/couch_mrview/src/couch_mrview_http.erl         |  2 +-
 src/couch_mrview/src/couch_mrview_util.erl         | 25 ++++++++++++++++------
 src/couch_mrview/test/couch_mrview_util_tests.erl  |  2 +-
 .../src/couch_replicator_httpd.erl                 |  2 +-
 src/fabric/src/fabric.erl                          |  2 +-
 8 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index ed0adea..bf1fe8c 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 3c05c64..799df61 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 82bbd79..a9d5d0a 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 004caef..9dae1d8 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 eb461d0..086bf9b 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 7046c9b..df50187 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 abd9f7f..f37d436 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 4a07271..1b761ab 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 ->