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 |
1
1
1
1
1
1
1
1
1
10250
10250
10250
11
11
10239
10239
3833
3833
3833
3833
1
20749
3831
3833
22356
3576
3576
5
3571
3576
3576
18780
18780
1605
1605
17175
3833
17175
1
18778
1605
17173
1
18780
18780
18780
18780
8530
10250
17175
1 | 'use strict';
var merge = require('../../merge');
var errors = require('../errors');
var updateDoc = require('./updateDoc');
var isDeleted = require('./isDeleted');
var isLocalId = require('./isLocalId');
var collections = require('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 = merge.winningRev(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 {
insertDoc(currentDoc, resultsIdx, docWritten);
}
}
nextDoc();
});
}
module.exports = processDocs; |