all files / lib/replicate/ getDocs.js

100% Statements 52/52
91.67% Branches 22/24
100% Functions 17/17
100% Lines 51/51
1 statement, 1 branch Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124                    5584×       2181× 2181× 437× 437× 1653×             2181×                           2212×   2212×     2181×   2181×   1798×     383×   383×   383× 1653× 1653× 1653×             2615×         1704×       1680×   1673× 2630×   103×       2527× 2527×             2212× 2995× 2995×   2212× 1704×       2181×     2212×    
'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'];