Merge remote branch 'cloudant:77984-upgrade-mrargs-record-phase1'

This closes #77

Signed-off-by: ILYA Khlopotov <iilyak@apache.org>
diff --git a/src/fabric_rpc.erl b/src/fabric_rpc.erl
index 9c7d518..b59c61e 100644
--- a/src/fabric_rpc.erl
+++ b/src/fabric_rpc.erl
@@ -92,18 +92,22 @@
         rexi:stream_last(Error)
     end.
 
-all_docs(DbName, Options, #mrargs{keys=undefined} = Args0) ->
-    set_io_priority(DbName, Options),
-    Args = fix_skip_and_limit(Args0),
-    {ok, Db} = get_or_create_db(DbName, Options),
-    VAcc0 = #vacc{db=Db},
-    couch_mrview:query_all_docs(Db, Args, fun view_cb/2, VAcc0).
+all_docs(DbName, Options, Args0) ->
+    case fabric_util:upgrade_mrargs(Args0) of
+        #mrargs{keys=undefined} ->
+            set_io_priority(DbName, Options),
+            Args = fix_skip_and_limit(Args0),
+            {ok, Db} = get_or_create_db(DbName, Options),
+            VAcc0 = #vacc{db=Db},
+            couch_mrview:query_all_docs(Db, Args, fun view_cb/2, VAcc0)
+    end.
 
 update_mrview(DbName, {DDocId, Rev}, ViewName, Args0) ->
     {ok, DDoc} = ddoc_cache:open_doc(mem3:dbname(DbName), DDocId, Rev),
     couch_util:with_db(DbName, fun(Db) ->
         UpdateSeq = couch_db:get_update_seq(Db),
-        {ok, Pid, _} = couch_mrview:get_view_index_pid(Db, DDoc, ViewName,                                                Args0),
+        {ok, Pid, _} = couch_mrview:get_view_index_pid(
+            Db, DDoc, ViewName, fabric_util:upgrade_mrargs(Args0)),
         couch_index:get_state(Pid, UpdateSeq)
     end).
 
@@ -116,7 +120,7 @@
     map_view(DbName, DDoc, ViewName, Args0, DbOptions);
 map_view(DbName, DDoc, ViewName, Args0, DbOptions) ->
     set_io_priority(DbName, DbOptions),
-    Args = fix_skip_and_limit(Args0),
+    Args = fix_skip_and_limit(fabric_util:upgrade_mrargs(Args0)),
     {ok, Db} = get_or_create_db(DbName, DbOptions),
     VAcc0 = #vacc{db=Db},
     couch_mrview:query_view(Db, DDoc, ViewName, Args, fun view_cb/2, VAcc0).
@@ -130,7 +134,7 @@
     reduce_view(DbName, DDoc, ViewName, Args0, DbOptions);
 reduce_view(DbName, DDoc, ViewName, Args0, DbOptions) ->
     set_io_priority(DbName, DbOptions),
-    Args = fix_skip_and_limit(Args0),
+    Args = fix_skip_and_limit(fabric_util:upgrade_mrargs(Args0)),
     {ok, Db} = get_or_create_db(DbName, DbOptions),
     VAcc0 = #vacc{db=Db},
     couch_mrview:query_view(Db, DDoc, ViewName, Args, fun reduce_cb/2, VAcc0).
diff --git a/src/fabric_util.erl b/src/fabric_util.erl
index 17e9c1e..e6dd86e 100644
--- a/src/fabric_util.erl
+++ b/src/fabric_util.erl
@@ -19,12 +19,14 @@
 -export([stream_start/2, stream_start/4]).
 -export([log_timeout/2, remove_done_workers/2]).
 -export([is_users_db/1, is_replicator_db/1, fake_db/2]).
+-export([upgrade_mrargs/1]).
 
 -compile({inline, [{doc_id_and_rev,1}]}).
 
 -include_lib("fabric/include/fabric.hrl").
 -include_lib("mem3/include/mem3.hrl").
 -include_lib("couch/include/couch_db.hrl").
+-include_lib("couch_mrview/include/couch_mrview.hrl").
 -include_lib("eunit/include/eunit.hrl").
 
 remove_down_workers(Workers, BadNode) ->
@@ -308,3 +310,63 @@
 
 doc_id_and_rev(#doc{id=DocId, revs={RevNum, [RevHash|_]}}) ->
     {DocId, {RevNum, RevHash}}.
+
+
+upgrade_mrargs(#mrargs{} = Args) ->
+    Args;
+
+upgrade_mrargs({mrargs,
+        ViewType,
+        Reduce,
+        PreflightFun,
+        StartKey,
+        StartKeyDocId,
+        EndKey,
+        EndKeyDocId,
+        Keys,
+        Direction,
+        Limit,
+        Skip,
+        GroupLevel,
+        Group,
+        Stable,
+        Update,
+        MultiGet,
+        InclusiveEnd,
+        IncludeDocs,
+        DocOptions,
+        UpdateSeq,
+        Conflicts,
+        Callback,
+        Sorted,
+        Extra}) ->
+    Stale = case {Stable, Update} of
+            {true, false} -> ok;
+            {true, lazy} -> update_after;
+            {_, _} -> false
+    end,
+    #mrargs{
+        view_type = ViewType,
+        reduce = Reduce,
+        preflight_fun = PreflightFun,
+        start_key = StartKey,
+        start_key_docid = StartKeyDocId,
+        end_key = EndKey,
+        end_key_docid = EndKeyDocId,
+        keys = Keys,
+        direction = Direction,
+        limit = Limit,
+        skip = Skip,
+        group_level = GroupLevel,
+        group = Group,
+        stale = Stale,
+        multi_get = MultiGet,
+        inclusive_end = InclusiveEnd,
+        include_docs = IncludeDocs,
+        doc_options = DocOptions,
+        update_seq = UpdateSeq,
+        conflicts = Conflicts,
+        callback = Callback,
+        sorted = Sorted,
+        extra = Extra
+    }.
diff --git a/src/fabric_view.erl b/src/fabric_view.erl
index 01291a9..a766348 100644
--- a/src/fabric_view.erl
+++ b/src/fabric_view.erl
@@ -302,13 +302,14 @@
 index_of(X, [_|Rest], I) ->
     index_of(X, Rest, I+1).
 
-get_shards(DbName, #mrargs{stable=true}) ->
+get_shards(DbName, #mrargs{stale=Stale})
+  when Stale == ok orelse Stale == update_after ->
     mem3:ushards(DbName);
-get_shards(DbName, #mrargs{stable=false}) ->
+get_shards(DbName, #mrargs{stale=false}) ->
     mem3:shards(DbName).
 
 maybe_update_others(DbName, DDoc, ShardsInvolved, ViewName,
-    #mrargs{update=lazy} = Args) ->
+    #mrargs{stale=update_after} = Args) ->
     ShardsNeedUpdated = mem3:shards(DbName) -- ShardsInvolved,
     lists:foreach(fun(#shard{node=Node, name=ShardName}) ->
         rpc:cast(Node, fabric_rpc, update_mrview, [ShardName, DDoc, ViewName, Args])