| 'use strict'; |
| var Promise = require('../utils').Promise; |
| |
| // 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) { |
| if (docId && typeof docId === 'object') { |
| docId = docId._id; |
| } |
| if (typeof docId !== 'string') { |
| return reject(new Error('doc id is required')); |
| } |
| |
| db.get(docId, function (err, doc) { |
| if (err) { |
| if (err.status !== 404) { |
| return reject(err); |
| } |
| return fulfill(tryAndPut(db, diffFun({_id : docId}), diffFun)); |
| } |
| var newDoc = diffFun(doc); |
| if (!newDoc) { |
| return fulfill(doc); |
| } |
| fulfill(tryAndPut(db, newDoc, diffFun)); |
| }); |
| }); |
| } |
| |
| function tryAndPut(db, doc, diffFun) { |
| return db.put(doc).catch(function (err) { |
| if (err.status !== 409) { |
| throw err; |
| } |
| return upsert(db, doc, diffFun); |
| }); |
| } |
| |
| module.exports = function (db, docId, diffFun, cb) { |
| if (typeof cb === 'function') { |
| upsert(db, docId, diffFun).then(function (resp) { |
| cb(null, resp); |
| }, cb); |
| } else { |
| return upsert(db, docId, diffFun); |
| } |
| }; |