| |
| // this is essentially the "update sugar" function from daleharvey/pouchdb#1388 |
| // the diffFun tells us what delta to apply to the doc. it either returns |
| // the doc, or false if it doesn't need to do an update after all |
| function upsert(db, docId, diffFun) { |
| return new Promise(function (fulfill, reject) { |
| db.get(docId, function (err, doc) { |
| if (err) { |
| /* istanbul ignore next */ |
| if (err.status !== 404) { |
| return reject(err); |
| } |
| doc = {}; |
| } |
| |
| // the user might change the _rev, so save it for posterity |
| var docRev = doc._rev; |
| var newDoc = diffFun(doc); |
| |
| if (!newDoc) { |
| // if the diffFun returns falsy, we short-circuit as |
| // an optimization |
| return fulfill({updated: false, rev: docRev}); |
| } |
| |
| // users aren't allowed to modify these values, |
| // so reset them here |
| newDoc._id = docId; |
| newDoc._rev = docRev; |
| fulfill(tryAndPut(db, newDoc, diffFun)); |
| }); |
| }); |
| } |
| |
| function tryAndPut(db, doc, diffFun) { |
| return db.put(doc).then(function (res) { |
| return { |
| updated: true, |
| rev: res.rev |
| }; |
| }, function (err) { |
| /* istanbul ignore next */ |
| if (err.status !== 409) { |
| throw err; |
| } |
| return upsert(db, doc._id, diffFun); |
| }); |
| } |
| |
| export default upsert; |