Repository: couchdb-couch-replicator
Updated Branches:
  refs/heads/master fd66cb6b3 -> ff49e1c47


Fix view filtered replication

The output for get_view_info function has been normalized
and URL for views' info got fixed.

The ddoc's update_seq is not applicable to a database changes feed
used for the filtering by none seq indexed views, so we'll use database
update_seq instead.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-replicator/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/couchdb-couch-replicator/commit/ff49e1c4
Tree: 
http://git-wip-us.apache.org/repos/asf/couchdb-couch-replicator/tree/ff49e1c4
Diff: 
http://git-wip-us.apache.org/repos/asf/couchdb-couch-replicator/diff/ff49e1c4

Branch: refs/heads/master
Commit: ff49e1c47323239dff568da3b90b596097dc8d99
Parents: fd66cb6
Author: Eric Avdey <e...@eiri.ca>
Authored: Tue Feb 23 10:13:06 2016 -0400
Committer: Eric Avdey <e...@eiri.ca>
Committed: Fri Feb 26 09:51:24 2016 -0400

----------------------------------------------------------------------
 src/couch_replicator.erl                 | 10 +-----
 src/couch_replicator_api_wrap.erl        |  8 +++--
 test/couch_replicator_filtered_tests.erl | 45 +++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-replicator/blob/ff49e1c4/src/couch_replicator.erl
----------------------------------------------------------------------
diff --git a/src/couch_replicator.erl b/src/couch_replicator.erl
index 29225e3..d6e9e39 100644
--- a/src/couch_replicator.erl
+++ b/src/couch_replicator.erl
@@ -642,15 +642,7 @@ init_state(Rep) ->
     StartSeq1 = get_value(since_seq, Options, StartSeq0),
     StartSeq = {0, StartSeq1},
 
-    SourceSeq = case Type of
-        db -> get_value(<<"update_seq">>, SourceInfo, ?LOWEST_SEQ);
-        view ->
-            {DDoc, VName} = View,
-            {ok, VInfo} = couch_replicator_api_wrap:get_view_info(Source, DDoc,
-                                                                  VName),
-            get_value(<<"update_seq">>, VInfo, ?LOWEST_SEQ)
-    end,
-
+    SourceSeq = get_value(<<"update_seq">>, SourceInfo, ?LOWEST_SEQ),
 
     #doc{body={CheckpointHistory}} = SourceLog,
     State = #rep_state{

http://git-wip-us.apache.org/repos/asf/couchdb-couch-replicator/blob/ff49e1c4/src/couch_replicator_api_wrap.erl
----------------------------------------------------------------------
diff --git a/src/couch_replicator_api_wrap.erl 
b/src/couch_replicator_api_wrap.erl
index 2fb6c84..b7d3bb6 100644
--- a/src/couch_replicator_api_wrap.erl
+++ b/src/couch_replicator_api_wrap.erl
@@ -178,13 +178,15 @@ get_pending_count(#db{name=DbName}=Db, Seq) when 
is_number(Seq) ->
     {ok, Pending}.
 
 get_view_info(#httpdb{} = Db, DDocId, ViewName) ->
-    Path = iolist_to_binary([DDocId, "/_view/", ViewName, "/_info"]),
+    Path = io_lib:format("~s/_view/~s/_info", [DDocId, ViewName]),
     send_req(Db, [{path, Path}],
         fun(200, _, {Props}) ->
-            {ok, Props}
+            {VInfo} = couch_util:get_value(<<"view_index">>, Props, {[]}),
+            {ok, VInfo}
         end);
 get_view_info(#db{name = DbName}, DDocId, ViewName) ->
-    couch_mrview:get_view_info(DbName, DDocId, ViewName).
+    {ok, VInfo} = couch_mrview:get_view_info(DbName, DDocId, ViewName),
+    {ok, [{couch_util:to_binary(K), V} || {K, V} <- VInfo]}.
 
 
 ensure_full_commit(#httpdb{} = Db) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch-replicator/blob/ff49e1c4/test/couch_replicator_filtered_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_replicator_filtered_tests.erl 
b/test/couch_replicator_filtered_tests.erl
index d39aabd..03cf44c 100644
--- a/test/couch_replicator_filtered_tests.erl
+++ b/test/couch_replicator_filtered_tests.erl
@@ -32,6 +32,17 @@
                 }
             }
         ">>}
+    ]}},
+    {<<"views">>, {[
+        {<<"mammals">>, {[
+            {<<"map">>, <<"
+                function(doc) {
+                    if (doc.class == 'mammal') {
+                        emit(doc._id, null);
+                    }
+                }
+            ">>}
+        ]}}
     ]}}
 ]}).
 
@@ -72,6 +83,17 @@ query_filtered_replication_test_() ->
         }
     }.
 
+view_filtered_replication_test_() ->
+    Pairs = [{local, local}],
+    {
+        "Filtered with a view replication tests",
+        {
+            foreachx,
+            fun setup/1, fun teardown/2,
+            [{Pair, fun should_succeed_with_view/2} || Pair <- Pairs]
+        }
+    }.
+
 should_succeed({From, To}, {_Ctx, {Source, Target}}) ->
     RepObject = {[
         {<<"source">>, db_url(From, Source)},
@@ -120,6 +142,29 @@ should_succeed_with_query({From, To}, {_Ctx, {Source, 
Target}}) ->
         ?_assert(lists:all(fun(Valid) -> Valid end, AllReplies))}
     ]}.
 
+should_succeed_with_view({From, To}, {_Ctx, {Source, Target}}) ->
+    RepObject = {[
+        {<<"source">>, db_url(From, Source)},
+        {<<"target">>, db_url(To, Target)},
+        {<<"filter">>, <<"_view">>},
+        {<<"query_params">>, {[
+            {<<"view">>, <<"filter_ddoc/mammals">>}
+        ]}}
+    ]},
+    {ok, _} = couch_replicator:replicate(RepObject, ?ADMIN_USER),
+    FilterFun = fun(_DocId, {Props}) ->
+        couch_util:get_value(<<"class">>, Props) == <<"mammal">>
+    end,
+    {ok, TargetDbInfo, AllReplies} = compare_dbs(Source, Target, FilterFun),
+    {lists:flatten(io_lib:format("~p -> ~p", [From, To])), [
+        {"Target DB has proper number of docs",
+        ?_assertEqual(1, proplists:get_value(doc_count, TargetDbInfo))},
+        {"Target DB doesn't have deleted docs",
+        ?_assertEqual(0, proplists:get_value(doc_del_count, TargetDbInfo))},
+        {"All the docs filtered as expected",
+        ?_assert(lists:all(fun(Valid) -> Valid end, AllReplies))}
+    ]}.
+
 compare_dbs(Source, Target, FilterFun) ->
     {ok, SourceDb} = couch_db:open_int(Source, []),
     {ok, TargetDb} = couch_db:open_int(Target, []),

Reply via email to