@mikro-orm/core 7.0.0-dev.113 → 7.0.0-dev.115
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 +8 -8
- package/EntityManager.js +47 -69
- package/MikroORM.d.ts +1 -1
- package/MikroORM.js +2 -3
- package/drivers/DatabaseDriver.d.ts +11 -11
- package/drivers/DatabaseDriver.js +8 -9
- package/drivers/IDatabaseDriver.d.ts +12 -12
- package/entity/Collection.js +7 -6
- package/entity/EntityAssigner.js +9 -9
- package/entity/EntityFactory.js +14 -17
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +2 -2
- package/entity/EntityLoader.d.ts +3 -3
- package/entity/EntityLoader.js +22 -35
- package/entity/WrappedEntity.js +1 -1
- package/entity/defineEntity.d.ts +11 -11
- package/entity/validators.js +2 -2
- package/errors.d.ts +8 -8
- package/errors.js +14 -13
- package/hydration/ObjectHydrator.js +25 -18
- package/metadata/EntitySchema.d.ts +5 -5
- package/metadata/EntitySchema.js +23 -21
- package/metadata/MetadataDiscovery.d.ts +2 -3
- package/metadata/MetadataDiscovery.js +119 -92
- package/metadata/MetadataProvider.js +2 -0
- package/metadata/MetadataStorage.d.ts +13 -6
- package/metadata/MetadataStorage.js +64 -19
- package/metadata/MetadataValidator.d.ts +2 -2
- package/metadata/MetadataValidator.js +22 -28
- package/metadata/types.d.ts +3 -3
- package/package.json +1 -1
- package/platforms/Platform.js +2 -2
- package/serialization/EntitySerializer.js +2 -2
- package/serialization/EntityTransformer.js +6 -6
- package/serialization/SerializationContext.d.ts +6 -6
- package/typings.d.ts +19 -17
- package/typings.js +15 -10
- package/unit-of-work/ChangeSet.d.ts +2 -3
- package/unit-of-work/ChangeSet.js +2 -3
- package/unit-of-work/ChangeSetComputer.js +3 -3
- package/unit-of-work/ChangeSetPersister.js +14 -14
- package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/UnitOfWork.d.ts +3 -3
- package/unit-of-work/UnitOfWork.js +46 -45
- package/utils/AbstractSchemaGenerator.js +7 -7
- package/utils/Configuration.d.ts +0 -5
- package/utils/Cursor.js +3 -3
- package/utils/DataloaderUtils.js +13 -11
- package/utils/EntityComparator.d.ts +6 -6
- package/utils/EntityComparator.js +30 -27
- package/utils/QueryHelper.d.ts +6 -6
- package/utils/QueryHelper.js +18 -17
- package/utils/RawQueryFragment.d.ts +11 -12
- package/utils/RawQueryFragment.js +28 -55
- package/utils/TransactionManager.js +1 -1
- package/utils/Utils.d.ts +3 -1
- package/utils/Utils.js +10 -2
- package/utils/clone.js +7 -21
- package/utils/env-vars.js +0 -1
- package/utils/upsert-utils.d.ts +4 -4
package/EntityManager.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { EntityLoader, type EntityLoaderOptions } from './entity/EntityLoader.js
|
|
|
7
7
|
import { Reference } from './entity/Reference.js';
|
|
8
8
|
import { UnitOfWork } from './unit-of-work/UnitOfWork.js';
|
|
9
9
|
import type { CountOptions, DeleteOptions, FilterOptions, FindAllOptions, FindByCursorOptions, FindOneOptions, FindOneOrFailOptions, FindOptions, GetReferenceOptions, IDatabaseDriver, LockOptions, NativeInsertUpdateOptions, StreamOptions, UpdateOptions, UpsertManyOptions, UpsertOptions } from './drivers/IDatabaseDriver.js';
|
|
10
|
-
import type { AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, EntityData, EntityDictionary, EntityDTO, EntityMetadata, EntityName, FilterDef, FilterQuery, FromEntityType, GetRepository, IHydrator, IsSubset, Loaded, MergeLoaded, MergeSelected, NoInfer, ObjectQuery, Primary, Ref, RequiredEntityData, UnboxArray } from './typings.js';
|
|
10
|
+
import type { AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, EntityClass, EntityData, EntityDictionary, EntityDTO, EntityMetadata, EntityName, FilterDef, FilterQuery, FromEntityType, GetRepository, IHydrator, IsSubset, Loaded, MergeLoaded, MergeSelected, NoInfer, ObjectQuery, Primary, Ref, RequiredEntityData, UnboxArray } from './typings.js';
|
|
11
11
|
import { FlushMode, LockMode, PopulatePath, type TransactionOptions } from './enums.js';
|
|
12
12
|
import type { MetadataStorage } from './metadata/MetadataStorage.js';
|
|
13
13
|
import type { Transaction } from './connections/Connection.js';
|
|
@@ -99,7 +99,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
99
99
|
/**
|
|
100
100
|
* Registers global filter to this entity manager. Global filters are enabled by default (unless disabled via last parameter).
|
|
101
101
|
*/
|
|
102
|
-
addFilter<T extends EntityName
|
|
102
|
+
addFilter<T extends EntityName | readonly EntityName[]>(options: FilterDef<T>): void;
|
|
103
103
|
/**
|
|
104
104
|
* Sets filter parameter values globally inside context defined by this entity manager.
|
|
105
105
|
* If you want to set shared value for all contexts, be sure to use the root entity manager.
|
|
@@ -120,21 +120,21 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
120
120
|
disableContextResolution?: boolean;
|
|
121
121
|
}): T;
|
|
122
122
|
setFlushMode(flushMode?: FlushMode | `${FlushMode}`): void;
|
|
123
|
-
protected processWhere<Entity extends object, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entityName:
|
|
124
|
-
protected applyDiscriminatorCondition<Entity extends object>(entityName:
|
|
123
|
+
protected processWhere<Entity extends object, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entityName: EntityName<Entity>, where: FilterQuery<Entity>, options: FindOptions<Entity, Hint, Fields, Excludes> | FindOneOptions<Entity, Hint, Fields, Excludes>, type: 'read' | 'update' | 'delete'): Promise<FilterQuery<Entity>>;
|
|
124
|
+
protected applyDiscriminatorCondition<Entity extends object>(entityName: EntityName<Entity>, where: FilterQuery<Entity>): FilterQuery<Entity>;
|
|
125
125
|
protected createPopulateWhere<Entity extends object>(cond: ObjectQuery<Entity>, options: FindOptions<Entity, any, any, any> | FindOneOptions<Entity, any, any, any> | CountOptions<Entity, any>): ObjectQuery<Entity>;
|
|
126
126
|
protected getJoinedFilters<Entity extends object>(meta: EntityMetadata<Entity>, options: FindOptions<Entity, any, any, any> | FindOneOptions<Entity, any, any, any>): Promise<ObjectQuery<Entity> | undefined>;
|
|
127
127
|
/**
|
|
128
128
|
* When filters are active on M:1 or 1:1 relations, we need to ref join them eagerly as they might affect the FK value.
|
|
129
129
|
*/
|
|
130
130
|
protected autoJoinRefsForFilters<T extends object>(meta: EntityMetadata<T>, options: FindOptions<T, any, any, any> | FindOneOptions<T, any, any, any>, parent?: {
|
|
131
|
-
|
|
131
|
+
class: EntityClass;
|
|
132
132
|
propName: string;
|
|
133
133
|
}): Promise<void>;
|
|
134
134
|
/**
|
|
135
135
|
* @internal
|
|
136
136
|
*/
|
|
137
|
-
applyFilters<Entity extends object>(entityName:
|
|
137
|
+
applyFilters<Entity extends object>(entityName: EntityName<Entity>, where: FilterQuery<Entity> | undefined, options: FilterOptions | undefined, type: 'read' | 'update' | 'delete', findOptions?: FindOptions<any, any, any, any> | FindOneOptions<any, any, any, any>): Promise<FilterQuery<Entity> | undefined>;
|
|
138
138
|
/**
|
|
139
139
|
* Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as tuple
|
|
140
140
|
* where the first element is the array of entities, and the second is the count.
|
|
@@ -508,11 +508,11 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
508
508
|
/**
|
|
509
509
|
* @internal
|
|
510
510
|
*/
|
|
511
|
-
cacheKey<T extends object>(entityName:
|
|
511
|
+
cacheKey<T extends object>(entityName: EntityName<T>, options: FindOptions<T, any, any, any> | FindOneOptions<T, any, any, any> | CountOptions<T, any>, method: string, where: FilterQuery<T>): unknown[];
|
|
512
512
|
/**
|
|
513
513
|
* @internal
|
|
514
514
|
*/
|
|
515
|
-
tryCache<T extends object, R>(entityName:
|
|
515
|
+
tryCache<T extends object, R>(entityName: EntityName<T>, config: boolean | number | [string, number] | undefined, key: unknown, refresh?: boolean, merge?: boolean): Promise<{
|
|
516
516
|
data?: R | null;
|
|
517
517
|
key: string;
|
|
518
518
|
} | undefined>;
|
package/EntityManager.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Cursor } from './utils/Cursor.js';
|
|
|
4
4
|
import { DataloaderUtils } from './utils/DataloaderUtils.js';
|
|
5
5
|
import { QueryHelper } from './utils/QueryHelper.js';
|
|
6
6
|
import { TransactionContext } from './utils/TransactionContext.js';
|
|
7
|
-
import { isRaw,
|
|
7
|
+
import { isRaw, Raw } from './utils/RawQueryFragment.js';
|
|
8
8
|
import { EntityFactory } from './entity/EntityFactory.js';
|
|
9
9
|
import { EntityAssigner } from './entity/EntityAssigner.js';
|
|
10
10
|
import { validateEmptyWhere, validateParams, validatePrimaryKey, validateProperty } from './entity/validators.js';
|
|
@@ -35,7 +35,7 @@ export class EntityManager {
|
|
|
35
35
|
global = false;
|
|
36
36
|
name;
|
|
37
37
|
loaders = {};
|
|
38
|
-
repositoryMap =
|
|
38
|
+
repositoryMap = new Map();
|
|
39
39
|
entityLoader;
|
|
40
40
|
comparator;
|
|
41
41
|
entityFactory;
|
|
@@ -88,13 +88,12 @@ export class EntityManager {
|
|
|
88
88
|
* Gets repository for given entity. You can pass either string name or entity class reference.
|
|
89
89
|
*/
|
|
90
90
|
getRepository(entityName) {
|
|
91
|
-
|
|
92
|
-
if (!this.repositoryMap
|
|
93
|
-
const meta = this.metadata.get(entityName);
|
|
91
|
+
const meta = this.metadata.get(entityName);
|
|
92
|
+
if (!this.repositoryMap.has(meta)) {
|
|
94
93
|
const RepositoryClass = this.config.getRepositoryClass(meta.repository);
|
|
95
|
-
this.repositoryMap
|
|
94
|
+
this.repositoryMap.set(meta, new RepositoryClass(this, entityName));
|
|
96
95
|
}
|
|
97
|
-
return this.repositoryMap
|
|
96
|
+
return this.repositoryMap.get(meta);
|
|
98
97
|
}
|
|
99
98
|
/**
|
|
100
99
|
* Shortcut for `em.getRepository()`.
|
|
@@ -116,7 +115,6 @@ export class EntityManager {
|
|
|
116
115
|
const em = this.getContext();
|
|
117
116
|
em.prepareOptions(options);
|
|
118
117
|
await em.tryFlush(entityName, options);
|
|
119
|
-
entityName = Utils.className(entityName);
|
|
120
118
|
where = await em.processWhere(entityName, where, options, 'read');
|
|
121
119
|
validateParams(where);
|
|
122
120
|
options.orderBy = options.orderBy || {};
|
|
@@ -192,7 +190,6 @@ export class EntityManager {
|
|
|
192
190
|
em.prepareOptions(options);
|
|
193
191
|
options.strategy = 'joined';
|
|
194
192
|
await em.tryFlush(entityName, options);
|
|
195
|
-
entityName = Utils.className(entityName);
|
|
196
193
|
const where = await em.processWhere(entityName, options.where ?? {}, options, 'read');
|
|
197
194
|
validateParams(where);
|
|
198
195
|
options.orderBy = options.orderBy || {};
|
|
@@ -303,15 +300,15 @@ export class EntityManager {
|
|
|
303
300
|
if (!meta?.discriminatorValue) {
|
|
304
301
|
return where;
|
|
305
302
|
}
|
|
306
|
-
const types = Object.values(meta.root.discriminatorMap).map(cls => this.metadata.
|
|
303
|
+
const types = Object.values(meta.root.discriminatorMap).map(cls => this.metadata.get(cls));
|
|
307
304
|
const children = [];
|
|
308
305
|
const lookUpChildren = (ret, type) => {
|
|
309
306
|
const children = types.filter(meta2 => meta2.extends === type);
|
|
310
|
-
children.forEach(m => lookUpChildren(ret, m.
|
|
307
|
+
children.forEach(m => lookUpChildren(ret, m.class));
|
|
311
308
|
ret.push(...children.filter(c => c.discriminatorValue));
|
|
312
309
|
return children;
|
|
313
310
|
};
|
|
314
|
-
lookUpChildren(children, meta.
|
|
311
|
+
lookUpChildren(children, meta.class);
|
|
315
312
|
/* v8 ignore next */
|
|
316
313
|
where[meta.root.discriminatorColumn] = children.length > 0 ? { $in: [meta.discriminatorValue, ...children.map(c => c.discriminatorValue)] } : meta.discriminatorValue;
|
|
317
314
|
return where;
|
|
@@ -341,7 +338,7 @@ export class EntityManager {
|
|
|
341
338
|
continue;
|
|
342
339
|
}
|
|
343
340
|
const filters = QueryHelper.mergePropertyFilters(prop.filters, options.filters);
|
|
344
|
-
const where = await this.applyFilters(prop.
|
|
341
|
+
const where = await this.applyFilters(prop.targetMeta.class, {}, filters, 'read', {
|
|
345
342
|
...options,
|
|
346
343
|
populate: hint.children,
|
|
347
344
|
});
|
|
@@ -377,11 +374,11 @@ export class EntityManager {
|
|
|
377
374
|
if (prop.object
|
|
378
375
|
|| ![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind)
|
|
379
376
|
|| !((options.fields?.length ?? 0) === 0 || options.fields?.some(f => prop.name === f || prop.name.startsWith(`${String(f)}.`)))
|
|
380
|
-
|| (parent?.
|
|
377
|
+
|| (parent?.class === prop.targetMeta.root.class && parent.propName === prop.inversedBy)) {
|
|
381
378
|
continue;
|
|
382
379
|
}
|
|
383
380
|
options = { ...options, filters: QueryHelper.mergePropertyFilters(prop.filters, options.filters) };
|
|
384
|
-
const cond = await this.applyFilters(prop.
|
|
381
|
+
const cond = await this.applyFilters(prop.targetMeta.class, {}, options.filters, 'read', options);
|
|
385
382
|
if (!Utils.isEmpty(cond)) {
|
|
386
383
|
const populated = options.populate.filter(({ field }) => field.split(':')[0] === prop.name);
|
|
387
384
|
let found = false;
|
|
@@ -404,7 +401,7 @@ export class EntityManager {
|
|
|
404
401
|
const prop = meta?.properties[field];
|
|
405
402
|
if (prop && !ref) {
|
|
406
403
|
hint.children ??= [];
|
|
407
|
-
await this.autoJoinRefsForFilters(prop.targetMeta, { ...options, populate: hint.children }, {
|
|
404
|
+
await this.autoJoinRefsForFilters(prop.targetMeta, { ...options, populate: hint.children }, { class: meta.root.class, propName: prop.name });
|
|
408
405
|
}
|
|
409
406
|
}
|
|
410
407
|
}
|
|
@@ -412,16 +409,13 @@ export class EntityManager {
|
|
|
412
409
|
* @internal
|
|
413
410
|
*/
|
|
414
411
|
async applyFilters(entityName, where, options, type, findOptions) {
|
|
415
|
-
const meta = this.metadata.
|
|
412
|
+
const meta = this.metadata.get(entityName);
|
|
416
413
|
const filters = [];
|
|
417
414
|
const ret = [];
|
|
418
|
-
if (!meta) {
|
|
419
|
-
return where;
|
|
420
|
-
}
|
|
421
415
|
const active = new Set();
|
|
422
416
|
const push = (source) => {
|
|
423
417
|
const activeFilters = QueryHelper
|
|
424
|
-
.getActiveFilters(
|
|
418
|
+
.getActiveFilters(meta, options, source)
|
|
425
419
|
.filter(f => !active.has(f.name));
|
|
426
420
|
filters.push(...activeFilters);
|
|
427
421
|
activeFilters.forEach(f => active.add(f.name));
|
|
@@ -440,7 +434,7 @@ export class EntityManager {
|
|
|
440
434
|
if (!args && filter.cond.length > 0 && filter.args !== false) {
|
|
441
435
|
throw new Error(`No arguments provided for filter '${filter.name}'`);
|
|
442
436
|
}
|
|
443
|
-
cond = await filter.cond(args, type, this, findOptions, entityName);
|
|
437
|
+
cond = await filter.cond(args, type, this, findOptions, Utils.className(entityName));
|
|
444
438
|
}
|
|
445
439
|
else {
|
|
446
440
|
cond = filter.cond;
|
|
@@ -457,7 +451,7 @@ export class EntityManager {
|
|
|
457
451
|
}
|
|
458
452
|
ret.push(cond);
|
|
459
453
|
}
|
|
460
|
-
const conds = [...ret, where].filter(c => Utils.hasObjectKeys(c));
|
|
454
|
+
const conds = [...ret, where].filter(c => Utils.hasObjectKeys(c) || Raw.hasObjectFragments(c));
|
|
461
455
|
return conds.length > 1 ? { $and: conds } : conds[0];
|
|
462
456
|
}
|
|
463
457
|
/**
|
|
@@ -468,12 +462,10 @@ export class EntityManager {
|
|
|
468
462
|
const em = this.getContext(false);
|
|
469
463
|
await em.tryFlush(entityName, options);
|
|
470
464
|
options.flushMode = 'commit'; // do not try to auto flush again
|
|
471
|
-
return
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
]);
|
|
476
|
-
});
|
|
465
|
+
return Promise.all([
|
|
466
|
+
em.find(entityName, where, options),
|
|
467
|
+
em.count(entityName, where, options),
|
|
468
|
+
]);
|
|
477
469
|
}
|
|
478
470
|
/**
|
|
479
471
|
* Calls `em.find()` and `em.count()` with the same arguments (where applicable) and returns the results as {@apilink Cursor} object.
|
|
@@ -533,10 +525,9 @@ export class EntityManager {
|
|
|
533
525
|
*/
|
|
534
526
|
async findByCursor(entityName, options) {
|
|
535
527
|
const em = this.getContext(false);
|
|
536
|
-
entityName = Utils.className(entityName);
|
|
537
528
|
options.overfetch ??= true;
|
|
538
529
|
options.where ??= {};
|
|
539
|
-
if (Utils.isEmpty(options.orderBy)) {
|
|
530
|
+
if (Utils.isEmpty(options.orderBy) && !Raw.hasObjectFragments(options.orderBy)) {
|
|
540
531
|
throw new Error('Explicit `orderBy` option required');
|
|
541
532
|
}
|
|
542
533
|
const [entities, count] = options.includeCount !== false
|
|
@@ -553,9 +544,9 @@ export class EntityManager {
|
|
|
553
544
|
const ret = await this.refresh(entity, options);
|
|
554
545
|
if (!ret) {
|
|
555
546
|
options.failHandler ??= this.config.get('findOneOrFailHandler');
|
|
556
|
-
const
|
|
557
|
-
const where =
|
|
558
|
-
throw options.failHandler(
|
|
547
|
+
const wrapped = helper(entity);
|
|
548
|
+
const where = wrapped.getPrimaryKey();
|
|
549
|
+
throw options.failHandler(wrapped.__meta.className, where);
|
|
559
550
|
}
|
|
560
551
|
return ret;
|
|
561
552
|
}
|
|
@@ -566,9 +557,8 @@ export class EntityManager {
|
|
|
566
557
|
*/
|
|
567
558
|
async refresh(entity, options = {}) {
|
|
568
559
|
const fork = this.fork({ keepTransactionContext: true });
|
|
569
|
-
const entityName = entity.constructor.name;
|
|
570
560
|
const wrapped = helper(entity);
|
|
571
|
-
const reloaded = await fork.findOne(
|
|
561
|
+
const reloaded = await fork.findOne(wrapped.__meta.class, entity, {
|
|
572
562
|
schema: wrapped.__schema,
|
|
573
563
|
...options,
|
|
574
564
|
flushMode: FlushMode.COMMIT,
|
|
@@ -580,7 +570,7 @@ export class EntityManager {
|
|
|
580
570
|
}
|
|
581
571
|
let found = false;
|
|
582
572
|
for (const e of fork.unitOfWork.getIdentityMap()) {
|
|
583
|
-
const ref = em.getReference(e.constructor
|
|
573
|
+
const ref = em.getReference(e.constructor, helper(e).getPrimaryKey());
|
|
584
574
|
const data = helper(e).serialize({ ignoreSerializers: true, includeHidden: true });
|
|
585
575
|
em.config.getHydrator(this.metadata).hydrate(ref, helper(ref).__meta, data, em.entityFactory, 'full', false, true);
|
|
586
576
|
Utils.merge(helper(ref).__originalEntityData, this.comparator.prepareEntity(e));
|
|
@@ -605,7 +595,6 @@ export class EntityManager {
|
|
|
605
595
|
return ret;
|
|
606
596
|
}
|
|
607
597
|
const em = this.getContext();
|
|
608
|
-
entityName = Utils.className(entityName);
|
|
609
598
|
em.prepareOptions(options);
|
|
610
599
|
let entity = em.unitOfWork.tryGetById(entityName, where, options.schema);
|
|
611
600
|
// query for a not managed entity which is already in the identity map as it
|
|
@@ -683,10 +672,10 @@ export class EntityManager {
|
|
|
683
672
|
if (!entity || isStrictViolation) {
|
|
684
673
|
const key = options.strict ? 'findExactlyOneOrFailHandler' : 'findOneOrFailHandler';
|
|
685
674
|
options.failHandler ??= this.config.get(key);
|
|
686
|
-
|
|
675
|
+
const name = Utils.className(entityName);
|
|
687
676
|
/* v8 ignore next */
|
|
688
677
|
where = Utils.isEntity(where) ? helper(where).getPrimaryKey() : where;
|
|
689
|
-
throw options.failHandler(
|
|
678
|
+
throw options.failHandler(name, where);
|
|
690
679
|
}
|
|
691
680
|
return entity;
|
|
692
681
|
}
|
|
@@ -726,11 +715,11 @@ export class EntityManager {
|
|
|
726
715
|
let where;
|
|
727
716
|
let entity = null;
|
|
728
717
|
if (data === undefined) {
|
|
729
|
-
entityName = entityNameOrEntity.constructor
|
|
718
|
+
entityName = entityNameOrEntity.constructor;
|
|
730
719
|
data = entityNameOrEntity;
|
|
731
720
|
}
|
|
732
721
|
else {
|
|
733
|
-
entityName =
|
|
722
|
+
entityName = entityNameOrEntity;
|
|
734
723
|
}
|
|
735
724
|
const meta = this.metadata.get(entityName);
|
|
736
725
|
const convertCustomTypes = !Utils.isEntity(data);
|
|
@@ -793,7 +782,7 @@ export class EntityManager {
|
|
|
793
782
|
where[meta.primaryKeys[0]] = ret.insertId;
|
|
794
783
|
}
|
|
795
784
|
}
|
|
796
|
-
const data2 = await this.driver.findOne(meta.
|
|
785
|
+
const data2 = await this.driver.findOne(meta.class, where, {
|
|
797
786
|
fields: returning,
|
|
798
787
|
ctx: em.transactionContext,
|
|
799
788
|
convertCustomTypes: true,
|
|
@@ -848,11 +837,11 @@ export class EntityManager {
|
|
|
848
837
|
let entityName;
|
|
849
838
|
let propIndex;
|
|
850
839
|
if (data === undefined) {
|
|
851
|
-
entityName = entityNameOrEntity[0].constructor
|
|
840
|
+
entityName = entityNameOrEntity[0].constructor;
|
|
852
841
|
data = entityNameOrEntity;
|
|
853
842
|
}
|
|
854
843
|
else {
|
|
855
|
-
entityName =
|
|
844
|
+
entityName = entityNameOrEntity;
|
|
856
845
|
}
|
|
857
846
|
const batchSize = options.batchSize ?? this.config.get('batchSize');
|
|
858
847
|
if (data.length > batchSize) {
|
|
@@ -960,7 +949,7 @@ export class EntityManager {
|
|
|
960
949
|
where.$or[idx][prop] = item[prop];
|
|
961
950
|
});
|
|
962
951
|
});
|
|
963
|
-
const data2 = await this.driver.find(meta.
|
|
952
|
+
const data2 = await this.driver.find(meta.class, where, {
|
|
964
953
|
fields: returning.concat(...add).concat(...(Array.isArray(uniqueFields) ? uniqueFields : [])),
|
|
965
954
|
ctx: em.transactionContext,
|
|
966
955
|
convertCustomTypes: true,
|
|
@@ -1113,11 +1102,11 @@ export class EntityManager {
|
|
|
1113
1102
|
em.prepareOptions(options);
|
|
1114
1103
|
let entityName;
|
|
1115
1104
|
if (data === undefined) {
|
|
1116
|
-
entityName = entityNameOrEntity.constructor
|
|
1105
|
+
entityName = entityNameOrEntity.constructor;
|
|
1117
1106
|
data = entityNameOrEntity;
|
|
1118
1107
|
}
|
|
1119
1108
|
else {
|
|
1120
|
-
entityName =
|
|
1109
|
+
entityName = entityNameOrEntity;
|
|
1121
1110
|
}
|
|
1122
1111
|
if (Utils.isEntity(data)) {
|
|
1123
1112
|
if (options.schema && helper(data).getSchema() == null) {
|
|
@@ -1148,11 +1137,11 @@ export class EntityManager {
|
|
|
1148
1137
|
em.prepareOptions(options);
|
|
1149
1138
|
let entityName;
|
|
1150
1139
|
if (data === undefined) {
|
|
1151
|
-
entityName = entityNameOrEntities[0].constructor
|
|
1140
|
+
entityName = entityNameOrEntities[0].constructor;
|
|
1152
1141
|
data = entityNameOrEntities;
|
|
1153
1142
|
}
|
|
1154
1143
|
else {
|
|
1155
|
-
entityName =
|
|
1144
|
+
entityName = entityNameOrEntities;
|
|
1156
1145
|
}
|
|
1157
1146
|
if (data.length === 0) {
|
|
1158
1147
|
return [];
|
|
@@ -1189,7 +1178,6 @@ export class EntityManager {
|
|
|
1189
1178
|
async nativeUpdate(entityName, where, data, options = {}) {
|
|
1190
1179
|
const em = this.getContext(false);
|
|
1191
1180
|
em.prepareOptions(options);
|
|
1192
|
-
entityName = Utils.className(entityName);
|
|
1193
1181
|
data = QueryHelper.processObjectParams(data);
|
|
1194
1182
|
where = await em.processWhere(entityName, where, { ...options, convertCustomTypes: false }, 'update');
|
|
1195
1183
|
validateParams(data, 'update data');
|
|
@@ -1203,7 +1191,6 @@ export class EntityManager {
|
|
|
1203
1191
|
async nativeDelete(entityName, where, options = {}) {
|
|
1204
1192
|
const em = this.getContext(false);
|
|
1205
1193
|
em.prepareOptions(options);
|
|
1206
|
-
entityName = Utils.className(entityName);
|
|
1207
1194
|
where = await em.processWhere(entityName, where, options, 'delete');
|
|
1208
1195
|
validateParams(where, 'delete condition');
|
|
1209
1196
|
const res = await em.driver.nativeDelete(entityName, where, { ctx: em.transactionContext, ...options });
|
|
@@ -1213,7 +1200,6 @@ export class EntityManager {
|
|
|
1213
1200
|
* Maps raw database result to an entity and merges it to this EntityManager.
|
|
1214
1201
|
*/
|
|
1215
1202
|
map(entityName, result, options = {}) {
|
|
1216
|
-
entityName = Utils.className(entityName);
|
|
1217
1203
|
const meta = this.metadata.get(entityName);
|
|
1218
1204
|
const data = this.driver.mapResult(result, meta);
|
|
1219
1205
|
for (const k of Object.keys(data)) {
|
|
@@ -1235,13 +1221,12 @@ export class EntityManager {
|
|
|
1235
1221
|
*/
|
|
1236
1222
|
merge(entityName, data, options = {}) {
|
|
1237
1223
|
if (Utils.isEntity(entityName)) {
|
|
1238
|
-
return this.merge(entityName.constructor
|
|
1224
|
+
return this.merge(entityName.constructor, entityName, data);
|
|
1239
1225
|
}
|
|
1240
1226
|
const em = options.disableContextResolution ? this : this.getContext();
|
|
1241
1227
|
options.schema ??= em._schema;
|
|
1242
1228
|
options.validate ??= true;
|
|
1243
1229
|
options.cascade ??= true;
|
|
1244
|
-
entityName = Utils.className(entityName);
|
|
1245
1230
|
validatePrimaryKey(data, em.metadata.get(entityName));
|
|
1246
1231
|
let entity = em.unitOfWork.tryGetById(entityName, data, options.schema, false);
|
|
1247
1232
|
if (entity && helper(entity).__managed && helper(entity).__initialized && !options.refresh) {
|
|
@@ -1295,7 +1280,7 @@ export class EntityManager {
|
|
|
1295
1280
|
getReference(entityName, id, options = {}) {
|
|
1296
1281
|
options.schema ??= this.schema;
|
|
1297
1282
|
options.convertCustomTypes ??= false;
|
|
1298
|
-
const meta = this.metadata.get(
|
|
1283
|
+
const meta = this.metadata.get(entityName);
|
|
1299
1284
|
if (Utils.isPrimaryKey(id)) {
|
|
1300
1285
|
if (meta.compositePK) {
|
|
1301
1286
|
throw ValidationError.invalidCompositeIdentifier(meta);
|
|
@@ -1316,7 +1301,6 @@ export class EntityManager {
|
|
|
1316
1301
|
// Shallow copy options since the object will be modified when deleting orderBy
|
|
1317
1302
|
options = { ...options };
|
|
1318
1303
|
em.prepareOptions(options);
|
|
1319
|
-
entityName = Utils.className(entityName);
|
|
1320
1304
|
await em.tryFlush(entityName, options);
|
|
1321
1305
|
where = await em.processWhere(entityName, where, options, 'read');
|
|
1322
1306
|
options.populate = await em.preparePopulate(entityName, options);
|
|
@@ -1352,7 +1336,7 @@ export class EntityManager {
|
|
|
1352
1336
|
for (const ent of entities) {
|
|
1353
1337
|
if (!Utils.isEntity(ent, true)) {
|
|
1354
1338
|
/* v8 ignore next */
|
|
1355
|
-
const meta = typeof ent === 'object' ? em.metadata.find(ent.constructor
|
|
1339
|
+
const meta = typeof ent === 'object' ? em.metadata.find(ent.constructor) : undefined;
|
|
1356
1340
|
throw ValidationError.notDiscoveredEntity(ent, meta);
|
|
1357
1341
|
}
|
|
1358
1342
|
// do not cascade just yet, cascading of entities in persist stack is done when flushing
|
|
@@ -1396,7 +1380,6 @@ export class EntityManager {
|
|
|
1396
1380
|
async tryFlush(entityName, options) {
|
|
1397
1381
|
const em = this.getContext();
|
|
1398
1382
|
const flushMode = options.flushMode ?? em.flushMode ?? em.config.get('flushMode');
|
|
1399
|
-
entityName = Utils.className(entityName);
|
|
1400
1383
|
const meta = em.metadata.get(entityName);
|
|
1401
1384
|
if (flushMode === FlushMode.COMMIT) {
|
|
1402
1385
|
return;
|
|
@@ -1415,7 +1398,6 @@ export class EntityManager {
|
|
|
1415
1398
|
* Checks whether given property can be populated on the entity.
|
|
1416
1399
|
*/
|
|
1417
1400
|
canPopulate(entityName, property) {
|
|
1418
|
-
entityName = Utils.className(entityName);
|
|
1419
1401
|
// eslint-disable-next-line prefer-const
|
|
1420
1402
|
let [p, ...parts] = property.split('.');
|
|
1421
1403
|
const meta = this.metadata.find(entityName);
|
|
@@ -1426,11 +1408,8 @@ export class EntityManager {
|
|
|
1426
1408
|
p = p.split(':', 2)[0];
|
|
1427
1409
|
}
|
|
1428
1410
|
const ret = p in meta.root.properties;
|
|
1429
|
-
if (!ret) {
|
|
1430
|
-
return !!this.metadata.find(property)?.pivotTable;
|
|
1431
|
-
}
|
|
1432
1411
|
if (parts.length > 0) {
|
|
1433
|
-
return this.canPopulate(
|
|
1412
|
+
return this.canPopulate(meta.root.properties[p].targetMeta.class, parts.join('.'));
|
|
1434
1413
|
}
|
|
1435
1414
|
return ret;
|
|
1436
1415
|
}
|
|
@@ -1444,7 +1423,7 @@ export class EntityManager {
|
|
|
1444
1423
|
}
|
|
1445
1424
|
const em = this.getContext();
|
|
1446
1425
|
em.prepareOptions(options);
|
|
1447
|
-
const entityName = arr[0].constructor
|
|
1426
|
+
const entityName = arr[0].constructor;
|
|
1448
1427
|
const preparedPopulate = await em.preparePopulate(entityName, { populate: populate, filters: options.filters }, options.validate);
|
|
1449
1428
|
await em.entityLoader.populate(entityName, arr, preparedPopulate, options);
|
|
1450
1429
|
return entities;
|
|
@@ -1573,7 +1552,6 @@ export class EntityManager {
|
|
|
1573
1552
|
*/
|
|
1574
1553
|
getMetadata(entityName) {
|
|
1575
1554
|
if (entityName) {
|
|
1576
|
-
entityName = Utils.className(entityName);
|
|
1577
1555
|
return this.metadata.get(entityName);
|
|
1578
1556
|
}
|
|
1579
1557
|
return this.metadata;
|
|
@@ -1602,8 +1580,8 @@ export class EntityManager {
|
|
|
1602
1580
|
lockTableAliases: options.lockTableAliases,
|
|
1603
1581
|
});
|
|
1604
1582
|
}
|
|
1605
|
-
const preparedPopulate = await this.preparePopulate(meta.
|
|
1606
|
-
await this.entityLoader.populate(meta.
|
|
1583
|
+
const preparedPopulate = await this.preparePopulate(meta.class, options);
|
|
1584
|
+
await this.entityLoader.populate(meta.class, [entity], preparedPopulate, {
|
|
1607
1585
|
...options,
|
|
1608
1586
|
...this.getPopulateWhere(where, options),
|
|
1609
1587
|
orderBy: options.populateOrderBy ?? options.orderBy,
|
|
@@ -1740,7 +1718,7 @@ export class EntityManager {
|
|
|
1740
1718
|
for (const k of ['ctx', 'strategy', 'flushMode', 'logging', 'loggerContext']) {
|
|
1741
1719
|
delete opts[k];
|
|
1742
1720
|
}
|
|
1743
|
-
return [entityName, method, opts, where];
|
|
1721
|
+
return [Utils.className(entityName), method, opts, where];
|
|
1744
1722
|
}
|
|
1745
1723
|
/**
|
|
1746
1724
|
* @internal
|
package/MikroORM.d.ts
CHANGED
|
@@ -94,7 +94,7 @@ export declare class MikroORM<Driver extends IDatabaseDriver = IDatabaseDriver,
|
|
|
94
94
|
/**
|
|
95
95
|
* Allows dynamically discovering new entity by reference, handy for testing schema diffing.
|
|
96
96
|
*/
|
|
97
|
-
discoverEntity<T extends Constructor | EntitySchema>(entities: T | T[], reset?:
|
|
97
|
+
discoverEntity<T extends Constructor | EntitySchema>(entities: T | T[], reset?: EntityName | EntityName[]): void;
|
|
98
98
|
/**
|
|
99
99
|
* Gets the SchemaGenerator.
|
|
100
100
|
*/
|
package/MikroORM.js
CHANGED
|
@@ -158,7 +158,6 @@ export class MikroORM {
|
|
|
158
158
|
*/
|
|
159
159
|
getMetadata(entityName) {
|
|
160
160
|
if (entityName) {
|
|
161
|
-
entityName = Utils.className(entityName);
|
|
162
161
|
return this.metadata.get(entityName);
|
|
163
162
|
}
|
|
164
163
|
return this.metadata;
|
|
@@ -181,8 +180,8 @@ export class MikroORM {
|
|
|
181
180
|
const tmp = this.discovery.discoverReferences(Utils.asArray(entities));
|
|
182
181
|
const metadata = this.discovery.processDiscoveredEntities(tmp);
|
|
183
182
|
for (const meta of metadata) {
|
|
184
|
-
this.metadata.set(meta.
|
|
185
|
-
meta.root = this.metadata.get(meta.root.
|
|
183
|
+
this.metadata.set(meta.class, meta);
|
|
184
|
+
meta.root = this.metadata.get(meta.root.class);
|
|
186
185
|
}
|
|
187
186
|
this.metadata.decorate(this.em);
|
|
188
187
|
}
|
|
@@ -22,18 +22,18 @@ export declare abstract class DatabaseDriver<C extends Connection> implements ID
|
|
|
22
22
|
protected comparator: EntityComparator;
|
|
23
23
|
protected metadata: MetadataStorage;
|
|
24
24
|
protected constructor(config: Configuration, dependencies: string[]);
|
|
25
|
-
abstract find<T extends object, P extends string = never, F extends string = '*', E extends string = never>(entityName:
|
|
26
|
-
abstract findOne<T extends object, P extends string = never, F extends string = '*', E extends string = never>(entityName:
|
|
27
|
-
abstract nativeInsert<T extends object>(entityName:
|
|
28
|
-
abstract nativeInsertMany<T extends object>(entityName:
|
|
29
|
-
abstract nativeUpdate<T extends object>(entityName:
|
|
30
|
-
nativeUpdateMany<T extends object>(entityName:
|
|
31
|
-
abstract nativeDelete<T extends object>(entityName:
|
|
32
|
-
abstract count<T extends object, P extends string = never>(entityName:
|
|
25
|
+
abstract find<T extends object, P extends string = never, F extends string = '*', E extends string = never>(entityName: EntityName<T>, where: FilterQuery<T>, options?: FindOptions<T, P, F, E>): Promise<EntityData<T>[]>;
|
|
26
|
+
abstract findOne<T extends object, P extends string = never, F extends string = '*', E extends string = never>(entityName: EntityName<T>, where: FilterQuery<T>, options?: FindOneOptions<T, P, F, E>): Promise<EntityData<T> | null>;
|
|
27
|
+
abstract nativeInsert<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
|
|
28
|
+
abstract nativeInsertMany<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>, transform?: (sql: string) => string): Promise<QueryResult<T>>;
|
|
29
|
+
abstract nativeUpdate<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
|
|
30
|
+
nativeUpdateMany<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>[], data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>): Promise<QueryResult<T>>;
|
|
31
|
+
abstract nativeDelete<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options?: DeleteOptions<T>): Promise<QueryResult<T>>;
|
|
32
|
+
abstract count<T extends object, P extends string = never>(entityName: EntityName<T>, where: FilterQuery<T>, options?: CountOptions<T, P>): Promise<number>;
|
|
33
33
|
createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
|
|
34
34
|
findVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
|
|
35
|
-
countVirtual<T extends object>(entityName:
|
|
36
|
-
aggregate(entityName:
|
|
35
|
+
countVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: CountOptions<T, any>): Promise<number>;
|
|
36
|
+
aggregate(entityName: EntityName, pipeline: any[]): Promise<any[]>;
|
|
37
37
|
loadFromPivotTable<T extends object, O extends object>(prop: EntityProperty, owners: Primary<O>[][], where?: FilterQuery<any>, orderBy?: OrderDefinition<T>, ctx?: Transaction, options?: FindOptions<T, any, any, any>, pivotJoin?: boolean): Promise<Dictionary<T[]>>;
|
|
38
38
|
syncCollections<T extends object, O extends object>(collections: Iterable<Collection<T, O>>, options?: DriverMethodOptions): Promise<void>;
|
|
39
39
|
mapResult<T extends object>(result: EntityDictionary<T>, meta?: EntityMetadata<T>, populate?: PopulateOptions<T>[]): EntityData<T> | null;
|
|
@@ -58,7 +58,7 @@ export declare abstract class DatabaseDriver<C extends Connection> implements ID
|
|
|
58
58
|
/** @internal */
|
|
59
59
|
mapDataToFieldNames(data: Dictionary, stringifyJsonArrays: boolean, properties?: Record<string, EntityProperty>, convertCustomTypes?: boolean, object?: boolean): Dictionary;
|
|
60
60
|
protected inlineEmbeddables<T extends object>(meta: EntityMetadata<T>, data: T, where?: boolean): void;
|
|
61
|
-
protected getPrimaryKeyFields(
|
|
61
|
+
protected getPrimaryKeyFields<T>(meta: EntityMetadata<T>): string[];
|
|
62
62
|
protected createReplicas(cb: (c: ConnectionOptions) => C): C[];
|
|
63
63
|
lockPessimistic<T extends object>(entity: T, options: LockOptions): Promise<void>;
|
|
64
64
|
abstract stream<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: StreamOptions<T>): AsyncIterableIterator<T>;
|
|
@@ -59,7 +59,7 @@ export class DatabaseDriver {
|
|
|
59
59
|
{
|
|
60
60
|
const pk = coll.property.targetMeta.primaryKeys[0];
|
|
61
61
|
const data = { [coll.property.name]: coll.getIdentifiers(pk) };
|
|
62
|
-
await this.nativeUpdate(coll.owner.constructor
|
|
62
|
+
await this.nativeUpdate(coll.owner.constructor, helper(coll.owner).getPrimaryKey(), data, options);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -67,7 +67,7 @@ export class DatabaseDriver {
|
|
|
67
67
|
if (!result || !meta) {
|
|
68
68
|
return result ?? null;
|
|
69
69
|
}
|
|
70
|
-
return this.comparator.mapResult(meta
|
|
70
|
+
return this.comparator.mapResult(meta, result);
|
|
71
71
|
}
|
|
72
72
|
async connect(options) {
|
|
73
73
|
await this.connection.connect(options);
|
|
@@ -152,7 +152,7 @@ export class DatabaseDriver {
|
|
|
152
152
|
}
|
|
153
153
|
const createOrderBy = (prop, direction) => {
|
|
154
154
|
if (Utils.isPlainObject(direction)) {
|
|
155
|
-
const value = Utils.
|
|
155
|
+
const value = Utils.getObjectQueryKeys(direction).reduce((o, key) => {
|
|
156
156
|
Object.assign(o, createOrderBy(key, direction[key]));
|
|
157
157
|
return o;
|
|
158
158
|
}, {});
|
|
@@ -277,14 +277,14 @@ export class DatabaseDriver {
|
|
|
277
277
|
// explicitly allow `$exists`, `$eq` and `$ne` operators here as they can't be misused this way
|
|
278
278
|
const operator = Object.keys(data[prop.name]).some(f => Utils.isOperator(f) && !['$exists', '$ne', '$eq'].includes(f));
|
|
279
279
|
if (operator) {
|
|
280
|
-
throw ValidationError.cannotUseOperatorsInsideEmbeddables(meta.
|
|
280
|
+
throw ValidationError.cannotUseOperatorsInsideEmbeddables(meta.class, prop.name, data);
|
|
281
281
|
}
|
|
282
282
|
if (prop.object && where) {
|
|
283
283
|
const inline = (payload, sub, path) => {
|
|
284
284
|
if (sub.kind === ReferenceKind.EMBEDDED && Utils.isObject(payload[sub.embedded[1]])) {
|
|
285
285
|
return Object.keys(payload[sub.embedded[1]]).forEach(kkk => {
|
|
286
286
|
if (!sub.embeddedProps[kkk]) {
|
|
287
|
-
throw ValidationError.invalidEmbeddableQuery(meta.
|
|
287
|
+
throw ValidationError.invalidEmbeddableQuery(meta.class, kkk, sub.type);
|
|
288
288
|
}
|
|
289
289
|
inline(payload[sub.embedded[1]], sub.embeddedProps[kkk], [...path, sub.embedded[1]]);
|
|
290
290
|
});
|
|
@@ -308,7 +308,7 @@ export class DatabaseDriver {
|
|
|
308
308
|
data[props[kk].name] = data[prop.name][props[kk].embedded[1]];
|
|
309
309
|
}
|
|
310
310
|
else {
|
|
311
|
-
throw ValidationError.invalidEmbeddableQuery(meta.
|
|
311
|
+
throw ValidationError.invalidEmbeddableQuery(meta.class, kk, prop.type);
|
|
312
312
|
}
|
|
313
313
|
});
|
|
314
314
|
if (!unknownProp) {
|
|
@@ -317,9 +317,8 @@ export class DatabaseDriver {
|
|
|
317
317
|
}
|
|
318
318
|
});
|
|
319
319
|
}
|
|
320
|
-
getPrimaryKeyFields(
|
|
321
|
-
|
|
322
|
-
return meta ? Utils.flatten(meta.getPrimaryProps().map(pk => pk.fieldNames)) : [this.config.getNamingStrategy().referenceColumnName()];
|
|
320
|
+
getPrimaryKeyFields(meta) {
|
|
321
|
+
return meta.getPrimaryProps().flatMap(pk => pk.fieldNames);
|
|
323
322
|
}
|
|
324
323
|
createReplicas(cb) {
|
|
325
324
|
const replicas = this.config.get('replicas', []);
|