Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Related to pouchdb/express-pouchdb#196 and apache/couchdb-chttpd#33 This adds a `bulkGet()` function to all PouchDB objects, which in the case of local databases runs a shim that simply collates a bunch of `get()` requests. This logic is in `bulk-get-shim.js`. In the case of the http adapter, the client checks if the server responds to `_bulk_get` with a 40x error. If no error is returned, then the server is assumed to implement `_bulk_get` and that API is used. Else the shim is used. I have tested this against CouchDB 1.6 and PouchDB Server (82b297e) with 100% success in both. Also manual testing showed that the `_bulk_get` API was used for PouchDB Server but not CouchDB. Three cheers for bulk replication!
- Loading branch information
1 parent
ce8b25a
commit a0ef9b8
Showing
5 changed files
with
194 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
'use strict'; | ||
|
||
var utils = require('../utils'); | ||
|
||
// shim for P/CouchDB adapters that don't directly implement | ||
// _bulk_get | ||
function bulkGet(db, opts, callback) { | ||
var requests = Array.isArray(opts) ? opts : opts.docs; | ||
if (!requests.length) { | ||
return callback(null, {results: []}); | ||
} | ||
|
||
// consolidate into one request per doc if possible | ||
var requestsById = {}; | ||
requests.forEach(function (request) { | ||
if (request.id in requestsById) { | ||
requestsById[request.id].push(request); | ||
} else { | ||
requestsById[request.id] = [request]; | ||
} | ||
}); | ||
|
||
var numDocs = Object.keys(requestsById).length; | ||
var numDone = 0; | ||
var perDocResults = new Array(numDocs); | ||
|
||
function collapseResults() { | ||
var results = []; | ||
perDocResults.forEach(function (res) { | ||
res.docs.forEach(function (info) { | ||
results.push({ | ||
id: res.id, | ||
docs: [info] | ||
}); | ||
}); | ||
}); | ||
callback(null, {results: results}); | ||
} | ||
|
||
function checkDone() { | ||
if (++numDone === numDocs) { | ||
collapseResults(); | ||
} | ||
} | ||
|
||
function gotResult(i, id, docs) { | ||
perDocResults[i] = {id: id, docs: docs}; | ||
checkDone(); | ||
} | ||
|
||
Object.keys(requestsById).forEach(function (docId, i) { | ||
|
||
var docRequests = requestsById[docId]; | ||
|
||
// just use the first request as the "template" | ||
// TODO: yeah... this API allows more subtle use cases than this, | ||
// but for now there's only one real client (replicate.js) since users | ||
// shouldn't need to touch this. so let's optimize for that case. | ||
var docOpts = utils.pick(docRequests[0], ['atts_since', 'attachments']); | ||
docOpts.open_revs = docRequests.map(function (request) { | ||
// rev is required, open_revs disallowed | ||
return request.rev; | ||
}); | ||
// globally-supplied options | ||
['revs', 'attachments', 'atts_since'].forEach(function (param) { | ||
if (param in opts) { | ||
docOpts[param] = opts[param]; | ||
} | ||
}); | ||
db.get(docId, docOpts, function (err, res) { | ||
gotResult(i, docId, err ? [{error: err}] : res); | ||
}); | ||
}); | ||
} | ||
|
||
module.exports = bulkGet; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters