Is it possible to put
or bulkDocs
into couchdb/pouchdb and get the same behaviour as in replication, i.e. winning revision with _conflicts
instead of a 409
response?
Basically I would like to avoid the conflict
case in the following code:
const docs = Object
.keys(pendingSet)
.map(id => toDoc(deepClone(pendingSet[id]), { id, rev: this.revCache.get(id) }))
const results = await this.db.bulkDocs(docs)
const conflicts = []
for (let n = 0; n < results.length; ++n) {
const result = results[n]
if (result.error === 'conflict') {
// TODO: This needs review...
const doc = await this.db.get(docs[n]._id)
const rev = `${doc._rev.split('-')[0]}-${this.serverName}`
conflicts.push({
...docs[n],
_rev: rev
})
this.revCache.set(doc._id, rev)
} else if (result.error) {
callback(result.error)
} else {
this.revCache.set(result.id, result.rev)
}
}
await this.db.bulkDocs(conflicts, { new_edits: false })
I've gotten a bit of a hint from pouchdb but I'm still unsure how to apply it.
EDIT1: Updated with latest code.
CouchDB tries to protect itself from conflicts, so if you try and modify a revision of a document that CouchDB 'knows' that has already been superseded, you will get a 409 response.
The way replication "gets away with it" is because documents are bulk written to the target machine with the flag "new_edits=false". This instructs CouchDB not to police the revision tokens, but to accept the incoming one (writes coming from a replication source already have their own revision trees).
You can do this yourself with calls like this:
ccurl -X POST -d '{"docs":[{"_id":"x","_rev":"1-myrevtoken","y":3}],"new_edits":false}' '/a/_bulk_docs'
In this case I have forced a second "revision 1" into a document that already had a "revision 2":
id = x
├─ 1
│ ├─ 1-myrevtoken
│ └─ 1-a6664c0114e6002415a47b18d4c9d32f
└─ 2-bca8f049e40b76dbfca560e132aa5c31 *
The winner is still "revision 2" but the conflict on revision 1 remains unresolved, until you decide to resolve it.