blob: 446f9091bad36f5c41f841ce245e7e9ca8d35915 [file] [log] [blame]
'use strict';
import errors from '../errors';
import updateDoc from './updateDoc';
import isDeleted from './isDeleted';
import isLocalId from './isLocalId';
import calculateWinningRev from '../../deps/merge/winningRev';
import merge from '../../deps/merge/index';
import collections from 'pouchdb-collections';
var Map = collections.Map;
function processDocs(docInfos, api, fetchedDocs, tx, results, writeDoc, opts,
overallCallback) {
function insertDoc(docInfo, resultsIdx, callback) {
// Cant insert new deleted documents
var winningRev = calculateWinningRev(docInfo.metadata);
var deleted = isDeleted(docInfo.metadata, winningRev);
if ('was_delete' in opts && deleted) {
results[resultsIdx] = errors.error(errors.MISSING_DOC, 'deleted');
return callback();
}
var delta = deleted ? 0 : 1;
writeDoc(docInfo, winningRev, deleted, deleted, false,
delta, resultsIdx, callback);
}
var newEdits = opts.new_edits;
var idsToDocs = new Map();
var docsDone = 0;
var docsToDo = docInfos.length;
function checkAllDocsDone() {
if (++docsDone === docsToDo && overallCallback) {
overallCallback();
}
}
docInfos.forEach(function (currentDoc, resultsIdx) {
if (currentDoc._id && isLocalId(currentDoc._id)) {
api[currentDoc._deleted ? '_removeLocal' : '_putLocal'](
currentDoc, {ctx: tx}, function (err) {
if (err) {
results[resultsIdx] = err;
} else {
results[resultsIdx] = {ok: true};
}
checkAllDocsDone();
});
return;
}
var id = currentDoc.metadata.id;
if (idsToDocs.has(id)) {
docsToDo--; // duplicate
idsToDocs.get(id).push([currentDoc, resultsIdx]);
} else {
idsToDocs.set(id, [[currentDoc, resultsIdx]]);
}
});
// in the case of new_edits, the user can provide multiple docs
// with the same id. these need to be processed sequentially
idsToDocs.forEach(function (docs, id) {
var numDone = 0;
function docWritten() {
if (++numDone < docs.length) {
nextDoc();
} else {
checkAllDocsDone();
}
}
function nextDoc() {
var value = docs[numDone];
var currentDoc = value[0];
var resultsIdx = value[1];
if (fetchedDocs.has(id)) {
updateDoc(fetchedDocs.get(id), currentDoc, results,
resultsIdx, docWritten, writeDoc, newEdits);
} else {
// Ensure stemming applies to new writes as well
var merged = merge([], currentDoc.metadata.rev_tree[0], 1000);
currentDoc.metadata.rev_tree = merged.tree;
insertDoc(currentDoc, resultsIdx, docWritten);
}
}
nextDoc();
});
}
export default processDocs;