cry-db 2.4.12 → 2.4.13
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.mjs +1 -1
- package/dist/base.mjs.map +1 -1
- package/dist/db.mjs.map +1 -1
- package/dist/mongo.d.mts.map +1 -1
- package/dist/mongo.mjs +160 -131
- package/dist/mongo.mjs.map +1 -1
- package/dist/repo.d.mts.map +1 -1
- package/dist/repo.mjs.map +1 -1
- package/package.json +2 -1
package/dist/mongo.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as bcrypt from 'bcrypt';
|
|
2
|
+
import { Formatter, FracturedJsonOptions } from 'fracturedjsonjs';
|
|
2
3
|
import cloneDeep from "lodash.clonedeep";
|
|
3
4
|
import { ObjectId, ReadConcern, ReadPreference, Timestamp, WriteConcern } from 'mongodb';
|
|
4
5
|
import { TypedEmitter } from "tiny-typed-emitter";
|
|
@@ -35,6 +36,34 @@ const TRANSACTION_OPTIONS = {
|
|
|
35
36
|
writeConcern: new WriteConcern("majority")
|
|
36
37
|
}
|
|
37
38
|
};
|
|
39
|
+
// FracturedJson formatter for readable object logging
|
|
40
|
+
const fjOptions = new FracturedJsonOptions();
|
|
41
|
+
fjOptions.MaxTotalLineLength = 120;
|
|
42
|
+
fjOptions.MaxInlineComplexity = 2;
|
|
43
|
+
const fjFormatter = new Formatter();
|
|
44
|
+
fjFormatter.Options = fjOptions;
|
|
45
|
+
const fj = (obj) => {
|
|
46
|
+
var _a;
|
|
47
|
+
if (obj === null || obj === undefined)
|
|
48
|
+
return String(obj);
|
|
49
|
+
if (typeof obj !== 'object')
|
|
50
|
+
return String(obj);
|
|
51
|
+
try {
|
|
52
|
+
return (_a = fjFormatter.Serialize(obj)) !== null && _a !== void 0 ? _a : JSON.stringify(obj);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return JSON.stringify(obj);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// Wrap log methods to auto-format objects with fracturedjson
|
|
59
|
+
const fjArgs = (args) => args.map(a => typeof a === 'object' && a !== null ? fj(a) : a);
|
|
60
|
+
const fjLog = {
|
|
61
|
+
debug: (...args) => { log.debug(...fjArgs(args)); },
|
|
62
|
+
trace: (...args) => { log.trace(...fjArgs(args)); },
|
|
63
|
+
info: (...args) => { log.info(...fjArgs(args)); },
|
|
64
|
+
warn: (...args) => { log.warn(...fjArgs(args)); },
|
|
65
|
+
error: (...args) => { log.error(...fjArgs(args)); },
|
|
66
|
+
};
|
|
38
67
|
// export const DummyExportToFixTsCompilation = true;
|
|
39
68
|
export class Mongo extends Db {
|
|
40
69
|
constructor(db, url) {
|
|
@@ -51,18 +80,18 @@ export class Mongo extends Db {
|
|
|
51
80
|
this.emitter = new TypedEmitter();
|
|
52
81
|
this.user = undefined;
|
|
53
82
|
this.audit = undefined;
|
|
54
|
-
|
|
83
|
+
fjLog.debug('new Mongo:', this.url, this.db);
|
|
55
84
|
}
|
|
56
85
|
on(evt, listener) {
|
|
57
|
-
|
|
86
|
+
fjLog.debug("on", evt, listener);
|
|
58
87
|
this.emitter.on(evt, listener);
|
|
59
88
|
}
|
|
60
89
|
off(evt, listener) {
|
|
61
|
-
|
|
90
|
+
fjLog.debug("off", evt, listener);
|
|
62
91
|
this.emitter.off(evt, listener);
|
|
63
92
|
}
|
|
64
93
|
once(evt, listener) {
|
|
65
|
-
|
|
94
|
+
fjLog.debug("once", evt, listener);
|
|
66
95
|
this.emitter.once(evt, listener);
|
|
67
96
|
}
|
|
68
97
|
setUser(username) {
|
|
@@ -137,18 +166,18 @@ export class Mongo extends Db {
|
|
|
137
166
|
this.revisions = true;
|
|
138
167
|
}
|
|
139
168
|
if (enabled)
|
|
140
|
-
|
|
169
|
+
fjLog.debug("publishing rev events");
|
|
141
170
|
return this.emittingPublishRevEvents = enabled;
|
|
142
171
|
}
|
|
143
172
|
emitsPublishRevEvents() {
|
|
144
173
|
return this.emittingPublishRevEvents;
|
|
145
174
|
}
|
|
146
175
|
async distinct(collection, field) {
|
|
147
|
-
|
|
176
|
+
fjLog.debug('distinct called', collection, field);
|
|
148
177
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
149
178
|
return await conn.distinct(field);
|
|
150
179
|
}, false, { operation: "distinct", collection, field });
|
|
151
|
-
|
|
180
|
+
fjLog.debug('distinct returns', ret);
|
|
152
181
|
return ret;
|
|
153
182
|
}
|
|
154
183
|
async count(collection, query = {}, opts = {}) {
|
|
@@ -157,11 +186,11 @@ export class Mongo extends Db {
|
|
|
157
186
|
if (!query._deleted)
|
|
158
187
|
query._deleted = { $exists: false };
|
|
159
188
|
}
|
|
160
|
-
|
|
189
|
+
fjLog.debug('count called', collection, query, opts);
|
|
161
190
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
162
191
|
return await conn.countDocuments(query, opts);
|
|
163
192
|
}, false, { operation: "count", collection, query, opts });
|
|
164
|
-
|
|
193
|
+
fjLog.debug('count returns', ret);
|
|
165
194
|
return ret;
|
|
166
195
|
}
|
|
167
196
|
async find(collection, query = {}, opts = {}) {
|
|
@@ -171,12 +200,12 @@ export class Mongo extends Db {
|
|
|
171
200
|
if (!query._deleted)
|
|
172
201
|
query._deleted = { $exists: false };
|
|
173
202
|
}
|
|
174
|
-
|
|
203
|
+
fjLog.debug('find called', collection, query, opts);
|
|
175
204
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
176
205
|
let r = this._applyQueryOpts(conn.find(query, this._buildFindOptions(opts)), opts);
|
|
177
206
|
return this._processReturnedObject(await r.toArray());
|
|
178
207
|
}, false, { operation: "find", collection, query, opts });
|
|
179
|
-
|
|
208
|
+
fjLog.debug('find returns', ret);
|
|
180
209
|
return ret;
|
|
181
210
|
}
|
|
182
211
|
async findAll(collection, query = {}, opts = {}) {
|
|
@@ -186,7 +215,7 @@ export class Mongo extends Db {
|
|
|
186
215
|
let r = this._applyQueryOpts(conn.find(query, this._buildFindOptions(opts)), opts);
|
|
187
216
|
return this._processReturnedObject(await r.toArray());
|
|
188
217
|
}, false, { operation: "findAll", collection, query, opts });
|
|
189
|
-
|
|
218
|
+
fjLog.debug('findAll returns', ret);
|
|
190
219
|
return ret;
|
|
191
220
|
}
|
|
192
221
|
async findNewer(collection, timestamp, query = {}, opts = {}) {
|
|
@@ -195,17 +224,17 @@ export class Mongo extends Db {
|
|
|
195
224
|
if (!query._deleted)
|
|
196
225
|
query._deleted = { $exists: false };
|
|
197
226
|
}
|
|
198
|
-
|
|
227
|
+
fjLog.debug('findNewer called', collection, timestamp, query, opts);
|
|
199
228
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
200
229
|
let r = this._applyQueryOpts(conn.find(query, this._buildFindOptions(opts)).sort({ _ts: 1 }), opts);
|
|
201
230
|
return this._processReturnedObject(await r.toArray());
|
|
202
231
|
}, false, { operation: "findNewer", collection, timestamp, query, opts });
|
|
203
|
-
|
|
232
|
+
fjLog.debug('findNewer returns', ret);
|
|
204
233
|
return ret;
|
|
205
234
|
}
|
|
206
235
|
async findNewerMany(spec = []) {
|
|
207
236
|
var _a;
|
|
208
|
-
|
|
237
|
+
fjLog.debug('findNewerMany called', spec);
|
|
209
238
|
const dbName = this.db; // Capture db at operation start
|
|
210
239
|
let conn = await this.connect();
|
|
211
240
|
const getOneColl = async (coll) => {
|
|
@@ -216,12 +245,12 @@ export class Mongo extends Db {
|
|
|
216
245
|
query._deleted = { $exists: false };
|
|
217
246
|
}
|
|
218
247
|
if (process.env.MONGO_DEBUG_FINDNEWERMANY) {
|
|
219
|
-
|
|
248
|
+
fjLog.debug("findNewerMany <-", coll.collection, coll.timestamp, coll.query, " -> ", JSON.stringify(query));
|
|
220
249
|
}
|
|
221
250
|
let r = this._applyQueryOpts(conn.db(dbName).collection(coll.collection).find(query, {}).sort({ _ts: 1 }), opts);
|
|
222
251
|
let data = await r.toArray();
|
|
223
252
|
if (process.env.MONGO_DEBUG_FINDNEWERMANY) {
|
|
224
|
-
|
|
253
|
+
fjLog.debug("findNewerMany ->", coll.collection, JSON.stringify(data, null, 2));
|
|
225
254
|
}
|
|
226
255
|
return { collection: coll.collection, data };
|
|
227
256
|
};
|
|
@@ -246,7 +275,7 @@ export class Mongo extends Db {
|
|
|
246
275
|
async latestTimestamps(collections) {
|
|
247
276
|
assert(collections);
|
|
248
277
|
assert(collections instanceof Array);
|
|
249
|
-
|
|
278
|
+
fjLog.debug('latestTimestamps called', collections);
|
|
250
279
|
const dbName = this.db; // Capture db at operation start
|
|
251
280
|
let conn = await this.connect();
|
|
252
281
|
const getOne = async (collection) => {
|
|
@@ -268,13 +297,13 @@ export class Mongo extends Db {
|
|
|
268
297
|
let out = {};
|
|
269
298
|
(await Promise.all(promises)).forEach(r => { if (r.ts)
|
|
270
299
|
out[r.collection] = r.ts; });
|
|
271
|
-
|
|
300
|
+
fjLog.debug('latestTimestamps returns', out);
|
|
272
301
|
return out;
|
|
273
302
|
}
|
|
274
303
|
async latestTimestamp(collection) {
|
|
275
304
|
var _a;
|
|
276
305
|
assert(collection);
|
|
277
|
-
|
|
306
|
+
fjLog.debug('latestTimestamp called', collection);
|
|
278
307
|
const dbName = this.db; // Capture db at operation start
|
|
279
308
|
let conn = await this.connect();
|
|
280
309
|
let cursor = conn
|
|
@@ -286,7 +315,7 @@ export class Mongo extends Db {
|
|
|
286
315
|
.limit(1);
|
|
287
316
|
let res = await cursor.toArray();
|
|
288
317
|
let ts = (_a = res === null || res === void 0 ? void 0 : res[0]) === null || _a === void 0 ? void 0 : _a._ts;
|
|
289
|
-
|
|
318
|
+
fjLog.debug('latestTimestamp returns', ts);
|
|
290
319
|
return ts;
|
|
291
320
|
}
|
|
292
321
|
_createQueryForNewer(timestamp, query) {
|
|
@@ -304,7 +333,7 @@ export class Mongo extends Db {
|
|
|
304
333
|
}
|
|
305
334
|
// async findAfter<T>(collection: string, csq: number, query: QuerySpec<T> = {}, opts: QueryOpts = {}): Promise<T[]> {
|
|
306
335
|
// // query._csq = { $gt: csq };
|
|
307
|
-
//
|
|
336
|
+
// fjLog.debug('findAfter called', collection, csq, query, opts)
|
|
308
337
|
// let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
309
338
|
// let optsIn: FindOptions<any> = {}
|
|
310
339
|
// if (opts.readPreference) optsIn.readPreference = opts.readPreference;
|
|
@@ -319,12 +348,12 @@ export class Mongo extends Db {
|
|
|
319
348
|
// if (opts.collation) r = r.collation(opts.collation);
|
|
320
349
|
// return this._processReturnedObject(await r.toArray());
|
|
321
350
|
// }, false, { operation: "findNewer", collection, csq, query, opts });
|
|
322
|
-
//
|
|
351
|
+
// fjLog.debug('findNewer returns', ret)
|
|
323
352
|
// return ret;
|
|
324
353
|
// }
|
|
325
354
|
// async findAfterMany<T>(spec: GetAfterSpec<T>[] = []):
|
|
326
355
|
// Promise<Record<string, any[]>> {
|
|
327
|
-
//
|
|
356
|
+
// fjLog.debug('findAfterMany called', spec)
|
|
328
357
|
// let conn = await this.connect()
|
|
329
358
|
// const getOneColl = async (coll: GetAfterSpec<T>): Promise<{ collection: string, data: any[] }> => {
|
|
330
359
|
// let r = conn
|
|
@@ -351,9 +380,9 @@ export class Mongo extends Db {
|
|
|
351
380
|
// }
|
|
352
381
|
// async findNewerFromDate<T>(collection: string, date: Date | string, query: QuerySpec<T> = {}, opts: QueryOpts = {}): Promise<T[]> {
|
|
353
382
|
// let ts = new Timestamp({ i: new Date(date).valueOf() % 1000, t: new Date(date).valueOf() / 1000 });
|
|
354
|
-
//
|
|
383
|
+
// fjLog.debug('findNewerFromDate called', collection, date, query, opts)
|
|
355
384
|
// let ret = await Mongo.prototype.findNewer.call(this, collection, ts, query, opts) // prevent calling Repo.findNewer
|
|
356
|
-
//
|
|
385
|
+
// fjLog.debug('findNewerFromDate returns', ret)
|
|
357
386
|
// return ret as T[];
|
|
358
387
|
// }
|
|
359
388
|
async findOne(collection, query, projection, opts = {}) {
|
|
@@ -365,9 +394,9 @@ export class Mongo extends Db {
|
|
|
365
394
|
query._deleted = { $exists: false };
|
|
366
395
|
}
|
|
367
396
|
// if (!query._blocked) query._blocked = { $exists: false }; // intentionally - blocked records are returned
|
|
368
|
-
|
|
397
|
+
fjLog.debug('findOne called', collection, query, projection);
|
|
369
398
|
let ret = await this.executeTransactionally(collection, async (conn) => await conn.findOne(query, { ...(projection ? { projection } : {}), ...this._sessionOpt() }), false, { operation: "findOne", collection, query, projection });
|
|
370
|
-
|
|
399
|
+
fjLog.debug('findOne returns', ret);
|
|
371
400
|
return this._processReturnedObject(ret);
|
|
372
401
|
}
|
|
373
402
|
async findById(collection, id, projection, opts = {}) {
|
|
@@ -380,15 +409,15 @@ export class Mongo extends Db {
|
|
|
380
409
|
_id: Mongo._toId(id),
|
|
381
410
|
// _deleted: { $exists: false }
|
|
382
411
|
};
|
|
383
|
-
|
|
384
|
-
|
|
412
|
+
fjLog.debug('findById called', dbName, collection, id, projection);
|
|
413
|
+
fjLog.trace('findById executing with query', collection, query, projection);
|
|
385
414
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
386
415
|
let r = await conn.findOne(query, { ...(projection ? { projection } : {}), ...this._sessionOpt() });
|
|
387
416
|
return r;
|
|
388
417
|
}, false, { operation: "findById", collection, id, projection });
|
|
389
418
|
if ((ret === null || ret === void 0 ? void 0 : ret._deleted) && this.softdelete && !opts.returnDeleted)
|
|
390
419
|
ret = null;
|
|
391
|
-
|
|
420
|
+
fjLog.debug('findById returns', ret);
|
|
392
421
|
return this._processReturnedObject(ret);
|
|
393
422
|
}
|
|
394
423
|
async findByIds(collection, ids, projection, opts = {}) {
|
|
@@ -398,7 +427,7 @@ export class Mongo extends Db {
|
|
|
398
427
|
return [];
|
|
399
428
|
const dbName = this.db;
|
|
400
429
|
const objectIds = ids.map(id => Mongo._toId(id));
|
|
401
|
-
|
|
430
|
+
fjLog.debug('findByIds called', dbName, collection, ids, projection);
|
|
402
431
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
403
432
|
let query = { _id: { $in: objectIds } };
|
|
404
433
|
if (this.softdelete && !opts.returnDeleted) {
|
|
@@ -407,7 +436,7 @@ export class Mongo extends Db {
|
|
|
407
436
|
let r = conn.find(query, { ...(projection ? { projection } : {}), ...this._sessionOpt() });
|
|
408
437
|
return await r.toArray();
|
|
409
438
|
}, false, { operation: "findByIds", collection, ids, projection });
|
|
410
|
-
|
|
439
|
+
fjLog.debug('findByIds returns', ret);
|
|
411
440
|
return this._processReturnedObject(ret);
|
|
412
441
|
}
|
|
413
442
|
async updateOne(collection, query, update, options = { returnFullObject: false }) {
|
|
@@ -423,7 +452,7 @@ export class Mongo extends Db {
|
|
|
423
452
|
...this._sessionOpt()
|
|
424
453
|
};
|
|
425
454
|
update = await this._processUpdateObject(update);
|
|
426
|
-
|
|
455
|
+
fjLog.debug('updateOne called', collection, query, update);
|
|
427
456
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
428
457
|
let obj = await this.executeTransactionally(collection, async (conn, client) => {
|
|
429
458
|
update.$set = update.$set || {};
|
|
@@ -438,7 +467,7 @@ export class Mongo extends Db {
|
|
|
438
467
|
await this._publishAndAudit('update', dbName, collection, resObj);
|
|
439
468
|
return resObj;
|
|
440
469
|
}, !!seqKeys, { operation: "updateOne", collection, query, update, options });
|
|
441
|
-
|
|
470
|
+
fjLog.debug('updateOne returns', obj);
|
|
442
471
|
return this._processReturnedObject(await obj);
|
|
443
472
|
}
|
|
444
473
|
async save(collection, update, id = undefined, options = { returnFullObject: false }) {
|
|
@@ -453,7 +482,7 @@ export class Mongo extends Db {
|
|
|
453
482
|
};
|
|
454
483
|
let _id = Mongo.toId(id || update._id) || Mongo.newid();
|
|
455
484
|
update = await this._processUpdateObject(update);
|
|
456
|
-
|
|
485
|
+
fjLog.debug('save called', collection, id, update);
|
|
457
486
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
458
487
|
let obj = await this.executeTransactionally(collection, async (conn, client) => {
|
|
459
488
|
update.$set = update.$set || {};
|
|
@@ -468,14 +497,14 @@ export class Mongo extends Db {
|
|
|
468
497
|
await this._publishAndAudit('update', dbName, collection, resObj);
|
|
469
498
|
return resObj;
|
|
470
499
|
}, !!seqKeys, { operation: "save", collection, _id, update, options });
|
|
471
|
-
|
|
500
|
+
fjLog.debug('save returns', obj);
|
|
472
501
|
return this._processReturnedObject(await obj);
|
|
473
502
|
}
|
|
474
503
|
async update(collection, query, update) {
|
|
475
504
|
assert(collection);
|
|
476
505
|
assert(query);
|
|
477
506
|
assert(update);
|
|
478
|
-
// if (this.syncSupport)
|
|
507
|
+
// if (this.syncSupport) fjLog.warn("update does not increase _csq, avoit it.")
|
|
479
508
|
if (!Object.keys(update).length)
|
|
480
509
|
return { n: 0, ok: false };
|
|
481
510
|
const dbName = this.db; // Capture db at operation start
|
|
@@ -487,7 +516,7 @@ export class Mongo extends Db {
|
|
|
487
516
|
...this._sessionOpt()
|
|
488
517
|
};
|
|
489
518
|
update = await this._processUpdateObject(update);
|
|
490
|
-
|
|
519
|
+
fjLog.debug('update called', collection, query, update);
|
|
491
520
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
492
521
|
let obj = await this.executeTransactionally(collection, async (conn, client) => {
|
|
493
522
|
update.$set = update.$set || {};
|
|
@@ -495,7 +524,7 @@ export class Mongo extends Db {
|
|
|
495
524
|
await this._processSequenceField(client, dbName, collection, update.$set, seqKeys);
|
|
496
525
|
if (update.$set === undefined || Object.keys(update.$set).length === 0)
|
|
497
526
|
delete update.$set;
|
|
498
|
-
|
|
527
|
+
fjLog.debug('update called', collection, query, update);
|
|
499
528
|
let res = await conn.updateMany(query, update, opts);
|
|
500
529
|
let resObj = {
|
|
501
530
|
n: res.modifiedCount,
|
|
@@ -504,7 +533,7 @@ export class Mongo extends Db {
|
|
|
504
533
|
await this._publishAndAudit('updateMany', dbName, collection, resObj);
|
|
505
534
|
return resObj;
|
|
506
535
|
}, !!seqKeys, { operation: "update", collection, query, update });
|
|
507
|
-
|
|
536
|
+
fjLog.debug('update returns', obj);
|
|
508
537
|
return await obj;
|
|
509
538
|
}
|
|
510
539
|
async upsert(collection, query, update, options = { returnFullObject: false }) {
|
|
@@ -522,10 +551,10 @@ export class Mongo extends Db {
|
|
|
522
551
|
returnDocument: "after",
|
|
523
552
|
...this._sessionOpt()
|
|
524
553
|
};
|
|
525
|
-
|
|
554
|
+
fjLog.debug('upsert called', collection, query, update);
|
|
526
555
|
update = await this._processUpdateObject(update);
|
|
527
556
|
let seqKeys = this._findSequenceKeys(update.$set);
|
|
528
|
-
|
|
557
|
+
fjLog.debug('upsert processed', collection, query, update);
|
|
529
558
|
if (Object.keys(query).length === 0)
|
|
530
559
|
query._id = Mongo.newid();
|
|
531
560
|
let ret = await this.executeTransactionally(collection, async (conn, client) => {
|
|
@@ -547,14 +576,14 @@ export class Mongo extends Db {
|
|
|
547
576
|
;
|
|
548
577
|
return ret;
|
|
549
578
|
}, !!seqKeys, { operation: "upsert", query, update, options });
|
|
550
|
-
|
|
579
|
+
fjLog.debug('upsert returns', ret);
|
|
551
580
|
return this._processReturnedObject(await ret);
|
|
552
581
|
}
|
|
553
582
|
async insert(collection, insert) {
|
|
554
583
|
assert(collection, "collection can't be null");
|
|
555
584
|
assert(insert, "insert can't be null");
|
|
556
585
|
assert(typeof insert === "object", "insert must be an object");
|
|
557
|
-
|
|
586
|
+
fjLog.debug('insert called', collection, insert);
|
|
558
587
|
const dbName = this.db; // Capture db at operation start
|
|
559
588
|
insert = this.replaceIds(insert);
|
|
560
589
|
if (this.revisions) {
|
|
@@ -571,7 +600,7 @@ export class Mongo extends Db {
|
|
|
571
600
|
await this._publishAndAudit('insert', dbName, collection, fullObj);
|
|
572
601
|
return fullObj;
|
|
573
602
|
}, !!seqKeys, { operation: "insert", collection, insert });
|
|
574
|
-
|
|
603
|
+
fjLog.debug('insert returns', ret);
|
|
575
604
|
return this._processReturnedObject(await ret);
|
|
576
605
|
}
|
|
577
606
|
/**
|
|
@@ -585,7 +614,7 @@ export class Mongo extends Db {
|
|
|
585
614
|
async updateCollections(collectionsBatches) {
|
|
586
615
|
assert(collectionsBatches, "collectionsBatches can't be null");
|
|
587
616
|
assert(collectionsBatches instanceof Array, "collectionsBatches must be an Array");
|
|
588
|
-
|
|
617
|
+
fjLog.debug('updateCollections called', collectionsBatches.length, 'collections');
|
|
589
618
|
const dbName = this.db;
|
|
590
619
|
const conn = await this.connect();
|
|
591
620
|
const results = [];
|
|
@@ -731,14 +760,14 @@ export class Mongo extends Db {
|
|
|
731
760
|
results.push(result);
|
|
732
761
|
}
|
|
733
762
|
}
|
|
734
|
-
|
|
763
|
+
fjLog.debug('updateCollections returns', results);
|
|
735
764
|
return results;
|
|
736
765
|
}
|
|
737
766
|
async upsertBatch(collection, batch) {
|
|
738
767
|
assert(collection, "collection can't be null");
|
|
739
768
|
assert(batch, "batch can't be null");
|
|
740
769
|
assert(batch instanceof Array, "batch must be an Array");
|
|
741
|
-
|
|
770
|
+
fjLog.debug('upsertBatch called', collection, batch);
|
|
742
771
|
const dbName = this.db; // Capture db at operation start
|
|
743
772
|
batch = this.replaceIds(batch);
|
|
744
773
|
await Promise.all(batch.map(item => this._processHashedKeys(item === null || item === void 0 ? void 0 : item.update)));
|
|
@@ -812,14 +841,14 @@ export class Mongo extends Db {
|
|
|
812
841
|
}
|
|
813
842
|
return changes;
|
|
814
843
|
}, false, { operation: "upsertBatch", collection, batch });
|
|
815
|
-
|
|
844
|
+
fjLog.debug('upsertBatch returns', ret);
|
|
816
845
|
return ret;
|
|
817
846
|
}
|
|
818
847
|
async insertMany(collection, insert) {
|
|
819
848
|
assert(collection, "collection can't be null");
|
|
820
849
|
assert(insert, "insert can't be null");
|
|
821
850
|
assert(insert instanceof Array, "insert must be an Array");
|
|
822
|
-
|
|
851
|
+
fjLog.debug('insertMany called', collection, insert);
|
|
823
852
|
const dbName = this.db; // Capture db at operation start
|
|
824
853
|
insert = this.replaceIds(insert);
|
|
825
854
|
await Promise.all(insert.map(item => this._processHashedKeys(item)));
|
|
@@ -842,7 +871,7 @@ export class Mongo extends Db {
|
|
|
842
871
|
}
|
|
843
872
|
return ret;
|
|
844
873
|
}, false, { operation: "insertMany", collection, insert });
|
|
845
|
-
|
|
874
|
+
fjLog.debug('insertMany returns', ret);
|
|
846
875
|
return ret;
|
|
847
876
|
}
|
|
848
877
|
async deleteOne(collection, query) {
|
|
@@ -852,14 +881,14 @@ export class Mongo extends Db {
|
|
|
852
881
|
query = this.replaceIds(query);
|
|
853
882
|
if (!this.softdelete) {
|
|
854
883
|
const opts = this._sessionOpt();
|
|
855
|
-
|
|
884
|
+
fjLog.debug('deleteOne called', this.softdelete, collection, query);
|
|
856
885
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
857
886
|
let obj = await conn.findOneAndDelete(query, opts);
|
|
858
887
|
if (obj)
|
|
859
888
|
await this._publishAndAudit('delete', dbName, collection, obj);
|
|
860
889
|
return obj;
|
|
861
890
|
}, false, { operation: "deleteOne", collection, query, softdelete: this.softdelete });
|
|
862
|
-
|
|
891
|
+
fjLog.debug('deleteOne returns', ret);
|
|
863
892
|
return ret;
|
|
864
893
|
}
|
|
865
894
|
else {
|
|
@@ -868,7 +897,7 @@ export class Mongo extends Db {
|
|
|
868
897
|
returnDocument: "after",
|
|
869
898
|
...this._sessionOpt()
|
|
870
899
|
};
|
|
871
|
-
|
|
900
|
+
fjLog.debug('deleteOne called', collection, query);
|
|
872
901
|
let ret = await this.executeTransactionally(collection, async (conn /*, client*/) => {
|
|
873
902
|
let del = {
|
|
874
903
|
$set: { _deleted: new Date() },
|
|
@@ -881,7 +910,7 @@ export class Mongo extends Db {
|
|
|
881
910
|
await this._publishAndAudit('delete', dbName, collection, obj);
|
|
882
911
|
return obj;
|
|
883
912
|
}, false, { operation: "deleteOne", collection, query, softdelete: this.softdelete });
|
|
884
|
-
|
|
913
|
+
fjLog.debug('deleteOne returns', ret);
|
|
885
914
|
return ret;
|
|
886
915
|
}
|
|
887
916
|
}
|
|
@@ -893,7 +922,7 @@ export class Mongo extends Db {
|
|
|
893
922
|
};
|
|
894
923
|
const dbName = this.db; // Capture db at operation start
|
|
895
924
|
query = this.replaceIds(query);
|
|
896
|
-
|
|
925
|
+
fjLog.debug('blockOne called', collection, query);
|
|
897
926
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
898
927
|
query._blocked = { $exists: 0 };
|
|
899
928
|
let update = {
|
|
@@ -910,7 +939,7 @@ export class Mongo extends Db {
|
|
|
910
939
|
await this._publishAndAudit('update', dbName, collection, obj);
|
|
911
940
|
return obj;
|
|
912
941
|
}, false, { operation: "blockOne", collection, query });
|
|
913
|
-
|
|
942
|
+
fjLog.debug('blockOne returns', ret);
|
|
914
943
|
return ret;
|
|
915
944
|
}
|
|
916
945
|
async unblockOne(collection, query) {
|
|
@@ -921,7 +950,7 @@ export class Mongo extends Db {
|
|
|
921
950
|
};
|
|
922
951
|
const dbName = this.db; // Capture db at operation start
|
|
923
952
|
query = this.replaceIds(query);
|
|
924
|
-
|
|
953
|
+
fjLog.debug('unblockOne called', collection, query);
|
|
925
954
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
926
955
|
query._blocked = { $exists: 1 };
|
|
927
956
|
let update = {
|
|
@@ -938,7 +967,7 @@ export class Mongo extends Db {
|
|
|
938
967
|
await this._publishAndAudit('update', dbName, collection, obj);
|
|
939
968
|
return obj;
|
|
940
969
|
}, false, { operation: "unblockOne", collection, query });
|
|
941
|
-
|
|
970
|
+
fjLog.debug('unblockOne returns', ret);
|
|
942
971
|
return ret;
|
|
943
972
|
}
|
|
944
973
|
async hardDeleteOne(collection, query) {
|
|
@@ -953,7 +982,7 @@ export class Mongo extends Db {
|
|
|
953
982
|
returnDocument: "after",
|
|
954
983
|
...this._sessionOpt()
|
|
955
984
|
};
|
|
956
|
-
|
|
985
|
+
fjLog.debug('hardDeleteOne called', collection, query);
|
|
957
986
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
958
987
|
let obj = await conn.findOneAndDelete(query, opts);
|
|
959
988
|
if (obj) {
|
|
@@ -961,18 +990,18 @@ export class Mongo extends Db {
|
|
|
961
990
|
}
|
|
962
991
|
return obj;
|
|
963
992
|
}, false, { operation: "hardDeleteOne", collection, query });
|
|
964
|
-
|
|
993
|
+
fjLog.debug('hardDeleteOne returns', ret);
|
|
965
994
|
return ret;
|
|
966
995
|
}
|
|
967
996
|
async delete(collection, query) {
|
|
968
997
|
assert(collection);
|
|
969
998
|
assert(query);
|
|
970
|
-
// if (this.syncSupport)
|
|
999
|
+
// if (this.syncSupport) fjLog.warn("delete does not increase _csq, avoit it.")
|
|
971
1000
|
const dbName = this.db; // Capture db at operation start
|
|
972
1001
|
query = this.replaceIds(query);
|
|
973
1002
|
if (!this.softdelete) {
|
|
974
1003
|
const opts = this._sessionOpt();
|
|
975
|
-
|
|
1004
|
+
fjLog.debug('delete called', collection, query);
|
|
976
1005
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
977
1006
|
let obj = await conn.deleteMany(query, opts);
|
|
978
1007
|
let resObj = {
|
|
@@ -982,7 +1011,7 @@ export class Mongo extends Db {
|
|
|
982
1011
|
await this._publishAndAudit('deleteMany', dbName, collection, resObj);
|
|
983
1012
|
return resObj;
|
|
984
1013
|
}, false, { operation: "delete", collection, query, softdelete: this.softdelete });
|
|
985
|
-
|
|
1014
|
+
fjLog.debug('delete returns', ret);
|
|
986
1015
|
return ret;
|
|
987
1016
|
}
|
|
988
1017
|
else {
|
|
@@ -992,7 +1021,7 @@ export class Mongo extends Db {
|
|
|
992
1021
|
...this._sessionOpt()
|
|
993
1022
|
};
|
|
994
1023
|
let date = new Date();
|
|
995
|
-
|
|
1024
|
+
fjLog.debug('delete called', collection, query);
|
|
996
1025
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
997
1026
|
let upd = {
|
|
998
1027
|
$set: { _deleted: date },
|
|
@@ -1007,18 +1036,18 @@ export class Mongo extends Db {
|
|
|
1007
1036
|
await this._publishAndAudit('deleteMany', dbName, collection, resObj);
|
|
1008
1037
|
return resObj;
|
|
1009
1038
|
}, false, { operation: "delete", collection, query, softdelete: this.softdelete });
|
|
1010
|
-
|
|
1039
|
+
fjLog.debug('delete returns', ret);
|
|
1011
1040
|
return ret;
|
|
1012
1041
|
}
|
|
1013
1042
|
}
|
|
1014
1043
|
async hardDelete(collection, query) {
|
|
1015
1044
|
assert(collection);
|
|
1016
1045
|
assert(query);
|
|
1017
|
-
// if (this.syncSupport)
|
|
1046
|
+
// if (this.syncSupport) fjLog.warn("hardDelete does not increase _csq, avoit it.")
|
|
1018
1047
|
const dbName = this.db; // Capture db at operation start
|
|
1019
1048
|
query = this.replaceIds(query);
|
|
1020
1049
|
const opts = this._sessionOpt();
|
|
1021
|
-
|
|
1050
|
+
fjLog.debug('hardDelete called', collection, query);
|
|
1022
1051
|
let ret = await this.executeTransactionally(collection, async (conn) => {
|
|
1023
1052
|
let obj = await conn.deleteMany(query, opts);
|
|
1024
1053
|
let resObj = {
|
|
@@ -1028,12 +1057,12 @@ export class Mongo extends Db {
|
|
|
1028
1057
|
await this._publishAndAudit('deleteMany', dbName, collection, resObj);
|
|
1029
1058
|
return resObj;
|
|
1030
1059
|
}, false, { operation: "hardDelete", collection, query, softdelete: this.softdelete });
|
|
1031
|
-
|
|
1060
|
+
fjLog.debug('hardDelete returns', ret);
|
|
1032
1061
|
return ret;
|
|
1033
1062
|
}
|
|
1034
1063
|
async testHash(collection, query, field, unhashedValue) {
|
|
1035
1064
|
let _field;
|
|
1036
|
-
|
|
1065
|
+
fjLog.debug('testHash called', collection, query, field, unhashedValue);
|
|
1037
1066
|
if (typeof field === "object") {
|
|
1038
1067
|
if (Object.keys(field).length === 1)
|
|
1039
1068
|
[_field, unhashedValue] = Object.entries(field)[0];
|
|
@@ -1048,11 +1077,11 @@ export class Mongo extends Db {
|
|
|
1048
1077
|
let conn = await this.connect();
|
|
1049
1078
|
let obj = await conn.db(dbName).collection(collection).findOne(query, { projection: { [_field]: 1 }, ...this._sessionOpt() });
|
|
1050
1079
|
if (!obj || !obj[_field]) {
|
|
1051
|
-
|
|
1080
|
+
fjLog.debug('testHash returns false', obj);
|
|
1052
1081
|
return false;
|
|
1053
1082
|
}
|
|
1054
1083
|
let res = await bcrypt.compare(unhashedValue, obj[_field].hash);
|
|
1055
|
-
|
|
1084
|
+
fjLog.debug('testHash returns', res);
|
|
1056
1085
|
return res;
|
|
1057
1086
|
}
|
|
1058
1087
|
async aggregate(collection, pipeline, opts = {
|
|
@@ -1060,7 +1089,7 @@ export class Mongo extends Db {
|
|
|
1060
1089
|
}) {
|
|
1061
1090
|
assert(collection);
|
|
1062
1091
|
assert(pipeline instanceof Array);
|
|
1063
|
-
|
|
1092
|
+
fjLog.debug('aggregate called', collection, pipeline);
|
|
1064
1093
|
pipeline = this.replaceIds(pipeline);
|
|
1065
1094
|
if (this.session)
|
|
1066
1095
|
opts.session = this.session;
|
|
@@ -1068,7 +1097,7 @@ export class Mongo extends Db {
|
|
|
1068
1097
|
let res = await conn.aggregate(pipeline, opts).toArray();
|
|
1069
1098
|
return res;
|
|
1070
1099
|
}, false, { operation: "aggregate", collection, pipeline, opts });
|
|
1071
|
-
|
|
1100
|
+
fjLog.debug('aggregare returns', ret);
|
|
1072
1101
|
return ret;
|
|
1073
1102
|
}
|
|
1074
1103
|
async isUnique(collection, field, value, id) {
|
|
@@ -1076,7 +1105,7 @@ export class Mongo extends Db {
|
|
|
1076
1105
|
assert(field);
|
|
1077
1106
|
if (!value)
|
|
1078
1107
|
return false;
|
|
1079
|
-
|
|
1108
|
+
fjLog.debug('isUnique called', collection, field, value, id);
|
|
1080
1109
|
let _id = id === null || id === void 0 ? void 0 : id.toString();
|
|
1081
1110
|
let query = typeof value === "object" ? value : { [field]: value };
|
|
1082
1111
|
query = this.replaceIds(query);
|
|
@@ -1086,21 +1115,21 @@ export class Mongo extends Db {
|
|
|
1086
1115
|
return res;
|
|
1087
1116
|
}, false, { operation: "isUnique", collection, field, value, id });
|
|
1088
1117
|
let ret = true;
|
|
1089
|
-
|
|
1090
|
-
|
|
1118
|
+
fjLog.debug(`isUnique query`, query);
|
|
1119
|
+
fjLog.debug(`isUnique matches`, matches);
|
|
1091
1120
|
for (let match of matches || []) {
|
|
1092
1121
|
if (match._id.toString() !== _id && !match._deleted) {
|
|
1093
1122
|
ret = false;
|
|
1094
1123
|
return false;
|
|
1095
1124
|
}
|
|
1096
1125
|
}
|
|
1097
|
-
|
|
1126
|
+
fjLog.debug('isUnique returns', ret);
|
|
1098
1127
|
return ret;
|
|
1099
1128
|
}
|
|
1100
1129
|
async collectFieldValues(collection, field, inArray = false, opts) {
|
|
1101
1130
|
assert(collection);
|
|
1102
1131
|
assert(field);
|
|
1103
|
-
|
|
1132
|
+
fjLog.debug('collectFieldValues called', collection, field);
|
|
1104
1133
|
let pipeline = [
|
|
1105
1134
|
{ $group: { _id: '$' + field } },
|
|
1106
1135
|
{ $sort: { _id: 1 } }
|
|
@@ -1116,34 +1145,34 @@ export class Mongo extends Db {
|
|
|
1116
1145
|
return res;
|
|
1117
1146
|
}, false, { operation: "collectFieldValues", collection, field, inArray, pipeline, opts });
|
|
1118
1147
|
let ret = res === null || res === void 0 ? void 0 : res.map((v) => v._id);
|
|
1119
|
-
|
|
1148
|
+
fjLog.debug('collectFieldValues returns', ret);
|
|
1120
1149
|
return ret;
|
|
1121
1150
|
}
|
|
1122
1151
|
async dropCollection(collection) {
|
|
1123
1152
|
assert(collection);
|
|
1124
|
-
|
|
1153
|
+
fjLog.debug('dropCollection called', this.auditCollections);
|
|
1125
1154
|
const dbName = this.db; // Capture db at operation start
|
|
1126
1155
|
let client = await this.connect();
|
|
1127
1156
|
let existing = await client.db(dbName).collections();
|
|
1128
1157
|
if (existing.map((c) => c.collectionName).includes(collection)) {
|
|
1129
1158
|
await client.db(dbName).dropCollection(collection);
|
|
1130
1159
|
}
|
|
1131
|
-
|
|
1160
|
+
fjLog.debug('dropCollection returns');
|
|
1132
1161
|
}
|
|
1133
1162
|
async resetCollectionSync(collection) {
|
|
1134
1163
|
assert(collection);
|
|
1135
|
-
|
|
1164
|
+
fjLog.debug('resetCollectionSync called for', collection);
|
|
1136
1165
|
const dbName = this.db; // Capture db at operation start
|
|
1137
1166
|
let client = await this.connect();
|
|
1138
1167
|
await client.db(dbName)
|
|
1139
1168
|
.collection(SEQUENCES_COLLECTION)
|
|
1140
1169
|
.findOneAndDelete({ collection });
|
|
1141
|
-
|
|
1170
|
+
fjLog.debug(`resetCollectionSync for ${collection} returns`);
|
|
1142
1171
|
}
|
|
1143
1172
|
async dropCollections(collections) {
|
|
1144
1173
|
assert(collections);
|
|
1145
1174
|
assert(collections instanceof Array);
|
|
1146
|
-
|
|
1175
|
+
fjLog.debug('dropCollections called', this.auditCollections);
|
|
1147
1176
|
const dbName = this.db; // Capture db at operation start
|
|
1148
1177
|
let client = await this.connect();
|
|
1149
1178
|
let existing = await client.db(dbName).collections();
|
|
@@ -1152,12 +1181,12 @@ export class Mongo extends Db {
|
|
|
1152
1181
|
await client.db(dbName).dropCollection(collection);
|
|
1153
1182
|
}
|
|
1154
1183
|
}
|
|
1155
|
-
|
|
1184
|
+
fjLog.debug('dropCollections returns');
|
|
1156
1185
|
}
|
|
1157
1186
|
async createCollections(collections) {
|
|
1158
1187
|
assert(collections);
|
|
1159
1188
|
assert(collections instanceof Array);
|
|
1160
|
-
|
|
1189
|
+
fjLog.debug('createCollections called', this.auditCollections);
|
|
1161
1190
|
const dbName = this.db; // Capture db at operation start
|
|
1162
1191
|
let client = await this.connect();
|
|
1163
1192
|
let existing = await this.getCollections();
|
|
@@ -1166,22 +1195,22 @@ export class Mongo extends Db {
|
|
|
1166
1195
|
await client.db(dbName).createCollection(collection);
|
|
1167
1196
|
}
|
|
1168
1197
|
}
|
|
1169
|
-
|
|
1198
|
+
fjLog.debug('createCollections returns');
|
|
1170
1199
|
}
|
|
1171
1200
|
async createCollection(collection) {
|
|
1172
1201
|
assert(collection);
|
|
1173
|
-
|
|
1202
|
+
fjLog.debug('createCollection called', collection);
|
|
1174
1203
|
const dbName = this.db; // Capture db at operation start
|
|
1175
1204
|
let client = await this.connect();
|
|
1176
1205
|
let existing = await this.getCollections();
|
|
1177
1206
|
if (!existing.includes(collection)) {
|
|
1178
1207
|
await client.db(dbName).createCollection(collection);
|
|
1179
1208
|
}
|
|
1180
|
-
|
|
1209
|
+
fjLog.debug('createCollection returns');
|
|
1181
1210
|
}
|
|
1182
1211
|
async dbLogPurge(collection, _id) {
|
|
1183
1212
|
assert(collection);
|
|
1184
|
-
|
|
1213
|
+
fjLog.debug('dblogPurge called', collection, _id);
|
|
1185
1214
|
const dbName = this.db; // Capture db at operation start
|
|
1186
1215
|
let ret = await this.executeTransactionally(collection, async () => {
|
|
1187
1216
|
let cond = { db: dbName, collection, };
|
|
@@ -1197,12 +1226,12 @@ export class Mongo extends Db {
|
|
|
1197
1226
|
n: ret.deletedCount
|
|
1198
1227
|
};
|
|
1199
1228
|
}, false, { operation: "dbLogPurge", collection, _id });
|
|
1200
|
-
|
|
1229
|
+
fjLog.debug('dblogPurge returns', ret);
|
|
1201
1230
|
return ret;
|
|
1202
1231
|
}
|
|
1203
1232
|
async dbLogGet(collection, _id) {
|
|
1204
1233
|
assert(collection);
|
|
1205
|
-
|
|
1234
|
+
fjLog.debug('dblogGet called', collection, _id);
|
|
1206
1235
|
const dbName = this.db; // Capture db at operation start
|
|
1207
1236
|
let ret = await this.executeTransactionally(collection, async () => {
|
|
1208
1237
|
let cond = { db: dbName, collection };
|
|
@@ -1217,7 +1246,7 @@ export class Mongo extends Db {
|
|
|
1217
1246
|
.toArray();
|
|
1218
1247
|
return ret;
|
|
1219
1248
|
}, false, { operation: "dbLogGet", collection, _id });
|
|
1220
|
-
|
|
1249
|
+
fjLog.debug('dblogGet returns', ret);
|
|
1221
1250
|
return ret;
|
|
1222
1251
|
}
|
|
1223
1252
|
// HELPER FUNCTIONS
|
|
@@ -1281,32 +1310,32 @@ export class Mongo extends Db {
|
|
|
1281
1310
|
if (this.session) {
|
|
1282
1311
|
try {
|
|
1283
1312
|
if (await this.inTransaction()) {
|
|
1284
|
-
|
|
1313
|
+
fjLog.warn("Aborting active transaction during close");
|
|
1285
1314
|
await this.session.abortTransaction();
|
|
1286
|
-
|
|
1315
|
+
fjLog.info("transaction aborted");
|
|
1287
1316
|
}
|
|
1288
1317
|
await this.session.endSession();
|
|
1289
|
-
|
|
1318
|
+
fjLog.info("session ended");
|
|
1290
1319
|
}
|
|
1291
1320
|
catch (err) {
|
|
1292
|
-
|
|
1321
|
+
fjLog.error(`Error ending session ${err.message}`);
|
|
1293
1322
|
}
|
|
1294
1323
|
}
|
|
1295
1324
|
// 2. Clean up event listeners
|
|
1296
1325
|
try {
|
|
1297
1326
|
this.emitter.removeAllListeners();
|
|
1298
|
-
|
|
1327
|
+
fjLog.debug("event listeners removed");
|
|
1299
1328
|
}
|
|
1300
1329
|
catch (err) {
|
|
1301
|
-
|
|
1330
|
+
fjLog.error(`Error removing event listeners ${err.message}`);
|
|
1302
1331
|
}
|
|
1303
1332
|
// 3. Close parent connection
|
|
1304
1333
|
try {
|
|
1305
1334
|
await super.close(force);
|
|
1306
|
-
|
|
1335
|
+
fjLog.info("connection closed");
|
|
1307
1336
|
}
|
|
1308
1337
|
catch (err) {
|
|
1309
|
-
|
|
1338
|
+
fjLog.debug(`close parent connection failed: ${err.message || err}`);
|
|
1310
1339
|
}
|
|
1311
1340
|
// 4. Clean up state
|
|
1312
1341
|
this.session = undefined;
|
|
@@ -1326,13 +1355,13 @@ export class Mongo extends Db {
|
|
|
1326
1355
|
let client = await this.connect();
|
|
1327
1356
|
if (!this.session) {
|
|
1328
1357
|
this.session = client.startSession();
|
|
1329
|
-
|
|
1358
|
+
fjLog.info("session started");
|
|
1330
1359
|
}
|
|
1331
1360
|
let session = this.session;
|
|
1332
1361
|
await session.withTransaction(async () => await funct(client, session));
|
|
1333
1362
|
if (!hadSession) {
|
|
1334
1363
|
session.endSession();
|
|
1335
|
-
|
|
1364
|
+
fjLog.info("session ended");
|
|
1336
1365
|
this.session = undefined;
|
|
1337
1366
|
}
|
|
1338
1367
|
return;
|
|
@@ -1341,7 +1370,7 @@ export class Mongo extends Db {
|
|
|
1341
1370
|
if (!hadSession && this.session) {
|
|
1342
1371
|
try {
|
|
1343
1372
|
await this.session.endSession();
|
|
1344
|
-
|
|
1373
|
+
fjLog.info("session ended after error");
|
|
1345
1374
|
}
|
|
1346
1375
|
catch { /* ignore cleanup errors */ }
|
|
1347
1376
|
this.session = undefined;
|
|
@@ -1356,24 +1385,24 @@ export class Mongo extends Db {
|
|
|
1356
1385
|
try {
|
|
1357
1386
|
if (!this.session) {
|
|
1358
1387
|
this.session = client.startSession(TRANSACTION_OPTIONS);
|
|
1359
|
-
|
|
1388
|
+
fjLog.info("session started");
|
|
1360
1389
|
}
|
|
1361
1390
|
if (!await this.inTransaction()) {
|
|
1362
1391
|
await this.session.startTransaction();
|
|
1363
|
-
|
|
1392
|
+
fjLog.info("transaction started");
|
|
1364
1393
|
}
|
|
1365
1394
|
}
|
|
1366
1395
|
catch (err) {
|
|
1367
|
-
|
|
1396
|
+
fjLog.error('startTransaction error', err);
|
|
1368
1397
|
try {
|
|
1369
1398
|
if (this.session) {
|
|
1370
1399
|
await this.session.endSession();
|
|
1371
|
-
|
|
1400
|
+
fjLog.info("session ended");
|
|
1372
1401
|
}
|
|
1373
1402
|
this.session = undefined;
|
|
1374
1403
|
}
|
|
1375
1404
|
catch (e) {
|
|
1376
|
-
|
|
1405
|
+
fjLog.error("startTransaction - error in endSession", e.message || e);
|
|
1377
1406
|
}
|
|
1378
1407
|
return;
|
|
1379
1408
|
}
|
|
@@ -1386,13 +1415,13 @@ export class Mongo extends Db {
|
|
|
1386
1415
|
return;
|
|
1387
1416
|
let session = this.session;
|
|
1388
1417
|
await session.commitTransaction();
|
|
1389
|
-
|
|
1418
|
+
fjLog.info("transaction committed");
|
|
1390
1419
|
session.endSession();
|
|
1391
1420
|
this.session = undefined;
|
|
1392
|
-
|
|
1421
|
+
fjLog.info("session ended");
|
|
1393
1422
|
}
|
|
1394
1423
|
catch (err) {
|
|
1395
|
-
|
|
1424
|
+
fjLog.error(`commitTransaction error ${err.message || err}`);
|
|
1396
1425
|
}
|
|
1397
1426
|
}
|
|
1398
1427
|
async abortTransaction() {
|
|
@@ -1403,13 +1432,13 @@ export class Mongo extends Db {
|
|
|
1403
1432
|
return;
|
|
1404
1433
|
let session = this.session;
|
|
1405
1434
|
await session.abortTransaction();
|
|
1406
|
-
|
|
1435
|
+
fjLog.info("transaction aborted");
|
|
1407
1436
|
await session.endSession();
|
|
1408
1437
|
this.session = undefined;
|
|
1409
|
-
|
|
1438
|
+
fjLog.info("session ended");
|
|
1410
1439
|
}
|
|
1411
1440
|
catch (err) {
|
|
1412
|
-
|
|
1441
|
+
fjLog.error(`abortTransaction error ${err.message || err}`);
|
|
1413
1442
|
}
|
|
1414
1443
|
}
|
|
1415
1444
|
async _try_once(useTransaction, f, collection, dbName) {
|
|
@@ -1434,7 +1463,7 @@ export class Mongo extends Db {
|
|
|
1434
1463
|
await this.abortTransaction();
|
|
1435
1464
|
}
|
|
1436
1465
|
catch (abortErr) {
|
|
1437
|
-
|
|
1466
|
+
fjLog.debug(`abort transaction failed: ${abortErr.message || abortErr}`);
|
|
1438
1467
|
}
|
|
1439
1468
|
throw err;
|
|
1440
1469
|
}
|
|
@@ -1449,13 +1478,13 @@ export class Mongo extends Db {
|
|
|
1449
1478
|
return await this._try_once(useTransaction, f, collection, dbName);
|
|
1450
1479
|
}
|
|
1451
1480
|
catch (err) {
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1481
|
+
fjLog.error(`Mongo command has failed for ${dbName}.${collection} - ${(this.session ? "ROLLBACK - " : "")} ${err.message || err}`);
|
|
1482
|
+
fjLog.error(debugObject);
|
|
1483
|
+
fjLog.debug(err);
|
|
1455
1484
|
let x = ((err === null || err === void 0 ? void 0 : err.message) || (err === null || err === void 0 ? void 0 : err.toString()) || "").toString();
|
|
1456
1485
|
// test for duplicate ID insert
|
|
1457
1486
|
if ((x === null || x === void 0 ? void 0 : x.match(/E11000/gi)) && debugObject.operation === "insert") {
|
|
1458
|
-
|
|
1487
|
+
fjLog.error("Duplicate ID insert - ignoring and returning inserted object");
|
|
1459
1488
|
return debugObject.insert;
|
|
1460
1489
|
}
|
|
1461
1490
|
let isRepeatable = x.match(/Topology is closed, please connect/i)
|
|
@@ -1466,21 +1495,21 @@ export class Mongo extends Db {
|
|
|
1466
1495
|
|| x.match(/Connection pool closed/i);
|
|
1467
1496
|
if (isRepeatable) {
|
|
1468
1497
|
try {
|
|
1469
|
-
|
|
1498
|
+
fjLog.error("Trying to reopen connection and repeat as");
|
|
1470
1499
|
await this.close();
|
|
1471
1500
|
// a single retry
|
|
1472
1501
|
await super.connect();
|
|
1473
1502
|
let ret = await this._try_once(useTransaction, f, collection, dbName);
|
|
1474
|
-
|
|
1475
|
-
|
|
1503
|
+
fjLog.error("OK - Retry succeeded.");
|
|
1504
|
+
fjLog.error("");
|
|
1476
1505
|
return ret;
|
|
1477
1506
|
}
|
|
1478
1507
|
catch (err2) {
|
|
1479
1508
|
/* intentional */
|
|
1480
1509
|
if (debugObject)
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1510
|
+
fjLog.error(debugObject);
|
|
1511
|
+
fjLog.error(`FAIL - Retry failed: ${err2.message || err2}`);
|
|
1512
|
+
fjLog.error("");
|
|
1484
1513
|
}
|
|
1485
1514
|
}
|
|
1486
1515
|
throw err;
|
|
@@ -1732,7 +1761,7 @@ export class Mongo extends Db {
|
|
|
1732
1761
|
return toPublish;
|
|
1733
1762
|
}
|
|
1734
1763
|
emit(event, what) {
|
|
1735
|
-
|
|
1764
|
+
fjLog.debug("emitting", event, what);
|
|
1736
1765
|
if (event === "publish")
|
|
1737
1766
|
this.emitter.emit(event, what);
|
|
1738
1767
|
if (event === "publishRev")
|
|
@@ -1766,11 +1795,11 @@ export class Mongo extends Db {
|
|
|
1766
1795
|
auditRecord.user = user;
|
|
1767
1796
|
if (audit)
|
|
1768
1797
|
auditRecord.audit = audit;
|
|
1769
|
-
|
|
1798
|
+
fjLog.trace('AUDITING', auditRecord);
|
|
1770
1799
|
let ret = await client.db(db)
|
|
1771
1800
|
.collection(this.auditCollectionName)
|
|
1772
1801
|
.insertOne(auditRecord, this._sessionOpt());
|
|
1773
|
-
|
|
1802
|
+
fjLog.debug('AUDITED', auditRecord, ret.insertedId);
|
|
1774
1803
|
}
|
|
1775
1804
|
_sessionOpt() {
|
|
1776
1805
|
return this.session ? { session: this.session } : {};
|