You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2014/02/09 00:46:36 UTC

[1/2] couchdb commit: updated refs/heads/1994-merge-rcouch to c246549

Updated Branches:
  refs/heads/1994-merge-rcouch 1e6114c56 -> c24654992


couch_mrview: add HTTP handler to retrieve the infos on a view.


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

Branch: refs/heads/1994-merge-rcouch
Commit: 0bbd65cdd6dc412c9944f7b49c10d63c61622267
Parents: 1e6114c
Author: Benoit Chesneau <be...@apache.org>
Authored: Sat Feb 8 23:15:28 2014 +0100
Committer: Benoit Chesneau <be...@apache.org>
Committed: Sat Feb 8 23:15:28 2014 +0100

----------------------------------------------------------------------
 apps/couch_mrview/src/couch_mrview.erl      |  6 +++---
 apps/couch_mrview/src/couch_mrview_http.erl | 12 ++++++++++++
 2 files changed, 15 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0bbd65cd/apps/couch_mrview/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/src/couch_mrview.erl b/apps/couch_mrview/src/couch_mrview.erl
index e5b0d99..a578b85 100644
--- a/apps/couch_mrview/src/couch_mrview.erl
+++ b/apps/couch_mrview/src/couch_mrview.erl
@@ -161,11 +161,11 @@ get_view_info(Db, DDoc, VName) ->
     {ok, TotalSeqs} = case SeqBtree of
         nil -> {ok, 0};
         _ ->
-            {ok, {Count, _Reds}} = couch_btree:full_reduce(SeqBtree),
-            {ok, Count}
+            couch_btree:full_reduce(SeqBtree)
     end,
 
-    {ok, [{update_seq, View#mrview.update_seq},
+    {ok, [{seq_indexed, View#mrview.seq_indexed},
+          {update_seq, View#mrview.update_seq},
           {purge_seq, View#mrview.purge_seq},
           {total_rows, TotalRows},
           {total_seqs, TotalSeqs}]}.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0bbd65cd/apps/couch_mrview/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/src/couch_mrview_http.erl b/apps/couch_mrview/src/couch_mrview_http.erl
index 4801e27..c5ba622 100644
--- a/apps/couch_mrview/src/couch_mrview_http.erl
+++ b/apps/couch_mrview/src/couch_mrview_http.erl
@@ -48,6 +48,18 @@ handle_all_docs_req(Req, _Db) ->
     couch_httpd:send_method_not_allowed(Req, "GET,POST,HEAD").
 
 
+handle_view_req(#httpd{method='GET',
+                      path_parts=[_, _, DDocName, _, VName, <<"_info">>]}=Req,
+                Db, DDoc) ->
+
+    DDocId = <<"_design/", DDocName/binary >>,
+    {ok, Info} = couch_mrview:get_view_info(Db#db.name, DDocId, VName),
+
+    FinalInfo = [{db_name, Db#db.name},
+                 {ddoc, DDocId},
+                 {view, VName}] ++ Info,
+    couch_httpd:send_json(Req, 200, {FinalInfo});
+
 handle_view_req(#httpd{method='GET'}=Req, Db, DDoc) ->
     [_, _, _, _, ViewName] = Req#httpd.path_parts,
     couch_stats_collector:increment({httpd, view_reads}),


[2/2] couchdb commit: updated refs/heads/1994-merge-rcouch to c246549

Posted by be...@apache.org.
couch_replicator: add replication using changes in a view

Instead of a database, the replicator can now filter the documents using
a view index. All documents having a key emitted in the view can be
replicated.

View parameters can be used. Which means that you can replicate results
corresponding to a key in a view or a range.


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

Branch: refs/heads/1994-merge-rcouch
Commit: c246549927f7578f33595fd4f7969fd11c762a9d
Parents: 0bbd65c
Author: Benoit Chesneau <be...@apache.org>
Authored: Sun Feb 9 00:43:23 2014 +0100
Committer: Benoit Chesneau <be...@apache.org>
Committed: Sun Feb 9 00:44:41 2014 +0100

----------------------------------------------------------------------
 apps/couch_httpd/src/couch_httpd_changes.erl    | 11 +++---
 apps/couch_mrview/src/couch_mrview_http.erl     |  2 +-
 apps/couch_replicator/src/couch_replicator.erl  | 39 ++++++++++++++++++--
 apps/couch_replicator/src/couch_replicator.hrl  |  2 +
 .../src/couch_replicator_api_wrap.erl           | 25 ++++++++++++-
 .../src/couch_replicator_utils.erl              | 27 +++++++++++++-
 6 files changed, 93 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c2465499/apps/couch_httpd/src/couch_httpd_changes.erl
----------------------------------------------------------------------
diff --git a/apps/couch_httpd/src/couch_httpd_changes.erl b/apps/couch_httpd/src/couch_httpd_changes.erl
index 1c4a147..6cb0b16 100644
--- a/apps/couch_httpd/src/couch_httpd_changes.erl
+++ b/apps/couch_httpd/src/couch_httpd_changes.erl
@@ -137,12 +137,15 @@ handle_view_changes(ChangesArgs, Req, Db) ->
     {DDocId, VName} = parse_view_param(Req),
 
     %% get view options
-    Query = case Req of
+    {Query, NoIndex} = case Req of
         {json_req, {Props}} ->
             {Q} = couch_util:get_value(<<"query">>, Props, {[]}),
-            Q;
+            NoIndex1 = (couch_util:get_value(<<"use_index">>, Q,
+                                            <<"yes">>) =:= <<"no">>),
+            {Q, NoIndex1};
         _ ->
-            couch_httpd:qs(Req)
+            NoIndex1 = couch_httpd:qs_value(Req, "use_index", "yes") =:= "no",
+            {couch_httpd:qs(Req), NoIndex1}
     end,
     ViewOptions = parse_view_options(Query, []),
 
@@ -151,8 +154,6 @@ handle_view_changes(ChangesArgs, Req, Db) ->
                              proplists:get_value(update_options, Infos,
                                                  [])),
 
-    NoIndex = couch_httpd:qs_value(Req, "use_index", "yes") =:= "no",
-
     case {IsIndexed, NoIndex} of
         {true, false} ->
             handle_view_changes(Db, DDocId, VName, ViewOptions, ChangesArgs,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c2465499/apps/couch_mrview/src/couch_mrview_http.erl
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/src/couch_mrview_http.erl b/apps/couch_mrview/src/couch_mrview_http.erl
index c5ba622..64c9fb1 100644
--- a/apps/couch_mrview/src/couch_mrview_http.erl
+++ b/apps/couch_mrview/src/couch_mrview_http.erl
@@ -50,7 +50,7 @@ handle_all_docs_req(Req, _Db) ->
 
 handle_view_req(#httpd{method='GET',
                       path_parts=[_, _, DDocName, _, VName, <<"_info">>]}=Req,
-                Db, DDoc) ->
+                Db, _DDoc) ->
 
     DDocId = <<"_design/", DDocName/binary >>,
     {ok, Info} = couch_mrview:get_view_info(Db#db.name, DDocId, VName),

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c2465499/apps/couch_replicator/src/couch_replicator.erl
----------------------------------------------------------------------
diff --git a/apps/couch_replicator/src/couch_replicator.erl b/apps/couch_replicator/src/couch_replicator.erl
index d470c8a..10aaf37 100644
--- a/apps/couch_replicator/src/couch_replicator.erl
+++ b/apps/couch_replicator/src/couch_replicator.erl
@@ -70,7 +70,9 @@
     target_monitor = nil,
     source_seq = nil,
     use_checkpoints = true,
-    checkpoint_interval = 5000
+    checkpoint_interval = 5000,
+    type = db,
+    view = nil
 }).
 
 
@@ -533,7 +535,8 @@ cancel_timer(#rep_state{timer = Timer} = State) ->
 init_state(Rep) ->
     #rep{
         source = Src, target = Tgt,
-        options = Options, user_ctx = UserCtx
+        options = Options, user_ctx = UserCtx,
+        type = Type, view = View
     } = Rep,
     {ok, Source} = couch_replicator_api_wrap:db_open(Src, [{user_ctx, UserCtx}]),
     {ok, Target} = couch_replicator_api_wrap:db_open(Tgt, [{user_ctx, UserCtx}],
@@ -547,6 +550,17 @@ init_state(Rep) ->
     {StartSeq0, History} = compare_replication_logs(SourceLog, TargetLog),
     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,
+
+
     #doc{body={CheckpointHistory}} = SourceLog,
     State = #rep_state{
         rep_details = Rep,
@@ -571,9 +585,12 @@ init_state(Rep) ->
             start_db_compaction_notifier(Target, self()),
         source_monitor = db_monitor(Source),
         target_monitor = db_monitor(Target),
-        source_seq = get_value(<<"update_seq">>, SourceInfo, ?LOWEST_SEQ),
+        source_seq = SourceSeq,
         use_checkpoints = get_value(use_checkpoints, Options, true),
-        checkpoint_interval = get_value(checkpoint_interval, Options, 5000)
+        checkpoint_interval = get_value(checkpoint_interval, Options,
+                                        5000),
+        type = Type,
+        view = View
     },
     State#rep_state{timer = start_timer(State)}.
 
@@ -914,6 +931,20 @@ db_monitor(#db{} = Db) ->
 db_monitor(_HttpDb) ->
     nil.
 
+source_cur_seq(#rep_state{source = #httpdb{} = Db, source_seq = Seq,
+                          type = view, view = {DDoc, VName}}) ->
+    case (catch couch_replicator_api_wrap:get_view_info(
+                Db#httpdb{retries = 3}, DDoc, VName)) of
+    {ok, Info} ->
+        get_value(<<"update_seq">>, Info, Seq);
+    _ ->
+        Seq
+    end;
+
+source_cur_seq(#rep_state{source = Db, source_seq = Seq,
+                          type = view, view = {DDoc, VName}}) ->
+    {ok, Info} = couch_replicator_api_wrap:get_view_info(Db, DDoc, VName),
+    get_value(<<"update_seq">>, Info, Seq);
 
 source_cur_seq(#rep_state{source = #httpdb{} = Db, source_seq = Seq}) ->
     case (catch couch_replicator_api_wrap:get_db_info(Db#httpdb{retries = 3})) of

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c2465499/apps/couch_replicator/src/couch_replicator.hrl
----------------------------------------------------------------------
diff --git a/apps/couch_replicator/src/couch_replicator.hrl b/apps/couch_replicator/src/couch_replicator.hrl
index 018aa4b..1eee88e 100644
--- a/apps/couch_replicator/src/couch_replicator.hrl
+++ b/apps/couch_replicator/src/couch_replicator.hrl
@@ -18,6 +18,8 @@
     target,
     options,
     user_ctx,
+    type = db,
+    view = nil,
     doc_id
 }).
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c2465499/apps/couch_replicator/src/couch_replicator_api_wrap.erl
----------------------------------------------------------------------
diff --git a/apps/couch_replicator/src/couch_replicator_api_wrap.erl b/apps/couch_replicator/src/couch_replicator_api_wrap.erl
index 311025b..1e0e660 100644
--- a/apps/couch_replicator/src/couch_replicator_api_wrap.erl
+++ b/apps/couch_replicator/src/couch_replicator_api_wrap.erl
@@ -19,6 +19,7 @@
 % Many options and apis aren't yet supported here, they are added as needed.
 
 -include_lib("couch/include/couch_db.hrl").
+-include_lib("couch_mrview/include/couch_mrview.hrl").
 -include("couch_replicator_api_wrap.hrl").
 
 -export([
@@ -26,6 +27,7 @@
     db_open/3,
     db_close/1,
     get_db_info/1,
+    get_view_info/3,
     update_doc/3,
     update_doc/4,
     update_docs/3,
@@ -121,6 +123,16 @@ get_db_info(#db{name = DbName, user_ctx = UserCtx}) ->
     {ok, [{couch_util:to_binary(K), V} || {K, V} <- Info]}.
 
 
+get_view_info(#httpdb{} = Db, DDocId, ViewName) ->
+    Path = iolist_to_binary([DDocId, "/_view/", ViewName, "/_info"]),
+    send_req(Db, [{path, Path}],
+        fun(200, _, {Props}) ->
+            {ok, Props}
+        end);
+get_view_info(#db{name = DbName}, DDocId, ViewName) ->
+    couch_mrview:get_view_info(DbName, DDocId, ViewName).
+
+
 ensure_full_commit(#httpdb{} = Db) ->
     send_req(
         Db,
@@ -439,7 +451,8 @@ changes_since(Db, Style, StartSeq, UserFun, Options) ->
     },
     QueryParams = get_value(query_params, Options, {[]}),
     Req = changes_json_req(Db, Filter, QueryParams, Options),
-    ChangesFeedFun = couch_changes:handle_changes(Args, {json_req, Req}, Db),
+    ChangesFeedFun = couch_httpd_changes:handle_changes(Args, {json_req, Req},
+                                                        Db),
     ChangesFeedFun(fun({change, Change, _}, _) ->
             UserFun(json_to_doc_info(Change));
         (_, _) ->
@@ -454,6 +467,10 @@ maybe_add_changes_filter_q_args(BaseQS, Options) ->
     undefined ->
         BaseQS;
     FilterName ->
+        %% get list of view attributes
+        ViewFields0 = [atom_to_list(F) || F <- record_info(fields,  mrargs)],
+        ViewFields = ["key" | ViewFields0],
+
         {Params} = get_value(query_params, Options, {[]}),
         [{"filter", ?b2l(FilterName)} | lists:foldl(
             fun({K, V}, QSAcc) ->
@@ -461,6 +478,12 @@ maybe_add_changes_filter_q_args(BaseQS, Options) ->
                 case lists:keymember(Ks, 1, QSAcc) of
                 true ->
                     QSAcc;
+                false when FilterName =:= <<"_view">> ->
+                    V1 = case lists:member(Ks, ViewFields) of
+                        true -> ?JSON_ENCODE(V);
+                        false -> couch_util:to_list(V)
+                    end,
+                    [{Ks, V1} | QSAcc];
                 false ->
                     [{Ks, couch_util:to_list(V)} | QSAcc]
                 end

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c2465499/apps/couch_replicator/src/couch_replicator_utils.erl
----------------------------------------------------------------------
diff --git a/apps/couch_replicator/src/couch_replicator_utils.erl b/apps/couch_replicator/src/couch_replicator_utils.erl
index 0baddc2..085df43 100644
--- a/apps/couch_replicator/src/couch_replicator_utils.erl
+++ b/apps/couch_replicator/src/couch_replicator_utils.erl
@@ -37,13 +37,34 @@ parse_rep_doc({Props}, UserCtx) ->
     true ->
         {ok, #rep{options = Options, user_ctx = UserCtx}};
     false ->
-        Source = parse_rep_db(get_value(<<"source">>, Props), ProxyParams, Options),
-        Target = parse_rep_db(get_value(<<"target">>, Props), ProxyParams, Options),
+        Source = parse_rep_db(get_value(<<"source">>, Props),
+                              ProxyParams, Options),
+        Target = parse_rep_db(get_value(<<"target">>, Props),
+                              ProxyParams, Options),
+
+
+        {RepType, View} = case get_value(<<"filter">>, Props) of
+                <<"_view">> ->
+                    {QP}  = get_value(query_params, Options, {[]}),
+                    ViewParam = get_value(<<"view">>, QP),
+                    View1 = case re:split(ViewParam, <<"/">>) of
+                        [DName, ViewName] ->
+                            {<< "_design/", DName/binary >>, ViewName};
+                        _ ->
+                            throw({bad_request, "Invalid `view` parameter."})
+                    end,
+                    {view, View1};
+                _ ->
+                    {db, nil}
+            end,
+
         Rep = #rep{
             source = Source,
             target = Target,
             options = Options,
             user_ctx = UserCtx,
+            type = RepType,
+            view = View,
             doc_id = get_value(<<"_id">>, Props, null)
         },
         {ok, Rep#rep{id = replication_id(Rep)}}
@@ -100,6 +121,8 @@ maybe_append_filters(Base,
             DocIds ->
                 [DocIds]
             end;
+        <<"_", _/binary>> = Filter ->
+                [Filter, get_value(query_params, Options, {[]})];
         Filter ->
             [filter_code(Filter, Source, UserCtx),
                 get_value(query_params, Options, {[]})]