UNPKG

pouchdb-upsert

Version:

PouchDB upsert and putIfNotExists functions

95 lines (81 loc) 2.24 kB
'use strict'; var PouchPromise = require('pouchdb-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 upsertInner(db, docId, diffFun) { if (typeof docId !== 'string') { return PouchPromise.reject(new Error('doc id is required')); } return db.get(docId).catch(function (err) { /* istanbul ignore next */ if (err.status !== 404) { throw err; } return {}; }).then(function (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 { updated: false, rev: docRev, id: docId }; } // users aren't allowed to modify these values, // so reset them here newDoc._id = docId; newDoc._rev = docRev; return tryAndPut(db, newDoc, diffFun); }); } function tryAndPut(db, doc, diffFun) { return db.put(doc).then(function (res) { return { updated: true, rev: res.rev, id: doc._id }; }, function (err) { /* istanbul ignore next */ if (err.status !== 409) { throw err; } return upsertInner(db, doc._id, diffFun); }); } exports.upsert = function upsert(docId, diffFun, cb) { var db = this; var promise = upsertInner(db, docId, diffFun); if (typeof cb !== 'function') { return promise; } promise.then(function (resp) { cb(null, resp); }, cb); }; exports.putIfNotExists = function putIfNotExists(docId, doc, cb) { var db = this; if (typeof docId !== 'string') { cb = doc; doc = docId; docId = doc._id; } var diffFun = function (existingDoc) { if (existingDoc._rev) { return false; // do nothing } return doc; }; var promise = upsertInner(db, docId, diffFun); if (typeof cb !== 'function') { return promise; } promise.then(function (resp) { cb(null, resp); }, cb); }; /* istanbul ignore next */ if (typeof window !== 'undefined' && window.PouchDB) { window.PouchDB.plugin(exports); }