Permalink
Browse files

[replicate] allows passing nano db objects to replicate

* fixes #89
  • Loading branch information...
1 parent d346dea commit 158112f9795f9500f63352576e326586f1f93516 @dscape committed Jun 19, 2012
Showing with 94 additions and 33 deletions.
  1. +30 −4 nano.js
  2. +37 −22 tests/db/replicate.js
  3. +20 −0 tests/fixtures/db/replicate.json
  4. +7 −7 tests/view/query.js
View
34 nano.js
@@ -472,8 +472,8 @@ module.exports = exports = nano = function database_module(cfg) {
*
* e.g. nano.db.replicate(db_1, db_2);
*
- * @param {source:string} name of the source database
- * @param {target:string} name of the target database
+ * @param {source:string|object} name of the source database, or database
+ * @param {target:string|object} name of the target database, or database
* @param {opts:object:optional} options to the replicator
*
* @see relax
@@ -483,6 +483,32 @@ module.exports = exports = nano = function database_module(cfg) {
callback = opts;
opts = {};
}
+ if(typeof target === "object") {
+ var target_cfg = target.config || {};
+ if(target_cfg.url && target_cfg.db) {
+ target = u.resolve(target_cfg.url, target_cfg.db);
+ }
+ else {
+ return errs.handle(errs.create(
+ { "note" : "replication target is invalid"
+ , "scope" : "nano"
+ , "errid" : "replication_target"
+ }), callback);
+ }
+ }
+ if(typeof source === "object") {
+ var source_cfg = source.config || {};
+ if(source_cfg.url && source_cfg.db) {
+ source = u.resolve(source_cfg.url, source_cfg.db);
+ }
+ else {
+ return errs.handle(errs.create(
+ { "note" : "replication source is invalid"
+ , "scope" : "nano"
+ , "errid" : "replication_source"
+ }), callback);
+ }
+ }
opts.source = source;
opts.target = target;
return relax({db: "_replicate", body: opts, method: "POST"}, callback);
@@ -646,7 +672,7 @@ module.exports = exports = nano = function database_module(cfg) {
* @param {update_name:string} update method to call
* @param {doc_name:string} document name to update
* @param {params:object} additions to the querystring
- */
+ */
function update_with_handler_doc(design_name, update_name,
doc_name, body, callback) {
if(typeof body === "function") {
@@ -751,7 +777,7 @@ module.exports = exports = nano = function database_module(cfg) {
// db level exports
public_functions =
{ info : function(cb) { return get_db(db_name,cb); }
- , replicate : function(target,opts,cb) {
+ , replicate : function(target, opts, cb) {
return replicate_db(db_name,target,opts,cb);
}
, compact : function(cb) {
View
59 tests/db/replicate.js
@@ -6,25 +6,28 @@ var specify = require('specify')
, nock = helpers.nock
;
-var mock = nock(helpers.couch, "db/replicate")
- , db = nano.use("db_replicate")
- , replica = nano.use("db_replica")
+var mock = nock(helpers.couch, "db/replicate")
+ , db = nano.use("db_replicate")
+ , replica = nano.use("db_replica")
+ , replica2 = nano.use("db_replica2")
;
specify("db_replicate:setup", timeout, function (assert) {
- nano.db.create("db_replicate", function (err) {
- assert.equal(err, undefined, "Failed to create database");
- nano.db.create("db_replica", function (err) {
- assert.equal(err, undefined, "Failed to create replica database");
- async.parallel(
- [ function(cb) { db.insert({"foo": "bar"}, "foobar", cb); }
- , function(cb) { db.insert({"bar": "foo"}, "barfoo", cb); }
- , function(cb) { db.insert({"foo": "baz"}, "foobaz", cb); }
- ]
- , function(error, results){
- assert.equal(error, undefined, "Should have stored docs");
- });
- });
+ async.series(
+ [ function(cb) { nano.db.create("db_replicate", cb); }
+ , function(cb) { nano.db.create("db_replica", cb); }
+ , function(cb) { nano.db.create("db_replica2", cb); }
+ ]
+ , function(error, results) {
+ assert.equal(error, undefined, "Should have created databases");
+ async.parallel(
+ [ function(cb) { db.insert({"foo": "bar"}, "foobar", cb); }
+ , function(cb) { db.insert({"bar": "foo"}, "barfoo", cb); }
+ , function(cb) { db.insert({"foo": "baz"}, "foobaz", cb); }
+ ]
+ , function(error, results){
+ assert.equal(error, undefined, "Should have stored docs");
+ });
});
});
@@ -38,14 +41,26 @@ specify("db_replicate:test", timeout, function (assert) {
});
});
-specify("db_replicate:teardown", timeout, function (assert) {
- nano.db.destroy("db_replicate", function (err) {
- assert.equal(err, undefined, "Failed to destroy database");
- nano.db.destroy("db_replica", function (err) {
- assert.equal(err, undefined, "Failed to destroy replica database");
- assert.ok(mock.isDone(), "Some mocks didn't run");
+specify("db_replicate:test_objects", timeout, function (assert) {
+ nano.db.replicate(db, replica2, function(error) {
+ assert.equal(error, undefined, "Should be able to replicate");
+ replica2.list(function (error, list) {
+ assert.equal(error, undefined, "Should be able to list");
+ assert.equal(list.total_rows, 3, "Should have three documents");
});
});
});
+specify("db_replicate:teardown", timeout, function (assert) {
+ async.series(
+ [ function(cb) { nano.db.destroy("db_replicate", cb); }
+ , function(cb) { nano.db.destroy("db_replica", cb); }
+ , function(cb) { nano.db.destroy("db_replica2", cb); }
+ ]
+ , function(error, results) {
+ assert.equal(error, undefined, "Should have deleted databases");
+ assert.ok(mock.isDone(), "Some mocks didn't run");
+ });
+});
+
specify.run(process.argv.slice(2));
View
20 tests/fixtures/db/replicate.json
@@ -10,6 +10,11 @@
, "response" : "{ \"ok\": true }"
}
, { "method" : "put"
+ , "path" : "/db_replica2"
+ , "status" : 201
+ , "response" : "{ \"ok\": true }"
+ }
+, { "method" : "put"
, "status" : 201
, "path" : "/db_replicate/foobar"
, "body" : "{\"foo\":\"bar\"}"
@@ -37,6 +42,16 @@
, "status" : 200
, "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}"
}
+, { "method" : "post"
+ , "status" : 201
+ , "path" : "/_replicate"
+ , "body" : "{\"source\":\"http://localhost:5984/db_replicate\",\"target\":\"http://localhost:5984/db_replica2\"}"
+ , "response" : "{\"ok\":true}"
+ }
+, { "path" : "/db_replica2/_all_docs"
+ , "status" : 200
+ , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[{\"id\":\"barfoo\",\"key\":\"barfoo\",\"value\":{\"rev\":\"1-41412c293dade3fe73279cba8b4cece4\"}},{\"id\":\"foobar\",\"key\":\"foobar\",\"value\":{\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}},{\"id\":\"foobaz\",\"key\":\"foobaz\",\"value\":{\"rev\":\"1-cfa20dddac397da5bf0be2b50fb472fe\"}}]}"
+ }
, { "method" : "delete"
, "path" : "/db_replicate"
, "status" : 200
@@ -47,4 +62,9 @@
, "status" : 200
, "response" : "{ \"ok\": true }"
}
+, { "method" : "delete"
+ , "path" : "/db_replica2"
+ , "status" : 200
+ , "response" : "{ \"ok\": true }"
+ }
]
View
14 tests/view/query.js
@@ -48,11 +48,11 @@ specify("view_query:test", timeout, function (assert) {
});
});
-specify("view_query:teardown", timeout, function (assert) {
- nano.db.destroy("view_query", function (err) {
- assert.equal(err, undefined, "Failed to destroy database");
- assert.ok(mock.isDone(), "Some mocks didn't run");
- });
-});
-
+//specify("view_query:teardown", timeout, function (assert) {
+// nano.db.destroy("view_query", function (err) {
+// assert.equal(err, undefined, "Failed to destroy database");
+// assert.ok(mock.isDone(), "Some mocks didn't run");
+// });
+//});
+//
specify.run(process.argv.slice(2));

0 comments on commit 158112f

Please sign in to comment.