'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _clone = require('../deps/clone');
var _clone2 = _interopRequireDefault(_clone);
var _promise = require('../deps/promise');
var _promise2 = _interopRequireDefault(_promise);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isGenOne(rev) {
return (/^1-/.test(rev)
);
}
function createBulkGetOpts(diffs) {
var requests = [];
Object.keys(diffs).forEach(function (id) {
var missingRevs = diffs[id].missing;
missingRevs.forEach(function (missingRev) {
requests.push({
id: id,
rev: missingRev
});
});
});
return {
docs: requests,
revs: true,
attachments: true,
binary: true
};
}
//
// Fetch all the documents from the src as described in the "diffs",
// which is a mapping of docs IDs to revisions. If the state ever
// changes to "cancelled", then the returned promise will be rejected.
// Else it will be resolved with a list of fetched documents.
//
function getDocs(src, diffs, state) {
diffs = (0, _clone2.default)(diffs); // we do not need to modify this
var resultDocs = [];
function getAllDocs() {
var bulkGetOpts = createBulkGetOpts(diffs);
if (!bulkGetOpts.docs.length) {
// optimization: skip empty requests
return;
}
return src.bulkGet(bulkGetOpts).then(function (bulkGetResponse) {
/* istanbul ignore if */
Iif (state.cancelled) {
throw new Error('cancelled');
}
bulkGetResponse.results.forEach(function (bulkGetInfo) {
bulkGetInfo.docs.forEach(function (doc) {
Eif (doc.ok) {
resultDocs.push(doc.ok);
}
});
});
});
}
function hasAttachments(doc) {
return doc._attachments && Object.keys(doc._attachments).length > 0;
}
function fetchRevisionOneDocs(ids) {
// Optimization: fetch gen-1 docs and attachments in
// a single request using _all_docs
return src.allDocs({
keys: ids,
include_docs: true
}).then(function (res) {
if (state.cancelled) {
throw new Error('cancelled');
}
res.rows.forEach(function (row) {
if (row.deleted || !row.doc || !isGenOne(row.value.rev) || hasAttachments(row.doc)) {
// if any of these conditions apply, we need to fetch using get()
return;
}
// the doc we got back from allDocs() is sufficient
resultDocs.push(row.doc);
delete diffs[row.id];
});
});
}
function getRevisionOneDocs() {
// filter out the generation 1 docs and get them
// leaving the non-generation one docs to be got otherwise
var ids = Object.keys(diffs).filter(function (id) {
var missing = diffs[id].missing;
return missing.length === 1 && isGenOne(missing[0]);
});
if (ids.length > 0) {
return fetchRevisionOneDocs(ids);
}
}
function returnDocs() {
return resultDocs;
}
return _promise2.default.resolve().then(getRevisionOneDocs).then(getAllDocs).then(returnDocs);
}
exports.default = getDocs;
module.exports = exports['default']; |