UNPKG

2.59 kBJavaScriptView Raw
1// Copyright © 2017, 2019 IBM Corp. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14'use strict';
15
16const async = require('async');
17const error = require('./error.js');
18const events = require('events');
19
20module.exports = function(db, options) {
21 const ee = new events.EventEmitter();
22 const start = new Date().getTime();
23 var batch = 0;
24 var hasErrored = false;
25 var startKey = null;
26 var total = 0;
27
28 async.doUntil(
29 function(callback) {
30 // Note, include_docs: true is set automatically when using the
31 // fetch function.
32 var opts = { limit: options.bufferSize };
33
34 // To avoid double fetching a document solely for the purposes of getting
35 // the next ID to use as a startkey for the next page we instead use the
36 // last ID of the current page and append the lowest unicode sort
37 // character.
38 if (startKey) opts.startkey = `${startKey}\0`;
39 db.fetch({}, opts, function(err, body) {
40 if (err) {
41 err = error.convertResponseError(err);
42 ee.emit('error', err);
43 hasErrored = true;
44 callback();
45 } else if (!body.rows) {
46 ee.emit('error', new error.BackupError(
47 'AllDocsError', 'ERROR: Invalid all docs response'));
48 callback();
49 } else {
50 if (body.rows.length < opts.limit) {
51 startKey = null; // last batch
52 } else {
53 startKey = body.rows[opts.limit - 1].id;
54 }
55
56 var docs = [];
57 body.rows.forEach(function(doc) {
58 docs.push(doc.doc);
59 });
60
61 if (docs.length > 0) {
62 ee.emit('received', {
63 batch: batch++,
64 data: docs,
65 length: docs.length,
66 time: (new Date().getTime() - start) / 1000,
67 total: total += docs.length
68 });
69 }
70 callback();
71 }
72 });
73 },
74 function(callback) { callback(null, hasErrored || startKey == null); },
75 function() { ee.emit('finished', { total: total }); }
76 );
77
78 return ee;
79};