• Stars
    star
    149
  • Rank 248,619 (Top 5 %)
  • Language
    JavaScript
  • License
    Apache License 2.0
  • Created almost 10 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

PouchDB plugin for upsert() and putIfNotExists() functions

PouchDB Upsert

Greenkeeper badge

Build Status

A tiny plugin for PouchDB that provides two convenience methods:

  • upsert() - update a document, or insert a new one if it doesn't exist ("upsert"). Will keep retrying (forever) if it gets 409 conflicts.
  • putIfNotExists() - create a new document if it doesn't exist. Does nothing if it already exists.

So basically, if you're tired of manually dealing with 409s or 404s in your PouchDB code, then this is the plugin for you.

Installation

Browser

bower install pouchdb-upsert

Or download from the dist/ folder and include it after pouchdb.js:

<script src="pouchdb.js"></script>
<script src="pouchdb.upsert.js"></script>

Node.js

npm install pouchdb-upsert

Then attach it to the PouchDB object:

var PouchDB = require('pouchdb');
PouchDB.plugin(require('pouchdb-upsert'));

API

Overview

db.upsert(docId, diffFunc [, callback])

Perform an upsert (update or insert) operation. If you don't specify a callback, then this function returns a Promise.

  • docId - the _id of the document.
  • diffFunc - function that takes the existing doc as input and returns an updated doc.
    • If this diffFunc returns falsey, then the update won't be performed (as an optimization).
    • If the document does not already exist, then {} will be the input to diffFunc.

Note: By design, the goal of this repo is to just provide a handler for synchronized logic. diffFunc must not make asynchronous calls.

Example 1

A doc with a basic counter:

db.upsert('myDocId', function (doc) {
  if (!doc.count) {
    doc.count = 0;
  }
  doc.count++;
  return doc;
}).then(function (res) {
  // success, res is {rev: '1-xxx', updated: true, id: 'myDocId'}
}).catch(function (err) {
  // error
});

Resulting doc (after 1 upsert):

{
  _id: 'myDocId',
  _rev: '1-cefef1ec19869d9441a47021f3fd4710',
  count: 1
}

Resulting doc (after 3 upserts):

{
  _id: 'myDocId',
  _rev: '3-536ef59f3ed17a181dc683a255caf1d9',
  count: 3
}
Example 2

A diffFunc that only updates the doc if it's missing a certain field:

db.upsert('myDocId', function (doc) {
  if (!doc.touched) {
    doc.touched = true;
    return doc;
  }
  return false; // don't update the doc; it's already been "touched"
}).then(function (res) {
  // success, res is {rev: '1-xxx', updated: true, id: 'myDocId'}
}).catch(function (err) {
  // error
});

Resulting doc:

{
  _id: 'myDocId',
  _rev: '1-cefef1ec19869d9441a47021f3fd4710',
  touched: true
}

The next time you try to upsert, the res will be {rev: '1-xxx', updated: false, id: 'myDocId'}. The updated: false indicates that the upsert function did not actually update the document, and the rev returned will be the previous winning revision.

Example 3

You can also return a new object. The _id and _rev are added automatically:

db.upsert('myDocId', function (doc) {
  return {thisIs: 'awesome!'};
}).then(function (res) {
  // success, res is {rev: '1-xxx', updated: true, id: 'myDocId'}
}).catch(function (err) {
  // error
});

Resulting doc:

{
  _id: 'myDocId',
  _rev: '1-cefef1ec19869d9441a47021f3fd4710',
  thisIs: 'awesome!'
}

db.putIfNotExists([docId, ] doc [, callback])

Put a new document with the given docId, if it doesn't already exist. If you don't specify a callback, then this function returns a Promise.

  • docId - the _id of the document. Optional if you already include it in the doc
  • doc - the document to insert. Should contain an _id if docId is not specified

If the document already exists, then the Promise will just resolve immediately.

Example 1

Put a doc if it doesn't exist

db.putIfNotExists('myDocId', {yo: 'dude'}).then(function (res) {
  // success, res is {rev: '1-xxx', updated: true, id: 'myDocId'}
}).catch(function (err) {
  // error
});

Resulting doc:

{
  _id: 'myDocId',
  _rev: '1-cefef1ec19869d9441a47021f3fd4710',
  yo: 'dude'
}

If you call putIfNotExists multiple times, then the document will not be updated the 2nd, 3rd, or 4th time (etc.).

If it's not updated, then the res will be {rev: '1-xxx', updated: false, id: 'myDocId'}, where rev is the first revision and updated: false indicates that it wasn't updated.

Example 2

You can also just include the _id inside the document itself:

db.putIfNotExists({_id: 'myDocId', yo: 'dude'}).then(function (res) {
  // success, res is {rev: '1-xxx', updated: true, id: 'myDocId'}
}).catch(function (err) {
  // error
});

Resulting doc (same as example 1):

{
  _id: 'myDocId',
  _rev: '1-cefef1ec19869d9441a47021f3fd4710',
  yo: 'dude'
}

Breaking changes

  • 2.0.0: breaks compatibility with PouchDB <4.0.1, see #9 for details.

Building

npm install
npm run build

Testing

In Node

This will run the tests in Node using LevelDB:

npm test

You can also check for 100% code coverage using:

npm run coverage

If you have mocha installed globally you can run single test with:

TEST_DB=local mocha --reporter spec --grep search_phrase

The TEST_DB environment variable specifies the database that PouchDB should use (see package.json).

Automated browser tests in PhantomJS

npm run test-browser

Debugging in the browser

npm run test-local

More Repositories

1

pouchdb

🦘 - PouchDB is a pocket-sized database.
JavaScript
16,664
star
2

pouchdb-server

CouchDB-compatible server built on PouchDB and Node
JavaScript
947
star
3

express-pouchdb

⚠️⚠️⚠️ THIS REPO HAS MOVED ⚠️⚠️⚠️
143
star
4

add-cors-to-couchdb

CLI to add a good default CORS configuration to CouchDB
JavaScript
132
star
5

pouchbase

Server that lets PouchDB applications sync with passwordless logins
JavaScript
97
star
6

geopouch

Spatial plugin from PouchDB extracted and supporting N dimentional coordinates.
JavaScript
85
star
7

collate

Collation functions for PouchDB map/ reduce and search plugins. ( ⚠️ moved to pouchdb core repo ⚠️ )
JavaScript
38
star
8

pouchdb-auth

A PouchDB plug-in that simulates CouchDB's authentication daemon. Includes a users db that functions like CouchDB's.
JavaScript
36
star
9

plugin-seed

Seed project for PouchDB plugins.
JavaScript
36
star
10

GQL

Google Query Language (GQL) interface for PouchDB
JavaScript
36
star
11

npm-browser

npm in your browser. Because why not. (UNMAINTAINED)
JavaScript
34
star
12

pouchdb-fauxton-chrome-extension

Unmaintained: see #17
JavaScript
26
star
13

pouchdb-express-router

An Express submodule with a CouchDB style REST interface to PouchDB.
JavaScript
24
star
14

mapreduce

PouchDB map/reduce plugin ( ⚠️ UPDATE: moved back to PouchDB core ⚠️ )
23
star
15

pouchdb-search

Search plugin for PouchDB.
JavaScript
15
star
16

couchdb-harness

A generalized port of the CouchDB JavaScript test harness.
JavaScript
12
star
17

pouchdb-validation

A PouchDB plug-in that allows you to re-use your CouchDB validate_doc_update functions on the client side.
JavaScript
10
star
18

pouchdb-fauxton-firefox-addon

JavaScript
7
star
19

pouchdb-fauxton-logic

JavaScript
7
star
20

http-pouchdb

MOVED - SEE THE pouchdb-server REPO
6
star
21

now

Small `now` app to quickly set up an in-memory PouchDB Server
5
star
22

pouchdb-security

This has moved to https://github.com/pouchdb/pouchdb-server
5
star
23

pouchdb-size

Adds disk_size to info()'s output for your leveldown backed PouchDB's.
JavaScript
5
star
24

pouchdb-update

A PouchDB plug-in that allows you to re-use your CouchDB update functions on the client side.
JavaScript
4
star
25

pouchdb-fauxton-base

JavaScript
3
star
26

errors

Utils for working with PouchDB-style error objects.
JavaScript
2
star
27

binary-util

Blob shim for PouchDB
JavaScript
2
star
28

pouchdb-extend

Extends method taken from JQuery 1.9.0 for use in PouchDB (DEPRECATED)
JavaScript
2
star
29

pouchdb-wrappers

Makes wrapping PouchDB functions a lot easier.
JavaScript
2
star
30

pouchdb-show

A PouchDB plug-in that allows you to re-use your CouchDB show functions on the client side.
JavaScript
2
star
31

ajax

Ajax module as used in PouchDB
JavaScript
1
star
32

couchdb-objects

Aids in the construction of JSON objects as used by CouchDB.
JavaScript
1
star
33

sublevel-pouchdb

Fork of level-sublevel with ony the subset of the API that PouchDB uses.
JavaScript
1
star
34

dashboard

JavaScript
1
star
35

pouchdb-bulkdocs-wrapper

Helper function that makes wrapping bulkDocs using pouchdb-wrappers easier.
JavaScript
1
star
36

pouchdb-plugin-error

A PouchDB-like error object, for use by plug-ins.
JavaScript
1
star
37

pouchdb-list

A PouchDB plug-in that allows you to re-use your CouchDB list functions on the client side.
JavaScript
1
star
38

pouchdb-bug-helper

Make awesome reproducable bug reports for PouchDB
HTML
1
star