UNPKG

2.66 kBJavaScriptView Raw
1// Copyright © 2017, 2021 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 let batch = 0;
24 let hasErrored = false;
25 let startKey = null;
26 let total = 0;
27
28 async.doUntil(
29 function(callback) {
30 // Note, include_docs: true is set automatically when using the
31 // fetch function.
32 const opts = { db: db.db, limit: options.bufferSize, includeDocs: true };
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.service.postAllDocs(opts).then(response => {
40 const body = response.result;
41 if (!body.rows) {
42 ee.emit('error', new error.BackupError(
43 'AllDocsError', 'ERROR: Invalid all docs response'));
44 callback();
45 } else {
46 if (body.rows.length < opts.limit) {
47 startKey = null; // last batch
48 } else {
49 startKey = body.rows[opts.limit - 1].id;
50 }
51
52 const docs = [];
53 body.rows.forEach(function(doc) {
54 docs.push(doc.doc);
55 });
56
57 if (docs.length > 0) {
58 ee.emit('received', {
59 batch: batch++,
60 data: docs,
61 length: docs.length,
62 time: (new Date().getTime() - start) / 1000,
63 total: total += docs.length
64 });
65 }
66 callback();
67 }
68 }).catch(err => {
69 err = error.convertResponseError(err);
70 ee.emit('error', err);
71 hasErrored = true;
72 callback();
73 });
74 },
75 function(callback) { callback(null, hasErrored || startKey == null); },
76 function() { ee.emit('finished', { total: total }); }
77 );
78
79 return ee;
80};