UNPKG

5.79 kBJavaScriptView Raw
1process.on('unhandledRejection', rejection => console.error(rejection));
2
3var _ = require('lodash');
4var fs = require('fs');
5var path = require('path');
6var Stagger = require('stagger');
7var request = require('request-promise');
8
9var args = process.argv.slice(2);
10
11if (args.length < 2) {
12 console.error('Usage: url [doc] db1[,db2,db3...]');
13 process.exit(0);
14}
15
16var DB_URL = args[0];
17var DB_NAME = args.length === 3 ? args[2] : args[1];
18var DOC_NAME = args.length === 3 ? args[1] : undefined;
19
20var COMMENT_PATTERN = new RegExp('(\\/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)', 'g');
21
22var docMap = {};
23
24function prepareFn (fn) {
25 fn = fn.toString();
26 fn = fn.replace(COMMENT_PATTERN, '');
27 fn = 'function ' + fn.slice(fn.indexOf('(')).replace(/\t|\n/g, '');
28 return fn;
29}
30
31function prepareDesignDoc (x) {
32 for (var i in x) {
33 if (i[0] !== '_') {
34 if (typeof x[i] === 'function') {
35 x[i] = prepareFn(x[i]);
36 } else if (toString.call(x[i]) === '[object Array]') {
37 x[i] = 'exports.' + x[i][0] + ' = ' + prepareFn(x[i][1]);
38 } else if (typeof x[i] === 'object') {
39 prepareDesignDoc(x[i]);
40 }
41 }
42 }
43}
44
45function getDirs (srcpath) {
46 return fs.readdirSync(srcpath).filter(function (file) {
47 return fs.statSync(path.join(srcpath, file)).isDirectory();
48 });
49}
50
51function deleteOldDesignDocs (newDesignDocs, dbName) {
52 return function (cb) {
53 request({
54 method: 'GET',
55 uri: [DB_URL, dbName, '_all_docs?startkey="_design"&endkey="_design0"&include_docs=true'].join('/'),
56 simple: false,
57 resolveWithFullResponse: true,
58 })
59 .then(
60 function (response) {
61 var result = JSON.parse(response.body);
62
63 if (result.error) {
64 console.error(dbName, result.error);
65 process.exit(0);
66 }
67
68 var oldDocs = result.rows.map(function(row) {
69 return row.doc;
70 });
71
72 oldDocs = oldDocs.filter(function (oldDoc) {
73 return newDesignDocs.indexOf(oldDoc._id.replace('_design/', '')) === -1;
74 });
75
76 if (!oldDocs.length) {
77 cb();
78 return;
79 }
80
81 oldDocs = oldDocs.map(oldDoc => ({
82 _id: oldDoc._id,
83 _rev: oldDoc._rev,
84 _deleted: true,
85 }));
86
87 request({
88 method: 'POST',
89 uri: [DB_URL, dbName, '_bulk_docs'].join('/'),
90 headers: {
91 'Content-Type': 'application/json',
92 },
93 body: JSON.stringify({
94 docs: oldDocs,
95 }),
96 simple: false,
97 resolveWithFullResponse: true,
98 })
99 .then(
100 function (response) {
101 console.log(dbName, 'deleted', oldDocs.map(function (oldDoc) { return oldDoc._id; }).join(', '));
102
103 cb();
104 },
105 function (error) {
106 console.error(error.error);
107 process.exit(1);
108 }
109 );
110 },
111 function (error) {
112 console.error(error.error);
113 process.exit(1);
114 }
115 );
116 };
117}
118
119function createNewDesignDocs(dbName, designDocName, designDoc) {
120 return function (cb) {
121 var uri = [DB_URL, dbName, '_design', designDocName].join('/');
122
123 docMap[uri] = _.cloneDeep(designDoc);
124
125 request({
126 method: 'GET',
127 uri: uri,
128 simple: false,
129 resolveWithFullResponse: true,
130 })
131 .then(
132 function (response) {
133 var result = JSON.parse(response.body);
134
135 if (result.error && result.error !== 'not_found') {
136 console.error(dbName, result.error);
137 process.exit(0);
138 }
139
140 var uri = response.request.uri.href;
141 var dDoc = docMap[uri];
142
143 if (response.statusCode === 200) {
144 dDoc._rev = JSON.parse(response.body)._rev;
145 }
146
147 request({
148 method: 'PUT',
149 uri: response.request.uri.href,
150 headers: {
151 'Content-Type': 'application/json',
152 },
153 body: JSON.stringify(dDoc),
154 simple: true,
155 resolveWithFullResponse: true,
156 })
157 .then(
158 function (response) {
159 var result = JSON.parse(response.body);
160
161 if (result.error) {
162 console.error(dbName, result.error);
163 process.exit(0);
164 }
165
166 console.log('%d %s', response.statusCode, response.request.uri.path);
167
168 cb();
169 },
170 function (error) {
171 console.error('%d %s', error.statusCode, error.response.request.uri.path);
172 process.exit(1);
173 }
174 );
175 },
176 function (error) {
177 console.error(error.error);
178 process.exit(1);
179 }
180 );
181 };
182}
183
184function init() {
185 var newDesignDocs = getDirs(path.resolve(__dirname));
186
187 var dbs = DB_NAME.split(',');
188
189 var part1 = new Stagger({
190 requestsPerSecond: 2,
191 });
192
193 dbs.forEach(function(dbName) {
194 part1.push(deleteOldDesignDocs(newDesignDocs, dbName));
195 });
196
197 part1.on('finish', function () {
198
199 var part2 = new Stagger({
200 requestsPerSecond: 2,
201 });
202
203 newDesignDocs.forEach(function (designDocName) {
204 if (DOC_NAME && DOC_NAME !== designDocName) {
205 return;
206 }
207
208 var designDoc = require(path.resolve(__dirname, designDocName));
209
210 prepareDesignDoc(designDoc);
211
212 dbs.forEach(function(dbName) {
213 part2.push(createNewDesignDocs(dbName, designDocName, designDoc));
214 });
215 });
216
217 part2.on('finish', function () {
218 console.log('finished');
219 });
220
221 part2.start();
222
223 });
224
225 part1.start();
226}
227
228init();