@mikro-orm/core 6.4.7-dev.1 → 7.0.0-dev.0
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/EntityManager.d.ts +3 -2
- package/EntityManager.js +119 -101
- package/MikroORM.d.ts +8 -8
- package/MikroORM.js +1 -1
- package/README.md +0 -2
- package/connections/Connection.d.ts +3 -7
- package/drivers/DatabaseDriver.js +2 -6
- package/entity/Collection.js +8 -8
- package/entity/Reference.js +5 -5
- package/events/EventManager.js +4 -4
- package/events/TransactionEventBroadcaster.d.ts +1 -5
- package/events/TransactionEventBroadcaster.js +6 -9
- package/index.mjs +2 -0
- package/logging/Logger.d.ts +1 -1
- package/metadata/MetadataDiscovery.js +12 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +1 -1
- package/naming-strategy/NamingStrategy.d.ts +1 -1
- package/package.json +3 -3
- package/platforms/Platform.d.ts +13 -4
- package/platforms/Platform.js +26 -6
- package/serialization/EntitySerializer.js +2 -1
- package/serialization/EntityTransformer.js +2 -1
- package/typings.d.ts +12 -4
- package/typings.js +23 -6
- package/unit-of-work/ChangeSetComputer.d.ts +1 -1
- package/unit-of-work/ChangeSetComputer.js +9 -9
- package/unit-of-work/ChangeSetPersister.d.ts +1 -1
- package/unit-of-work/ChangeSetPersister.js +19 -18
- package/unit-of-work/UnitOfWork.js +1 -1
- package/utils/AbstractSchemaGenerator.js +3 -1
- package/utils/Configuration.d.ts +6 -20
- package/utils/Configuration.js +11 -5
- package/utils/ConfigurationLoader.js +7 -8
- package/utils/DataloaderUtils.d.ts +0 -2
- package/utils/DataloaderUtils.js +0 -10
- package/utils/QueryHelper.js +5 -5
- package/utils/RawQueryFragment.d.ts +2 -0
- package/utils/RawQueryFragment.js +8 -2
- package/utils/Utils.d.ts +1 -1
- package/utils/Utils.js +1 -1
package/EntityManager.js
CHANGED
|
@@ -6,7 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.EntityManager = void 0;
|
|
7
7
|
const node_util_1 = require("node:util");
|
|
8
8
|
const dataloader_1 = __importDefault(require("dataloader"));
|
|
9
|
-
const
|
|
9
|
+
const upsert_utils_1 = require("./utils/upsert-utils");
|
|
10
|
+
const Utils_1 = require("./utils/Utils");
|
|
11
|
+
const Cursor_1 = require("./utils/Cursor");
|
|
12
|
+
const DataloaderUtils_1 = require("./utils/DataloaderUtils");
|
|
13
|
+
const QueryHelper_1 = require("./utils/QueryHelper");
|
|
14
|
+
const TransactionContext_1 = require("./utils/TransactionContext");
|
|
15
|
+
const RawQueryFragment_1 = require("./utils/RawQueryFragment");
|
|
10
16
|
const entity_1 = require("./entity");
|
|
11
17
|
const unit_of_work_1 = require("./unit-of-work");
|
|
12
18
|
const enums_1 = require("./enums");
|
|
@@ -27,8 +33,8 @@ class EntityManager {
|
|
|
27
33
|
_id = EntityManager.counter++;
|
|
28
34
|
global = false;
|
|
29
35
|
name;
|
|
30
|
-
refLoader = new dataloader_1.default(
|
|
31
|
-
colLoader = new dataloader_1.default(
|
|
36
|
+
refLoader = new dataloader_1.default(DataloaderUtils_1.DataloaderUtils.getRefBatchLoadFn(this));
|
|
37
|
+
colLoader = new dataloader_1.default(DataloaderUtils_1.DataloaderUtils.getColBatchLoadFn(this));
|
|
32
38
|
validator;
|
|
33
39
|
repositoryMap = {};
|
|
34
40
|
entityLoader;
|
|
@@ -84,7 +90,7 @@ class EntityManager {
|
|
|
84
90
|
* Gets repository for given entity. You can pass either string name or entity class reference.
|
|
85
91
|
*/
|
|
86
92
|
getRepository(entityName) {
|
|
87
|
-
entityName =
|
|
93
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
88
94
|
if (!this.repositoryMap[entityName]) {
|
|
89
95
|
const meta = this.metadata.get(entityName);
|
|
90
96
|
const RepositoryClass = this.config.getRepositoryClass(meta.repository);
|
|
@@ -118,7 +124,7 @@ class EntityManager {
|
|
|
118
124
|
const em = this.getContext();
|
|
119
125
|
em.prepareOptions(options);
|
|
120
126
|
await em.tryFlush(entityName, options);
|
|
121
|
-
entityName =
|
|
127
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
122
128
|
where = await em.processWhere(entityName, where, options, 'read');
|
|
123
129
|
em.validator.validateParams(where);
|
|
124
130
|
options.orderBy = options.orderBy || {};
|
|
@@ -157,7 +163,7 @@ class EntityManager {
|
|
|
157
163
|
});
|
|
158
164
|
ret.push(entity);
|
|
159
165
|
}
|
|
160
|
-
const unique =
|
|
166
|
+
const unique = Utils_1.Utils.unique(ret);
|
|
161
167
|
await em.entityLoader.populate(entityName, unique, populate, {
|
|
162
168
|
...options,
|
|
163
169
|
...em.getPopulateWhere(where, options),
|
|
@@ -199,7 +205,7 @@ class EntityManager {
|
|
|
199
205
|
addFilter(name, cond, entityName, enabled = true) {
|
|
200
206
|
const options = { name, cond, default: enabled };
|
|
201
207
|
if (entityName) {
|
|
202
|
-
options.entity =
|
|
208
|
+
options.entity = Utils_1.Utils.asArray(entityName).map(n => Utils_1.Utils.className(n));
|
|
203
209
|
}
|
|
204
210
|
this.getContext(false).filters[name] = options;
|
|
205
211
|
}
|
|
@@ -234,7 +240,7 @@ class EntityManager {
|
|
|
234
240
|
this.getContext(false).flushMode = flushMode;
|
|
235
241
|
}
|
|
236
242
|
async processWhere(entityName, where, options, type) {
|
|
237
|
-
where =
|
|
243
|
+
where = QueryHelper_1.QueryHelper.processWhere({
|
|
238
244
|
where,
|
|
239
245
|
entityName,
|
|
240
246
|
metadata: this.metadata,
|
|
@@ -269,10 +275,10 @@ class EntityManager {
|
|
|
269
275
|
const ret = {};
|
|
270
276
|
const populateWhere = options.populateWhere ?? this.config.get('populateWhere');
|
|
271
277
|
if (populateWhere === enums_1.PopulateHint.INFER) {
|
|
272
|
-
|
|
278
|
+
Utils_1.Utils.merge(ret, cond);
|
|
273
279
|
}
|
|
274
280
|
else if (typeof populateWhere === 'object') {
|
|
275
|
-
|
|
281
|
+
Utils_1.Utils.merge(ret, populateWhere);
|
|
276
282
|
}
|
|
277
283
|
return ret;
|
|
278
284
|
}
|
|
@@ -288,12 +294,12 @@ class EntityManager {
|
|
|
288
294
|
}
|
|
289
295
|
const where = await this.applyFilters(prop.type, {}, options.filters ?? {}, 'read', { ...options, populate: hint.children });
|
|
290
296
|
const where2 = await this.getJoinedFilters(prop.targetMeta, {}, { ...options, populate: hint.children, populateWhere: enums_1.PopulateHint.ALL });
|
|
291
|
-
if (
|
|
297
|
+
if (Utils_1.Utils.hasObjectKeys(where)) {
|
|
292
298
|
ret[field] = ret[field] ? { $and: [where, ret[field]] } : where;
|
|
293
299
|
}
|
|
294
|
-
if (
|
|
300
|
+
if (Utils_1.Utils.hasObjectKeys(where2)) {
|
|
295
301
|
if (ret[field]) {
|
|
296
|
-
|
|
302
|
+
Utils_1.Utils.merge(ret[field], where2);
|
|
297
303
|
}
|
|
298
304
|
else {
|
|
299
305
|
ret[field] = where2;
|
|
@@ -317,7 +323,7 @@ class EntityManager {
|
|
|
317
323
|
const ret = options.populate;
|
|
318
324
|
for (const prop of props) {
|
|
319
325
|
const cond = await this.applyFilters(prop.type, {}, options.filters ?? {}, 'read', options);
|
|
320
|
-
if (!
|
|
326
|
+
if (!Utils_1.Utils.isEmpty(cond)) {
|
|
321
327
|
const populated = options.populate.filter(({ field }) => field.split(':')[0] === prop.name);
|
|
322
328
|
if (populated.length > 0) {
|
|
323
329
|
populated.forEach(hint => hint.filter = true);
|
|
@@ -340,7 +346,7 @@ class EntityManager {
|
|
|
340
346
|
}
|
|
341
347
|
const active = new Set();
|
|
342
348
|
const push = (source) => {
|
|
343
|
-
const activeFilters =
|
|
349
|
+
const activeFilters = QueryHelper_1.QueryHelper
|
|
344
350
|
.getActiveFilters(entityName, options, source)
|
|
345
351
|
.filter(f => !active.has(f.name));
|
|
346
352
|
filters.push(...activeFilters);
|
|
@@ -356,7 +362,7 @@ class EntityManager {
|
|
|
356
362
|
let cond;
|
|
357
363
|
if (filter.cond instanceof Function) {
|
|
358
364
|
// @ts-ignore
|
|
359
|
-
const args =
|
|
365
|
+
const args = Utils_1.Utils.isPlainObject(options[filter.name]) ? options[filter.name] : this.getContext().filterParams[filter.name];
|
|
360
366
|
if (!args && filter.cond.length > 0 && filter.args !== false) {
|
|
361
367
|
throw new Error(`No arguments provided for filter '${filter.name}'`);
|
|
362
368
|
}
|
|
@@ -365,7 +371,7 @@ class EntityManager {
|
|
|
365
371
|
else {
|
|
366
372
|
cond = filter.cond;
|
|
367
373
|
}
|
|
368
|
-
ret.push(
|
|
374
|
+
ret.push(QueryHelper_1.QueryHelper.processWhere({
|
|
369
375
|
where: cond,
|
|
370
376
|
entityName,
|
|
371
377
|
metadata: this.metadata,
|
|
@@ -373,7 +379,7 @@ class EntityManager {
|
|
|
373
379
|
aliased: type === 'read',
|
|
374
380
|
}));
|
|
375
381
|
}
|
|
376
|
-
const conds = [...ret, where].filter(c =>
|
|
382
|
+
const conds = [...ret, where].filter(c => Utils_1.Utils.hasObjectKeys(c));
|
|
377
383
|
return conds.length > 1 ? { $and: conds } : conds[0];
|
|
378
384
|
}
|
|
379
385
|
/**
|
|
@@ -384,7 +390,7 @@ class EntityManager {
|
|
|
384
390
|
const em = this.getContext(false);
|
|
385
391
|
await em.tryFlush(entityName, options);
|
|
386
392
|
options.flushMode = 'commit'; // do not try to auto flush again
|
|
387
|
-
return
|
|
393
|
+
return RawQueryFragment_1.RawQueryFragment.run(async () => {
|
|
388
394
|
return Promise.all([
|
|
389
395
|
em.find(entityName, where, options),
|
|
390
396
|
em.count(entityName, where, options),
|
|
@@ -445,13 +451,13 @@ class EntityManager {
|
|
|
445
451
|
*/
|
|
446
452
|
async findByCursor(entityName, where, options) {
|
|
447
453
|
const em = this.getContext(false);
|
|
448
|
-
entityName =
|
|
454
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
449
455
|
options.overfetch ??= true;
|
|
450
|
-
if (
|
|
456
|
+
if (Utils_1.Utils.isEmpty(options.orderBy)) {
|
|
451
457
|
throw new Error('Explicit `orderBy` option required');
|
|
452
458
|
}
|
|
453
459
|
const [entities, count] = await em.findAndCount(entityName, where, options);
|
|
454
|
-
return new
|
|
460
|
+
return new Cursor_1.Cursor(entities, count, options, this.metadata.get(entityName));
|
|
455
461
|
}
|
|
456
462
|
/**
|
|
457
463
|
* Refreshes the persistent state of an entity from the database, overriding any local changes that have not yet been
|
|
@@ -501,7 +507,7 @@ class EntityManager {
|
|
|
501
507
|
return ret;
|
|
502
508
|
}
|
|
503
509
|
const em = this.getContext();
|
|
504
|
-
entityName =
|
|
510
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
505
511
|
em.prepareOptions(options);
|
|
506
512
|
let entity = em.unitOfWork.tryGetById(entityName, where, options.schema);
|
|
507
513
|
// query for a not managed entity which is already in the identity map as it
|
|
@@ -515,7 +521,7 @@ class EntityManager {
|
|
|
515
521
|
where = await em.processWhere(entityName, where, options, 'read');
|
|
516
522
|
em.validator.validateEmptyWhere(where);
|
|
517
523
|
em.checkLockRequirements(options.lockMode, meta);
|
|
518
|
-
const isOptimisticLocking = !
|
|
524
|
+
const isOptimisticLocking = !Utils_1.Utils.isDefined(options.lockMode) || options.lockMode === enums_1.LockMode.OPTIMISTIC;
|
|
519
525
|
if (entity && !em.shouldRefresh(meta, entity, options) && isOptimisticLocking) {
|
|
520
526
|
return em.lockAndPopulate(meta, entity, where, options);
|
|
521
527
|
}
|
|
@@ -577,9 +583,9 @@ class EntityManager {
|
|
|
577
583
|
if (!entity || isStrictViolation) {
|
|
578
584
|
const key = options.strict ? 'findExactlyOneOrFailHandler' : 'findOneOrFailHandler';
|
|
579
585
|
options.failHandler ??= this.config.get(key);
|
|
580
|
-
entityName =
|
|
586
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
581
587
|
/* istanbul ignore next */
|
|
582
|
-
where =
|
|
588
|
+
where = Utils_1.Utils.isEntity(where) ? (0, entity_1.helper)(where).getPrimaryKey() : where;
|
|
583
589
|
throw options.failHandler(entityName, where);
|
|
584
590
|
}
|
|
585
591
|
return entity;
|
|
@@ -624,11 +630,11 @@ class EntityManager {
|
|
|
624
630
|
data = entityNameOrEntity;
|
|
625
631
|
}
|
|
626
632
|
else {
|
|
627
|
-
entityName =
|
|
633
|
+
entityName = Utils_1.Utils.className(entityNameOrEntity);
|
|
628
634
|
}
|
|
629
635
|
const meta = this.metadata.get(entityName);
|
|
630
|
-
const convertCustomTypes = !
|
|
631
|
-
if (
|
|
636
|
+
const convertCustomTypes = !Utils_1.Utils.isEntity(data);
|
|
637
|
+
if (Utils_1.Utils.isEntity(data)) {
|
|
632
638
|
entity = data;
|
|
633
639
|
if ((0, entity_1.helper)(entity).__managed && (0, entity_1.helper)(entity).__em === em && !this.config.get('upsertManaged')) {
|
|
634
640
|
em.entityFactory.mergeData(meta, entity, data, { initialized: true });
|
|
@@ -638,8 +644,8 @@ class EntityManager {
|
|
|
638
644
|
data = em.comparator.prepareEntity(entity);
|
|
639
645
|
}
|
|
640
646
|
else {
|
|
641
|
-
data =
|
|
642
|
-
where =
|
|
647
|
+
data = Utils_1.Utils.copy(QueryHelper_1.QueryHelper.processParams(data));
|
|
648
|
+
where = Utils_1.Utils.extractPK(data, meta);
|
|
643
649
|
if (where && !this.config.get('upsertManaged')) {
|
|
644
650
|
const exists = em.unitOfWork.getById(entityName, where, options.schema);
|
|
645
651
|
if (exists) {
|
|
@@ -648,15 +654,15 @@ class EntityManager {
|
|
|
648
654
|
}
|
|
649
655
|
}
|
|
650
656
|
const unique = options.onConflictFields ?? meta.props.filter(p => p.unique).map(p => p.name);
|
|
651
|
-
const propIndex = !
|
|
657
|
+
const propIndex = !(0, RawQueryFragment_1.isRaw)(unique) && unique.findIndex(p => data[p] != null);
|
|
652
658
|
if (options.onConflictFields || where == null) {
|
|
653
659
|
if (propIndex !== false && propIndex >= 0) {
|
|
654
660
|
where = { [unique[propIndex]]: data[unique[propIndex]] };
|
|
655
661
|
}
|
|
656
662
|
else if (meta.uniques.length > 0) {
|
|
657
663
|
for (const u of meta.uniques) {
|
|
658
|
-
if (
|
|
659
|
-
where =
|
|
664
|
+
if (Utils_1.Utils.asArray(u.properties).every(p => data[p] != null)) {
|
|
665
|
+
where = Utils_1.Utils.asArray(u.properties).reduce((o, key) => {
|
|
660
666
|
o[key] = data[key];
|
|
661
667
|
return o;
|
|
662
668
|
}, {});
|
|
@@ -665,7 +671,7 @@ class EntityManager {
|
|
|
665
671
|
}
|
|
666
672
|
}
|
|
667
673
|
}
|
|
668
|
-
data =
|
|
674
|
+
data = QueryHelper_1.QueryHelper.processObjectParams(data);
|
|
669
675
|
em.validator.validateParams(data, 'insert data');
|
|
670
676
|
if (em.eventManager.hasListeners(enums_1.EventType.beforeUpsert, meta)) {
|
|
671
677
|
await em.eventManager.dispatchEvent(enums_1.EventType.beforeUpsert, { entity: data, em, meta }, meta);
|
|
@@ -682,8 +688,8 @@ class EntityManager {
|
|
|
682
688
|
initialized: true,
|
|
683
689
|
schema: options.schema,
|
|
684
690
|
});
|
|
685
|
-
const uniqueFields = options.onConflictFields ?? (
|
|
686
|
-
const returning = (0,
|
|
691
|
+
const uniqueFields = options.onConflictFields ?? (Utils_1.Utils.isPlainObject(where) ? Object.keys(where) : meta.primaryKeys);
|
|
692
|
+
const returning = (0, upsert_utils_1.getOnConflictReturningFields)(meta, data, uniqueFields, options);
|
|
687
693
|
if (options.onConflictAction === 'ignore' || !(0, entity_1.helper)(entity).hasPrimaryKey() || (returning.length > 0 && !(this.getPlatform().usesReturningStatement() && ret.row))) {
|
|
688
694
|
const where = {};
|
|
689
695
|
if (Array.isArray(uniqueFields)) {
|
|
@@ -696,6 +702,14 @@ class EntityManager {
|
|
|
696
702
|
}
|
|
697
703
|
}
|
|
698
704
|
}
|
|
705
|
+
else {
|
|
706
|
+
Object.keys(data).forEach(prop => {
|
|
707
|
+
where[prop] = data[prop];
|
|
708
|
+
});
|
|
709
|
+
if (meta.simplePK && ret.insertId != null) {
|
|
710
|
+
where[meta.primaryKeys[0]] = ret.insertId;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
699
713
|
const data2 = await this.driver.findOne(meta.className, where, {
|
|
700
714
|
fields: returning,
|
|
701
715
|
ctx: em.transactionContext,
|
|
@@ -754,7 +768,7 @@ class EntityManager {
|
|
|
754
768
|
data = entityNameOrEntity;
|
|
755
769
|
}
|
|
756
770
|
else {
|
|
757
|
-
entityName =
|
|
771
|
+
entityName = Utils_1.Utils.className(entityNameOrEntity);
|
|
758
772
|
}
|
|
759
773
|
const batchSize = options.batchSize ?? this.config.get('batchSize');
|
|
760
774
|
if (data.length > batchSize) {
|
|
@@ -766,7 +780,7 @@ class EntityManager {
|
|
|
766
780
|
return ret;
|
|
767
781
|
}
|
|
768
782
|
const meta = this.metadata.get(entityName);
|
|
769
|
-
const convertCustomTypes = !
|
|
783
|
+
const convertCustomTypes = !Utils_1.Utils.isEntity(data[0]);
|
|
770
784
|
const allData = [];
|
|
771
785
|
const allWhere = [];
|
|
772
786
|
const entities = new Map();
|
|
@@ -774,7 +788,7 @@ class EntityManager {
|
|
|
774
788
|
for (let i = 0; i < data.length; i++) {
|
|
775
789
|
let row = data[i];
|
|
776
790
|
let where;
|
|
777
|
-
if (
|
|
791
|
+
if (Utils_1.Utils.isEntity(row)) {
|
|
778
792
|
const entity = row;
|
|
779
793
|
if ((0, entity_1.helper)(entity).__managed && (0, entity_1.helper)(entity).__em === em && !this.config.get('upsertManaged')) {
|
|
780
794
|
em.entityFactory.mergeData(meta, entity, row, { initialized: true });
|
|
@@ -786,8 +800,8 @@ class EntityManager {
|
|
|
786
800
|
row = em.comparator.prepareEntity(entity);
|
|
787
801
|
}
|
|
788
802
|
else {
|
|
789
|
-
row = data[i] =
|
|
790
|
-
where =
|
|
803
|
+
row = data[i] = Utils_1.Utils.copy(QueryHelper_1.QueryHelper.processParams(row));
|
|
804
|
+
where = Utils_1.Utils.extractPK(row, meta);
|
|
791
805
|
if (where && !this.config.get('upsertManaged')) {
|
|
792
806
|
const exists = em.unitOfWork.getById(entityName, where, options.schema);
|
|
793
807
|
if (exists) {
|
|
@@ -806,8 +820,8 @@ class EntityManager {
|
|
|
806
820
|
}
|
|
807
821
|
else if (meta.uniques.length > 0) {
|
|
808
822
|
for (const u of meta.uniques) {
|
|
809
|
-
if (
|
|
810
|
-
where =
|
|
823
|
+
if (Utils_1.Utils.asArray(u.properties).every(p => row[p] != null)) {
|
|
824
|
+
where = Utils_1.Utils.asArray(u.properties).reduce((o, key) => {
|
|
811
825
|
o[key] = row[key];
|
|
812
826
|
return o;
|
|
813
827
|
}, {});
|
|
@@ -816,8 +830,8 @@ class EntityManager {
|
|
|
816
830
|
}
|
|
817
831
|
}
|
|
818
832
|
}
|
|
819
|
-
row =
|
|
820
|
-
where =
|
|
833
|
+
row = QueryHelper_1.QueryHelper.processObjectParams(row);
|
|
834
|
+
where = QueryHelper_1.QueryHelper.processWhere({
|
|
821
835
|
where,
|
|
822
836
|
entityName,
|
|
823
837
|
metadata: this.metadata,
|
|
@@ -846,8 +860,8 @@ class EntityManager {
|
|
|
846
860
|
entitiesByData.clear();
|
|
847
861
|
const loadPK = new Map();
|
|
848
862
|
allData.forEach((row, i) => {
|
|
849
|
-
em.unitOfWork.getChangeSetPersister().mapReturnedValues(
|
|
850
|
-
const entity =
|
|
863
|
+
em.unitOfWork.getChangeSetPersister().mapReturnedValues(Utils_1.Utils.isEntity(data[i]) ? data[i] : null, Utils_1.Utils.isEntity(data[i]) ? {} : data[i], res.rows?.[i], meta, true);
|
|
864
|
+
const entity = Utils_1.Utils.isEntity(data[i]) ? data[i] : em.entityFactory.create(entityName, row, {
|
|
851
865
|
refresh: true,
|
|
852
866
|
initialized: true,
|
|
853
867
|
schema: options.schema,
|
|
@@ -859,24 +873,23 @@ class EntityManager {
|
|
|
859
873
|
entitiesByData.set(row, entity);
|
|
860
874
|
});
|
|
861
875
|
// skip if we got the PKs via returning statement (`rows`)
|
|
862
|
-
const uniqueFields = options.onConflictFields ?? (
|
|
863
|
-
const returning = (0,
|
|
876
|
+
const uniqueFields = options.onConflictFields ?? (Utils_1.Utils.isPlainObject(allWhere[0]) ? Object.keys(allWhere[0]).flatMap(key => Utils_1.Utils.splitPrimaryKeys(key)) : meta.primaryKeys);
|
|
877
|
+
const returning = (0, upsert_utils_1.getOnConflictReturningFields)(meta, data[0], uniqueFields, options);
|
|
864
878
|
const reloadFields = returning.length > 0 && !(this.getPlatform().usesReturningStatement() && res.rows?.length);
|
|
865
879
|
if (options.onConflictAction === 'ignore' || (!res.rows?.length && loadPK.size > 0) || reloadFields) {
|
|
866
880
|
const unique = meta.hydrateProps.filter(p => !p.lazy).map(p => p.name);
|
|
867
881
|
const add = new Set(propIndex >= 0 ? [unique[propIndex]] : []);
|
|
868
882
|
for (const cond of loadPK.values()) {
|
|
869
|
-
|
|
883
|
+
Utils_1.Utils.keys(cond).forEach(key => add.add(key));
|
|
870
884
|
}
|
|
871
885
|
const where = { $or: [] };
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
});
|
|
886
|
+
data.forEach((item, idx) => {
|
|
887
|
+
where.$or[idx] = {};
|
|
888
|
+
const props = Array.isArray(uniqueFields) ? uniqueFields : Object.keys(item);
|
|
889
|
+
props.forEach(prop => {
|
|
890
|
+
where.$or[idx][prop] = item[prop];
|
|
878
891
|
});
|
|
879
|
-
}
|
|
892
|
+
});
|
|
880
893
|
const data2 = await this.driver.find(meta.className, where, {
|
|
881
894
|
fields: returning.concat(...add).concat(...(Array.isArray(uniqueFields) ? uniqueFields : [])),
|
|
882
895
|
ctx: em.transactionContext,
|
|
@@ -953,7 +966,7 @@ class EntityManager {
|
|
|
953
966
|
});
|
|
954
967
|
options.ctx ??= em.transactionContext;
|
|
955
968
|
const propagateToUpperContext = !em.global || this.config.get('allowGlobalContext');
|
|
956
|
-
return
|
|
969
|
+
return TransactionContext_1.TransactionContext.create(fork, async () => {
|
|
957
970
|
return fork.getConnection().transactional(async (trx) => {
|
|
958
971
|
fork.transactionContext = trx;
|
|
959
972
|
if (propagateToUpperContext) {
|
|
@@ -975,7 +988,7 @@ class EntityManager {
|
|
|
975
988
|
}
|
|
976
989
|
}
|
|
977
990
|
return ret;
|
|
978
|
-
}, { ...options, eventBroadcaster: new events_1.TransactionEventBroadcaster(fork,
|
|
991
|
+
}, { ...options, eventBroadcaster: new events_1.TransactionEventBroadcaster(fork, { topLevelTransaction: !options.ctx }) });
|
|
979
992
|
});
|
|
980
993
|
}
|
|
981
994
|
/**
|
|
@@ -988,7 +1001,7 @@ class EntityManager {
|
|
|
988
1001
|
const em = this.getContext(false);
|
|
989
1002
|
em.transactionContext = await em.getConnection('write').begin({
|
|
990
1003
|
...options,
|
|
991
|
-
eventBroadcaster: new events_1.TransactionEventBroadcaster(em,
|
|
1004
|
+
eventBroadcaster: new events_1.TransactionEventBroadcaster(em, { topLevelTransaction: !options.ctx }),
|
|
992
1005
|
});
|
|
993
1006
|
}
|
|
994
1007
|
/**
|
|
@@ -1026,7 +1039,7 @@ class EntityManager {
|
|
|
1026
1039
|
* Runs your callback wrapped inside a database transaction.
|
|
1027
1040
|
*/
|
|
1028
1041
|
async lock(entity, lockMode, options = {}) {
|
|
1029
|
-
options =
|
|
1042
|
+
options = Utils_1.Utils.isPlainObject(options) ? options : { lockVersion: options };
|
|
1030
1043
|
await this.getUnitOfWork().lock(entity, { lockMode, ...options });
|
|
1031
1044
|
}
|
|
1032
1045
|
/**
|
|
@@ -1041,9 +1054,9 @@ class EntityManager {
|
|
|
1041
1054
|
data = entityNameOrEntity;
|
|
1042
1055
|
}
|
|
1043
1056
|
else {
|
|
1044
|
-
entityName =
|
|
1057
|
+
entityName = Utils_1.Utils.className(entityNameOrEntity);
|
|
1045
1058
|
}
|
|
1046
|
-
if (
|
|
1059
|
+
if (Utils_1.Utils.isEntity(data)) {
|
|
1047
1060
|
if (options.schema && (0, entity_1.helper)(data).getSchema() == null) {
|
|
1048
1061
|
(0, entity_1.helper)(data).setSchema(options.schema);
|
|
1049
1062
|
}
|
|
@@ -1059,7 +1072,7 @@ class EntityManager {
|
|
|
1059
1072
|
await em.unitOfWork.getChangeSetPersister().executeInserts([cs], { ctx: em.transactionContext, ...options });
|
|
1060
1073
|
return cs.getPrimaryKey();
|
|
1061
1074
|
}
|
|
1062
|
-
data =
|
|
1075
|
+
data = QueryHelper_1.QueryHelper.processObjectParams(data);
|
|
1063
1076
|
em.validator.validateParams(data, 'insert data');
|
|
1064
1077
|
const res = await em.driver.nativeInsert(entityName, data, { ctx: em.transactionContext, ...options });
|
|
1065
1078
|
return res.insertId;
|
|
@@ -1076,12 +1089,12 @@ class EntityManager {
|
|
|
1076
1089
|
data = entityNameOrEntities;
|
|
1077
1090
|
}
|
|
1078
1091
|
else {
|
|
1079
|
-
entityName =
|
|
1092
|
+
entityName = Utils_1.Utils.className(entityNameOrEntities);
|
|
1080
1093
|
}
|
|
1081
1094
|
if (data.length === 0) {
|
|
1082
1095
|
return [];
|
|
1083
1096
|
}
|
|
1084
|
-
if (
|
|
1097
|
+
if (Utils_1.Utils.isEntity(data[0])) {
|
|
1085
1098
|
const meta = (0, entity_1.helper)(data[0]).__meta;
|
|
1086
1099
|
const css = data.map(row => {
|
|
1087
1100
|
if (options.schema && (0, entity_1.helper)(row).getSchema() == null) {
|
|
@@ -1099,7 +1112,7 @@ class EntityManager {
|
|
|
1099
1112
|
await em.unitOfWork.getChangeSetPersister().executeInserts(css, { ctx: em.transactionContext, ...options });
|
|
1100
1113
|
return css.map(cs => cs.getPrimaryKey());
|
|
1101
1114
|
}
|
|
1102
|
-
data = data.map(row =>
|
|
1115
|
+
data = data.map(row => QueryHelper_1.QueryHelper.processObjectParams(row));
|
|
1103
1116
|
data.forEach(row => em.validator.validateParams(row, 'insert data'));
|
|
1104
1117
|
const res = await em.driver.nativeInsertMany(entityName, data, { ctx: em.transactionContext, ...options });
|
|
1105
1118
|
if (res.insertedIds) {
|
|
@@ -1113,8 +1126,8 @@ class EntityManager {
|
|
|
1113
1126
|
async nativeUpdate(entityName, where, data, options = {}) {
|
|
1114
1127
|
const em = this.getContext(false);
|
|
1115
1128
|
em.prepareOptions(options);
|
|
1116
|
-
entityName =
|
|
1117
|
-
data =
|
|
1129
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1130
|
+
data = QueryHelper_1.QueryHelper.processObjectParams(data);
|
|
1118
1131
|
where = await em.processWhere(entityName, where, { ...options, convertCustomTypes: false }, 'update');
|
|
1119
1132
|
em.validator.validateParams(data, 'update data');
|
|
1120
1133
|
em.validator.validateParams(where, 'update condition');
|
|
@@ -1127,7 +1140,7 @@ class EntityManager {
|
|
|
1127
1140
|
async nativeDelete(entityName, where, options = {}) {
|
|
1128
1141
|
const em = this.getContext(false);
|
|
1129
1142
|
em.prepareOptions(options);
|
|
1130
|
-
entityName =
|
|
1143
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1131
1144
|
where = await em.processWhere(entityName, where, options, 'delete');
|
|
1132
1145
|
em.validator.validateParams(where, 'delete condition');
|
|
1133
1146
|
const res = await em.driver.nativeDelete(entityName, where, { ctx: em.transactionContext, ...options });
|
|
@@ -1137,7 +1150,7 @@ class EntityManager {
|
|
|
1137
1150
|
* Maps raw database result to an entity and merges it to this EntityManager.
|
|
1138
1151
|
*/
|
|
1139
1152
|
map(entityName, result, options = {}) {
|
|
1140
|
-
entityName =
|
|
1153
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1141
1154
|
const meta = this.metadata.get(entityName);
|
|
1142
1155
|
const data = this.driver.mapResult(result, meta);
|
|
1143
1156
|
Object.keys(data).forEach(k => {
|
|
@@ -1157,11 +1170,11 @@ class EntityManager {
|
|
|
1157
1170
|
*/
|
|
1158
1171
|
merge(entityName, data, options = {}) {
|
|
1159
1172
|
const em = this.getContext();
|
|
1160
|
-
if (
|
|
1173
|
+
if (Utils_1.Utils.isEntity(entityName)) {
|
|
1161
1174
|
return em.merge(entityName.constructor.name, entityName, data);
|
|
1162
1175
|
}
|
|
1163
1176
|
options.schema ??= em._schema;
|
|
1164
|
-
entityName =
|
|
1177
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1165
1178
|
em.validator.validatePrimaryKey(data, em.metadata.get(entityName));
|
|
1166
1179
|
let entity = em.unitOfWork.tryGetById(entityName, data, options.schema, false);
|
|
1167
1180
|
if (entity && (0, entity_1.helper)(entity).__managed && (0, entity_1.helper)(entity).__initialized && !options.refresh) {
|
|
@@ -1169,7 +1182,7 @@ class EntityManager {
|
|
|
1169
1182
|
}
|
|
1170
1183
|
const meta = em.metadata.find(entityName);
|
|
1171
1184
|
const childMeta = em.metadata.getByDiscriminatorColumn(meta, data);
|
|
1172
|
-
entity =
|
|
1185
|
+
entity = Utils_1.Utils.isEntity(data) ? data : em.entityFactory.create(entityName, data, { merge: true, ...options });
|
|
1173
1186
|
em.validator.validate(entity, data, childMeta ?? meta);
|
|
1174
1187
|
em.unitOfWork.merge(entity);
|
|
1175
1188
|
return entity;
|
|
@@ -1215,8 +1228,8 @@ class EntityManager {
|
|
|
1215
1228
|
getReference(entityName, id, options = {}) {
|
|
1216
1229
|
options.schema ??= this.schema;
|
|
1217
1230
|
options.convertCustomTypes ??= false;
|
|
1218
|
-
const meta = this.metadata.get(
|
|
1219
|
-
if (
|
|
1231
|
+
const meta = this.metadata.get(Utils_1.Utils.className(entityName));
|
|
1232
|
+
if (Utils_1.Utils.isPrimaryKey(id)) {
|
|
1220
1233
|
if (meta.compositePK) {
|
|
1221
1234
|
throw errors_1.ValidationError.invalidCompositeIdentifier(meta);
|
|
1222
1235
|
}
|
|
@@ -1238,7 +1251,7 @@ class EntityManager {
|
|
|
1238
1251
|
schema: em._schema,
|
|
1239
1252
|
...options,
|
|
1240
1253
|
};
|
|
1241
|
-
entityName =
|
|
1254
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1242
1255
|
await em.tryFlush(entityName, options);
|
|
1243
1256
|
where = await em.processWhere(entityName, where, options, 'read');
|
|
1244
1257
|
options.populate = await em.preparePopulate(entityName, options);
|
|
@@ -1265,14 +1278,14 @@ class EntityManager {
|
|
|
1265
1278
|
*/
|
|
1266
1279
|
persist(entity) {
|
|
1267
1280
|
const em = this.getContext();
|
|
1268
|
-
if (
|
|
1281
|
+
if (Utils_1.Utils.isEntity(entity)) {
|
|
1269
1282
|
// do not cascade just yet, cascading of entities in persist stack is done when flushing
|
|
1270
1283
|
em.unitOfWork.persist(entity, undefined, { cascade: false });
|
|
1271
1284
|
return em;
|
|
1272
1285
|
}
|
|
1273
|
-
const entities =
|
|
1286
|
+
const entities = Utils_1.Utils.asArray(entity);
|
|
1274
1287
|
for (const ent of entities) {
|
|
1275
|
-
if (!
|
|
1288
|
+
if (!Utils_1.Utils.isEntity(ent, true)) {
|
|
1276
1289
|
/* istanbul ignore next */
|
|
1277
1290
|
const meta = typeof ent === 'object' ? em.metadata.find(ent.constructor.name) : undefined;
|
|
1278
1291
|
throw errors_1.ValidationError.notDiscoveredEntity(ent, meta);
|
|
@@ -1297,14 +1310,14 @@ class EntityManager {
|
|
|
1297
1310
|
*/
|
|
1298
1311
|
remove(entity) {
|
|
1299
1312
|
const em = this.getContext();
|
|
1300
|
-
if (
|
|
1313
|
+
if (Utils_1.Utils.isEntity(entity)) {
|
|
1301
1314
|
// do not cascade just yet, cascading of entities in persist stack is done when flushing
|
|
1302
1315
|
em.unitOfWork.remove(entity, undefined, { cascade: false });
|
|
1303
1316
|
return em;
|
|
1304
1317
|
}
|
|
1305
|
-
const entities =
|
|
1318
|
+
const entities = Utils_1.Utils.asArray(entity, true);
|
|
1306
1319
|
for (const ent of entities) {
|
|
1307
|
-
if (!
|
|
1320
|
+
if (!Utils_1.Utils.isEntity(ent, true)) {
|
|
1308
1321
|
throw new Error(`You need to pass entity instance or reference to 'em.remove()'. To remove entities by condition, use 'em.nativeDelete()'.`);
|
|
1309
1322
|
}
|
|
1310
1323
|
// do not cascade just yet, cascading of entities in remove stack is done when flushing
|
|
@@ -1332,7 +1345,7 @@ class EntityManager {
|
|
|
1332
1345
|
async tryFlush(entityName, options) {
|
|
1333
1346
|
const em = this.getContext();
|
|
1334
1347
|
const flushMode = options.flushMode ?? em.flushMode ?? em.config.get('flushMode');
|
|
1335
|
-
entityName =
|
|
1348
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1336
1349
|
const meta = em.metadata.get(entityName);
|
|
1337
1350
|
if (flushMode === enums_1.FlushMode.COMMIT) {
|
|
1338
1351
|
return;
|
|
@@ -1351,7 +1364,7 @@ class EntityManager {
|
|
|
1351
1364
|
* Checks whether given property can be populated on the entity.
|
|
1352
1365
|
*/
|
|
1353
1366
|
canPopulate(entityName, property) {
|
|
1354
|
-
entityName =
|
|
1367
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1355
1368
|
// eslint-disable-next-line prefer-const
|
|
1356
1369
|
let [p, ...parts] = property.split('.');
|
|
1357
1370
|
const meta = this.metadata.find(entityName);
|
|
@@ -1374,7 +1387,7 @@ class EntityManager {
|
|
|
1374
1387
|
* Loads specified relations in batch. This will execute one query for each relation, that will populate it on all the specified entities.
|
|
1375
1388
|
*/
|
|
1376
1389
|
async populate(entities, populate, options = {}) {
|
|
1377
|
-
const arr =
|
|
1390
|
+
const arr = Utils_1.Utils.asArray(entities);
|
|
1378
1391
|
if (arr.length === 0) {
|
|
1379
1392
|
return entities;
|
|
1380
1393
|
}
|
|
@@ -1410,8 +1423,8 @@ class EntityManager {
|
|
|
1410
1423
|
fork.transactionContext = em.transactionContext;
|
|
1411
1424
|
}
|
|
1412
1425
|
fork.filters = { ...em.filters };
|
|
1413
|
-
fork.filterParams =
|
|
1414
|
-
fork.loggerContext =
|
|
1426
|
+
fork.filterParams = Utils_1.Utils.copy(em.filterParams);
|
|
1427
|
+
fork.loggerContext = Utils_1.Utils.merge({}, em.loggerContext, options.loggerContext);
|
|
1415
1428
|
fork._schema = options.schema ?? em._schema;
|
|
1416
1429
|
if (!options.clear) {
|
|
1417
1430
|
for (const entity of em.unitOfWork.getIdentityMap()) {
|
|
@@ -1452,7 +1465,7 @@ class EntityManager {
|
|
|
1452
1465
|
if (!this.useContext) {
|
|
1453
1466
|
return this;
|
|
1454
1467
|
}
|
|
1455
|
-
let em =
|
|
1468
|
+
let em = TransactionContext_1.TransactionContext.getEntityManager(this.name); // prefer the tx context
|
|
1456
1469
|
if (em) {
|
|
1457
1470
|
return em;
|
|
1458
1471
|
}
|
|
@@ -1482,7 +1495,12 @@ class EntityManager {
|
|
|
1482
1495
|
* Sets the transaction context.
|
|
1483
1496
|
*/
|
|
1484
1497
|
setTransactionContext(ctx) {
|
|
1485
|
-
|
|
1498
|
+
if (!ctx) {
|
|
1499
|
+
this.resetTransactionContext();
|
|
1500
|
+
}
|
|
1501
|
+
else {
|
|
1502
|
+
this.getContext(false).transactionContext = ctx;
|
|
1503
|
+
}
|
|
1486
1504
|
}
|
|
1487
1505
|
/**
|
|
1488
1506
|
* Resets the transaction context.
|
|
@@ -1495,7 +1513,7 @@ class EntityManager {
|
|
|
1495
1513
|
*/
|
|
1496
1514
|
getMetadata(entityName) {
|
|
1497
1515
|
if (entityName) {
|
|
1498
|
-
entityName =
|
|
1516
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
1499
1517
|
return this.metadata.get(entityName);
|
|
1500
1518
|
}
|
|
1501
1519
|
return this.metadata;
|
|
@@ -1537,8 +1555,8 @@ class EntityManager {
|
|
|
1537
1555
|
}
|
|
1538
1556
|
buildFields(fields) {
|
|
1539
1557
|
return fields.reduce((ret, f) => {
|
|
1540
|
-
if (
|
|
1541
|
-
|
|
1558
|
+
if (Utils_1.Utils.isPlainObject(f)) {
|
|
1559
|
+
Utils_1.Utils.keys(f).forEach(ff => ret.push(...this.buildFields(f[ff]).map(field => `${ff}.${field}`)));
|
|
1542
1560
|
}
|
|
1543
1561
|
else {
|
|
1544
1562
|
ret.push(f);
|
|
@@ -1581,7 +1599,7 @@ class EntityManager {
|
|
|
1581
1599
|
ret.push(...inner.map(c => `${key}.${c}`));
|
|
1582
1600
|
}
|
|
1583
1601
|
}
|
|
1584
|
-
return
|
|
1602
|
+
return Utils_1.Utils.unique(ret);
|
|
1585
1603
|
};
|
|
1586
1604
|
options.populate = pruneToOneRelations(meta, this.buildFields(options.fields));
|
|
1587
1605
|
}
|
|
@@ -1591,7 +1609,7 @@ class EntityManager {
|
|
|
1591
1609
|
return populate;
|
|
1592
1610
|
}
|
|
1593
1611
|
if (typeof options.populate !== 'boolean') {
|
|
1594
|
-
options.populate =
|
|
1612
|
+
options.populate = Utils_1.Utils.asArray(options.populate).map(field => {
|
|
1595
1613
|
/* istanbul ignore next */
|
|
1596
1614
|
if (typeof field === 'boolean' || field === enums_1.PopulatePath.ALL) {
|
|
1597
1615
|
return [{ field: meta.primaryKeys[0], strategy: options.strategy, all: !!field }]; //
|
|
@@ -1602,7 +1620,7 @@ class EntityManager {
|
|
|
1602
1620
|
options.flags.push(enums_1.QueryFlag.INFER_POPULATE);
|
|
1603
1621
|
return [];
|
|
1604
1622
|
}
|
|
1605
|
-
if (
|
|
1623
|
+
if (Utils_1.Utils.isString(field)) {
|
|
1606
1624
|
return [{ field, strategy: options.strategy }];
|
|
1607
1625
|
}
|
|
1608
1626
|
return [field];
|
|
@@ -1648,11 +1666,11 @@ class EntityManager {
|
|
|
1648
1666
|
return !!options.populate;
|
|
1649
1667
|
}
|
|
1650
1668
|
prepareOptions(options) {
|
|
1651
|
-
if (!
|
|
1669
|
+
if (!Utils_1.Utils.isEmpty(options.fields) && !Utils_1.Utils.isEmpty(options.exclude)) {
|
|
1652
1670
|
throw new errors_1.ValidationError(`Cannot combine 'fields' and 'exclude' option.`);
|
|
1653
1671
|
}
|
|
1654
1672
|
options.schema ??= this._schema;
|
|
1655
|
-
options.logging =
|
|
1673
|
+
options.logging = Utils_1.Utils.merge({ id: this.id }, this.loggerContext, options.loggerContext, options.logging);
|
|
1656
1674
|
}
|
|
1657
1675
|
/**
|
|
1658
1676
|
* @internal
|
|
@@ -1686,7 +1704,7 @@ class EntityManager {
|
|
|
1686
1704
|
recomputeSnapshot: true,
|
|
1687
1705
|
}));
|
|
1688
1706
|
}
|
|
1689
|
-
else if (
|
|
1707
|
+
else if (Utils_1.Utils.isObject(cached) && merge) {
|
|
1690
1708
|
data = em.entityFactory.create(entityName, cached, {
|
|
1691
1709
|
merge: true,
|
|
1692
1710
|
convertCustomTypes: true,
|
|
@@ -1709,7 +1727,7 @@ class EntityManager {
|
|
|
1709
1727
|
config ??= this.config.get('resultCache').global;
|
|
1710
1728
|
if (config) {
|
|
1711
1729
|
const em = this.getContext();
|
|
1712
|
-
const expiration = Array.isArray(config) ? config[1] : (
|
|
1730
|
+
const expiration = Array.isArray(config) ? config[1] : (Utils_1.Utils.isNumber(config) ? config : undefined);
|
|
1713
1731
|
await em.resultCache.set(key.key, data instanceof Function ? data() : data, '', expiration);
|
|
1714
1732
|
}
|
|
1715
1733
|
}
|