blob: 0fbfb5ac6e6d6ef45298bac4b78a84d03d61711d [file] [log] [blame]
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;
// 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 optional, open_revs disallowed
return request.rev;
});
// remove falsey / undefined revisions
docOpts.open_revs = docOpts.open_revs.filter(function (e) { return e; });
var formatResult = function (result) { return result; };
if (docOpts.open_revs.length === 0) {
delete docOpts.open_revs;
// when fetching only the "winning" leaf,
// transform the result so it looks like an open_revs
// request
formatResult = function (result) {
return [{
ok: result
}];
};
}
// 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}] : formatResult(res));
});
});
}
export default bulkGet;