couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r824029 - in /couchdb/trunk: share/www/script/couch.js share/www/script/test/replication.js src/couchdb/couch_httpd.erl src/couchdb/couch_rep.erl src/couchdb/couch_rep_httpc.erl
Date Sun, 11 Oct 2009 05:49:20 GMT
Author: jan
Date: Sun Oct 11 05:49:19 2009
New Revision: 824029

URL: http://svn.apache.org/viewvc?rev=824029&view=rev
Log:
add create_target:true option to _replicate that creates the target database

Modified:
    couchdb/trunk/share/www/script/couch.js
    couchdb/trunk/share/www/script/test/replication.js
    couchdb/trunk/src/couchdb/couch_httpd.erl
    couchdb/trunk/src/couchdb/couch_rep.erl
    couchdb/trunk/src/couchdb/couch_rep_httpc.erl

Modified: couchdb/trunk/share/www/script/couch.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/couch.js?rev=824029&r1=824028&r2=824029&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/couch.js [utf-8] (original)
+++ couchdb/trunk/share/www/script/couch.js [utf-8] Sun Oct 11 05:49:19 2009
@@ -387,9 +387,12 @@
 CouchDB.replicate = function(source, target, rep_options) {
   rep_options = rep_options || {};
   var headers = rep_options.headers || {};
+  var body = rep_options.body || {};
+  body.source = source;
+  body.target = target;
   CouchDB.last_req = CouchDB.request("POST", "/_replicate", {
     headers: headers,
-    body: JSON.stringify({source: source, target: target})
+    body: JSON.stringify(body)
   });
   CouchDB.maybeThrowError(CouchDB.last_req);
   return JSON.parse(CouchDB.last_req.responseText);

Modified: couchdb/trunk/share/www/script/test/replication.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/replication.js?rev=824029&r1=824028&r2=824029&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/replication.js (original)
+++ couchdb/trunk/share/www/script/test/replication.js Sun Oct 11 05:49:19 2009
@@ -277,4 +277,28 @@
     T(result2.no_changes == true);
     T(result2.session_id == result.session_id);
   }
+
+  // test optional automatic creation of the target db
+
+  var dbA = new CouchDB("test_suite_db_a", {"X-Couch-Full-Commit":"false"});
+  var dbB = new CouchDB("test_suite_db_b", {"X-Couch-Full-Commit":"false"});
+  
+  dbA.deleteDb();
+  dbA.createDb();
+  dbB.deleteDb();
+  
+  // local
+  CouchDB.replicate(dbA.name, "test_suite_db_b", {
+    body: {"create_target": true}
+  });
+  TEquals("test_suite_db_b", dbB.info().db_name,
+    "Target database should exist");
+
+  // remote
+  dbB.deleteDb();
+  CouchDB.replicate(dbA.name, "http://" + CouchDB.host + "/test_suite_db_b", {
+    body: {"create_target": true}
+  });
+  TEquals("test_suite_db_b", dbB.info().db_name,
+    "Target database should exist");
 };

Modified: couchdb/trunk/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd.erl?rev=824029&r1=824028&r2=824029&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd.erl Sun Oct 11 05:49:19 2009
@@ -362,7 +362,9 @@
         RespFun()
     end.
 
-verify_is_server_admin(#httpd{user_ctx=#user_ctx{roles=Roles}}) ->
+verify_is_server_admin(#httpd{user_ctx=UserCtx}) ->
+    verify_is_server_admin(UserCtx);
+verify_is_server_admin(#user_ctx{roles=Roles}) ->
     case lists:member(<<"_admin">>, Roles) of
     true -> ok;
     false -> throw({unauthorized, <<"You are not a server admin.">>})

Modified: couchdb/trunk/src/couchdb/couch_rep.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_rep.erl?rev=824029&r1=824028&r2=824029&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_rep.erl (original)
+++ couchdb/trunk/src/couchdb/couch_rep.erl Sun Oct 11 05:49:19 2009
@@ -28,6 +28,7 @@
     source,
     target,
     continuous,
+    create_target,
     init_args,
     checkpoint_scheduled = nil,
 
@@ -102,9 +103,10 @@
     TargetProps = proplists:get_value(<<"target">>, PostProps),
 
     Continuous = proplists:get_value(<<"continuous">>, PostProps, false),
+    CreateTarget = proplists:get_value(<<"create_target">>, PostProps, false),
 
     Source = open_db(SourceProps, UserCtx),
-    Target = open_db(TargetProps, UserCtx),
+    Target = open_db(TargetProps, UserCtx, CreateTarget),
 
     SourceLog = open_replication_log(Source, RepId),
     TargetLog = open_replication_log(Target, RepId),
@@ -143,6 +145,7 @@
         source = Source,
         target = Target,
         continuous = Continuous,
+        create_target = CreateTarget,
         init_args = InitArgs,
         stats = Stats,
         checkpoint_scheduled = nil,
@@ -375,6 +378,17 @@
         has_session_id(SessionId, Rest)
     end.
 
+maybe_append_options(Options, Props) ->
+    lists:foldl(fun(Option, Acc) ->
+        Acc ++ 
+        case proplists:get_value(Option, Props, false) of
+        true ->
+            "+" ++ ?b2l(Option);
+        false ->
+            ""
+        end
+    end, [], Options).
+
 make_replication_id({Props}, UserCtx) ->
     %% funky algorithm to preserve backwards compatibility
     {ok, HostName} = inet:gethostname(),
@@ -382,12 +396,8 @@
     Src = get_rep_endpoint(UserCtx, proplists:get_value(<<"source">>, Props)),
     Tgt = get_rep_endpoint(UserCtx, proplists:get_value(<<"target">>, Props)),
   
     Base = couch_util:to_hex(erlang:md5(term_to_binary([HostName, Src, Tgt]))),
-    Extension = case proplists:get_value(<<"continuous">>, Props, false) of
-    true ->
-        "+continuous";
-    false ->
-        ""
-    end,
+    Extension = maybe_append_options(
+        [<<"continuous">>, <<"create_target">>], Props),
     {Base, Extension}.
 
 maybe_add_trailing_slash(Url) ->
@@ -432,7 +442,10 @@
         #doc{id=DocId}
     end.
 
-open_db({Props}, _UserCtx) ->
+open_db(Props, UserCtx) ->
+    open_db(Props, UserCtx, false).
+
+open_db({Props}, _UserCtx, CreateTarget) ->
     Url = maybe_add_trailing_slash(proplists:get_value(<<"url">>, Props)),
     {AuthProps} = proplists:get_value(<<"auth">>, Props, {[]}),
     {BinHeaders} = proplists:get_value(<<"headers">>, Props, {[]}),
@@ -443,12 +456,18 @@
         auth = AuthProps,
         headers = lists:ukeymerge(1, Headers, DefaultHeaders)
     },
-    couch_rep_httpc:db_exists(Db);
-open_db(<<"http://",_/binary>>=Url, _) ->
-    open_db({[{<<"url">>,Url}]}, []);
-open_db(<<"https://",_/binary>>=Url, _) ->
-    open_db({[{<<"url">>,Url}]}, []);
-open_db(<<DbName/binary>>, UserCtx) ->
+    couch_rep_httpc:db_exists(Db, CreateTarget);
+open_db(<<"http://",_/binary>>=Url, _, CreateTarget) ->
+    open_db({[{<<"url">>,Url}]}, [], CreateTarget);
+open_db(<<"https://",_/binary>>=Url, _, CreateTarget) ->
+    open_db({[{<<"url">>,Url}]}, [], CreateTarget);
+open_db(<<DbName/binary>>, UserCtx, CreateTarget) ->
+    ok = couch_httpd:verify_is_server_admin(UserCtx),
+    case CreateTarget of
+    true -> couch_server:create(DbName, [{user_ctx, UserCtx}]);
+    false -> ok
+    end,
+
     case couch_db:open(DbName, [{user_ctx, UserCtx}]) of
     {ok, Db} ->
         couch_db:monitor(Db),

Modified: couchdb/trunk/src/couchdb/couch_rep_httpc.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_rep_httpc.erl?rev=824029&r1=824028&r2=824029&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_rep_httpc.erl (original)
+++ couchdb/trunk/src/couchdb/couch_rep_httpc.erl Sun Oct 11 05:49:19 2009
@@ -14,7 +14,7 @@
 -include("couch_db.hrl").
 -include("../ibrowse/ibrowse.hrl").
 
--export([db_exists/1, full_url/1, request/1, spawn_worker_process/1,
+-export([db_exists/1, db_exists/2, full_url/1, request/1, spawn_worker_process/1,
     spawn_link_worker_process/1]).
 
 request(Req) when is_record(Req, http_db) ->
@@ -59,7 +59,16 @@
 db_exists(Req) ->
     db_exists(Req, Req#http_db.url).
 
+db_exists(Req, true) ->
+    db_exists(Req, Req#http_db.url, true);
+
+db_exists(Req, false) ->
+    db_exists(Req, Req#http_db.url, false);
+
 db_exists(Req, CanonicalUrl) ->
+    db_exists(Req, CanonicalUrl, false).
+
+db_exists(Req, CanonicalUrl, CreateDB) ->
     #http_db{
         auth = Auth,
         headers = Headers0,
@@ -71,6 +80,11 @@
     {OAuthProps} ->
         [oauth_header(Url, [], head, OAuthProps) | Headers0]
     end,
+    case CreateDB of
+        true ->
+            catch ibrowse:send_req(Url, Headers, put);
+        _Else -> ok
+    end,
     case catch ibrowse:send_req(Url, Headers, head) of
     {ok, "200", _, _} ->
         Req#http_db{url = CanonicalUrl};



Mime
View raw message