blob: ae2cd10b04adbc01926ca5fff5d2ec329da30108 [file] [log] [blame]
'use strict';
import pick from '../deps/pick';
// 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: The _bulk_get API allows for more subtle use cases than this,
// but for now it is unlikely that there will be a mix of different
// "atts_since" or "attachments" in the same request, since it's just
// replicate.js that is using this for the moment.
// Also, atts_since is aspirational, since we don't support it yet.
var docOpts = 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', 'binary'].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);
});
});
}
export default bulkGet;