Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D1B03183BA for ; Fri, 26 Feb 2016 14:22:17 +0000 (UTC) Received: (qmail 24588 invoked by uid 500); 26 Feb 2016 14:22:17 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 24535 invoked by uid 500); 26 Feb 2016 14:22:17 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 24526 invoked by uid 99); 26 Feb 2016 14:22:17 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Feb 2016 14:22:17 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 826B6E0019; Fri, 26 Feb 2016 14:22:17 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: eiri@apache.org To: commits@couchdb.apache.org Message-Id: <68bef184b20043e0ae71a20d4cb7e7b8@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: couch-replicator commit: updated refs/heads/master to ff49e1c Date: Fri, 26 Feb 2016 14:22:17 +0000 (UTC) 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 Authored: Tue Feb 23 10:13:06 2016 -0400 Committer: Eric Avdey 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, []),