@iobroker/db-objects-file 4.0.21 → 4.1.0-alpha.0-20220819-74ceeddc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.ts +5 -0
- package/{index.js → build/index.js} +2 -0
- package/build/lib/objects/objectsInMemFileDB.d.ts +100 -0
- package/build/lib/objects/objectsInMemFileDB.d.ts.map +1 -0
- package/{lib → build/lib}/objects/objectsInMemFileDB.js +125 -210
- package/build/lib/objects/objectsInMemFileDB.js.map +1 -0
- package/build/lib/objects/objectsInMemServerClass.d.ts +14 -0
- package/build/lib/objects/objectsInMemServerClass.d.ts.map +1 -0
- package/{lib → build/lib}/objects/objectsInMemServerClass.js +1 -9
- package/build/lib/objects/objectsInMemServerClass.js.map +1 -0
- package/build/lib/objects/objectsInMemServerRedis.d.ts +89 -0
- package/build/lib/objects/objectsInMemServerRedis.d.ts.map +1 -0
- package/{lib → build/lib}/objects/objectsInMemServerRedis.js +218 -285
- package/build/lib/objects/objectsInMemServerRedis.js.map +1 -0
- package/package.json +13 -9
|
@@ -6,20 +6,17 @@
|
|
|
6
6
|
* MIT License
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
9
|
/* jshint -W097 */
|
|
11
10
|
/* jshint strict: false */
|
|
12
11
|
/* jslint node: true */
|
|
13
12
|
/* jshint -W061 */
|
|
14
13
|
'use strict';
|
|
15
|
-
|
|
16
14
|
const fs = require('fs-extra');
|
|
17
15
|
const path = require('path');
|
|
18
|
-
const InMemoryFileDB = require('@iobroker/db-base')
|
|
16
|
+
const { InMemoryFileDB } = require('@iobroker/db-base');
|
|
19
17
|
const tools = require('@iobroker/db-base').tools;
|
|
20
18
|
const utils = require('@iobroker/db-objects-redis').objectsUtils;
|
|
21
19
|
const deepClone = require('deep-clone');
|
|
22
|
-
|
|
23
20
|
/**
|
|
24
21
|
* This class inherits InMemoryFileDB class and adds all relevant logic for objects
|
|
25
22
|
* including the available methods for use by js-controller directly
|
|
@@ -32,7 +29,6 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
32
29
|
backupDirName: 'backup-objects'
|
|
33
30
|
};
|
|
34
31
|
super(settings);
|
|
35
|
-
|
|
36
32
|
if (!this.change) {
|
|
37
33
|
this.change = id => {
|
|
38
34
|
this.log.silly(`${this.namespace} objects change: ${id} ${JSON.stringify(this.change)}`);
|
|
@@ -52,12 +48,9 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
52
48
|
if (!settings.jsonlDB) {
|
|
53
49
|
this.log.silly(`${this.namespace} Objects DB uses file write interval of ${this.writeFileInterval} ms`);
|
|
54
50
|
}
|
|
55
|
-
|
|
56
51
|
this.objectsDir = path.join(this.dataDir, 'files');
|
|
57
|
-
|
|
58
52
|
// cached meta information for file operations
|
|
59
53
|
this.existingMetaObjects = {};
|
|
60
|
-
|
|
61
54
|
// Handle some < js-controller 2.0 broken objects and correct them
|
|
62
55
|
for (const key of Object.keys(this.dataset)) {
|
|
63
56
|
const obj = this.dataset[key];
|
|
@@ -67,19 +60,16 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
67
60
|
this.dataset[key] = obj;
|
|
68
61
|
}
|
|
69
62
|
}
|
|
70
|
-
|
|
71
63
|
// init default new acl
|
|
72
64
|
const configObj = this.dataset['system.config'];
|
|
73
65
|
if (configObj && configObj.common && configObj.common.defaultNewAcl) {
|
|
74
66
|
this.defaultNewAcl = deepClone(configObj.common.defaultNewAcl);
|
|
75
67
|
}
|
|
76
68
|
}
|
|
77
|
-
|
|
78
69
|
// internal functionality
|
|
79
70
|
_normalizeFilename(name) {
|
|
80
71
|
return name ? name.replace(/[/\\]+/g, '/') : name;
|
|
81
72
|
}
|
|
82
|
-
|
|
83
73
|
// -------------- FILE FUNCTIONS -------------------------------------------
|
|
84
74
|
// internal functionality
|
|
85
75
|
_saveFileSettings(id, force) {
|
|
@@ -87,11 +77,8 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
87
77
|
force = id;
|
|
88
78
|
id = undefined;
|
|
89
79
|
}
|
|
90
|
-
|
|
91
80
|
id !== undefined && !this.writeIds.includes(id) && this.writeIds.push(id);
|
|
92
|
-
|
|
93
81
|
this.writeTimer && clearTimeout(this.writeTimer);
|
|
94
|
-
|
|
95
82
|
// if store immediately
|
|
96
83
|
if (force) {
|
|
97
84
|
this.writeTimer = null;
|
|
@@ -102,19 +89,22 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
102
89
|
if (fs.existsSync(path.join(this.objectsDir, this.writeIds[_id]))) {
|
|
103
90
|
fs.writeFileSync(location, JSON.stringify(this.fileOptions[this.writeIds[_id]]));
|
|
104
91
|
}
|
|
105
|
-
}
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
106
94
|
this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);
|
|
107
95
|
}
|
|
108
96
|
}
|
|
109
97
|
this.writeIds = [];
|
|
110
|
-
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
111
100
|
this.writeTimer = setTimeout(() => {
|
|
112
101
|
// Store dirs description
|
|
113
102
|
for (let id = 0; id < this.writeIds.length; id++) {
|
|
114
103
|
const location = path.join(this.objectsDir, this.writeIds[id], '_data.json');
|
|
115
104
|
try {
|
|
116
105
|
fs.writeFileSync(location, JSON.stringify(this.fileOptions[this.writeIds[id]]));
|
|
117
|
-
}
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
118
108
|
this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);
|
|
119
109
|
}
|
|
120
110
|
}
|
|
@@ -122,7 +112,6 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
122
112
|
}, 1000);
|
|
123
113
|
}
|
|
124
114
|
}
|
|
125
|
-
|
|
126
115
|
// internal functionality
|
|
127
116
|
_loadFileSettings(id) {
|
|
128
117
|
if (!this.fileOptions[id]) {
|
|
@@ -130,7 +119,8 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
130
119
|
if (fs.existsSync(location)) {
|
|
131
120
|
try {
|
|
132
121
|
this.fileOptions[id] = fs.readJSONSync(location);
|
|
133
|
-
}
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
134
124
|
this.log.error(`${this.namespace} Cannot parse ${location}: ${e.message}`);
|
|
135
125
|
this.fileOptions[id] = {};
|
|
136
126
|
}
|
|
@@ -146,22 +136,22 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
146
136
|
if (corrected) {
|
|
147
137
|
try {
|
|
148
138
|
fs.writeFileSync(location, JSON.stringify(this.fileOptions[id]));
|
|
149
|
-
}
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
150
141
|
this.log.error(`${this.namespace} Cannot write files: ${location}: ${e.message}`);
|
|
151
142
|
}
|
|
152
143
|
}
|
|
153
144
|
});
|
|
154
|
-
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
155
147
|
this.fileOptions[id] = {};
|
|
156
148
|
}
|
|
157
149
|
}
|
|
158
150
|
}
|
|
159
|
-
|
|
160
151
|
// server only functionality
|
|
161
152
|
syncFileDirectory(limitId) {
|
|
162
153
|
const resNotifies = [];
|
|
163
154
|
let resSynced = 0;
|
|
164
|
-
|
|
165
155
|
function getAllFiles(dir) {
|
|
166
156
|
let results = [];
|
|
167
157
|
const list = fs.readdirSync(dir);
|
|
@@ -171,19 +161,17 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
171
161
|
if (stat && stat.isDirectory()) {
|
|
172
162
|
/* Recurse into a subdirectory */
|
|
173
163
|
results = results.concat(getAllFiles(file));
|
|
174
|
-
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
175
166
|
/* Is a file */
|
|
176
167
|
results.push(file);
|
|
177
168
|
}
|
|
178
169
|
});
|
|
179
170
|
return results;
|
|
180
171
|
}
|
|
181
|
-
|
|
182
172
|
const res = this._getObjectView('system', 'meta', null);
|
|
183
|
-
|
|
184
173
|
// collect meta ids to generate warning if non existing
|
|
185
174
|
const metaIds = res.rows.map(obj => obj.id).filter(id => !limitId || limitId === id);
|
|
186
|
-
|
|
187
175
|
if (!fs.existsSync(this.objectsDir)) {
|
|
188
176
|
return {
|
|
189
177
|
numberSuccess: resSynced,
|
|
@@ -205,9 +193,7 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
205
193
|
return;
|
|
206
194
|
}
|
|
207
195
|
if (!metaIds.includes(dir)) {
|
|
208
|
-
resNotifies.push(
|
|
209
|
-
`Ignoring Directory "${dir}" because officially not created as meta object. Please remove directory!`
|
|
210
|
-
);
|
|
196
|
+
resNotifies.push(`Ignoring Directory "${dir}" because officially not created as meta object. Please remove directory!`);
|
|
211
197
|
return;
|
|
212
198
|
}
|
|
213
199
|
this._loadFileSettings(dir);
|
|
@@ -223,16 +209,13 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
223
209
|
const mime = utils.getMimeType(ext);
|
|
224
210
|
const _mimeType = mime.mimeType;
|
|
225
211
|
const isBinary = mime.isBinary;
|
|
226
|
-
|
|
227
212
|
this.fileOptions[dir][localFile] = {
|
|
228
213
|
createdAt: fileStat.ctimeMs,
|
|
229
214
|
acl: {
|
|
230
215
|
owner: (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,
|
|
231
|
-
ownerGroup:
|
|
232
|
-
(this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
216
|
+
ownerGroup: (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
233
217
|
utils.CONSTS.SYSTEM_ADMIN_GROUP,
|
|
234
|
-
permissions:
|
|
235
|
-
(this.defaultNewAcl && this.defaultNewAcl.file) ||
|
|
218
|
+
permissions: (this.defaultNewAcl && this.defaultNewAcl.file) ||
|
|
236
219
|
utils.CONSTS.ACCESS_USER_RW |
|
|
237
220
|
utils.CONSTS.ACCESS_GROUP_READ |
|
|
238
221
|
utils.CONSTS.ACCESS_EVERY_READ // 0x644
|
|
@@ -253,7 +236,6 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
253
236
|
notifications: resNotifies
|
|
254
237
|
};
|
|
255
238
|
}
|
|
256
|
-
|
|
257
239
|
// needed by server
|
|
258
240
|
_writeFile(id, name, data, options) {
|
|
259
241
|
if (typeof options === 'string') {
|
|
@@ -262,17 +244,12 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
262
244
|
if (options && options.acl) {
|
|
263
245
|
options.acl = null;
|
|
264
246
|
}
|
|
265
|
-
|
|
266
247
|
const _path = utils.sanitizePath(id, name);
|
|
267
248
|
id = _path.id;
|
|
268
249
|
name = _path.name;
|
|
269
|
-
|
|
270
250
|
options = options || {};
|
|
271
|
-
|
|
272
251
|
this._loadFileSettings(id);
|
|
273
|
-
|
|
274
252
|
this.files[id] = this.files[id] || {};
|
|
275
|
-
|
|
276
253
|
try {
|
|
277
254
|
if (!fs.existsSync(this.objectsDir)) {
|
|
278
255
|
fs.mkdirSync(this.objectsDir);
|
|
@@ -280,42 +257,33 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
280
257
|
if (!fs.existsSync(path.join(this.objectsDir, id))) {
|
|
281
258
|
fs.mkdirSync(path.join(this.objectsDir, id));
|
|
282
259
|
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
);
|
|
287
|
-
this.log.error(
|
|
288
|
-
`${this.namespace} Check the permissions! Or run installation fixer or "iobroker fix" command!`
|
|
289
|
-
);
|
|
260
|
+
}
|
|
261
|
+
catch (e) {
|
|
262
|
+
this.log.error(`${this.namespace} Cannot create directories: ${path.join(this.objectsDir, id)}: ${e.message}`);
|
|
263
|
+
this.log.error(`${this.namespace} Check the permissions! Or run installation fixer or "iobroker fix" command!`);
|
|
290
264
|
throw e;
|
|
291
265
|
}
|
|
292
|
-
|
|
293
266
|
const ext = path.extname(name);
|
|
294
267
|
const mime = utils.getMimeType(ext);
|
|
295
268
|
const _mimeType = mime.mimeType;
|
|
296
269
|
const isBinary = mime.isBinary;
|
|
297
|
-
|
|
298
270
|
this.fileOptions[id][name] = this.fileOptions[id][name] || { createdAt: Date.now() };
|
|
299
271
|
this.fileOptions[id][name].acl = this.fileOptions[id][name].acl || {
|
|
300
272
|
owner: options.user || (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,
|
|
301
|
-
ownerGroup:
|
|
302
|
-
options.group ||
|
|
273
|
+
ownerGroup: options.group ||
|
|
303
274
|
(this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
304
275
|
utils.CONSTS.SYSTEM_ADMIN_GROUP,
|
|
305
|
-
permissions:
|
|
306
|
-
options.mode ||
|
|
276
|
+
permissions: options.mode ||
|
|
307
277
|
(this.defaultNewAcl && this.defaultNewAcl.file) ||
|
|
308
278
|
utils.CONSTS.ACCESS_USER_RW | utils.CONSTS.ACCESS_GROUP_READ | utils.CONSTS.ACCESS_EVERY_READ // 0x644
|
|
309
279
|
};
|
|
310
|
-
|
|
311
280
|
this.fileOptions[id][name].mimeType = options.mimeType || _mimeType;
|
|
312
281
|
this.fileOptions[id][name].binary = isBinary;
|
|
313
282
|
this.fileOptions[id][name].acl.ownerGroup =
|
|
314
283
|
this.fileOptions[id][name].acl.ownerGroup ||
|
|
315
|
-
|
|
316
|
-
|
|
284
|
+
(this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
285
|
+
utils.CONSTS.SYSTEM_ADMIN_GROUP;
|
|
317
286
|
this.fileOptions[id][name].modifiedAt = Date.now();
|
|
318
|
-
|
|
319
287
|
try {
|
|
320
288
|
// Create directories if complex structure
|
|
321
289
|
fs.ensureDirSync(path.join(this.objectsDir, id, path.dirname(name)));
|
|
@@ -324,40 +292,38 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
324
292
|
flag: 'w',
|
|
325
293
|
encoding: isBinary ? 'binary' : 'utf8'
|
|
326
294
|
});
|
|
327
|
-
|
|
328
295
|
if (isBinary) {
|
|
329
296
|
// Reload by read
|
|
330
297
|
delete this.files[id][name];
|
|
331
|
-
}
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
332
300
|
this.files[id][name] = data;
|
|
333
301
|
}
|
|
334
|
-
|
|
335
302
|
// Store dir description
|
|
336
303
|
this._saveFileSettings(id);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
);
|
|
304
|
+
}
|
|
305
|
+
catch (e) {
|
|
306
|
+
this.log.error(`${this.namespace} Cannot write files: ${path.join(this.objectsDir, id, name)}: ${e.message}`);
|
|
341
307
|
throw e;
|
|
342
308
|
}
|
|
309
|
+
setImmediate((name, size) => {
|
|
310
|
+
// publish event in states
|
|
311
|
+
this.log.silly(`${this.namespace} memory publish ${id} ${JSON.stringify({ name, file: true, size })}`);
|
|
312
|
+
this.publishAll('files', `${id}$%$${name}`, size);
|
|
313
|
+
}, name, data.byteLength);
|
|
343
314
|
}
|
|
344
|
-
|
|
345
315
|
// needed by server
|
|
346
316
|
_readFile(id, name, options) {
|
|
347
317
|
if (options && options.acl) {
|
|
348
318
|
options.acl = null;
|
|
349
319
|
}
|
|
350
|
-
|
|
351
320
|
const _path = utils.sanitizePath(id, name);
|
|
352
321
|
id = _path.id;
|
|
353
322
|
name = _path.name;
|
|
354
|
-
|
|
355
323
|
options = options || {};
|
|
356
324
|
try {
|
|
357
325
|
this._loadFileSettings(id);
|
|
358
|
-
|
|
359
326
|
this.files[id] = this.files[id] || {};
|
|
360
|
-
|
|
361
327
|
if (!this.files[id][name] || this.settings.connection.noFileCache || options.noFileCache) {
|
|
362
328
|
const location = path.join(this.objectsDir, id, name);
|
|
363
329
|
if (fs.existsSync(location)) {
|
|
@@ -365,11 +331,9 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
365
331
|
this.fileOptions[id][name] = this.fileOptions[id][name] || {
|
|
366
332
|
acl: {
|
|
367
333
|
owner: (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,
|
|
368
|
-
ownerGroup:
|
|
369
|
-
(this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
334
|
+
ownerGroup: (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
370
335
|
utils.CONSTS.SYSTEM_ADMIN_GROUP,
|
|
371
|
-
permissions:
|
|
372
|
-
(this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||
|
|
336
|
+
permissions: (this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||
|
|
373
337
|
utils.CONSTS.ACCESS_USER_ALL |
|
|
374
338
|
utils.CONSTS.ACCESS_GROUP_ALL |
|
|
375
339
|
utils.CONSTS.ACCESS_EVERY_ALL // 777
|
|
@@ -379,20 +343,16 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
379
343
|
this.fileOptions[id][name] = {
|
|
380
344
|
mimeType: this.fileOptions[id][name],
|
|
381
345
|
acl: {
|
|
382
|
-
owner:
|
|
383
|
-
|
|
384
|
-
ownerGroup:
|
|
385
|
-
(this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
346
|
+
owner: (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,
|
|
347
|
+
ownerGroup: (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
386
348
|
utils.CONSTS.SYSTEM_ADMIN_GROUP,
|
|
387
|
-
permissions:
|
|
388
|
-
(this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||
|
|
349
|
+
permissions: (this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||
|
|
389
350
|
utils.CONSTS.ACCESS_USER_ALL |
|
|
390
351
|
utils.CONSTS.ACCESS_GROUP_ALL |
|
|
391
352
|
utils.CONSTS.ACCESS_EVERY_ALL // 777
|
|
392
353
|
}
|
|
393
354
|
};
|
|
394
355
|
}
|
|
395
|
-
|
|
396
356
|
this.files[id][name] = fs.readFileSync(location);
|
|
397
357
|
if (this.fileOptions[id][name].binary === undefined) {
|
|
398
358
|
const ext = path.extname(name);
|
|
@@ -400,13 +360,13 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
400
360
|
this.fileOptions[id][name].binary = mimeType.isBinary;
|
|
401
361
|
this.fileOptions[id][name].mimeType = mimeType.mimeType;
|
|
402
362
|
}
|
|
403
|
-
|
|
404
363
|
if (!this.fileOptions[id][name].binary) {
|
|
405
364
|
if (this.files[id][name]) {
|
|
406
365
|
this.files[id][name] = this.files[id][name].toString();
|
|
407
366
|
}
|
|
408
367
|
}
|
|
409
|
-
}
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
410
370
|
if (this.fileOptions[id][name] !== undefined) {
|
|
411
371
|
delete this.fileOptions[id][name];
|
|
412
372
|
}
|
|
@@ -415,19 +375,15 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
415
375
|
}
|
|
416
376
|
}
|
|
417
377
|
}
|
|
418
|
-
|
|
419
378
|
if (this.fileOptions[id][name] && !this.fileOptions[id][name].acl) {
|
|
420
379
|
// all files belongs to admin by default, but everyone can edit it
|
|
421
380
|
this.fileOptions[id][name].acl = {
|
|
422
381
|
owner: (this.defaultNewAcl && this.defaultNewAcl.owner) || utils.CONSTS.SYSTEM_ADMIN_USER,
|
|
423
|
-
ownerGroup:
|
|
424
|
-
|
|
425
|
-
permissions:
|
|
426
|
-
(this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||
|
|
382
|
+
ownerGroup: (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) || utils.CONSTS.SYSTEM_ADMIN_GROUP,
|
|
383
|
+
permissions: (this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||
|
|
427
384
|
utils.CONSTS.ACCESS_USER_ALL | utils.CONSTS.ACCESS_GROUP_ALL | utils.CONSTS.ACCESS_EVERY_RW // 776
|
|
428
385
|
};
|
|
429
386
|
}
|
|
430
|
-
|
|
431
387
|
if (this.fileOptions[id][name] !== null && this.fileOptions[id][name] !== undefined) {
|
|
432
388
|
if (!this.fileOptions[id][name].mimeType) {
|
|
433
389
|
const _ext = path.extname(name);
|
|
@@ -439,13 +395,13 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
439
395
|
fileMime: this.fileOptions[id][name].mimeType
|
|
440
396
|
};
|
|
441
397
|
}
|
|
442
|
-
}
|
|
398
|
+
}
|
|
399
|
+
catch (e) {
|
|
443
400
|
this.log.warn(`${this.namespace} Cannot read file ${id} / ${name}: ${e.message}`);
|
|
444
401
|
throw e;
|
|
445
402
|
}
|
|
446
403
|
throw new Error(utils.ERRORS.ERROR_NOT_FOUND);
|
|
447
404
|
}
|
|
448
|
-
|
|
449
405
|
/**
|
|
450
406
|
* Check if given object exists
|
|
451
407
|
*
|
|
@@ -458,16 +414,15 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
458
414
|
if (!id || typeof id !== 'string') {
|
|
459
415
|
throw new Error(`invalid id ${JSON.stringify(id)}`);
|
|
460
416
|
}
|
|
461
|
-
|
|
462
417
|
try {
|
|
463
418
|
// check if the id exists
|
|
464
419
|
return Object.prototype.hasOwnProperty.call(this.dataset, id);
|
|
465
|
-
}
|
|
420
|
+
}
|
|
421
|
+
catch (e) {
|
|
466
422
|
this.log.error(`${this.namespace} Cannot check object existence of "${id}": ${e.message}`);
|
|
467
423
|
throw new Error(`Cannot check object existence of "${id}": ${e.message}`);
|
|
468
424
|
}
|
|
469
425
|
}
|
|
470
|
-
|
|
471
426
|
/**
|
|
472
427
|
* Check if given file exists
|
|
473
428
|
*
|
|
@@ -480,13 +435,12 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
480
435
|
if (typeof name !== 'string') {
|
|
481
436
|
name = '';
|
|
482
437
|
}
|
|
483
|
-
|
|
484
438
|
const location = path.join(this.objectsDir, id, name);
|
|
485
|
-
|
|
486
439
|
try {
|
|
487
440
|
const stat = fs.statSync(location);
|
|
488
441
|
return stat.isFile();
|
|
489
|
-
}
|
|
442
|
+
}
|
|
443
|
+
catch (e) {
|
|
490
444
|
if (e.code !== 'ENOENT') {
|
|
491
445
|
this.log.error(`${this.namespace} Cannot check file existence of "${location}": ${e.message}`);
|
|
492
446
|
throw new Error(`Cannot check file existence of "${location}": ${e.message}`);
|
|
@@ -494,7 +448,6 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
494
448
|
return false;
|
|
495
449
|
}
|
|
496
450
|
}
|
|
497
|
-
|
|
498
451
|
/**
|
|
499
452
|
* Check if given directory exists
|
|
500
453
|
*
|
|
@@ -507,13 +460,12 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
507
460
|
if (typeof name !== 'string') {
|
|
508
461
|
name = '';
|
|
509
462
|
}
|
|
510
|
-
|
|
511
463
|
const location = path.join(this.objectsDir, id, name);
|
|
512
|
-
|
|
513
464
|
try {
|
|
514
465
|
const stat = fs.statSync(location);
|
|
515
466
|
return stat.isDirectory();
|
|
516
|
-
}
|
|
467
|
+
}
|
|
468
|
+
catch (e) {
|
|
517
469
|
if (e.code !== 'ENOENT') {
|
|
518
470
|
this.log.error(`${this.namespace} Cannot check directory existence of "${location}": ${e.message}`);
|
|
519
471
|
throw new Error(`Cannot check directory existence of "${location}": ${e.message}`);
|
|
@@ -521,59 +473,58 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
521
473
|
return false;
|
|
522
474
|
}
|
|
523
475
|
}
|
|
524
|
-
|
|
525
476
|
// needed by server
|
|
526
477
|
_unlink(id, name) {
|
|
527
478
|
const _path = utils.sanitizePath(id, name);
|
|
528
479
|
id = _path.id;
|
|
529
480
|
name = _path.name;
|
|
530
|
-
|
|
531
481
|
this._loadFileSettings(id);
|
|
532
|
-
|
|
533
482
|
const location = path.join(this.objectsDir, id, name);
|
|
534
483
|
if (fs.existsSync(location)) {
|
|
535
484
|
const stat = fs.statSync(location);
|
|
536
|
-
|
|
537
485
|
if (stat.isDirectory()) {
|
|
538
486
|
// read all entries and delete every one
|
|
539
487
|
fs.readdirSync(location).forEach(dir => this._unlink(id, name + '/' + dir));
|
|
540
|
-
|
|
541
488
|
this.log.debug('Delete directory ' + path.join(id, name));
|
|
542
489
|
try {
|
|
543
490
|
fs.removeSync(location);
|
|
544
|
-
}
|
|
491
|
+
}
|
|
492
|
+
catch (e) {
|
|
545
493
|
this.log.error(`${this.namespace} Cannot delete directory "${path.join(id, name)}": ${e.message}`);
|
|
546
494
|
throw e;
|
|
547
495
|
}
|
|
548
|
-
|
|
549
496
|
if (this.fileOptions[id]) {
|
|
550
497
|
delete this.fileOptions[id];
|
|
551
498
|
}
|
|
552
499
|
if (this.files[id] && this.files[id]) {
|
|
553
500
|
delete this.files[id];
|
|
554
501
|
}
|
|
555
|
-
}
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
556
504
|
this.log.debug('Delete file ' + path.join(id, name));
|
|
557
505
|
try {
|
|
558
506
|
fs.removeSync(location);
|
|
559
|
-
}
|
|
507
|
+
}
|
|
508
|
+
catch (e) {
|
|
560
509
|
this.log.error(`${this.namespace} Cannot delete file "${path.join(id, name)}": ${e.message}`);
|
|
561
510
|
throw e;
|
|
562
511
|
}
|
|
563
|
-
|
|
564
512
|
if (this.fileOptions[id][name]) {
|
|
565
513
|
delete this.fileOptions[id][name];
|
|
566
514
|
}
|
|
567
515
|
if (this.files[id] && this.files[id][name]) {
|
|
568
516
|
delete this.files[id][name];
|
|
569
517
|
}
|
|
570
|
-
|
|
571
518
|
// Store dir description
|
|
572
519
|
this._saveFileSettings(id, true);
|
|
573
520
|
}
|
|
521
|
+
setImmediate((id, name) => {
|
|
522
|
+
// publish event in states
|
|
523
|
+
this.log.silly(`${this.namespace} memory publish ${id} ${JSON.stringify({ name, file: true, size: null })}`);
|
|
524
|
+
this.publishAll('files', `${id}$%$${name}`, null);
|
|
525
|
+
}, id, name);
|
|
574
526
|
}
|
|
575
527
|
}
|
|
576
|
-
|
|
577
528
|
// needed by server
|
|
578
529
|
_readDir(id, name, options) {
|
|
579
530
|
if (options && options.acl) {
|
|
@@ -581,25 +532,22 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
581
532
|
}
|
|
582
533
|
if ((id === '' || id === '/' || id === '*') && (name === '' || name === '*')) {
|
|
583
534
|
// read root of xxx-data/files
|
|
584
|
-
}
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
585
537
|
const _path = utils.sanitizePath(id, name);
|
|
586
538
|
id = _path.id;
|
|
587
539
|
name = _path.name;
|
|
588
540
|
}
|
|
589
|
-
|
|
590
541
|
options = options || {};
|
|
591
542
|
// Find all files and directories starts with name
|
|
592
543
|
const _files = [];
|
|
593
|
-
|
|
594
544
|
if (id && id === '*') {
|
|
595
545
|
id = '';
|
|
596
546
|
}
|
|
597
547
|
if (name && name[name.length - 1] !== '/') {
|
|
598
548
|
name += '/';
|
|
599
549
|
}
|
|
600
|
-
|
|
601
550
|
this._loadFileSettings(id);
|
|
602
|
-
|
|
603
551
|
const len = name ? name.length : 0;
|
|
604
552
|
for (const f of Object.keys(this.fileOptions[id])) {
|
|
605
553
|
if (!name || f.substring(0, len) === name) {
|
|
@@ -611,7 +559,6 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
611
559
|
}
|
|
612
560
|
}
|
|
613
561
|
}
|
|
614
|
-
|
|
615
562
|
const location = path.join(this.objectsDir, id, name);
|
|
616
563
|
if (fs.existsSync(location)) {
|
|
617
564
|
const dirFiles = fs.readdirSync(location);
|
|
@@ -623,10 +570,10 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
623
570
|
_files.push(dirFiles[i]);
|
|
624
571
|
}
|
|
625
572
|
}
|
|
626
|
-
}
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
627
575
|
throw new Error(utils.ERRORS.ERROR_NOT_FOUND);
|
|
628
576
|
}
|
|
629
|
-
|
|
630
577
|
_files.sort();
|
|
631
578
|
const res = [];
|
|
632
579
|
for (let j = 0; j < _files.length; j++) {
|
|
@@ -636,50 +583,38 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
636
583
|
if (fs.existsSync(path.join(location, _files[j]))) {
|
|
637
584
|
try {
|
|
638
585
|
const stats = fs.statSync(path.join(location, _files[j]));
|
|
639
|
-
const acl =
|
|
640
|
-
this.fileOptions[id][name + _files[j]]
|
|
641
|
-
|
|
642
|
-
:
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
utils.CONSTS.ACCESS_USER_RW |
|
|
654
|
-
utils.CONSTS.ACCESS_GROUP_READ |
|
|
655
|
-
utils.CONSTS.ACCESS_EVERY_READ
|
|
656
|
-
};
|
|
657
|
-
|
|
586
|
+
const acl = this.fileOptions[id][name + _files[j]] && this.fileOptions[id][name + _files[j]].acl
|
|
587
|
+
? deepClone(this.fileOptions[id][name + _files[j]].acl) // copy settings
|
|
588
|
+
: {
|
|
589
|
+
read: true,
|
|
590
|
+
write: true,
|
|
591
|
+
owner: (this.defaultNewAcl && this.defaultNewAcl.owner) ||
|
|
592
|
+
utils.CONSTS.SYSTEM_ADMIN_USER,
|
|
593
|
+
ownerGroup: (this.defaultNewAcl && this.defaultNewAcl.ownerGroup) ||
|
|
594
|
+
utils.CONSTS.SYSTEM_ADMIN_GROUP,
|
|
595
|
+
permissions: (this.defaultNewAcl && this.defaultNewAcl.file.permissions) ||
|
|
596
|
+
utils.CONSTS.ACCESS_USER_RW |
|
|
597
|
+
utils.CONSTS.ACCESS_GROUP_READ |
|
|
598
|
+
utils.CONSTS.ACCESS_EVERY_READ
|
|
599
|
+
};
|
|
658
600
|
// if filter for user
|
|
659
601
|
if (options.filter && acl) {
|
|
660
602
|
// If user may not write
|
|
661
603
|
if (!options.acl.file.write) {
|
|
662
604
|
// write
|
|
663
|
-
acl.permissions &= ~(
|
|
664
|
-
utils.CONSTS.ACCESS_USER_WRITE |
|
|
605
|
+
acl.permissions &= ~(utils.CONSTS.ACCESS_USER_WRITE |
|
|
665
606
|
utils.CONSTS.ACCESS_GROUP_WRITE |
|
|
666
|
-
utils.CONSTS.ACCESS_EVERY_WRITE
|
|
667
|
-
);
|
|
607
|
+
utils.CONSTS.ACCESS_EVERY_WRITE);
|
|
668
608
|
}
|
|
669
609
|
// If user may not read
|
|
670
610
|
if (!options.acl.file.read) {
|
|
671
611
|
// read
|
|
672
|
-
acl.permissions &= ~(
|
|
673
|
-
utils.CONSTS.ACCESS_USER_READ |
|
|
612
|
+
acl.permissions &= ~(utils.CONSTS.ACCESS_USER_READ |
|
|
674
613
|
utils.CONSTS.ACCESS_GROUP_READ |
|
|
675
|
-
utils.CONSTS.ACCESS_EVERY_READ
|
|
676
|
-
);
|
|
614
|
+
utils.CONSTS.ACCESS_EVERY_READ);
|
|
677
615
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
options.user !== utils.CONSTS.SYSTEM_ADMIN_USER &&
|
|
681
|
-
options.groups.includes(utils.CONSTS.SYSTEM_ADMIN_GROUP)
|
|
682
|
-
) {
|
|
616
|
+
if (options.user !== utils.CONSTS.SYSTEM_ADMIN_USER &&
|
|
617
|
+
options.groups.includes(utils.CONSTS.SYSTEM_ADMIN_GROUP)) {
|
|
683
618
|
if (acl.owner !== options.user) {
|
|
684
619
|
// Check if the user is in the group
|
|
685
620
|
if (options.groups.includes(acl.ownerGroup)) {
|
|
@@ -689,7 +624,8 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
689
624
|
}
|
|
690
625
|
acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_GROUP_READ);
|
|
691
626
|
acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_GROUP_WRITE);
|
|
692
|
-
}
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
693
629
|
// everybody
|
|
694
630
|
if (!(acl.permissions & utils.CONSTS.ACCESS_EVERY_RW)) {
|
|
695
631
|
continue;
|
|
@@ -697,7 +633,8 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
697
633
|
acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_EVERY_READ);
|
|
698
634
|
acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_EVERY_WRITE);
|
|
699
635
|
}
|
|
700
|
-
}
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
701
638
|
// Check user rights
|
|
702
639
|
if (!(acl.permissions & utils.CONSTS.ACCESS_USER_RW)) {
|
|
703
640
|
continue;
|
|
@@ -705,12 +642,12 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
705
642
|
acl.read = !!(acl.permissions & utils.CONSTS.ACCESS_USER_READ);
|
|
706
643
|
acl.write = !!(acl.permissions & utils.CONSTS.ACCESS_USER_WRITE);
|
|
707
644
|
}
|
|
708
|
-
}
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
709
647
|
acl.read = true;
|
|
710
648
|
acl.write = true;
|
|
711
649
|
}
|
|
712
650
|
}
|
|
713
|
-
|
|
714
651
|
res.push({
|
|
715
652
|
file: _files[j],
|
|
716
653
|
stats: stats,
|
|
@@ -723,22 +660,14 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
723
660
|
? this.fileOptions[id][name + _files[j]].createdAt
|
|
724
661
|
: undefined
|
|
725
662
|
});
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
this.objectsDir,
|
|
730
|
-
id,
|
|
731
|
-
name,
|
|
732
|
-
_files[j]
|
|
733
|
-
)}: ${e.message}`
|
|
734
|
-
);
|
|
663
|
+
}
|
|
664
|
+
catch (e) {
|
|
665
|
+
this.log.error(`${this.namespace} Cannot read permissions of ${path.join(this.objectsDir, id, name, _files[j])}: ${e.message}`);
|
|
735
666
|
}
|
|
736
667
|
}
|
|
737
668
|
}
|
|
738
|
-
|
|
739
669
|
return res;
|
|
740
670
|
}
|
|
741
|
-
|
|
742
671
|
// needed by server
|
|
743
672
|
_rename(id, oldName, newName) {
|
|
744
673
|
const _path = utils.sanitizePath(id, oldName);
|
|
@@ -747,15 +676,13 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
747
676
|
if (newName[0] === '/') {
|
|
748
677
|
newName = newName.substring(1);
|
|
749
678
|
}
|
|
750
|
-
|
|
751
679
|
this._loadFileSettings(id);
|
|
752
|
-
|
|
753
680
|
if (fs.existsSync(path.join(this.objectsDir, id, oldName))) {
|
|
754
681
|
fs.renameSync(path.join(this.objectsDir, id, oldName), path.join(this.objectsDir, id, newName));
|
|
755
|
-
}
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
756
684
|
throw new Error(utils.ERRORS.ERROR_NOT_FOUND);
|
|
757
685
|
}
|
|
758
|
-
|
|
759
686
|
Object.keys(this.fileOptions[id]).forEach(name => {
|
|
760
687
|
const type = this.fileOptions[id][name];
|
|
761
688
|
if (name.startsWith(oldName)) {
|
|
@@ -772,39 +699,50 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
772
699
|
});
|
|
773
700
|
this._saveFileSettings(id, true);
|
|
774
701
|
}
|
|
775
|
-
|
|
776
702
|
// internal functionality
|
|
777
703
|
_clone(obj) {
|
|
778
704
|
if (obj === null || obj === undefined || !tools.isObject(obj)) {
|
|
779
705
|
return obj;
|
|
780
706
|
}
|
|
781
|
-
|
|
782
707
|
const temp = obj.constructor(); // changed
|
|
783
|
-
|
|
784
708
|
for (const key of Object.keys(obj)) {
|
|
785
709
|
temp[key] = this._clone(obj[key]);
|
|
786
710
|
}
|
|
787
711
|
return temp;
|
|
788
712
|
}
|
|
789
|
-
|
|
713
|
+
_subscribeMeta(client, pattern) {
|
|
714
|
+
this.handleSubscribe(client, 'meta', pattern);
|
|
715
|
+
}
|
|
790
716
|
// needed by server
|
|
791
717
|
_subscribeConfigForClient(client, pattern) {
|
|
792
718
|
this.handleSubscribe(client, 'objects', pattern);
|
|
793
719
|
}
|
|
794
|
-
|
|
795
|
-
_subscribeMeta(client, pattern) {
|
|
796
|
-
this.handleSubscribe(client, 'meta', pattern);
|
|
797
|
-
}
|
|
798
720
|
// needed by server
|
|
799
721
|
_unsubscribeConfigForClient(client, pattern) {
|
|
800
722
|
this.handleUnsubscribe(client, 'objects', pattern); // ignore options => unsubscribe may everyone
|
|
801
723
|
}
|
|
802
|
-
|
|
724
|
+
// needed by server
|
|
725
|
+
_subscribeFileForClient(client, id, pattern) {
|
|
726
|
+
if (Array.isArray(pattern)) {
|
|
727
|
+
pattern.forEach(pattern => this.handleSubscribe(client, 'files', `${id}$%$${pattern}`));
|
|
728
|
+
}
|
|
729
|
+
else {
|
|
730
|
+
this.handleSubscribe(client, 'files', `${id}$%$${pattern}`);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
// needed by server
|
|
734
|
+
_unsubscribeFileForClient(client, id, pattern) {
|
|
735
|
+
if (Array.isArray(pattern)) {
|
|
736
|
+
pattern.forEach(pattern => this.handleUnsubscribe(client, 'files', `${id}$%$${pattern}`));
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
this.handleUnsubscribe(client, 'files', `${id}$%$${pattern}`);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
803
742
|
// needed by server
|
|
804
743
|
_getObject(id) {
|
|
805
744
|
return this.dataset[id];
|
|
806
745
|
}
|
|
807
|
-
|
|
808
746
|
// needed by server
|
|
809
747
|
_getKeys(pattern) {
|
|
810
748
|
const r = new RegExp(tools.pattern2RegEx(pattern));
|
|
@@ -812,16 +750,13 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
812
750
|
result.sort();
|
|
813
751
|
return result;
|
|
814
752
|
}
|
|
815
|
-
|
|
816
753
|
// needed by server
|
|
817
754
|
_getObjects(keys) {
|
|
818
755
|
if (!keys) {
|
|
819
756
|
throw new Error('no keys');
|
|
820
757
|
}
|
|
821
|
-
|
|
822
758
|
return keys.map(id => this.dataset[id]);
|
|
823
759
|
}
|
|
824
|
-
|
|
825
760
|
_ensureMetaDict() {
|
|
826
761
|
let meta = this.dataset['**META**'];
|
|
827
762
|
if (!meta) {
|
|
@@ -830,7 +765,6 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
830
765
|
}
|
|
831
766
|
return meta;
|
|
832
767
|
}
|
|
833
|
-
|
|
834
768
|
/**
|
|
835
769
|
* Get value of given meta id
|
|
836
770
|
*
|
|
@@ -841,7 +775,6 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
841
775
|
const meta = this._ensureMetaDict();
|
|
842
776
|
return meta[id];
|
|
843
777
|
}
|
|
844
|
-
|
|
845
778
|
/**
|
|
846
779
|
* Sets given value to id in metaNamespace
|
|
847
780
|
*
|
|
@@ -853,70 +786,54 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
853
786
|
meta[id] = value;
|
|
854
787
|
// Make sure the object gets re-written, especially when using an external DB
|
|
855
788
|
this.dataset['**META**'] = meta;
|
|
856
|
-
|
|
857
789
|
setImmediate(() => {
|
|
858
790
|
// publish event in states
|
|
859
791
|
this.log.silly(`${this.namespace} memory publish meta ${id} ${value}`);
|
|
860
792
|
this.publishAll('meta', id, value);
|
|
861
793
|
});
|
|
862
|
-
|
|
863
794
|
if (!this.stateTimer) {
|
|
864
795
|
this.stateTimer = setTimeout(() => this.saveState(), this.writeFileInterval);
|
|
865
796
|
}
|
|
866
797
|
}
|
|
867
|
-
|
|
868
798
|
// needed by server
|
|
869
799
|
_setObjectDirect(id, obj) {
|
|
870
800
|
this.dataset[id] = obj;
|
|
871
|
-
|
|
872
801
|
// object updated -> if type changed to meta -> cache
|
|
873
802
|
if (obj.type === 'meta' && this.existingMetaObjects[id] === false) {
|
|
874
803
|
this.existingMetaObjects[id] = true;
|
|
875
804
|
}
|
|
876
|
-
|
|
877
805
|
setImmediate(() => this.publishAll('objects', id, obj));
|
|
878
|
-
|
|
879
806
|
this.stateTimer = this.stateTimer || setTimeout(() => this.saveState(), this.writeFileInterval);
|
|
880
807
|
}
|
|
881
|
-
|
|
882
808
|
// needed by server
|
|
883
809
|
_delObject(id) {
|
|
884
810
|
const obj = this.dataset[id];
|
|
885
811
|
if (!obj) {
|
|
886
812
|
throw new Error(utils.ERRORS.ERROR_NOT_FOUND);
|
|
887
813
|
}
|
|
888
|
-
|
|
889
814
|
if (obj.common && obj.common.dontDelete) {
|
|
890
815
|
throw new Error('Object is marked as non deletable');
|
|
891
816
|
}
|
|
892
|
-
|
|
893
817
|
delete this.dataset[id];
|
|
894
|
-
|
|
895
818
|
// object has been deleted -> remove from cached meta if there
|
|
896
819
|
if (this.existingMetaObjects[id]) {
|
|
897
820
|
this.existingMetaObjects[id] = false;
|
|
898
821
|
}
|
|
899
|
-
|
|
900
822
|
setImmediate(() => this.publishAll('objects', id, null));
|
|
901
|
-
|
|
902
823
|
if (!this.stateTimer) {
|
|
903
824
|
this.stateTimer = setTimeout(() => this.saveState(), this.writeFileInterval);
|
|
904
825
|
}
|
|
905
826
|
}
|
|
906
|
-
|
|
907
827
|
// internal functionality
|
|
908
828
|
_applyView(func, params) {
|
|
909
829
|
const result = {
|
|
910
830
|
rows: []
|
|
911
831
|
};
|
|
912
|
-
|
|
913
832
|
// eslint-disable-next-line no-unused-vars
|
|
914
833
|
function _emit_(id, obj) {
|
|
915
834
|
result.rows.push({ id: id, value: obj });
|
|
916
835
|
}
|
|
917
|
-
|
|
918
836
|
const f = eval('(' + func.map.replace(/emit/g, '_emit_') + ')');
|
|
919
|
-
|
|
920
837
|
for (const id of Object.keys(this.dataset)) {
|
|
921
838
|
if (params) {
|
|
922
839
|
if (params.startkey && id < params.startkey) {
|
|
@@ -930,7 +847,8 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
930
847
|
if (obj) {
|
|
931
848
|
try {
|
|
932
849
|
f(obj);
|
|
933
|
-
}
|
|
850
|
+
}
|
|
851
|
+
catch (e) {
|
|
934
852
|
this.log.warn(`${this.namespace} Cannot execute map: ${e.message}`);
|
|
935
853
|
}
|
|
936
854
|
}
|
|
@@ -945,14 +863,13 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
945
863
|
}
|
|
946
864
|
if (max !== null) {
|
|
947
865
|
result.rows = [{ id: '_stats', value: { max: max } }];
|
|
948
|
-
}
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
949
868
|
result.rows = [];
|
|
950
869
|
}
|
|
951
870
|
}
|
|
952
|
-
|
|
953
871
|
return result;
|
|
954
872
|
}
|
|
955
|
-
|
|
956
873
|
// needed by server
|
|
957
874
|
_getObjectView(design, search, params) {
|
|
958
875
|
const designObj = this.dataset[`_design/${design}`];
|
|
@@ -966,11 +883,9 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
966
883
|
}
|
|
967
884
|
return this._applyView(designObj.views[search], params);
|
|
968
885
|
}
|
|
969
|
-
|
|
970
886
|
// Destructor of the class. Called by shutting down.
|
|
971
887
|
async destroy() {
|
|
972
888
|
await super.destroy();
|
|
973
|
-
|
|
974
889
|
this._saveFileSettings(true);
|
|
975
890
|
if (this.stateTimer) {
|
|
976
891
|
clearTimeout(this.stateTimer);
|
|
@@ -982,5 +897,5 @@ class ObjectsInMemoryFileDB extends InMemoryFileDB {
|
|
|
982
897
|
}
|
|
983
898
|
}
|
|
984
899
|
}
|
|
985
|
-
|
|
986
900
|
module.exports = ObjectsInMemoryFileDB;
|
|
901
|
+
//# sourceMappingURL=objectsInMemFileDB.js.map
|