cry-db 2.1.25 → 2.1.28
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/dist/base.js +33 -31
- package/dist/base.js.map +1 -1
- package/dist/db.js +14 -18
- package/dist/db.js.map +1 -1
- package/dist/index.js +6 -35
- package/dist/index.js.map +1 -1
- package/dist/mongo.js +233 -231
- package/dist/mongo.js.map +1 -1
- package/dist/repo.js +11 -16
- package/dist/repo.js.map +1 -1
- package/dist/types.js +1 -4
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/dist/mongo.js
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const mongodb_1 = require("mongodb");
|
|
10
|
-
const tiny_typed_emitter_1 = require("tiny-typed-emitter");
|
|
11
|
-
const _1 = require(".");
|
|
12
|
-
const db_1 = require("./db");
|
|
13
|
-
const types_1 = require("./types");
|
|
14
|
-
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import bcrypt from 'bcrypt';
|
|
3
|
+
import { ObjectId, ReadConcern, ReadPreference, Timestamp, WriteConcern } from 'mongodb';
|
|
4
|
+
import { TypedEmitter } from "tiny-typed-emitter";
|
|
5
|
+
import { Base } from '.';
|
|
6
|
+
import { Db, log } from './db';
|
|
7
|
+
import { SEQUENCES_COLLECTION } from './types';
|
|
8
|
+
import cloneDeep from "lodash.clonedeep";
|
|
15
9
|
const saltRounds = 10;
|
|
16
10
|
const TRANSACTION_OPTIONS = {
|
|
17
11
|
defaultTransactionOptions: {
|
|
18
|
-
readPreference: new
|
|
19
|
-
readConcern: new
|
|
20
|
-
writeConcern: new
|
|
12
|
+
readPreference: new ReadPreference("primary"),
|
|
13
|
+
readConcern: new ReadConcern("local"),
|
|
14
|
+
writeConcern: new WriteConcern("majority")
|
|
21
15
|
}
|
|
22
16
|
};
|
|
23
|
-
|
|
24
|
-
class Mongo extends
|
|
17
|
+
export const DummyExportToFixTsCompilation = true;
|
|
18
|
+
export default class Mongo extends Db {
|
|
19
|
+
revisions;
|
|
20
|
+
softdelete;
|
|
21
|
+
session;
|
|
22
|
+
emittingPublishEvents;
|
|
23
|
+
auditing;
|
|
24
|
+
auditCollectionName;
|
|
25
|
+
auditedCollections;
|
|
26
|
+
emitter;
|
|
27
|
+
user;
|
|
28
|
+
audit;
|
|
29
|
+
syncSupport;
|
|
25
30
|
constructor(db, url) {
|
|
26
31
|
super(db, url);
|
|
27
32
|
this.revisions = false;
|
|
@@ -32,30 +37,30 @@ class Mongo extends db_1.Db {
|
|
|
32
37
|
this.auditing = false;
|
|
33
38
|
this.auditCollectionName = "dblog";
|
|
34
39
|
this.auditedCollections = this.auditCollections(process.env.AUDIT_COLLECTIONS || []);
|
|
35
|
-
this.emitter = new
|
|
40
|
+
this.emitter = new TypedEmitter();
|
|
36
41
|
this.user = undefined;
|
|
37
42
|
this.audit = undefined;
|
|
38
|
-
|
|
43
|
+
log.debug('new Mongo:', this.url, this.db);
|
|
39
44
|
}
|
|
40
45
|
static newid() {
|
|
41
|
-
return
|
|
46
|
+
return Db.newid();
|
|
42
47
|
}
|
|
43
48
|
static toId(id) {
|
|
44
|
-
return
|
|
49
|
+
return Db.toId(id);
|
|
45
50
|
}
|
|
46
51
|
static objectid(o) {
|
|
47
|
-
return
|
|
52
|
+
return Db.objectid(o);
|
|
48
53
|
}
|
|
49
54
|
on(evt, listener) {
|
|
50
|
-
|
|
55
|
+
log.debug("on", evt, listener);
|
|
51
56
|
this.emitter.on(evt, listener);
|
|
52
57
|
}
|
|
53
58
|
off(evt, listener) {
|
|
54
|
-
|
|
59
|
+
log.debug("off", evt, listener);
|
|
55
60
|
this.emitter.off(evt, listener);
|
|
56
61
|
}
|
|
57
62
|
once(evt, listener) {
|
|
58
|
-
|
|
63
|
+
log.debug("off", evt, listener);
|
|
59
64
|
this.emitter.off(evt, listener);
|
|
60
65
|
}
|
|
61
66
|
setUser(username) {
|
|
@@ -125,29 +130,29 @@ class Mongo extends db_1.Db {
|
|
|
125
130
|
return this.emittingPublishEvents;
|
|
126
131
|
}
|
|
127
132
|
async distinct(collection, field) {
|
|
128
|
-
|
|
133
|
+
log.debug('distinct called', collection, field);
|
|
129
134
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
130
135
|
return await conn.distinct(field);
|
|
131
136
|
}, false, { operation: "distinct", collection, field });
|
|
132
|
-
|
|
137
|
+
log.debug('distinct returns', ret);
|
|
133
138
|
return ret;
|
|
134
139
|
}
|
|
135
140
|
async count(collection, query = {}, opts = {}) {
|
|
136
|
-
|
|
141
|
+
log.debug('distinct called', collection, query, opts);
|
|
137
142
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
138
143
|
return await conn.countDocuments(query, opts);
|
|
139
144
|
}, false, { operation: "count", collection, query, opts });
|
|
140
|
-
|
|
145
|
+
log.debug('count returns', ret);
|
|
141
146
|
return ret;
|
|
142
147
|
}
|
|
143
148
|
async find(collection, query = {}, opts = {}) {
|
|
144
|
-
(
|
|
149
|
+
assert(collection);
|
|
145
150
|
query = this.replaceIds(query);
|
|
146
151
|
if (this.softdelete) {
|
|
147
152
|
if (!query._deleted)
|
|
148
153
|
query._deleted = { $exists: false };
|
|
149
154
|
}
|
|
150
|
-
|
|
155
|
+
log.debug('find called', collection, query, opts);
|
|
151
156
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
152
157
|
let optsIn = {};
|
|
153
158
|
if (opts.readPreference)
|
|
@@ -168,11 +173,11 @@ class Mongo extends db_1.Db {
|
|
|
168
173
|
let res = await r.toArray();
|
|
169
174
|
return this._processReturnedObject(res);
|
|
170
175
|
}, false, { operation: "find", collection, query, opts });
|
|
171
|
-
|
|
176
|
+
log.debug('find returns', ret);
|
|
172
177
|
return ret;
|
|
173
178
|
}
|
|
174
179
|
async findAll(collection, query = {}, opts = {}) {
|
|
175
|
-
(
|
|
180
|
+
assert(collection);
|
|
176
181
|
query = this.replaceIds(query);
|
|
177
182
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
178
183
|
let optsIn = {};
|
|
@@ -193,12 +198,12 @@ class Mongo extends db_1.Db {
|
|
|
193
198
|
r = r.collation(opts.collation);
|
|
194
199
|
return this._processReturnedObject(await r.toArray());
|
|
195
200
|
}, false, { operation: "findAll", collection, query, opts });
|
|
196
|
-
|
|
201
|
+
log.debug('findAll returns', ret);
|
|
197
202
|
return ret;
|
|
198
203
|
}
|
|
199
204
|
async findNewer(collection, timestamp, query = {}, opts = {}) {
|
|
200
205
|
query = this._createQueryForNewer(timestamp, query);
|
|
201
|
-
|
|
206
|
+
log.debug('findNewer called', collection, timestamp, query, opts);
|
|
202
207
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
203
208
|
let optsIn = {};
|
|
204
209
|
if (opts.readPreference)
|
|
@@ -220,11 +225,11 @@ class Mongo extends db_1.Db {
|
|
|
220
225
|
r = r.collation(opts.collation);
|
|
221
226
|
return this._processReturnedObject(await r.toArray());
|
|
222
227
|
}, false, { operation: "findNewer", collection, timestamp, query, opts });
|
|
223
|
-
|
|
228
|
+
log.debug('findNewer returns', ret);
|
|
224
229
|
return ret;
|
|
225
230
|
}
|
|
226
231
|
async findNewerMany(spec = []) {
|
|
227
|
-
|
|
232
|
+
log.debug('findNewerMany called', spec);
|
|
228
233
|
let conn = await this.connect();
|
|
229
234
|
const getOneColl = async (coll) => {
|
|
230
235
|
let query = this._createQueryForNewer(coll.timestamp, coll.query);
|
|
@@ -257,7 +262,7 @@ class Mongo extends db_1.Db {
|
|
|
257
262
|
_createQueryForNewer(timestamp, query) {
|
|
258
263
|
let ts = (timestamp === 1 || timestamp === "1" || timestamp === "0" || timestamp === 0)
|
|
259
264
|
? {}
|
|
260
|
-
: { _ts: { $gt:
|
|
265
|
+
: { _ts: { $gt: Base.timestamp(timestamp) } };
|
|
261
266
|
query = {
|
|
262
267
|
...ts,
|
|
263
268
|
...(query || {}),
|
|
@@ -267,7 +272,7 @@ class Mongo extends db_1.Db {
|
|
|
267
272
|
}
|
|
268
273
|
async findAfter(collection, csq, query = {}, opts = {}) {
|
|
269
274
|
query._csq = { $gt: csq };
|
|
270
|
-
|
|
275
|
+
log.debug('findAfter called', collection, csq, query, opts);
|
|
271
276
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
272
277
|
let optsIn = {};
|
|
273
278
|
if (opts.readPreference)
|
|
@@ -289,11 +294,11 @@ class Mongo extends db_1.Db {
|
|
|
289
294
|
r = r.collation(opts.collation);
|
|
290
295
|
return this._processReturnedObject(await r.toArray());
|
|
291
296
|
}, false, { operation: "findNewer", collection, csq, query, opts });
|
|
292
|
-
|
|
297
|
+
log.debug('findNewer returns', ret);
|
|
293
298
|
return ret;
|
|
294
299
|
}
|
|
295
300
|
async findAfterMany(spec = []) {
|
|
296
|
-
|
|
301
|
+
log.debug('findAfterMany called', spec);
|
|
297
302
|
let conn = await this.connect();
|
|
298
303
|
const getOneColl = async (coll) => {
|
|
299
304
|
let r = conn
|
|
@@ -325,48 +330,48 @@ class Mongo extends db_1.Db {
|
|
|
325
330
|
return out;
|
|
326
331
|
}
|
|
327
332
|
async findNewerFromDate(collection, date, query = {}, opts = {}) {
|
|
328
|
-
let ts = new
|
|
329
|
-
|
|
333
|
+
let ts = new Timestamp(0, new Date(date).valueOf() / 1000);
|
|
334
|
+
log.debug('findNewerFromDate called', collection, date, query, opts);
|
|
330
335
|
let ret = await Mongo.prototype.findNewer.call(this, collection, ts, query, opts); // prevent calling Repo.findNewer
|
|
331
|
-
|
|
336
|
+
log.debug('findNewerFromDate returns', ret);
|
|
332
337
|
return ret;
|
|
333
338
|
}
|
|
334
339
|
async findOne(collection, query, projection) {
|
|
335
|
-
(
|
|
336
|
-
(
|
|
340
|
+
assert(collection);
|
|
341
|
+
assert(query);
|
|
337
342
|
query = this.replaceIds(query);
|
|
338
343
|
if (!query._deleted)
|
|
339
344
|
query._deleted = { $exists: false };
|
|
340
345
|
// if (!query._blocked) query._blocked = { $exists: false }; // intentionally - blocked records are returned
|
|
341
|
-
|
|
346
|
+
log.debug('findOne called', collection, query, projection);
|
|
342
347
|
let ret = await this.executeTransactionally(collection, async (conn) => await conn.findOne(query, { projection, session: this.session }), false, { operation: "findOne", collection, query, projection });
|
|
343
|
-
|
|
348
|
+
log.debug('findOne returns', ret);
|
|
344
349
|
return this._processReturnedObject(ret);
|
|
345
350
|
}
|
|
346
351
|
async findById(collection, id, projection) {
|
|
347
|
-
(
|
|
348
|
-
(
|
|
352
|
+
assert(collection);
|
|
353
|
+
assert(id);
|
|
349
354
|
if (!id)
|
|
350
355
|
return null;
|
|
351
356
|
let query = {
|
|
352
357
|
_id: Mongo._toId(id),
|
|
353
358
|
// _deleted: { $exists: false }
|
|
354
359
|
};
|
|
355
|
-
|
|
356
|
-
|
|
360
|
+
log.debug('findById called', this.db, collection, id, projection);
|
|
361
|
+
log.trace('findById executing with query', collection, query, projection);
|
|
357
362
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
358
363
|
let r = await conn.findOne(query, { projection, session: this.session });
|
|
359
364
|
return r;
|
|
360
365
|
}, false, { operation: "findById", collection, id, projection });
|
|
361
|
-
if (ret
|
|
366
|
+
if (ret?._deleted)
|
|
362
367
|
ret = null;
|
|
363
|
-
|
|
368
|
+
log.debug('findById returns', ret);
|
|
364
369
|
return this._processReturnedObject(ret);
|
|
365
370
|
}
|
|
366
371
|
async updateOne(collection, query, update, options = { returnFullObject: false }) {
|
|
367
|
-
(
|
|
368
|
-
(
|
|
369
|
-
(
|
|
372
|
+
assert(collection);
|
|
373
|
+
assert(query);
|
|
374
|
+
assert(update);
|
|
370
375
|
query = this.replaceIds(query);
|
|
371
376
|
update = this.replaceIds(update);
|
|
372
377
|
let opts = {
|
|
@@ -375,7 +380,7 @@ class Mongo extends db_1.Db {
|
|
|
375
380
|
session: this.session,
|
|
376
381
|
};
|
|
377
382
|
update = await this._processUpdateObject(update);
|
|
378
|
-
|
|
383
|
+
log.debug('updateOne called', collection, query, update);
|
|
379
384
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
380
385
|
let obj = await this.executeTransactionally(collection, async (conn, client) => {
|
|
381
386
|
update.$set = update.$set || {};
|
|
@@ -386,16 +391,16 @@ class Mongo extends db_1.Db {
|
|
|
386
391
|
let res = await conn.findOneAndUpdate(query, update, opts);
|
|
387
392
|
if (!res.value)
|
|
388
393
|
return null;
|
|
389
|
-
let resObj = this._removeUnchanged(res.value, update, !!
|
|
394
|
+
let resObj = this._removeUnchanged(res.value, update, !!options?.returnFullObject);
|
|
390
395
|
await this._publishAndAudit('update', this.db, collection, resObj);
|
|
391
396
|
return resObj;
|
|
392
397
|
}, !!seqKeys, { operation: "updateOne", collection, query, update, options });
|
|
393
|
-
|
|
398
|
+
log.debug('updateOne returns', obj);
|
|
394
399
|
return this._processReturnedObject(await obj);
|
|
395
400
|
}
|
|
396
401
|
async save(collection, update, id = undefined, options = { returnFullObject: false }) {
|
|
397
|
-
(
|
|
398
|
-
(
|
|
402
|
+
assert(collection);
|
|
403
|
+
assert(update);
|
|
399
404
|
update = this.replaceIds(update);
|
|
400
405
|
let opts = {
|
|
401
406
|
upsert: true,
|
|
@@ -404,7 +409,7 @@ class Mongo extends db_1.Db {
|
|
|
404
409
|
};
|
|
405
410
|
let _id = Mongo.toId(id || update._id) || Mongo.newid();
|
|
406
411
|
update = await this._processUpdateObject(update);
|
|
407
|
-
|
|
412
|
+
log.debug('save called', collection, id, update);
|
|
408
413
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
409
414
|
let obj = await this.executeTransactionally(collection, async (conn, client) => {
|
|
410
415
|
update.$set = update.$set || {};
|
|
@@ -415,19 +420,19 @@ class Mongo extends db_1.Db {
|
|
|
415
420
|
let res = await conn.findOneAndUpdate({ _id }, update, opts);
|
|
416
421
|
if (!res.value)
|
|
417
422
|
return null;
|
|
418
|
-
let resObj = this._removeUnchanged(res.value, update, !!
|
|
423
|
+
let resObj = this._removeUnchanged(res.value, update, !!options?.returnFullObject);
|
|
419
424
|
await this._publishAndAudit('update', this.db, collection, resObj);
|
|
420
425
|
return resObj;
|
|
421
426
|
}, !!seqKeys, { operation: "save", collection, _id, update, options });
|
|
422
|
-
|
|
427
|
+
log.debug('save returns', obj);
|
|
423
428
|
return this._processReturnedObject(await obj);
|
|
424
429
|
}
|
|
425
430
|
async update(collection, query, update) {
|
|
426
|
-
(
|
|
427
|
-
(
|
|
428
|
-
(
|
|
431
|
+
assert(collection);
|
|
432
|
+
assert(query);
|
|
433
|
+
assert(update);
|
|
429
434
|
if (this.syncSupport)
|
|
430
|
-
|
|
435
|
+
log.warn("update does not increase _csq, avoit it.");
|
|
431
436
|
if (!Object.keys(update).length)
|
|
432
437
|
return { n: 0, ok: false };
|
|
433
438
|
query = this.replaceIds(query);
|
|
@@ -438,7 +443,7 @@ class Mongo extends db_1.Db {
|
|
|
438
443
|
session: this.session,
|
|
439
444
|
};
|
|
440
445
|
update = await this._processUpdateObject(update);
|
|
441
|
-
|
|
446
|
+
log.debug('update called', collection, query, update);
|
|
442
447
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
443
448
|
let obj = await this.executeTransactionally(collection, async (conn, client) => {
|
|
444
449
|
update.$set = update.$set || {};
|
|
@@ -446,7 +451,7 @@ class Mongo extends db_1.Db {
|
|
|
446
451
|
await this._processSequenceField(client, collection, update.$set, seqKeys);
|
|
447
452
|
if (update.$set === undefined || Object.keys(update.$set).length === 0)
|
|
448
453
|
delete update.$set;
|
|
449
|
-
|
|
454
|
+
log.debug('update called', collection, query, update);
|
|
450
455
|
let res = await conn.updateMany(query, update, opts);
|
|
451
456
|
let resObj = {
|
|
452
457
|
n: res.modifiedCount,
|
|
@@ -455,14 +460,14 @@ class Mongo extends db_1.Db {
|
|
|
455
460
|
await this._publishAndAudit('updateMany', this.db, collection, resObj);
|
|
456
461
|
return resObj;
|
|
457
462
|
}, !!seqKeys, { operation: "update", collection, query, update });
|
|
458
|
-
|
|
463
|
+
log.debug('update returns', obj);
|
|
459
464
|
return await obj;
|
|
460
465
|
}
|
|
461
466
|
async upsert(collection, query, update, options = { returnFullObject: false }) {
|
|
462
|
-
(
|
|
463
|
-
(
|
|
464
|
-
(
|
|
465
|
-
(
|
|
467
|
+
assert(collection);
|
|
468
|
+
assert(query);
|
|
469
|
+
assert(update);
|
|
470
|
+
assert(typeof update === 'object', 'update must be an object');
|
|
466
471
|
// if (!Object.keys(update).length) return null;
|
|
467
472
|
query = this.replaceIds(query);
|
|
468
473
|
update = this.replaceIds(update);
|
|
@@ -472,14 +477,13 @@ class Mongo extends db_1.Db {
|
|
|
472
477
|
returnDocument: "after",
|
|
473
478
|
session: this.session,
|
|
474
479
|
};
|
|
475
|
-
|
|
480
|
+
log.debug('upsert called', collection, query, update);
|
|
476
481
|
update = await this._processUpdateObject(update);
|
|
477
482
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
478
|
-
|
|
483
|
+
log.debug('upsert processed', collection, query, update);
|
|
479
484
|
if (Object.keys(query).length === 0)
|
|
480
485
|
query._id = Mongo.newid();
|
|
481
486
|
let ret = await this.executeTransactionally(collection, async (conn, client) => {
|
|
482
|
-
var _a;
|
|
483
487
|
update.$set = update.$set || {};
|
|
484
488
|
if (seqKeys)
|
|
485
489
|
await this._processSequenceField(client, collection, update.$set, seqKeys);
|
|
@@ -487,26 +491,26 @@ class Mongo extends db_1.Db {
|
|
|
487
491
|
delete update.$set;
|
|
488
492
|
let ret = await conn.findOneAndUpdate(query, update, opts);
|
|
489
493
|
if (ret.value) {
|
|
490
|
-
let oper =
|
|
491
|
-
let retObj = oper === "insert" ? ret.value : this._removeUnchanged(ret.value, update, !!
|
|
494
|
+
let oper = ret.lastErrorObject?.updatedExisting ? "update" : "insert";
|
|
495
|
+
let retObj = oper === "insert" ? ret.value : this._removeUnchanged(ret.value, update, !!options?.returnFullObject);
|
|
492
496
|
await this._publishAndAudit(oper, this.db, collection, retObj);
|
|
493
497
|
return retObj;
|
|
494
498
|
}
|
|
495
499
|
;
|
|
496
500
|
return ret;
|
|
497
501
|
}, !!seqKeys, { operation: "upsert", query, update, options });
|
|
498
|
-
|
|
502
|
+
log.debug('upsert returns', ret);
|
|
499
503
|
return this._processReturnedObject(await ret);
|
|
500
504
|
}
|
|
501
505
|
async insert(collection, insert) {
|
|
502
|
-
(
|
|
503
|
-
(
|
|
504
|
-
(
|
|
505
|
-
|
|
506
|
+
assert(collection, "collection can't be null");
|
|
507
|
+
assert(insert, "insert can't be null");
|
|
508
|
+
assert(typeof insert === "object", "insert must be an object");
|
|
509
|
+
log.debug('insert called', collection, insert);
|
|
506
510
|
insert = this.replaceIds(insert);
|
|
507
511
|
if (this.revisions) {
|
|
508
512
|
insert._rev = 1;
|
|
509
|
-
insert._ts =
|
|
513
|
+
insert._ts = Base.timestamp();
|
|
510
514
|
}
|
|
511
515
|
await this._processHashedKeys(insert);
|
|
512
516
|
let seqKeys = this._findSequenceKeys(insert);
|
|
@@ -518,19 +522,18 @@ class Mongo extends db_1.Db {
|
|
|
518
522
|
await this._publishAndAudit('insert', this.db, collection, fullObj);
|
|
519
523
|
return fullObj;
|
|
520
524
|
}, !!seqKeys, { operation: "insert", collection, insert });
|
|
521
|
-
|
|
525
|
+
log.debug('insert returns', ret);
|
|
522
526
|
return this._processReturnedObject(await ret);
|
|
523
527
|
}
|
|
524
528
|
async upsertBatch(collection, batch) {
|
|
525
|
-
(
|
|
526
|
-
(
|
|
527
|
-
(
|
|
528
|
-
|
|
529
|
+
assert(collection, "collection can't be null");
|
|
530
|
+
assert(batch, "batch can't be null");
|
|
531
|
+
assert(batch instanceof Array, "batch must be an Array");
|
|
532
|
+
log.debug('upsertBatch called', collection, batch);
|
|
529
533
|
batch = this.replaceIds(batch);
|
|
530
534
|
for (let i = 0; i < batch.length; i++)
|
|
531
535
|
await this._processHashedKeys(batch[i].update);
|
|
532
536
|
let ret = await this.executeTransactionally(collection, async (conn, client) => {
|
|
533
|
-
var _a, _b;
|
|
534
537
|
await this._processSequenceFieldForMany(client, collection, batch.map(b => b.update));
|
|
535
538
|
let publications = [];
|
|
536
539
|
let changes = [];
|
|
@@ -544,9 +547,9 @@ class Mongo extends db_1.Db {
|
|
|
544
547
|
};
|
|
545
548
|
update = await this._processUpdateObject(update);
|
|
546
549
|
let ret = (await conn.findOneAndUpdate(query, update, options));
|
|
547
|
-
if (
|
|
548
|
-
let oper =
|
|
549
|
-
let retObj = oper === "insert" ? ret.value : this._removeUnchanged(ret.value, update, !!
|
|
550
|
+
if (ret?.value?._id) {
|
|
551
|
+
let oper = ret.lastErrorObject?.updatedExisting ? "update" : "insert";
|
|
552
|
+
let retObj = oper === "insert" ? ret.value : this._removeUnchanged(ret.value, update, !!opts?.returnFullObject);
|
|
550
553
|
publications.push(await this._publishAndAudit(oper, this.db, collection, retObj, true));
|
|
551
554
|
changes.push(retObj);
|
|
552
555
|
}
|
|
@@ -559,25 +562,25 @@ class Mongo extends db_1.Db {
|
|
|
559
562
|
operation: "batch",
|
|
560
563
|
db: this.db,
|
|
561
564
|
collection,
|
|
562
|
-
data: publications.map(p => p
|
|
565
|
+
data: publications.map(p => p?.payload).filter(p => !!p)
|
|
563
566
|
}
|
|
564
567
|
});
|
|
565
568
|
}
|
|
566
569
|
return changes;
|
|
567
570
|
}, false, { operation: "upsertBatch", collection, batch });
|
|
568
|
-
|
|
571
|
+
log.debug('upsertBatch returns', ret);
|
|
569
572
|
return ret;
|
|
570
573
|
}
|
|
571
574
|
async insertMany(collection, insert) {
|
|
572
|
-
(
|
|
573
|
-
(
|
|
574
|
-
(
|
|
575
|
-
|
|
575
|
+
assert(collection, "collection can't be null");
|
|
576
|
+
assert(insert, "insert can't be null");
|
|
577
|
+
assert(insert instanceof Array, "insert must be an Array");
|
|
578
|
+
log.debug('insertMany called', collection, insert);
|
|
576
579
|
insert = this.replaceIds(insert);
|
|
577
580
|
for (let i = 0; i < insert.length; i++)
|
|
578
581
|
await this._processHashedKeys(insert[i]);
|
|
579
582
|
if (this.revisions)
|
|
580
|
-
insert.forEach(ins => { ins._rev = 1; ins._ts =
|
|
583
|
+
insert.forEach(ins => { ins._rev = 1; ins._ts = Base.timestamp(); });
|
|
581
584
|
let ret = await this.executeTransactionally(collection, async (conn, client) => {
|
|
582
585
|
await this._processSequenceFieldForMany(client, collection, insert);
|
|
583
586
|
let obj = await conn.insertMany(insert, { session: this.session });
|
|
@@ -597,26 +600,26 @@ class Mongo extends db_1.Db {
|
|
|
597
600
|
}
|
|
598
601
|
return ret;
|
|
599
602
|
}, false, { operation: "insertMany", collection, insert });
|
|
600
|
-
|
|
603
|
+
log.debug('insertMany returns', ret);
|
|
601
604
|
return ret;
|
|
602
605
|
}
|
|
603
606
|
async deleteOne(collection, query) {
|
|
604
|
-
(
|
|
605
|
-
(
|
|
607
|
+
assert(collection);
|
|
608
|
+
assert(query);
|
|
606
609
|
query = this.replaceIds(query);
|
|
607
610
|
if (!this.softdelete) {
|
|
608
611
|
let opts = {
|
|
609
612
|
returnDocument: "after",
|
|
610
613
|
session: this.session,
|
|
611
614
|
};
|
|
612
|
-
|
|
615
|
+
log.debug('deleteOne called', collection, query);
|
|
613
616
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
614
617
|
let obj = await conn.findOneAndDelete(query, opts);
|
|
615
618
|
if (obj.value)
|
|
616
619
|
await this._publishAndAudit('delete', this.db, collection, obj.value);
|
|
617
620
|
return obj.value;
|
|
618
621
|
}, false, { operation: "deleteOne", collection, query, softdelete: this.softdelete });
|
|
619
|
-
|
|
622
|
+
log.debug('deleteOne returns', ret);
|
|
620
623
|
return ret;
|
|
621
624
|
}
|
|
622
625
|
else {
|
|
@@ -625,7 +628,7 @@ class Mongo extends db_1.Db {
|
|
|
625
628
|
returnDocument: "after",
|
|
626
629
|
session: this.session,
|
|
627
630
|
};
|
|
628
|
-
|
|
631
|
+
log.debug('deleteOne called', collection, query);
|
|
629
632
|
let ret = await this.executeTransactionally(collection, async (conn, client) => {
|
|
630
633
|
let del = {
|
|
631
634
|
$set: { _deleted: new Date() },
|
|
@@ -639,7 +642,7 @@ class Mongo extends db_1.Db {
|
|
|
639
642
|
await this._publishAndAudit('delete', this.db, collection, obj.value);
|
|
640
643
|
return obj.value;
|
|
641
644
|
}, false, { operation: "deleteOne", collection, query, softdelete: this.softdelete });
|
|
642
|
-
|
|
645
|
+
log.debug('deleteOne returns', ret);
|
|
643
646
|
return ret;
|
|
644
647
|
}
|
|
645
648
|
}
|
|
@@ -650,7 +653,7 @@ class Mongo extends db_1.Db {
|
|
|
650
653
|
session: this.session,
|
|
651
654
|
};
|
|
652
655
|
query = this.replaceIds(query);
|
|
653
|
-
|
|
656
|
+
log.debug('blockOne called', collection, query);
|
|
654
657
|
let ret = await this.executeTransactionally(collection, async (conn, client) => {
|
|
655
658
|
query._blocked = { $exists: 0 };
|
|
656
659
|
let update = {
|
|
@@ -672,7 +675,7 @@ class Mongo extends db_1.Db {
|
|
|
672
675
|
await this._publishAndAudit('block', this.db, collection, retObj);
|
|
673
676
|
return retObj;
|
|
674
677
|
}, false, { operation: "blockOne", collection, query });
|
|
675
|
-
|
|
678
|
+
log.debug('blockOne returns', ret);
|
|
676
679
|
return ret;
|
|
677
680
|
}
|
|
678
681
|
async unblockOne(collection, query) {
|
|
@@ -682,7 +685,7 @@ class Mongo extends db_1.Db {
|
|
|
682
685
|
session: this.session,
|
|
683
686
|
};
|
|
684
687
|
query = this.replaceIds(query);
|
|
685
|
-
|
|
688
|
+
log.debug('unblockOne called', collection, query);
|
|
686
689
|
let ret = await this.executeTransactionally(collection, async (conn, client) => {
|
|
687
690
|
query._blocked = { $exists: 1 };
|
|
688
691
|
let update = {
|
|
@@ -703,18 +706,18 @@ class Mongo extends db_1.Db {
|
|
|
703
706
|
await this._publishAndAudit('unblock', this.db, collection, retObj);
|
|
704
707
|
return retObj;
|
|
705
708
|
}, false, { operation: "unblockOne", collection, query });
|
|
706
|
-
|
|
709
|
+
log.debug('unblockOne returns', ret);
|
|
707
710
|
return ret;
|
|
708
711
|
}
|
|
709
712
|
async hardDeleteOne(collection, query) {
|
|
710
|
-
(
|
|
711
|
-
(
|
|
713
|
+
assert(collection);
|
|
714
|
+
assert(query);
|
|
712
715
|
query = this.replaceIds(query);
|
|
713
716
|
let opts = {
|
|
714
717
|
returnDocument: "after",
|
|
715
718
|
session: this.session,
|
|
716
719
|
};
|
|
717
|
-
|
|
720
|
+
log.debug('hardDeleteOne called', collection, query);
|
|
718
721
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
719
722
|
let obj = await conn.findOneAndDelete(query, opts);
|
|
720
723
|
if (obj.value) {
|
|
@@ -722,21 +725,21 @@ class Mongo extends db_1.Db {
|
|
|
722
725
|
}
|
|
723
726
|
return obj.value;
|
|
724
727
|
}, false, { operation: "hardDeleteOne", collection, query });
|
|
725
|
-
|
|
728
|
+
log.debug('hardDeleteOne returns', ret);
|
|
726
729
|
return ret;
|
|
727
730
|
}
|
|
728
731
|
async delete(collection, query) {
|
|
729
|
-
(
|
|
730
|
-
(
|
|
732
|
+
assert(collection);
|
|
733
|
+
assert(query);
|
|
731
734
|
if (this.syncSupport)
|
|
732
|
-
|
|
735
|
+
log.warn("delete does not increase _csq, avoit it.");
|
|
733
736
|
query = this.replaceIds(query);
|
|
734
737
|
if (!this.softdelete) {
|
|
735
738
|
let opts = {
|
|
736
739
|
returnDocument: "after",
|
|
737
740
|
session: this.session,
|
|
738
741
|
};
|
|
739
|
-
|
|
742
|
+
log.debug('delete called', collection, query);
|
|
740
743
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
741
744
|
let obj = await conn.deleteMany(query, opts);
|
|
742
745
|
let resObj = {
|
|
@@ -746,7 +749,7 @@ class Mongo extends db_1.Db {
|
|
|
746
749
|
await this._publishAndAudit('deleteMany', this.db, collection, resObj);
|
|
747
750
|
return resObj;
|
|
748
751
|
}, false, { operation: "delete", collection, query, softdelete: this.softdelete });
|
|
749
|
-
|
|
752
|
+
log.debug('delete returns', ret);
|
|
750
753
|
return ret;
|
|
751
754
|
}
|
|
752
755
|
else {
|
|
@@ -756,7 +759,7 @@ class Mongo extends db_1.Db {
|
|
|
756
759
|
session: this.session,
|
|
757
760
|
};
|
|
758
761
|
let date = new Date();
|
|
759
|
-
|
|
762
|
+
log.debug('delete called', collection, query);
|
|
760
763
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
761
764
|
let obj = await conn.updateMany(query, { $set: { _deleted: date } }, opts);
|
|
762
765
|
let resObj = {
|
|
@@ -766,21 +769,21 @@ class Mongo extends db_1.Db {
|
|
|
766
769
|
await this._publishAndAudit('deleteMany', this.db, collection, resObj);
|
|
767
770
|
return resObj;
|
|
768
771
|
}, false, { operation: "delete", collection, query, softdelete: this.softdelete });
|
|
769
|
-
|
|
772
|
+
log.debug('delete returns', ret);
|
|
770
773
|
return ret;
|
|
771
774
|
}
|
|
772
775
|
}
|
|
773
776
|
async hardDelete(collection, query) {
|
|
774
|
-
(
|
|
775
|
-
(
|
|
777
|
+
assert(collection);
|
|
778
|
+
assert(query);
|
|
776
779
|
if (this.syncSupport)
|
|
777
|
-
|
|
780
|
+
log.warn("hardDelete does not increase _csq, avoit it.");
|
|
778
781
|
query = this.replaceIds(query);
|
|
779
782
|
let opts = {
|
|
780
783
|
returnDocument: "after",
|
|
781
784
|
session: this.session,
|
|
782
785
|
};
|
|
783
|
-
|
|
786
|
+
log.debug('hardDelete called', collection, query);
|
|
784
787
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
785
788
|
let obj = await conn.deleteMany(query, opts);
|
|
786
789
|
let resObj = {
|
|
@@ -790,12 +793,12 @@ class Mongo extends db_1.Db {
|
|
|
790
793
|
await this._publishAndAudit('deleteMany', this.db, collection, resObj);
|
|
791
794
|
return resObj;
|
|
792
795
|
}, false, { operation: "hardDelete", collection, query, softdelete: this.softdelete });
|
|
793
|
-
|
|
796
|
+
log.debug('hardDelete returns', ret);
|
|
794
797
|
return ret;
|
|
795
798
|
}
|
|
796
799
|
async testHash(collection, query, field, unhashedValue) {
|
|
797
800
|
let _field;
|
|
798
|
-
|
|
801
|
+
log.debug('teshHash called', collection, query, field, unhashedValue);
|
|
799
802
|
if (typeof field === "object") {
|
|
800
803
|
if (Object.keys(field).length === 1)
|
|
801
804
|
[_field, unhashedValue] = Object.entries(field)[0];
|
|
@@ -809,19 +812,19 @@ class Mongo extends db_1.Db {
|
|
|
809
812
|
let conn = await this.connect();
|
|
810
813
|
let obj = await conn.db(this.db).collection(collection).findOne(query, { projection: { [_field]: 1 }, session: this.session });
|
|
811
814
|
if (!obj || !obj[_field]) {
|
|
812
|
-
|
|
815
|
+
log.debug('teshHash returns false', obj);
|
|
813
816
|
return false;
|
|
814
817
|
}
|
|
815
|
-
let res = await
|
|
816
|
-
|
|
818
|
+
let res = await bcrypt.compare(unhashedValue, obj[_field].hash);
|
|
819
|
+
log.debug('teshHash returns', res);
|
|
817
820
|
return res;
|
|
818
821
|
}
|
|
819
822
|
async aggregate(collection, pipeline, opts = {
|
|
820
|
-
readPreference:
|
|
823
|
+
readPreference: ReadPreference.SECONDARY_PREFERRED,
|
|
821
824
|
}) {
|
|
822
|
-
(
|
|
823
|
-
(
|
|
824
|
-
|
|
825
|
+
assert(collection);
|
|
826
|
+
assert(pipeline instanceof Array);
|
|
827
|
+
log.debug('aggregate called', collection, pipeline);
|
|
825
828
|
pipeline = this.replaceIds(pipeline);
|
|
826
829
|
if (this.session)
|
|
827
830
|
opts.session = this.session;
|
|
@@ -829,15 +832,15 @@ class Mongo extends db_1.Db {
|
|
|
829
832
|
let res = await conn.aggregate(pipeline, opts).toArray();
|
|
830
833
|
return res;
|
|
831
834
|
}, false, { operation: "aggregate", collection, pipeline, opts });
|
|
832
|
-
|
|
835
|
+
log.debug('aggregare returns', ret);
|
|
833
836
|
return ret;
|
|
834
837
|
}
|
|
835
838
|
async isUnique(collection, field, value, id) {
|
|
836
|
-
(
|
|
837
|
-
(
|
|
838
|
-
(
|
|
839
|
-
|
|
840
|
-
let _id = id
|
|
839
|
+
assert(collection);
|
|
840
|
+
assert(field);
|
|
841
|
+
assert(value);
|
|
842
|
+
log.debug('isUnuqie called', collection, field, value, id);
|
|
843
|
+
let _id = id?.toString();
|
|
841
844
|
let matches = await this.executeTransactionally(collection, async (conn) => {
|
|
842
845
|
let agg = await conn.find({ [field]: value });
|
|
843
846
|
let res = await agg.toArray();
|
|
@@ -850,13 +853,13 @@ class Mongo extends db_1.Db {
|
|
|
850
853
|
return false;
|
|
851
854
|
}
|
|
852
855
|
}
|
|
853
|
-
|
|
856
|
+
log.debug('isUnuqie returns', ret);
|
|
854
857
|
return ret;
|
|
855
858
|
}
|
|
856
859
|
async collectFieldValues(collection, field, inArray = false, opts) {
|
|
857
|
-
(
|
|
858
|
-
(
|
|
859
|
-
|
|
860
|
+
assert(collection);
|
|
861
|
+
assert(field);
|
|
862
|
+
log.debug('collectFieldValues called', collection, field);
|
|
860
863
|
let pipeline = [
|
|
861
864
|
{ $group: { _id: '$' + field } },
|
|
862
865
|
{ $sort: { _id: 1 } }
|
|
@@ -871,33 +874,33 @@ class Mongo extends db_1.Db {
|
|
|
871
874
|
let res = await agg.toArray();
|
|
872
875
|
return res;
|
|
873
876
|
}, false, { operation: "collectFieldValues", collection, field, inArray, pipeline, opts });
|
|
874
|
-
let ret = res
|
|
875
|
-
|
|
877
|
+
let ret = res?.map((v) => v._id);
|
|
878
|
+
log.debug('collectFieldValues returns', ret);
|
|
876
879
|
return ret;
|
|
877
880
|
}
|
|
878
881
|
async dropCollection(collection) {
|
|
879
|
-
(
|
|
880
|
-
|
|
882
|
+
assert(collection);
|
|
883
|
+
log.debug('dropCollection called', this.auditCollections);
|
|
881
884
|
let client = await this.connect();
|
|
882
885
|
let existing = await client.db(this.db).collections();
|
|
883
886
|
if (existing.map((c) => c.s.name).includes(collection)) {
|
|
884
887
|
await client.db(this.db).dropCollection(collection);
|
|
885
888
|
}
|
|
886
|
-
|
|
889
|
+
log.debug('dropCollection returns');
|
|
887
890
|
}
|
|
888
891
|
async resetCollectionSync(collection) {
|
|
889
|
-
(
|
|
890
|
-
|
|
892
|
+
assert(collection);
|
|
893
|
+
log.debug('resetCollectionSync called for', collection);
|
|
891
894
|
let client = await this.connect();
|
|
892
895
|
await client.db(this.db)
|
|
893
|
-
.collection(
|
|
896
|
+
.collection(SEQUENCES_COLLECTION)
|
|
894
897
|
.findOneAndDelete({ collection });
|
|
895
|
-
|
|
898
|
+
log.debug(`resetCollectionSync for ${collection} returns`);
|
|
896
899
|
}
|
|
897
900
|
async dropCollections(collections) {
|
|
898
|
-
(
|
|
899
|
-
(
|
|
900
|
-
|
|
901
|
+
assert(collections);
|
|
902
|
+
assert(collections instanceof Array);
|
|
903
|
+
log.debug('dropCollections called', this.auditCollections);
|
|
901
904
|
let client = await this.connect();
|
|
902
905
|
let existing = await client.db(this.db).collections();
|
|
903
906
|
for await (let collection of collections) {
|
|
@@ -905,12 +908,12 @@ class Mongo extends db_1.Db {
|
|
|
905
908
|
await client.db(this.db).dropCollection(collection);
|
|
906
909
|
}
|
|
907
910
|
}
|
|
908
|
-
|
|
911
|
+
log.debug('dropCollections returns');
|
|
909
912
|
}
|
|
910
913
|
async createCollections(collections) {
|
|
911
|
-
(
|
|
912
|
-
(
|
|
913
|
-
|
|
914
|
+
assert(collections);
|
|
915
|
+
assert(collections instanceof Array);
|
|
916
|
+
log.debug('createCollections called', this.auditCollections);
|
|
914
917
|
let client = await this.connect();
|
|
915
918
|
let existing = await this.getCollections();
|
|
916
919
|
for await (let collection of collections) {
|
|
@@ -918,21 +921,21 @@ class Mongo extends db_1.Db {
|
|
|
918
921
|
await client.db(this.db).createCollection(collection);
|
|
919
922
|
}
|
|
920
923
|
}
|
|
921
|
-
|
|
924
|
+
log.debug('createCollections returns');
|
|
922
925
|
}
|
|
923
926
|
async createCollection(collection) {
|
|
924
|
-
(
|
|
925
|
-
|
|
927
|
+
assert(collection);
|
|
928
|
+
log.debug('createCollection called', collection);
|
|
926
929
|
let client = await this.connect();
|
|
927
930
|
let existing = await this.getCollections();
|
|
928
931
|
if (!existing.includes(collection)) {
|
|
929
932
|
await client.db(this.db).createCollection(collection);
|
|
930
933
|
}
|
|
931
|
-
|
|
934
|
+
log.debug('createCollection returns');
|
|
932
935
|
}
|
|
933
936
|
async dbLogPurge(collection, _id) {
|
|
934
|
-
(
|
|
935
|
-
|
|
937
|
+
assert(collection);
|
|
938
|
+
log.debug('dblogPurge called', collection, _id);
|
|
936
939
|
let ret = await this.executeTransactionally(collection, async () => {
|
|
937
940
|
let cond = { db: this.db, collection, };
|
|
938
941
|
if (_id !== undefined)
|
|
@@ -947,12 +950,12 @@ class Mongo extends db_1.Db {
|
|
|
947
950
|
n: ret.deletedCount
|
|
948
951
|
};
|
|
949
952
|
}, false, { operation: "dbLogPurge", collection, _id });
|
|
950
|
-
|
|
953
|
+
log.debug('dblogPurge returns', ret);
|
|
951
954
|
return ret;
|
|
952
955
|
}
|
|
953
956
|
async dbLogGet(collection, _id) {
|
|
954
|
-
(
|
|
955
|
-
|
|
957
|
+
assert(collection);
|
|
958
|
+
log.debug('dblogGet called', collection, _id);
|
|
956
959
|
let ret = await this.executeTransactionally(collection, async () => {
|
|
957
960
|
let cond = { db: this.db, collection };
|
|
958
961
|
if (_id)
|
|
@@ -966,7 +969,7 @@ class Mongo extends db_1.Db {
|
|
|
966
969
|
.toArray();
|
|
967
970
|
return ret;
|
|
968
971
|
}, false, { operation: "dbLogGet", collection, _id });
|
|
969
|
-
|
|
972
|
+
log.debug('dblogGet returns', ret);
|
|
970
973
|
return ret;
|
|
971
974
|
}
|
|
972
975
|
// HELPER FUNCTIONS
|
|
@@ -984,9 +987,9 @@ class Mongo extends db_1.Db {
|
|
|
984
987
|
return undefined;
|
|
985
988
|
if (typeof data === "symbol")
|
|
986
989
|
return data.toString();
|
|
987
|
-
if (data instanceof
|
|
990
|
+
if (data instanceof ObjectId)
|
|
988
991
|
return data;
|
|
989
|
-
if (data instanceof
|
|
992
|
+
if (data instanceof Timestamp)
|
|
990
993
|
return data;
|
|
991
994
|
if (data instanceof Date)
|
|
992
995
|
return data;
|
|
@@ -996,17 +999,17 @@ class Mongo extends db_1.Db {
|
|
|
996
999
|
return data;
|
|
997
1000
|
if (data instanceof String)
|
|
998
1001
|
return data;
|
|
999
|
-
if (typeof data === "string" &&
|
|
1000
|
-
return new
|
|
1002
|
+
if (typeof data === "string" && data?.match(/^[0-9a-f]{24,24}$/g))
|
|
1003
|
+
return new ObjectId(data);
|
|
1001
1004
|
if (typeof data === "string")
|
|
1002
1005
|
return data;
|
|
1003
1006
|
if (data instanceof Array) {
|
|
1004
1007
|
return data.map(d => this.replaceIds(d));
|
|
1005
1008
|
}
|
|
1006
|
-
if (typeof data == 'object' &&
|
|
1007
|
-
return
|
|
1008
|
-
if (typeof data == 'object' &&
|
|
1009
|
-
return
|
|
1009
|
+
if (typeof data == 'object' && data?.t && data?.i !== undefined)
|
|
1010
|
+
return Base.timestamp(data);
|
|
1011
|
+
if (typeof data == 'object' && data?.high && data?.low !== undefined)
|
|
1012
|
+
return Base.timestamp(data);
|
|
1010
1013
|
if (typeof data == 'object') {
|
|
1011
1014
|
for (let key in data) {
|
|
1012
1015
|
data[key] = this.replaceIds(data[key]);
|
|
@@ -1021,7 +1024,7 @@ class Mongo extends db_1.Db {
|
|
|
1021
1024
|
}
|
|
1022
1025
|
}
|
|
1023
1026
|
async connect() {
|
|
1024
|
-
super.connect();
|
|
1027
|
+
await super.connect();
|
|
1025
1028
|
// this.session = undefined;
|
|
1026
1029
|
return this.client;
|
|
1027
1030
|
}
|
|
@@ -1029,16 +1032,16 @@ class Mongo extends db_1.Db {
|
|
|
1029
1032
|
if (this.session)
|
|
1030
1033
|
try {
|
|
1031
1034
|
await this.session.endSession();
|
|
1032
|
-
|
|
1035
|
+
log.info("session ended");
|
|
1033
1036
|
}
|
|
1034
1037
|
catch (err) {
|
|
1035
|
-
|
|
1038
|
+
log.error(`Error ending session ${err.message}`);
|
|
1036
1039
|
}
|
|
1037
1040
|
try {
|
|
1038
1041
|
await super.close();
|
|
1039
|
-
|
|
1042
|
+
log.info("connection closed");
|
|
1040
1043
|
}
|
|
1041
|
-
catch
|
|
1044
|
+
catch { /** intentionally */ }
|
|
1042
1045
|
this.session = undefined;
|
|
1043
1046
|
}
|
|
1044
1047
|
async inTransaction() {
|
|
@@ -1056,13 +1059,13 @@ class Mongo extends db_1.Db {
|
|
|
1056
1059
|
let hadSession = !!this.session;
|
|
1057
1060
|
if (!this.session) {
|
|
1058
1061
|
this.session = client.startSession();
|
|
1059
|
-
|
|
1062
|
+
log.info("session started");
|
|
1060
1063
|
}
|
|
1061
1064
|
let session = this.session;
|
|
1062
1065
|
await session.withTransaction(async () => await funct(client, session));
|
|
1063
1066
|
if (!hadSession) {
|
|
1064
1067
|
session.endSession();
|
|
1065
|
-
|
|
1068
|
+
log.info("session ended");
|
|
1066
1069
|
this.session = undefined;
|
|
1067
1070
|
}
|
|
1068
1071
|
return;
|
|
@@ -1078,24 +1081,24 @@ class Mongo extends db_1.Db {
|
|
|
1078
1081
|
try {
|
|
1079
1082
|
if (!this.session) {
|
|
1080
1083
|
this.session = client.startSession(TRANSACTION_OPTIONS);
|
|
1081
|
-
|
|
1084
|
+
log.info("session started");
|
|
1082
1085
|
}
|
|
1083
1086
|
if (!await this.inTransaction()) {
|
|
1084
1087
|
await this.session.startTransaction();
|
|
1085
|
-
|
|
1088
|
+
log.info("transaction started");
|
|
1086
1089
|
}
|
|
1087
1090
|
}
|
|
1088
1091
|
catch (err) {
|
|
1089
|
-
|
|
1092
|
+
log.error('startTransaction error', err);
|
|
1090
1093
|
try {
|
|
1091
1094
|
if (this.session) {
|
|
1092
1095
|
await this.session.endSession();
|
|
1093
|
-
|
|
1096
|
+
log.info("session ended");
|
|
1094
1097
|
}
|
|
1095
1098
|
this.session = undefined;
|
|
1096
1099
|
}
|
|
1097
1100
|
catch (e) {
|
|
1098
|
-
|
|
1101
|
+
log.error("startTransaction - error in endSession", e.message || e);
|
|
1099
1102
|
}
|
|
1100
1103
|
return;
|
|
1101
1104
|
}
|
|
@@ -1108,13 +1111,13 @@ class Mongo extends db_1.Db {
|
|
|
1108
1111
|
return;
|
|
1109
1112
|
let session = this.session;
|
|
1110
1113
|
await session.commitTransaction();
|
|
1111
|
-
|
|
1114
|
+
log.info("transaction committed");
|
|
1112
1115
|
session.endSession();
|
|
1113
1116
|
this.session = undefined;
|
|
1114
|
-
|
|
1117
|
+
log.info("session ended");
|
|
1115
1118
|
}
|
|
1116
1119
|
catch (err) {
|
|
1117
|
-
|
|
1120
|
+
log.error(`commitTransaction error ${err.message || err}`);
|
|
1118
1121
|
}
|
|
1119
1122
|
}
|
|
1120
1123
|
async abortTransaction() {
|
|
@@ -1125,13 +1128,13 @@ class Mongo extends db_1.Db {
|
|
|
1125
1128
|
return;
|
|
1126
1129
|
let session = this.session;
|
|
1127
1130
|
await session.abortTransaction();
|
|
1128
|
-
|
|
1131
|
+
log.info("transaction aborted");
|
|
1129
1132
|
await session.endSession();
|
|
1130
1133
|
this.session = undefined;
|
|
1131
|
-
|
|
1134
|
+
log.info("session ended");
|
|
1132
1135
|
}
|
|
1133
1136
|
catch (err) {
|
|
1134
|
-
|
|
1137
|
+
log.error(`abortTransaction error ${err.message || err}`);
|
|
1135
1138
|
}
|
|
1136
1139
|
}
|
|
1137
1140
|
async _try_once(useTransaction, f, collection) {
|
|
@@ -1155,7 +1158,7 @@ class Mongo extends db_1.Db {
|
|
|
1155
1158
|
if (useTransaction)
|
|
1156
1159
|
await this.abortTransaction();
|
|
1157
1160
|
}
|
|
1158
|
-
catch
|
|
1161
|
+
catch { /* intentionally */ }
|
|
1159
1162
|
throw err;
|
|
1160
1163
|
}
|
|
1161
1164
|
}
|
|
@@ -1168,8 +1171,9 @@ class Mongo extends db_1.Db {
|
|
|
1168
1171
|
return await this._try_once(useTransaction, f, collection);
|
|
1169
1172
|
}
|
|
1170
1173
|
catch (err) {
|
|
1171
|
-
|
|
1172
|
-
|
|
1174
|
+
log.error(`Mongo command has failed for ${this.db}.${collection} - ${(this.session ? "ROLLBACK - " : "")} ${err.message || err}`);
|
|
1175
|
+
log.error(debugObject);
|
|
1176
|
+
log.debug(err);
|
|
1173
1177
|
let x = (err || "").toString();
|
|
1174
1178
|
console.log('x');
|
|
1175
1179
|
let isRepeatable = x.match(/Topology is closed, please connect/i)
|
|
@@ -1178,21 +1182,21 @@ class Mongo extends db_1.Db {
|
|
|
1178
1182
|
|| x.match(/Topology closed/);
|
|
1179
1183
|
if (isRepeatable) {
|
|
1180
1184
|
try {
|
|
1181
|
-
|
|
1185
|
+
log.error("Trying to reopen connection and repeat as");
|
|
1182
1186
|
await this.close();
|
|
1183
1187
|
// a single retry
|
|
1184
1188
|
await super.connect();
|
|
1185
1189
|
let ret = await this._try_once(useTransaction, f, collection);
|
|
1186
|
-
|
|
1187
|
-
|
|
1190
|
+
log.error("OK - Retry succeeded.");
|
|
1191
|
+
log.error("");
|
|
1188
1192
|
return ret;
|
|
1189
1193
|
}
|
|
1190
1194
|
catch (err2) {
|
|
1191
1195
|
/* intentional */
|
|
1192
1196
|
if (debugObject)
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1197
|
+
log.error(debugObject);
|
|
1198
|
+
log.error(`FAIL - Retry failed: ${err2.message || err2}`);
|
|
1199
|
+
log.error("");
|
|
1196
1200
|
}
|
|
1197
1201
|
}
|
|
1198
1202
|
throw err;
|
|
@@ -1209,32 +1213,31 @@ class Mongo extends db_1.Db {
|
|
|
1209
1213
|
return parseInt(maxfld[0][key]) || 0;
|
|
1210
1214
|
}
|
|
1211
1215
|
async _getNextCollectionUpdateSeqNo(collection, conn) {
|
|
1212
|
-
var _a;
|
|
1213
1216
|
let opts = {
|
|
1214
1217
|
upsert: true,
|
|
1215
1218
|
returnDocument: "after",
|
|
1216
1219
|
};
|
|
1217
1220
|
let nextSeq = await (conn.db(this.db)
|
|
1218
|
-
.collection(
|
|
1221
|
+
.collection(SEQUENCES_COLLECTION)
|
|
1219
1222
|
.findOneAndUpdate({ collection }, {
|
|
1220
1223
|
$inc: { seq: 1 },
|
|
1221
1224
|
$currentDate: { last: { $type: "date" }, ts: { $type: "timestamp" } }
|
|
1222
1225
|
}, opts));
|
|
1223
1226
|
conn.db(this.db).collection(collection);
|
|
1224
|
-
return
|
|
1227
|
+
return nextSeq?.value?.seq || 1;
|
|
1225
1228
|
}
|
|
1226
1229
|
_findSequenceKeys(object) {
|
|
1227
1230
|
if (!object)
|
|
1228
1231
|
return;
|
|
1229
1232
|
let seqKeys = Object.keys(object).filter(key => object[key] === 'SEQ_NEXT' || object[key] === 'SEQ_LAST');
|
|
1230
|
-
return (
|
|
1233
|
+
return (seqKeys?.length > 0 || this.syncSupport) ? { seqKeys } : undefined;
|
|
1231
1234
|
}
|
|
1232
1235
|
async _processSequenceField(client, collection, insert, seqKeys) {
|
|
1233
|
-
(
|
|
1236
|
+
assert(this.client);
|
|
1234
1237
|
if (this.syncSupport) {
|
|
1235
1238
|
insert._csq = (await this._getNextCollectionUpdateSeqNo(collection, client));
|
|
1236
1239
|
}
|
|
1237
|
-
for await (let seqKey of
|
|
1240
|
+
for await (let seqKey of seqKeys?.seqKeys || []) {
|
|
1238
1241
|
let last = await this._findLastSequenceForKey(client.db(this.db).collection(collection), seqKey);
|
|
1239
1242
|
if (last === undefined) {
|
|
1240
1243
|
await this.createCollection(collection);
|
|
@@ -1246,21 +1249,21 @@ class Mongo extends db_1.Db {
|
|
|
1246
1249
|
return insert;
|
|
1247
1250
|
}
|
|
1248
1251
|
async _processSequenceFieldForMany(connection, collection, inserts) {
|
|
1249
|
-
(
|
|
1250
|
-
(
|
|
1251
|
-
if (!
|
|
1252
|
+
assert(this.client);
|
|
1253
|
+
assert(connection);
|
|
1254
|
+
if (!inserts?.length)
|
|
1252
1255
|
return;
|
|
1253
1256
|
let seqKeys = this._findSequenceKeys(inserts[0]);
|
|
1254
1257
|
let seq = 0;
|
|
1255
1258
|
if (this.syncSupport)
|
|
1256
1259
|
seq = await this._getNextCollectionUpdateSeqNo(collection, connection);
|
|
1257
|
-
for await (let seqKey of
|
|
1260
|
+
for await (let seqKey of seqKeys?.seqKeys || []) {
|
|
1258
1261
|
let last = await this._findLastSequenceForKey(connection.db(this.db).collection(collection), seqKey);
|
|
1259
1262
|
if (last === undefined) {
|
|
1260
1263
|
try {
|
|
1261
1264
|
await this.createCollection(collection);
|
|
1262
1265
|
}
|
|
1263
|
-
catch
|
|
1266
|
+
catch { /* intentionaly */ }
|
|
1264
1267
|
last = 0;
|
|
1265
1268
|
}
|
|
1266
1269
|
for (let insert of inserts) {
|
|
@@ -1311,7 +1314,7 @@ class Mongo extends db_1.Db {
|
|
|
1311
1314
|
async _publishAndAudit(operation, db, collection, dataToPublish, noEmit) {
|
|
1312
1315
|
if (!dataToPublish._id && !["deleteMany", "updateMany"].includes(operation))
|
|
1313
1316
|
throw new Error(`_publishAndAudit requires _id for ${operation}`);
|
|
1314
|
-
let data = (
|
|
1317
|
+
let data = cloneDeep(dataToPublish);
|
|
1315
1318
|
if (data._id && /[0-9a-f]{24,24}/i.test(data._id.toString()))
|
|
1316
1319
|
data._id = data._id.toHexString();
|
|
1317
1320
|
let toPublish = undefined;
|
|
@@ -1342,7 +1345,7 @@ class Mongo extends db_1.Db {
|
|
|
1342
1345
|
return toPublish;
|
|
1343
1346
|
}
|
|
1344
1347
|
emit(what) {
|
|
1345
|
-
|
|
1348
|
+
log.debug("emitting publish", what);
|
|
1346
1349
|
this.emitter.emit('publish', what);
|
|
1347
1350
|
}
|
|
1348
1351
|
async _writeAuditRecord(collection, operation, data, user = this.user, audit = this.audit) {
|
|
@@ -1362,9 +1365,9 @@ class Mongo extends db_1.Db {
|
|
|
1362
1365
|
let auditRecord = {
|
|
1363
1366
|
db: this.db,
|
|
1364
1367
|
collection: collection,
|
|
1365
|
-
entityid:
|
|
1368
|
+
entityid: Base.objectid(data._id),
|
|
1366
1369
|
rev: previousAuditRecord.rev + 1,
|
|
1367
|
-
ts:
|
|
1370
|
+
ts: Base.timestamp(),
|
|
1368
1371
|
on: new Date(),
|
|
1369
1372
|
operation: operation,
|
|
1370
1373
|
changes: dataNoId,
|
|
@@ -1373,11 +1376,11 @@ class Mongo extends db_1.Db {
|
|
|
1373
1376
|
auditRecord.user = user;
|
|
1374
1377
|
if (audit)
|
|
1375
1378
|
auditRecord.audit = audit;
|
|
1376
|
-
|
|
1379
|
+
log.trace('AUDITING', auditRecord);
|
|
1377
1380
|
let ret = await client.db(this.db)
|
|
1378
1381
|
.collection(this.auditCollectionName)
|
|
1379
1382
|
.insertOne(auditRecord, { session: this.session });
|
|
1380
|
-
|
|
1383
|
+
log.debug('AUDITED', auditRecord, ret.insertedId);
|
|
1381
1384
|
}
|
|
1382
1385
|
async _processUpdateObject(update) {
|
|
1383
1386
|
await this._processHashedKeys(update);
|
|
@@ -1416,8 +1419,8 @@ class Mongo extends db_1.Db {
|
|
|
1416
1419
|
for await (let key of Object.keys(update)) {
|
|
1417
1420
|
let shouldBeHashed = /^__hashed_(.+)$/.test(key);
|
|
1418
1421
|
if (shouldBeHashed) {
|
|
1419
|
-
let salt = await
|
|
1420
|
-
let hash = await
|
|
1422
|
+
let salt = await bcrypt.genSalt(saltRounds);
|
|
1423
|
+
let hash = await bcrypt.hash(update[key], salt);
|
|
1421
1424
|
update[key] = { salt, hash };
|
|
1422
1425
|
}
|
|
1423
1426
|
}
|
|
@@ -1441,6 +1444,5 @@ class Mongo extends db_1.Db {
|
|
|
1441
1444
|
return ret;
|
|
1442
1445
|
}
|
|
1443
1446
|
}
|
|
1444
|
-
exports.default = Mongo;
|
|
1445
1447
|
module.exports = Mongo;
|
|
1446
1448
|
//# sourceMappingURL=mongo.js.map
|