@yandjin-mikro-orm/core 6.1.4-rc-sti-changes-1
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 +553 -0
- package/EntityManager.js +1736 -0
- package/LICENSE +21 -0
- package/MikroORM.d.ts +102 -0
- package/MikroORM.js +258 -0
- package/README.md +383 -0
- package/cache/CacheAdapter.d.ts +40 -0
- package/cache/CacheAdapter.js +2 -0
- package/cache/FileCacheAdapter.d.ts +31 -0
- package/cache/FileCacheAdapter.js +90 -0
- package/cache/GeneratedCacheAdapter.d.ts +25 -0
- package/cache/GeneratedCacheAdapter.js +38 -0
- package/cache/MemoryCacheAdapter.d.ts +24 -0
- package/cache/MemoryCacheAdapter.js +44 -0
- package/cache/NullCacheAdapter.d.ts +19 -0
- package/cache/NullCacheAdapter.js +30 -0
- package/cache/index.d.ts +5 -0
- package/cache/index.js +21 -0
- package/connections/Connection.d.ts +85 -0
- package/connections/Connection.js +128 -0
- package/connections/index.d.ts +1 -0
- package/connections/index.js +17 -0
- package/decorators/Check.d.ts +3 -0
- package/decorators/Check.js +17 -0
- package/decorators/CreateRequestContext.d.ts +2 -0
- package/decorators/CreateRequestContext.js +31 -0
- package/decorators/Embeddable.d.ts +8 -0
- package/decorators/Embeddable.js +15 -0
- package/decorators/Embedded.d.ts +13 -0
- package/decorators/Embedded.js +21 -0
- package/decorators/EnsureRequestContext.d.ts +2 -0
- package/decorators/EnsureRequestContext.js +26 -0
- package/decorators/Entity.d.ts +18 -0
- package/decorators/Entity.js +17 -0
- package/decorators/Enum.d.ts +9 -0
- package/decorators/Enum.js +20 -0
- package/decorators/Filter.d.ts +2 -0
- package/decorators/Filter.js +12 -0
- package/decorators/Formula.d.ts +5 -0
- package/decorators/Formula.js +19 -0
- package/decorators/Indexed.d.ts +12 -0
- package/decorators/Indexed.js +25 -0
- package/decorators/ManyToMany.d.ts +21 -0
- package/decorators/ManyToMany.js +17 -0
- package/decorators/ManyToOne.d.ts +15 -0
- package/decorators/ManyToOne.js +17 -0
- package/decorators/OneToMany.d.ts +18 -0
- package/decorators/OneToMany.js +21 -0
- package/decorators/OneToOne.d.ts +12 -0
- package/decorators/OneToOne.js +11 -0
- package/decorators/PrimaryKey.d.ts +8 -0
- package/decorators/PrimaryKey.js +24 -0
- package/decorators/Property.d.ts +218 -0
- package/decorators/Property.js +35 -0
- package/decorators/Subscriber.d.ts +1 -0
- package/decorators/Subscriber.js +2 -0
- package/decorators/hooks.d.ts +16 -0
- package/decorators/hooks.js +60 -0
- package/decorators/index.d.ts +17 -0
- package/decorators/index.js +36 -0
- package/drivers/DatabaseDriver.d.ts +72 -0
- package/drivers/DatabaseDriver.js +358 -0
- package/drivers/IDatabaseDriver.d.ts +193 -0
- package/drivers/IDatabaseDriver.js +4 -0
- package/drivers/index.d.ts +2 -0
- package/drivers/index.js +18 -0
- package/entity/ArrayCollection.d.ts +113 -0
- package/entity/ArrayCollection.js +386 -0
- package/entity/BaseEntity.d.ts +22 -0
- package/entity/BaseEntity.js +47 -0
- package/entity/Collection.d.ts +104 -0
- package/entity/Collection.js +373 -0
- package/entity/EntityAssigner.d.ts +28 -0
- package/entity/EntityAssigner.js +226 -0
- package/entity/EntityFactory.d.ts +41 -0
- package/entity/EntityFactory.js +302 -0
- package/entity/EntityHelper.d.ts +29 -0
- package/entity/EntityHelper.js +250 -0
- package/entity/EntityIdentifier.d.ts +10 -0
- package/entity/EntityIdentifier.js +19 -0
- package/entity/EntityLoader.d.ts +65 -0
- package/entity/EntityLoader.js +579 -0
- package/entity/EntityRepository.d.ts +161 -0
- package/entity/EntityRepository.js +207 -0
- package/entity/EntityValidator.d.ts +19 -0
- package/entity/EntityValidator.js +152 -0
- package/entity/Reference.d.ts +89 -0
- package/entity/Reference.js +242 -0
- package/entity/WrappedEntity.d.ts +67 -0
- package/entity/WrappedEntity.js +146 -0
- package/entity/index.d.ts +13 -0
- package/entity/index.js +29 -0
- package/entity/wrap.d.ts +15 -0
- package/entity/wrap.js +26 -0
- package/enums.d.ts +160 -0
- package/enums.js +169 -0
- package/errors.d.ts +65 -0
- package/errors.js +222 -0
- package/events/EventManager.d.ts +17 -0
- package/events/EventManager.js +77 -0
- package/events/EventSubscriber.d.ts +39 -0
- package/events/EventSubscriber.js +2 -0
- package/events/TransactionEventBroadcaster.d.ts +11 -0
- package/events/TransactionEventBroadcaster.js +17 -0
- package/events/index.d.ts +3 -0
- package/events/index.js +19 -0
- package/exceptions.d.ts +104 -0
- package/exceptions.js +130 -0
- package/hydration/Hydrator.d.ts +23 -0
- package/hydration/Hydrator.js +51 -0
- package/hydration/ObjectHydrator.d.ts +24 -0
- package/hydration/ObjectHydrator.js +332 -0
- package/hydration/index.d.ts +2 -0
- package/hydration/index.js +18 -0
- package/index.d.ts +25 -0
- package/index.js +50 -0
- package/index.mjs +192 -0
- package/logging/DefaultLogger.d.ts +32 -0
- package/logging/DefaultLogger.js +90 -0
- package/logging/Logger.d.ts +56 -0
- package/logging/Logger.js +2 -0
- package/logging/SimpleLogger.d.ts +17 -0
- package/logging/SimpleLogger.js +31 -0
- package/logging/colors.d.ts +9 -0
- package/logging/colors.js +20 -0
- package/logging/index.d.ts +4 -0
- package/logging/index.js +20 -0
- package/metadata/EntitySchema.d.ts +74 -0
- package/metadata/EntitySchema.js +293 -0
- package/metadata/MetadataDiscovery.d.ts +71 -0
- package/metadata/MetadataDiscovery.js +1244 -0
- package/metadata/MetadataProvider.d.ts +11 -0
- package/metadata/MetadataProvider.js +23 -0
- package/metadata/MetadataStorage.d.ts +22 -0
- package/metadata/MetadataStorage.js +87 -0
- package/metadata/MetadataValidator.d.ts +24 -0
- package/metadata/MetadataValidator.js +213 -0
- package/metadata/ReflectMetadataProvider.d.ts +8 -0
- package/metadata/ReflectMetadataProvider.js +48 -0
- package/metadata/index.d.ts +6 -0
- package/metadata/index.js +22 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +18 -0
- package/naming-strategy/AbstractNamingStrategy.js +48 -0
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +12 -0
- package/naming-strategy/EntityCaseNamingStrategy.js +32 -0
- package/naming-strategy/MongoNamingStrategy.d.ts +9 -0
- package/naming-strategy/MongoNamingStrategy.js +25 -0
- package/naming-strategy/NamingStrategy.d.ts +52 -0
- package/naming-strategy/NamingStrategy.js +2 -0
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +10 -0
- package/naming-strategy/UnderscoreNamingStrategy.js +28 -0
- package/naming-strategy/index.d.ts +5 -0
- package/naming-strategy/index.js +21 -0
- package/package.json +70 -0
- package/platforms/ExceptionConverter.d.ts +5 -0
- package/platforms/ExceptionConverter.js +11 -0
- package/platforms/Platform.d.ts +201 -0
- package/platforms/Platform.js +452 -0
- package/platforms/index.d.ts +2 -0
- package/platforms/index.js +18 -0
- package/serialization/EntitySerializer.d.ts +34 -0
- package/serialization/EntitySerializer.js +206 -0
- package/serialization/EntityTransformer.d.ts +8 -0
- package/serialization/EntityTransformer.js +192 -0
- package/serialization/SerializationContext.d.ts +30 -0
- package/serialization/SerializationContext.js +111 -0
- package/serialization/index.d.ts +3 -0
- package/serialization/index.js +19 -0
- package/types/ArrayType.d.ts +13 -0
- package/types/ArrayType.js +47 -0
- package/types/BigIntType.d.ts +16 -0
- package/types/BigIntType.js +45 -0
- package/types/BlobType.d.ts +10 -0
- package/types/BlobType.js +27 -0
- package/types/BooleanType.d.ts +8 -0
- package/types/BooleanType.js +16 -0
- package/types/DateTimeType.d.ts +8 -0
- package/types/DateTimeType.js +16 -0
- package/types/DateType.d.ts +8 -0
- package/types/DateType.js +16 -0
- package/types/DecimalType.d.ts +11 -0
- package/types/DecimalType.js +22 -0
- package/types/DoubleType.d.ts +11 -0
- package/types/DoubleType.js +22 -0
- package/types/EnumArrayType.d.ts +9 -0
- package/types/EnumArrayType.js +32 -0
- package/types/EnumType.d.ts +8 -0
- package/types/EnumType.js +16 -0
- package/types/FloatType.d.ts +8 -0
- package/types/FloatType.js +16 -0
- package/types/IntegerType.d.ts +8 -0
- package/types/IntegerType.js +16 -0
- package/types/IntervalType.d.ts +8 -0
- package/types/IntervalType.js +16 -0
- package/types/JsonType.d.ts +13 -0
- package/types/JsonType.js +34 -0
- package/types/MediumIntType.d.ts +6 -0
- package/types/MediumIntType.js +10 -0
- package/types/SmallIntType.d.ts +8 -0
- package/types/SmallIntType.js +16 -0
- package/types/StringType.d.ts +8 -0
- package/types/StringType.js +16 -0
- package/types/TextType.d.ts +8 -0
- package/types/TextType.js +16 -0
- package/types/TimeType.d.ts +9 -0
- package/types/TimeType.js +23 -0
- package/types/TinyIntType.d.ts +8 -0
- package/types/TinyIntType.js +16 -0
- package/types/Type.d.ts +64 -0
- package/types/Type.js +84 -0
- package/types/Uint8ArrayType.d.ts +11 -0
- package/types/Uint8ArrayType.js +37 -0
- package/types/UnknownType.d.ts +7 -0
- package/types/UnknownType.js +13 -0
- package/types/UuidType.d.ts +7 -0
- package/types/UuidType.js +13 -0
- package/types/index.d.ts +75 -0
- package/types/index.js +77 -0
- package/typings.d.ts +767 -0
- package/typings.js +198 -0
- package/unit-of-work/ChangeSet.d.ts +34 -0
- package/unit-of-work/ChangeSet.js +62 -0
- package/unit-of-work/ChangeSetComputer.d.ts +26 -0
- package/unit-of-work/ChangeSetComputer.js +153 -0
- package/unit-of-work/ChangeSetPersister.d.ts +50 -0
- package/unit-of-work/ChangeSetPersister.js +361 -0
- package/unit-of-work/CommitOrderCalculator.d.ts +62 -0
- package/unit-of-work/CommitOrderCalculator.js +113 -0
- package/unit-of-work/IdentityMap.d.ts +17 -0
- package/unit-of-work/IdentityMap.js +84 -0
- package/unit-of-work/UnitOfWork.d.ts +124 -0
- package/unit-of-work/UnitOfWork.js +1013 -0
- package/unit-of-work/index.d.ts +6 -0
- package/unit-of-work/index.js +22 -0
- package/utils/AbstractSchemaGenerator.d.ts +38 -0
- package/utils/AbstractSchemaGenerator.js +101 -0
- package/utils/Configuration.d.ts +390 -0
- package/utils/Configuration.js +357 -0
- package/utils/ConfigurationLoader.d.ts +29 -0
- package/utils/ConfigurationLoader.js +282 -0
- package/utils/Cursor.d.ts +77 -0
- package/utils/Cursor.js +169 -0
- package/utils/DataloaderUtils.d.ts +43 -0
- package/utils/DataloaderUtils.js +194 -0
- package/utils/EntityComparator.d.ts +73 -0
- package/utils/EntityComparator.js +568 -0
- package/utils/NullHighlighter.d.ts +4 -0
- package/utils/NullHighlighter.js +9 -0
- package/utils/QueryHelper.d.ts +28 -0
- package/utils/QueryHelper.js +228 -0
- package/utils/RawQueryFragment.d.ts +96 -0
- package/utils/RawQueryFragment.js +188 -0
- package/utils/RequestContext.d.ts +34 -0
- package/utils/RequestContext.js +54 -0
- package/utils/TransactionContext.d.ts +19 -0
- package/utils/TransactionContext.js +34 -0
- package/utils/Utils.d.ts +274 -0
- package/utils/Utils.js +1073 -0
- package/utils/clone.d.ts +6 -0
- package/utils/clone.js +127 -0
- package/utils/index.d.ts +13 -0
- package/utils/index.js +29 -0
- package/utils/upsert-utils.d.ts +6 -0
- package/utils/upsert-utils.js +33 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityFactory = void 0;
|
|
4
|
+
const Utils_1 = require("../utils/Utils");
|
|
5
|
+
const QueryHelper_1 = require("../utils/QueryHelper");
|
|
6
|
+
const enums_1 = require("../enums");
|
|
7
|
+
const Reference_1 = require("./Reference");
|
|
8
|
+
const wrap_1 = require("./wrap");
|
|
9
|
+
const EntityHelper_1 = require("./EntityHelper");
|
|
10
|
+
class EntityFactory {
|
|
11
|
+
em;
|
|
12
|
+
driver;
|
|
13
|
+
platform;
|
|
14
|
+
config;
|
|
15
|
+
metadata;
|
|
16
|
+
hydrator;
|
|
17
|
+
eventManager;
|
|
18
|
+
comparator;
|
|
19
|
+
constructor(em) {
|
|
20
|
+
this.em = em;
|
|
21
|
+
this.driver = this.em.getDriver();
|
|
22
|
+
this.platform = this.driver.getPlatform();
|
|
23
|
+
this.config = this.em.config;
|
|
24
|
+
this.metadata = this.em.getMetadata();
|
|
25
|
+
this.hydrator = this.config.getHydrator(this.metadata);
|
|
26
|
+
this.eventManager = this.em.getEventManager();
|
|
27
|
+
this.comparator = this.em.getComparator();
|
|
28
|
+
}
|
|
29
|
+
create(entityName, data, options = {}) {
|
|
30
|
+
data = Reference_1.Reference.unwrapReference(data);
|
|
31
|
+
options.initialized ??= true;
|
|
32
|
+
if (data.__entity) {
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
36
|
+
const meta = this.metadata.get(entityName);
|
|
37
|
+
if (meta.virtual) {
|
|
38
|
+
data = { ...data };
|
|
39
|
+
const entity = this.createEntity(data, meta, options);
|
|
40
|
+
this.hydrate(entity, meta, data, options);
|
|
41
|
+
return entity;
|
|
42
|
+
}
|
|
43
|
+
if (this.platform.usesDifferentSerializedPrimaryKey()) {
|
|
44
|
+
meta.primaryKeys.forEach(pk => this.denormalizePrimaryKey(data, pk, meta.properties[pk]));
|
|
45
|
+
}
|
|
46
|
+
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
47
|
+
const exists = this.findEntity(data, meta2, options);
|
|
48
|
+
let wrapped = exists && (0, wrap_1.helper)(exists);
|
|
49
|
+
if (wrapped && !options.refresh) {
|
|
50
|
+
wrapped.__processing = true;
|
|
51
|
+
this.mergeData(meta2, exists, data, options);
|
|
52
|
+
wrapped.__processing = false;
|
|
53
|
+
if (wrapped.isInitialized()) {
|
|
54
|
+
return exists;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
data = { ...data };
|
|
58
|
+
const entity = exists ?? this.createEntity(data, meta2, options);
|
|
59
|
+
wrapped = (0, wrap_1.helper)(entity);
|
|
60
|
+
wrapped.__processing = true;
|
|
61
|
+
wrapped.__initialized = options.initialized;
|
|
62
|
+
if (options.newEntity || meta.forceConstructor || meta.virtual) {
|
|
63
|
+
const tmp = { ...data };
|
|
64
|
+
meta.constructorParams.forEach(prop => delete tmp[prop]);
|
|
65
|
+
this.hydrate(entity, meta2, tmp, options);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
this.hydrate(entity, meta2, data, options);
|
|
69
|
+
}
|
|
70
|
+
wrapped.__touched = false;
|
|
71
|
+
if (exists && meta.discriminatorColumn && !(entity instanceof meta2.class)) {
|
|
72
|
+
Object.setPrototypeOf(entity, meta2.prototype);
|
|
73
|
+
}
|
|
74
|
+
if (options.merge && wrapped.hasPrimaryKey()) {
|
|
75
|
+
this.unitOfWork.register(entity, data, {
|
|
76
|
+
refresh: options.refresh && options.initialized,
|
|
77
|
+
newEntity: options.newEntity,
|
|
78
|
+
loaded: options.initialized,
|
|
79
|
+
});
|
|
80
|
+
if (options.recomputeSnapshot) {
|
|
81
|
+
wrapped.__originalEntityData = this.comparator.prepareEntity(entity);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (this.eventManager.hasListeners(enums_1.EventType.onInit, meta2)) {
|
|
85
|
+
this.eventManager.dispatchEvent(enums_1.EventType.onInit, { entity, meta: meta2, em: this.em });
|
|
86
|
+
}
|
|
87
|
+
wrapped.__processing = false;
|
|
88
|
+
return entity;
|
|
89
|
+
}
|
|
90
|
+
mergeData(meta, entity, data, options = {}) {
|
|
91
|
+
// merge unchanged properties automatically
|
|
92
|
+
data = QueryHelper_1.QueryHelper.processParams(data);
|
|
93
|
+
const existsData = this.comparator.prepareEntity(entity);
|
|
94
|
+
const originalEntityData = (0, wrap_1.helper)(entity).__originalEntityData ?? {};
|
|
95
|
+
const diff = this.comparator.diffEntities(meta.className, originalEntityData, existsData);
|
|
96
|
+
// version properties are not part of entity snapshots
|
|
97
|
+
if (meta.versionProperty && data[meta.versionProperty] && data[meta.versionProperty] !== originalEntityData[meta.versionProperty]) {
|
|
98
|
+
diff[meta.versionProperty] = data[meta.versionProperty];
|
|
99
|
+
}
|
|
100
|
+
const diff2 = this.comparator.diffEntities(meta.className, existsData, data);
|
|
101
|
+
// do not override values changed by user
|
|
102
|
+
Utils_1.Utils.keys(diff).forEach(key => delete diff2[key]);
|
|
103
|
+
Utils_1.Utils.keys(diff2).filter(key => {
|
|
104
|
+
// ignore null values if there is already present non-null value
|
|
105
|
+
if (existsData[key] != null) {
|
|
106
|
+
return diff2[key] == null;
|
|
107
|
+
}
|
|
108
|
+
return diff2[key] === undefined;
|
|
109
|
+
}).forEach(key => delete diff2[key]);
|
|
110
|
+
// but always add collection properties and formulas if they are part of the `data`
|
|
111
|
+
Utils_1.Utils.keys(data)
|
|
112
|
+
.filter(key => meta.properties[key]?.formula || [enums_1.ReferenceKind.ONE_TO_MANY, enums_1.ReferenceKind.MANY_TO_MANY].includes(meta.properties[key]?.kind))
|
|
113
|
+
.forEach(key => diff2[key] = data[key]);
|
|
114
|
+
// rehydrated with the new values, skip those changed by user
|
|
115
|
+
this.hydrate(entity, meta, diff2, options);
|
|
116
|
+
// we need to update the entity data only with keys that were not present before
|
|
117
|
+
const nullVal = this.config.get('forceUndefined') ? undefined : null;
|
|
118
|
+
Utils_1.Utils.keys(diff2).forEach(key => {
|
|
119
|
+
const prop = meta.properties[key];
|
|
120
|
+
if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils_1.Utils.isPlainObject(data[prop.name])) {
|
|
121
|
+
diff2[key] = entity[prop.name] ? (0, wrap_1.helper)(entity[prop.name]).getPrimaryKey(options.convertCustomTypes) : null;
|
|
122
|
+
}
|
|
123
|
+
originalEntityData[key] = diff2[key] === null ? nullVal : diff2[key];
|
|
124
|
+
(0, wrap_1.helper)(entity).__loadedProperties.add(key);
|
|
125
|
+
});
|
|
126
|
+
// in case of joined loading strategy, we need to cascade the merging to possibly loaded relations manually
|
|
127
|
+
meta.relations.forEach(prop => {
|
|
128
|
+
if ([enums_1.ReferenceKind.MANY_TO_MANY, enums_1.ReferenceKind.ONE_TO_MANY].includes(prop.kind) && Array.isArray(data[prop.name])) {
|
|
129
|
+
// instead of trying to match the collection items (which could easily fail if the collection was loaded with different ordering),
|
|
130
|
+
// we just create the entity from scratch, which will automatically pick the right one from the identity map and call `mergeData` on it
|
|
131
|
+
data[prop.name]
|
|
132
|
+
.filter(child => Utils_1.Utils.isPlainObject(child)) // objects with prototype can be PKs (e.g. `ObjectId`)
|
|
133
|
+
.forEach(child => this.create(prop.type, child, options)); // we can ignore the value, we just care about the `mergeData` call
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if ([enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind) && Utils_1.Utils.isPlainObject(data[prop.name]) && entity[prop.name] && (0, wrap_1.helper)(entity[prop.name]).__initialized) {
|
|
137
|
+
this.create(prop.type, data[prop.name], options); // we can ignore the value, we just care about the `mergeData` call
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
(0, wrap_1.helper)(entity).__touched = false;
|
|
141
|
+
}
|
|
142
|
+
createReference(entityName, id, options = {}) {
|
|
143
|
+
options.convertCustomTypes ??= true;
|
|
144
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
145
|
+
const meta = this.metadata.get(entityName);
|
|
146
|
+
const schema = this.driver.getSchemaName(meta, options);
|
|
147
|
+
if (Array.isArray(id)) {
|
|
148
|
+
id = Utils_1.Utils.getPrimaryKeyCondFromArray(id, meta);
|
|
149
|
+
}
|
|
150
|
+
const pks = Utils_1.Utils.getOrderedPrimaryKeys(id, meta);
|
|
151
|
+
const exists = this.unitOfWork.getById(entityName, pks, schema);
|
|
152
|
+
if (exists) {
|
|
153
|
+
return exists;
|
|
154
|
+
}
|
|
155
|
+
if (Utils_1.Utils.isPrimaryKey(id)) {
|
|
156
|
+
id = { [meta.primaryKeys[0]]: id };
|
|
157
|
+
}
|
|
158
|
+
return this.create(entityName, id, { ...options, initialized: false });
|
|
159
|
+
}
|
|
160
|
+
createEmbeddable(entityName, data, options = {}) {
|
|
161
|
+
entityName = Utils_1.Utils.className(entityName);
|
|
162
|
+
data = { ...data };
|
|
163
|
+
const meta = this.metadata.get(entityName);
|
|
164
|
+
const meta2 = this.processDiscriminatorColumn(meta, data);
|
|
165
|
+
return this.createEntity(data, meta2, options);
|
|
166
|
+
}
|
|
167
|
+
getComparator() {
|
|
168
|
+
return this.comparator;
|
|
169
|
+
}
|
|
170
|
+
createEntity(data, meta, options) {
|
|
171
|
+
if (options.newEntity || meta.forceConstructor || meta.virtual) {
|
|
172
|
+
if (!meta.class) {
|
|
173
|
+
throw new Error(`Cannot create entity ${meta.className}, class prototype is unknown`);
|
|
174
|
+
}
|
|
175
|
+
options.initialized = options.newEntity || options.initialized;
|
|
176
|
+
const params = this.extractConstructorParams(meta, data, options);
|
|
177
|
+
const Entity = meta.class;
|
|
178
|
+
// creates new instance via constructor as this is the new entity
|
|
179
|
+
const entity = new Entity(...params);
|
|
180
|
+
// creating managed entity instance when `forceEntityConstructor` is enabled,
|
|
181
|
+
// we need to wipe all the values as they would cause update queries on next flush
|
|
182
|
+
if (!options.initialized && this.config.get('forceEntityConstructor')) {
|
|
183
|
+
meta.props
|
|
184
|
+
.filter(prop => prop.persist !== false && !prop.primary && data[prop.name] === undefined)
|
|
185
|
+
.forEach(prop => delete entity[prop.name]);
|
|
186
|
+
}
|
|
187
|
+
if (meta.virtual) {
|
|
188
|
+
return entity;
|
|
189
|
+
}
|
|
190
|
+
(0, wrap_1.helper)(entity).__schema = this.driver.getSchemaName(meta, options);
|
|
191
|
+
if (options.initialized) {
|
|
192
|
+
EntityHelper_1.EntityHelper.ensurePropagation(entity);
|
|
193
|
+
}
|
|
194
|
+
return entity;
|
|
195
|
+
}
|
|
196
|
+
// creates new entity instance, bypassing constructor call as its already persisted entity
|
|
197
|
+
const entity = Object.create(meta.class.prototype);
|
|
198
|
+
(0, wrap_1.helper)(entity).__managed = true;
|
|
199
|
+
(0, wrap_1.helper)(entity).__processing = !meta.embeddable && !meta.virtual;
|
|
200
|
+
(0, wrap_1.helper)(entity).__schema = this.driver.getSchemaName(meta, options);
|
|
201
|
+
if (options.merge && !options.newEntity) {
|
|
202
|
+
this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, this.driver.getSchemaName(meta, options));
|
|
203
|
+
this.unitOfWork.register(entity);
|
|
204
|
+
}
|
|
205
|
+
if (options.initialized) {
|
|
206
|
+
EntityHelper_1.EntityHelper.ensurePropagation(entity);
|
|
207
|
+
}
|
|
208
|
+
return entity;
|
|
209
|
+
}
|
|
210
|
+
hydrate(entity, meta, data, options) {
|
|
211
|
+
if (options.initialized) {
|
|
212
|
+
this.hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, this.driver.getSchemaName(meta, options));
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
this.hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, this.driver.getSchemaName(meta, options));
|
|
216
|
+
}
|
|
217
|
+
Utils_1.Utils.keys(data).forEach(key => {
|
|
218
|
+
(0, wrap_1.helper)(entity)?.__loadedProperties.add(key);
|
|
219
|
+
(0, wrap_1.helper)(entity)?.__serializationContext.fields?.add(key);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
findEntity(data, meta, options) {
|
|
223
|
+
const schema = this.driver.getSchemaName(meta, options);
|
|
224
|
+
if (meta.simplePK) {
|
|
225
|
+
return this.unitOfWork.getById(meta.className, data[meta.primaryKeys[0]], schema);
|
|
226
|
+
}
|
|
227
|
+
if (!Array.isArray(data) && meta.primaryKeys.some(pk => data[pk] == null)) {
|
|
228
|
+
return undefined;
|
|
229
|
+
}
|
|
230
|
+
const pks = Utils_1.Utils.getOrderedPrimaryKeys(data, meta);
|
|
231
|
+
return this.unitOfWork.getById(meta.className, pks, schema);
|
|
232
|
+
}
|
|
233
|
+
processDiscriminatorColumn(meta, data) {
|
|
234
|
+
if (!meta.root.discriminatorColumn) {
|
|
235
|
+
return meta;
|
|
236
|
+
}
|
|
237
|
+
const prop = meta.properties[meta.root.discriminatorColumn];
|
|
238
|
+
const value = data[prop.name];
|
|
239
|
+
const type = meta.root.discriminatorMap[value];
|
|
240
|
+
meta = type ? this.metadata.find(type) : meta;
|
|
241
|
+
return meta;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* denormalize PK to value required by driver (e.g. ObjectId)
|
|
245
|
+
*/
|
|
246
|
+
denormalizePrimaryKey(data, primaryKey, prop) {
|
|
247
|
+
const pk = this.platform.getSerializedPrimaryKeyField(primaryKey);
|
|
248
|
+
if (data[pk] != null || data[primaryKey] != null) {
|
|
249
|
+
let id = (data[pk] || data[primaryKey]);
|
|
250
|
+
if (prop.type.toLowerCase() === 'objectid') {
|
|
251
|
+
id = this.platform.denormalizePrimaryKey(id);
|
|
252
|
+
}
|
|
253
|
+
delete data[pk];
|
|
254
|
+
data[primaryKey] = id;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* returns parameters for entity constructor, creating references from plain ids
|
|
259
|
+
*/
|
|
260
|
+
extractConstructorParams(meta, data, options) {
|
|
261
|
+
return meta.constructorParams.map(k => {
|
|
262
|
+
if (meta.properties[k] && [enums_1.ReferenceKind.MANY_TO_ONE, enums_1.ReferenceKind.ONE_TO_ONE].includes(meta.properties[k].kind) && data[k]) {
|
|
263
|
+
const entity = this.unitOfWork.getById(meta.properties[k].type, data[k], options.schema);
|
|
264
|
+
if (entity) {
|
|
265
|
+
return entity;
|
|
266
|
+
}
|
|
267
|
+
if (Utils_1.Utils.isEntity(data[k])) {
|
|
268
|
+
return data[k];
|
|
269
|
+
}
|
|
270
|
+
if (Utils_1.Utils.isObject(data[k]) && !Utils_1.Utils.extractPK(data[k], meta.properties[k].targetMeta, true)) {
|
|
271
|
+
return this.create(meta.properties[k].type, data[k], options);
|
|
272
|
+
}
|
|
273
|
+
const { newEntity, initialized, ...rest } = options;
|
|
274
|
+
return this.createReference(meta.properties[k].type, data[k], rest);
|
|
275
|
+
}
|
|
276
|
+
if (meta.properties[k]?.kind === enums_1.ReferenceKind.EMBEDDED && data[k]) {
|
|
277
|
+
/* istanbul ignore next */
|
|
278
|
+
if (Utils_1.Utils.isEntity(data[k])) {
|
|
279
|
+
return data[k];
|
|
280
|
+
}
|
|
281
|
+
return this.createEmbeddable(meta.properties[k].type, data[k], options);
|
|
282
|
+
}
|
|
283
|
+
if (!meta.properties[k]) {
|
|
284
|
+
const tmp = { ...data };
|
|
285
|
+
for (const prop of meta.props) {
|
|
286
|
+
if (options.convertCustomTypes && prop.customType && tmp[prop.name] != null) {
|
|
287
|
+
tmp[prop.name] = prop.customType.convertToJSValue(tmp[prop.name], this.platform);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return tmp;
|
|
291
|
+
}
|
|
292
|
+
if (options.convertCustomTypes && meta.properties[k].customType && data[k] != null) {
|
|
293
|
+
return meta.properties[k].customType.convertToJSValue(data[k], this.platform);
|
|
294
|
+
}
|
|
295
|
+
return data[k];
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
get unitOfWork() {
|
|
299
|
+
return this.em.getUnitOfWork(false);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
exports.EntityFactory = EntityFactory;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { EntityManager } from '../EntityManager';
|
|
2
|
+
import { type EntityMetadata, type EntityProperty, type IHydrator } from '../typings';
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare class EntityHelper {
|
|
7
|
+
static decorate<T extends object>(meta: EntityMetadata<T>, em: EntityManager): void;
|
|
8
|
+
/**
|
|
9
|
+
* As a performance optimization, we create entity state methods in a lazy manner. We first add
|
|
10
|
+
* the `null` value to the prototype to reserve space in memory. Then we define a setter on the
|
|
11
|
+
* prototype, that will be executed exactly once per entity instance. There we redefine given
|
|
12
|
+
* property on the entity instance, so shadowing the prototype setter.
|
|
13
|
+
*/
|
|
14
|
+
private static defineBaseProperties;
|
|
15
|
+
/**
|
|
16
|
+
* Defines getter and setter for every owning side of m:1 and 1:1 relation. This is then used for propagation of
|
|
17
|
+
* changes to the inverse side of bi-directional relations. Rest of the properties are also defined this way to
|
|
18
|
+
* achieve dirtiness, which is then used for fast checks whether we need to auto-flush because of managed entities.
|
|
19
|
+
*
|
|
20
|
+
* First defines a setter on the prototype, once called, actual get/set handlers are registered on the instance rather
|
|
21
|
+
* than on its prototype. Thanks to this we still have those properties enumerable (e.g. part of `Object.keys(entity)`).
|
|
22
|
+
*/
|
|
23
|
+
private static defineProperties;
|
|
24
|
+
static defineCustomInspect<T extends object>(meta: EntityMetadata<T>): void;
|
|
25
|
+
static defineReferenceProperty<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T>, ref: T, hydrator: IHydrator): void;
|
|
26
|
+
static propagate<T extends object>(meta: EntityMetadata<T>, entity: T, owner: T, prop: EntityProperty<T>, value?: T[keyof T & string], old?: T): void;
|
|
27
|
+
private static propagateOneToOne;
|
|
28
|
+
static ensurePropagation<T extends object>(entity: T): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityHelper = void 0;
|
|
4
|
+
const util_1 = require("util");
|
|
5
|
+
const typings_1 = require("../typings");
|
|
6
|
+
const EntityTransformer_1 = require("../serialization/EntityTransformer");
|
|
7
|
+
const Reference_1 = require("./Reference");
|
|
8
|
+
const Utils_1 = require("../utils/Utils");
|
|
9
|
+
const WrappedEntity_1 = require("./WrappedEntity");
|
|
10
|
+
const enums_1 = require("../enums");
|
|
11
|
+
const wrap_1 = require("./wrap");
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
class EntityHelper {
|
|
16
|
+
static decorate(meta, em) {
|
|
17
|
+
const fork = em.fork(); // use fork so we can access `EntityFactory`
|
|
18
|
+
const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
|
|
19
|
+
if (serializedPrimaryKey) {
|
|
20
|
+
Object.defineProperty(meta.prototype, serializedPrimaryKey.name, {
|
|
21
|
+
get() {
|
|
22
|
+
return this._id ? em.getPlatform().normalizePrimaryKey(this._id) : null;
|
|
23
|
+
},
|
|
24
|
+
set(id) {
|
|
25
|
+
this._id = id ? em.getPlatform().denormalizePrimaryKey(id) : null;
|
|
26
|
+
},
|
|
27
|
+
configurable: true,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
EntityHelper.defineBaseProperties(meta, meta.prototype, fork);
|
|
31
|
+
EntityHelper.defineCustomInspect(meta);
|
|
32
|
+
if (em.config.get('propagationOnPrototype') && !meta.embeddable && !meta.virtual) {
|
|
33
|
+
EntityHelper.defineProperties(meta, fork);
|
|
34
|
+
}
|
|
35
|
+
const prototype = meta.prototype;
|
|
36
|
+
if (!prototype.toJSON) { // toJSON can be overridden
|
|
37
|
+
prototype.toJSON = function (...args) {
|
|
38
|
+
return EntityTransformer_1.EntityTransformer.toObject(this, ...args.slice(meta.toJsonParams.length));
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* As a performance optimization, we create entity state methods in a lazy manner. We first add
|
|
44
|
+
* the `null` value to the prototype to reserve space in memory. Then we define a setter on the
|
|
45
|
+
* prototype, that will be executed exactly once per entity instance. There we redefine given
|
|
46
|
+
* property on the entity instance, so shadowing the prototype setter.
|
|
47
|
+
*/
|
|
48
|
+
static defineBaseProperties(meta, prototype, em) {
|
|
49
|
+
const helperParams = meta.embeddable || meta.virtual ? [] : [em.getComparator().getPkGetter(meta), em.getComparator().getPkSerializer(meta), em.getComparator().getPkGetterConverted(meta)];
|
|
50
|
+
Object.defineProperties(prototype, {
|
|
51
|
+
__entity: { value: !meta.embeddable, configurable: true },
|
|
52
|
+
__meta: { value: meta, configurable: true },
|
|
53
|
+
__config: { value: em.config, configurable: true },
|
|
54
|
+
__platform: { value: em.getPlatform(), configurable: true },
|
|
55
|
+
__factory: { value: em.getEntityFactory(), configurable: true },
|
|
56
|
+
__helper: {
|
|
57
|
+
get() {
|
|
58
|
+
Object.defineProperty(this, '__helper', {
|
|
59
|
+
value: new WrappedEntity_1.WrappedEntity(this, em.getHydrator(), ...helperParams),
|
|
60
|
+
enumerable: false,
|
|
61
|
+
configurable: true,
|
|
62
|
+
});
|
|
63
|
+
return this.__helper;
|
|
64
|
+
},
|
|
65
|
+
configurable: true, // otherwise jest fails when trying to compare entities ¯\_(ツ)_/¯
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Defines getter and setter for every owning side of m:1 and 1:1 relation. This is then used for propagation of
|
|
71
|
+
* changes to the inverse side of bi-directional relations. Rest of the properties are also defined this way to
|
|
72
|
+
* achieve dirtiness, which is then used for fast checks whether we need to auto-flush because of managed entities.
|
|
73
|
+
*
|
|
74
|
+
* First defines a setter on the prototype, once called, actual get/set handlers are registered on the instance rather
|
|
75
|
+
* than on its prototype. Thanks to this we still have those properties enumerable (e.g. part of `Object.keys(entity)`).
|
|
76
|
+
*/
|
|
77
|
+
static defineProperties(meta, em) {
|
|
78
|
+
Object
|
|
79
|
+
.values(meta.properties)
|
|
80
|
+
.forEach(prop => {
|
|
81
|
+
const isCollection = [enums_1.ReferenceKind.ONE_TO_MANY, enums_1.ReferenceKind.MANY_TO_MANY].includes(prop.kind);
|
|
82
|
+
const isReference = [enums_1.ReferenceKind.ONE_TO_ONE, enums_1.ReferenceKind.MANY_TO_ONE].includes(prop.kind) && (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
|
|
83
|
+
if (isReference) {
|
|
84
|
+
Object.defineProperty(meta.prototype, prop.name, {
|
|
85
|
+
set(val) {
|
|
86
|
+
EntityHelper.defineReferenceProperty(meta, prop, this, em.getHydrator());
|
|
87
|
+
this[prop.name] = val;
|
|
88
|
+
},
|
|
89
|
+
configurable: true,
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (prop.inherited || prop.primary || prop.persist === false || prop.trackChanges === false || prop.embedded || isCollection) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
Object.defineProperty(meta.prototype, prop.name, {
|
|
97
|
+
set(val) {
|
|
98
|
+
Object.defineProperty(this, prop.name, {
|
|
99
|
+
get() {
|
|
100
|
+
return this.__helper?.__data[prop.name];
|
|
101
|
+
},
|
|
102
|
+
set(val) {
|
|
103
|
+
this.__helper.__data[prop.name] = val;
|
|
104
|
+
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
105
|
+
},
|
|
106
|
+
enumerable: true,
|
|
107
|
+
configurable: true,
|
|
108
|
+
});
|
|
109
|
+
this.__helper.__data[prop.name] = val;
|
|
110
|
+
this.__helper.__touched = !this.__helper.hydrator.isRunning();
|
|
111
|
+
},
|
|
112
|
+
configurable: true,
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
static defineCustomInspect(meta) {
|
|
117
|
+
// @ts-ignore
|
|
118
|
+
meta.prototype[util_1.inspect.custom] ??= function (depth) {
|
|
119
|
+
const object = { ...this };
|
|
120
|
+
// ensure we dont have internal symbols in the POJO
|
|
121
|
+
[typings_1.OptionalProps, typings_1.EntityRepositoryType, typings_1.PrimaryKeyProp, typings_1.EagerProps, typings_1.HiddenProps].forEach(sym => delete object[sym]);
|
|
122
|
+
meta.props
|
|
123
|
+
.filter(prop => object[prop.name] === undefined)
|
|
124
|
+
.forEach(prop => delete object[prop.name]);
|
|
125
|
+
const ret = (0, util_1.inspect)(object, { depth });
|
|
126
|
+
let name = (this).constructor.name;
|
|
127
|
+
const showEM = ['true', 't', '1'].includes(process.env.MIKRO_ORM_LOG_EM_ID?.toString().toLowerCase() ?? '');
|
|
128
|
+
if (showEM) {
|
|
129
|
+
if ((0, wrap_1.helper)(this).__em) {
|
|
130
|
+
name += ` [managed by ${(0, wrap_1.helper)(this).__em.id}]`;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
name += ` [not managed]`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// distinguish not initialized entities
|
|
137
|
+
if (!(0, wrap_1.helper)(this).__initialized) {
|
|
138
|
+
name = `(${name})`;
|
|
139
|
+
}
|
|
140
|
+
return ret === '[Object]' ? `[${name}]` : name + ' ' + ret;
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
static defineReferenceProperty(meta, prop, ref, hydrator) {
|
|
144
|
+
const wrapped = (0, wrap_1.helper)(ref);
|
|
145
|
+
Object.defineProperty(ref, prop.name, {
|
|
146
|
+
get() {
|
|
147
|
+
return (0, wrap_1.helper)(ref).__data[prop.name];
|
|
148
|
+
},
|
|
149
|
+
set(val) {
|
|
150
|
+
const entity = Reference_1.Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
|
|
151
|
+
const old = Reference_1.Reference.unwrapReference(wrapped.__data[prop.name]);
|
|
152
|
+
wrapped.__data[prop.name] = Reference_1.Reference.wrapReference(val, prop);
|
|
153
|
+
// when propagation from inside hydration, we set the FK to the entity data immediately
|
|
154
|
+
if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
|
|
155
|
+
wrapped.__originalEntityData[prop.name] = Utils_1.Utils.getPrimaryKeyValues(wrapped.__data[prop.name], prop.targetMeta.primaryKeys, true);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
wrapped.__touched = !hydrator.isRunning();
|
|
159
|
+
}
|
|
160
|
+
EntityHelper.propagate(meta, entity, this, prop, Reference_1.Reference.unwrapReference(val), old);
|
|
161
|
+
},
|
|
162
|
+
enumerable: true,
|
|
163
|
+
configurable: true,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
static propagate(meta, entity, owner, prop, value, old) {
|
|
167
|
+
const inverseProps = prop.targetMeta.bidirectionalRelations
|
|
168
|
+
.filter(prop2 => (prop2.inversedBy || prop2.mappedBy) === prop.name)
|
|
169
|
+
.filter(prop2 => {
|
|
170
|
+
const meta2 = prop2.targetMeta;
|
|
171
|
+
return meta2.abstract ? meta2.root.className === meta.root.className : meta2.className === meta.className;
|
|
172
|
+
});
|
|
173
|
+
for (const prop2 of inverseProps) {
|
|
174
|
+
const inverse = value?.[prop2.name];
|
|
175
|
+
if (prop.kind === enums_1.ReferenceKind.MANY_TO_ONE && Utils_1.Utils.isCollection(inverse) && inverse.isInitialized()) {
|
|
176
|
+
inverse.add(owner);
|
|
177
|
+
}
|
|
178
|
+
if (prop.kind === enums_1.ReferenceKind.ONE_TO_ONE && entity && (!prop.owner || (0, wrap_1.helper)(entity).__initialized)) {
|
|
179
|
+
if ((value != null && Reference_1.Reference.unwrapReference(inverse) !== owner) ||
|
|
180
|
+
(value == null && entity[prop2.name] != null)) {
|
|
181
|
+
EntityHelper.propagateOneToOne(entity, owner, prop, prop2, value, old);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
static propagateOneToOne(entity, owner, prop, prop2, value, old) {
|
|
187
|
+
(0, wrap_1.helper)(entity).__pk = (0, wrap_1.helper)(entity).getPrimaryKey();
|
|
188
|
+
// the inverse side will be changed on the `value` too, so we need to clean-up and schedule orphan removal there too
|
|
189
|
+
if (!prop.primary && !prop2.mapToPk && value?.[prop2.name] != null && Reference_1.Reference.unwrapReference(value[prop2.name]) !== entity) {
|
|
190
|
+
const other = Reference_1.Reference.unwrapReference(value[prop2.name]);
|
|
191
|
+
delete (0, wrap_1.helper)(other).__data[prop.name];
|
|
192
|
+
if (prop2.orphanRemoval) {
|
|
193
|
+
(0, wrap_1.helper)(other).__em?.getUnitOfWork().scheduleOrphanRemoval(other);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (value == null) {
|
|
197
|
+
entity[prop2.name] = value;
|
|
198
|
+
}
|
|
199
|
+
else if (prop2.mapToPk) {
|
|
200
|
+
entity[prop2.name] = (0, wrap_1.helper)(owner).getPrimaryKey();
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
entity[prop2.name] = Reference_1.Reference.wrapReference(owner, prop);
|
|
204
|
+
}
|
|
205
|
+
if (old && prop.orphanRemoval) {
|
|
206
|
+
(0, wrap_1.helper)(old).__em?.getUnitOfWork().scheduleOrphanRemoval(old);
|
|
207
|
+
}
|
|
208
|
+
if (old?.[prop2.name] != null) {
|
|
209
|
+
delete (0, wrap_1.helper)(old).__data[prop2.name];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
static ensurePropagation(entity) {
|
|
213
|
+
if (entity.__gettersDefined) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const wrapped = (0, wrap_1.helper)(entity);
|
|
217
|
+
const meta = wrapped.__meta;
|
|
218
|
+
const platform = wrapped.__platform;
|
|
219
|
+
const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
|
|
220
|
+
const values = [];
|
|
221
|
+
if (serializedPrimaryKey) {
|
|
222
|
+
const pk = meta.getPrimaryProps()[0];
|
|
223
|
+
const val = entity[serializedPrimaryKey.name];
|
|
224
|
+
delete entity[serializedPrimaryKey.name];
|
|
225
|
+
Object.defineProperty(entity, serializedPrimaryKey.name, {
|
|
226
|
+
get() {
|
|
227
|
+
return this[pk.name] ? platform.normalizePrimaryKey(this[pk.name]) : null;
|
|
228
|
+
},
|
|
229
|
+
set(id) {
|
|
230
|
+
this[pk.name] = id ? platform.denormalizePrimaryKey(id) : null;
|
|
231
|
+
},
|
|
232
|
+
configurable: true,
|
|
233
|
+
});
|
|
234
|
+
if (entity[pk.name] == null && val != null) {
|
|
235
|
+
values.push([serializedPrimaryKey.name, val]);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
meta.trackingProps.forEach(prop => {
|
|
239
|
+
if (entity[prop.name] !== undefined) {
|
|
240
|
+
values.push([prop.name, entity[prop.name]]);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
meta.trackingProps.forEach(prop => {
|
|
244
|
+
delete entity[prop.name];
|
|
245
|
+
});
|
|
246
|
+
Object.defineProperties(entity, meta.definedProperties);
|
|
247
|
+
values.forEach(val => entity[val[0]] = val[1]);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.EntityHelper = EntityHelper;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IPrimaryKey } from '../typings';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export declare class EntityIdentifier {
|
|
6
|
+
private value?;
|
|
7
|
+
constructor(value?: import("../typings").IPrimaryKeyValue | undefined);
|
|
8
|
+
setValue(value: IPrimaryKey): void;
|
|
9
|
+
getValue<T extends IPrimaryKey = IPrimaryKey>(): T;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntityIdentifier = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
class EntityIdentifier {
|
|
8
|
+
value;
|
|
9
|
+
constructor(value) {
|
|
10
|
+
this.value = value;
|
|
11
|
+
}
|
|
12
|
+
setValue(value) {
|
|
13
|
+
this.value = value;
|
|
14
|
+
}
|
|
15
|
+
getValue() {
|
|
16
|
+
return this.value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.EntityIdentifier = EntityIdentifier;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ConnectionType, Dictionary, FilterQuery, PopulateOptions } from '../typings';
|
|
2
|
+
import type { EntityManager } from '../EntityManager';
|
|
3
|
+
import { LoadStrategy, type LockMode, type PopulateHint, type QueryOrderMap } from '../enums';
|
|
4
|
+
import type { EntityField } from '../drivers/IDatabaseDriver';
|
|
5
|
+
import type { LoggingOptions } from '../logging/Logger';
|
|
6
|
+
export type EntityLoaderOptions<Entity, Fields extends string = '*', Excludes extends string = never> = {
|
|
7
|
+
where?: FilterQuery<Entity>;
|
|
8
|
+
populateWhere?: PopulateHint | `${PopulateHint}`;
|
|
9
|
+
fields?: readonly EntityField<Entity, Fields>[];
|
|
10
|
+
exclude?: readonly EntityField<Entity, Excludes>[];
|
|
11
|
+
orderBy?: QueryOrderMap<Entity> | QueryOrderMap<Entity>[];
|
|
12
|
+
refresh?: boolean;
|
|
13
|
+
validate?: boolean;
|
|
14
|
+
lookup?: boolean;
|
|
15
|
+
convertCustomTypes?: boolean;
|
|
16
|
+
ignoreLazyScalarProperties?: boolean;
|
|
17
|
+
filters?: Dictionary<boolean | Dictionary> | string[] | boolean;
|
|
18
|
+
strategy?: LoadStrategy;
|
|
19
|
+
lockMode?: Exclude<LockMode, LockMode.OPTIMISTIC>;
|
|
20
|
+
schema?: string;
|
|
21
|
+
connectionType?: ConnectionType;
|
|
22
|
+
logging?: LoggingOptions;
|
|
23
|
+
};
|
|
24
|
+
export declare class EntityLoader {
|
|
25
|
+
private readonly em;
|
|
26
|
+
private readonly metadata;
|
|
27
|
+
private readonly driver;
|
|
28
|
+
constructor(em: EntityManager);
|
|
29
|
+
/**
|
|
30
|
+
* Loads specified relations in batch.
|
|
31
|
+
* This will execute one query for each relation, that will populate it on all the specified entities.
|
|
32
|
+
*/
|
|
33
|
+
populate<Entity extends object, Fields extends string = '*'>(entityName: string, entities: Entity[], populate: PopulateOptions<Entity>[] | boolean, options: EntityLoaderOptions<Entity, Fields>): Promise<void>;
|
|
34
|
+
normalizePopulate<Entity>(entityName: string, populate: (PopulateOptions<Entity> | boolean)[] | PopulateOptions<Entity> | boolean, strategy?: LoadStrategy, lookup?: boolean): PopulateOptions<Entity>[];
|
|
35
|
+
private expandDotPaths;
|
|
36
|
+
/**
|
|
37
|
+
* Merge multiple populates for the same entity with different children. Also skips `*` fields, those can come from
|
|
38
|
+
* partial loading hints (`fields`) that are used to infer the `populate` hint if missing.
|
|
39
|
+
*/
|
|
40
|
+
private mergeNestedPopulate;
|
|
41
|
+
/**
|
|
42
|
+
* Expands `books.perex` like populate to use `children` array instead of the dot syntax
|
|
43
|
+
*/
|
|
44
|
+
private expandNestedPopulate;
|
|
45
|
+
/**
|
|
46
|
+
* preload everything in one call (this will update already existing references in IM)
|
|
47
|
+
*/
|
|
48
|
+
private populateMany;
|
|
49
|
+
private initializeCollections;
|
|
50
|
+
private initializeOneToMany;
|
|
51
|
+
private initializeManyToMany;
|
|
52
|
+
private findChildren;
|
|
53
|
+
private mergePrimaryCondition;
|
|
54
|
+
private populateField;
|
|
55
|
+
private findChildrenFromPivotTable;
|
|
56
|
+
private extractChildCondition;
|
|
57
|
+
private buildFields;
|
|
58
|
+
private getChildReferences;
|
|
59
|
+
private filterCollections;
|
|
60
|
+
private filterReferences;
|
|
61
|
+
private filterByReferences;
|
|
62
|
+
private lookupAllRelationships;
|
|
63
|
+
private getRelationName;
|
|
64
|
+
private lookupEagerLoadedRelationships;
|
|
65
|
+
}
|