Skip to content

Commit

Permalink
(#5832) - new feature: force update.
Browse files Browse the repository at this point in the history
* (#5832) - new feature: force update.
add a `force` option to `put` operation to allow update based on
non-leaf revison and generate a new conflict revision, instead of
reporting update conflict error.
it is implemented by generating `new_edits=false` option.

* optimized force update feature with method proposed by @ronag.
need not to fetch `revisions` from db, 2 revisions are enough,
namely the new generated one and the old one provided by the user.

* bugfix:explictly set radix to 10 for parseInt().

* fix an unintented change caused coverage becomes < 100%.

* replace const with var to fix PhantomJS tests failure.

* add test case of force putting on second level parent node.

* a simple note on the new `force` option for put() api.
  • Loading branch information
simpzan authored and nolanlawson committed May 17, 2017
1 parent 49e4945 commit dd59491
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/_includes/api/create_document.html
Expand Up @@ -7,6 +7,8 @@

Create a new document or update an existing document. If the document already exists, you must specify its revision `_rev`, otherwise a conflict will occur.

If you want to update an existing document even if there's conflict, you should specify the base revision `_rev` and use `force=true` option, then a new conflict revision will be created.

There are some [restrictions on valid property names of the documents](http://wiki.apache.org/couchdb/HTTP_Document_API#Special_Fields). If you try to store non-JSON data (for instance `Date` objects) you may see [inconsistent results](http://pouchdb.com/errors.html#could_not_be_cloned).

#### Example Usage:
Expand Down
35 changes: 32 additions & 3 deletions packages/node_modules/pouchdb-core/src/adapter.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions tests/integration/test.conflicts.js
Expand Up @@ -116,6 +116,78 @@ adapters.forEach(function (adapter) {
});
});

it('force put ok on 1st level', function () {
var db = new PouchDB(dbs.name);
var docId = "docId";
var rev1, rev2, rev3, rev2_;
// given
return db.put({_id: docId, update:1}).then(function (result) {
rev1 = result.rev;
return db.put({_id: docId, update:2.1, _rev: rev1});
}).then(function (result) {
rev2 = result.rev;
return db.put({_id: docId, update:3, _rev:rev2});
})
// when
.then(function (result) {
rev3 = result.rev;
return db.put({_id: docId, update:2.2, _rev: rev1}, {force: true});
})
// then
.then(function (result) {
rev2_ = result.rev;
rev2_.should.not.equal(rev3);
rev2_.substring(0, 2).should.equal('2-');
should.exist(result.ok, 'update based on nonleaf revision');

return db.get(docId, {conflicts: true, revs: true});
}).then(function (doc) {
doc._rev.should.equal(rev3);
doc._conflicts.should.eql([rev2_]);

return db.get(docId, {conflicts: true, revs: true, rev: rev2_});
}).then(function (doc) {
console.log("the force doc", doc);
});
});

it('force put ok on 2nd level', function () {
var db = new PouchDB(dbs.name);
var docId = "docId";
var rev2, rev3, rev4, rev3_;
// given
return db.put({_id: docId, update: 1}).then(function (result) {
return db.put({_id: docId, update: 2, _rev: result.rev});
}).then(function (result) {
rev2 = result.rev;
return db.put({_id: docId, update: 3.1, _rev: rev2});
}).then(function (result) {
rev3 = result.rev;
return db.put({_id: docId, update: 4, _rev: rev3});
})
// when
.then(function (result) {
rev4 = result.rev;
return db.put({_id: docId, update:3.2, _rev: rev2}, {force: true});
})
// then
.then(function (result) {
rev3_ = result.rev;
rev3_.should.not.equal(rev4);
rev3_.substring(0, 2).should.equal('3-');
should.exist(result.ok, 'update based on nonleaf revision');

return db.get(docId, {conflicts: true, revs: true});
}).then(function (doc) {
doc._rev.should.equal(rev4);
doc._conflicts.should.eql([rev3_]);

return db.get(docId, {conflicts: true, revs: true, rev: rev3_});
}).then(function (doc) {
console.log("the force put doc", doc);
});
});

// Each revision includes a list of previous revisions. The
// revision with the longest revision history list becomes the
// winning revision. If they are the same, the _rev values are
Expand Down

0 comments on commit dd59491

Please sign in to comment.