@mikro-orm/core 7.0.0-dev.3 → 7.0.0-dev.300
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 +114 -63
- package/EntityManager.js +385 -310
- package/MikroORM.d.ts +44 -35
- package/MikroORM.js +109 -143
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +17 -8
- package/cache/GeneratedCacheAdapter.d.ts +0 -1
- package/cache/GeneratedCacheAdapter.js +0 -2
- package/cache/index.d.ts +0 -1
- package/cache/index.js +0 -1
- package/connections/Connection.d.ts +16 -7
- package/connections/Connection.js +23 -14
- package/drivers/DatabaseDriver.d.ts +25 -16
- package/drivers/DatabaseDriver.js +119 -36
- package/drivers/IDatabaseDriver.d.ts +125 -23
- package/entity/BaseEntity.d.ts +63 -4
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +102 -31
- package/entity/Collection.js +446 -108
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +26 -18
- package/entity/EntityFactory.d.ts +13 -1
- package/entity/EntityFactory.js +106 -60
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +65 -20
- package/entity/EntityLoader.d.ts +13 -11
- package/entity/EntityLoader.js +257 -107
- package/entity/EntityRepository.d.ts +28 -8
- package/entity/EntityRepository.js +8 -2
- package/entity/PolymorphicRef.d.ts +12 -0
- package/entity/PolymorphicRef.js +18 -0
- package/entity/Reference.d.ts +9 -12
- package/entity/Reference.js +34 -9
- package/entity/WrappedEntity.d.ts +3 -8
- package/entity/WrappedEntity.js +3 -8
- package/entity/defineEntity.d.ts +753 -0
- package/entity/defineEntity.js +537 -0
- package/entity/index.d.ts +4 -2
- package/entity/index.js +4 -2
- package/entity/utils.d.ts +13 -1
- package/entity/utils.js +49 -4
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +65 -0
- package/enums.d.ts +23 -8
- package/enums.js +15 -1
- package/errors.d.ts +25 -9
- package/errors.js +67 -21
- package/events/EventManager.d.ts +2 -1
- package/events/EventManager.js +19 -11
- package/events/EventSubscriber.d.ts +3 -1
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +89 -36
- package/index.d.ts +2 -2
- package/index.js +1 -2
- package/logging/DefaultLogger.d.ts +1 -1
- package/logging/DefaultLogger.js +1 -0
- package/logging/SimpleLogger.d.ts +1 -1
- package/logging/colors.d.ts +1 -1
- package/logging/colors.js +7 -6
- package/logging/index.d.ts +1 -0
- package/logging/index.js +1 -0
- package/logging/inspect.d.ts +2 -0
- package/logging/inspect.js +11 -0
- package/metadata/EntitySchema.d.ts +53 -27
- package/metadata/EntitySchema.js +125 -52
- package/metadata/MetadataDiscovery.d.ts +64 -10
- package/metadata/MetadataDiscovery.js +823 -344
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +66 -2
- package/metadata/MetadataStorage.d.ts +13 -11
- package/metadata/MetadataStorage.js +71 -38
- package/metadata/MetadataValidator.d.ts +32 -9
- package/metadata/MetadataValidator.js +198 -42
- package/metadata/discover-entities.d.ts +5 -0
- package/metadata/discover-entities.js +40 -0
- package/metadata/index.d.ts +1 -1
- package/metadata/index.js +1 -1
- package/metadata/types.d.ts +577 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +16 -4
- package/naming-strategy/AbstractNamingStrategy.js +20 -2
- package/naming-strategy/EntityCaseNamingStrategy.d.ts +3 -3
- package/naming-strategy/EntityCaseNamingStrategy.js +6 -5
- package/naming-strategy/MongoNamingStrategy.d.ts +3 -3
- package/naming-strategy/MongoNamingStrategy.js +6 -6
- package/naming-strategy/NamingStrategy.d.ts +28 -4
- package/naming-strategy/UnderscoreNamingStrategy.d.ts +3 -3
- package/naming-strategy/UnderscoreNamingStrategy.js +6 -6
- package/not-supported.d.ts +2 -0
- package/not-supported.js +4 -0
- package/package.json +22 -11
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +14 -16
- package/platforms/Platform.js +24 -44
- package/serialization/EntitySerializer.d.ts +8 -3
- package/serialization/EntitySerializer.js +47 -27
- package/serialization/EntityTransformer.js +33 -21
- package/serialization/SerializationContext.d.ts +6 -6
- package/serialization/SerializationContext.js +16 -13
- package/types/ArrayType.d.ts +1 -1
- package/types/ArrayType.js +2 -3
- package/types/BigIntType.d.ts +9 -6
- package/types/BigIntType.js +4 -1
- package/types/BlobType.d.ts +0 -1
- package/types/BlobType.js +0 -3
- package/types/BooleanType.d.ts +2 -1
- package/types/BooleanType.js +3 -0
- package/types/DecimalType.d.ts +6 -4
- package/types/DecimalType.js +3 -3
- package/types/DoubleType.js +2 -2
- package/types/EnumArrayType.js +1 -2
- package/types/JsonType.d.ts +1 -1
- package/types/JsonType.js +7 -2
- package/types/TinyIntType.js +1 -1
- package/types/Type.d.ts +2 -4
- package/types/Type.js +3 -3
- package/types/Uint8ArrayType.d.ts +0 -1
- package/types/Uint8ArrayType.js +1 -4
- package/types/index.d.ts +1 -1
- package/typings.d.ts +469 -175
- package/typings.js +120 -45
- package/unit-of-work/ChangeSet.d.ts +4 -6
- package/unit-of-work/ChangeSet.js +4 -5
- package/unit-of-work/ChangeSetComputer.d.ts +3 -8
- package/unit-of-work/ChangeSetComputer.js +44 -21
- package/unit-of-work/ChangeSetPersister.d.ts +15 -12
- package/unit-of-work/ChangeSetPersister.js +113 -45
- package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/IdentityMap.d.ts +12 -0
- package/unit-of-work/IdentityMap.js +39 -1
- package/unit-of-work/UnitOfWork.d.ts +28 -3
- package/unit-of-work/UnitOfWork.js +315 -110
- package/utils/AbstractMigrator.d.ts +101 -0
- package/utils/AbstractMigrator.js +305 -0
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +32 -18
- package/utils/AsyncContext.d.ts +6 -0
- package/utils/AsyncContext.js +42 -0
- package/utils/Configuration.d.ts +801 -207
- package/utils/Configuration.js +150 -191
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +3 -6
- package/utils/Cursor.js +27 -11
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +65 -17
- package/utils/EntityComparator.d.ts +21 -10
- package/utils/EntityComparator.js +243 -106
- package/utils/QueryHelper.d.ts +24 -6
- package/utils/QueryHelper.js +122 -26
- package/utils/RawQueryFragment.d.ts +60 -32
- package/utils/RawQueryFragment.js +69 -66
- package/utils/RequestContext.js +2 -2
- package/utils/TransactionContext.js +2 -2
- package/utils/TransactionManager.d.ts +65 -0
- package/utils/TransactionManager.js +223 -0
- package/utils/Utils.d.ts +15 -122
- package/utils/Utils.js +108 -376
- package/utils/clone.js +8 -23
- package/utils/env-vars.d.ts +7 -0
- package/utils/env-vars.js +97 -0
- package/utils/fs-utils.d.ts +34 -0
- package/utils/fs-utils.js +196 -0
- package/utils/index.d.ts +2 -3
- package/utils/index.js +2 -3
- package/utils/upsert-utils.d.ts +9 -4
- package/utils/upsert-utils.js +55 -4
- package/decorators/Check.d.ts +0 -3
- package/decorators/Check.js +0 -13
- package/decorators/CreateRequestContext.d.ts +0 -3
- package/decorators/CreateRequestContext.js +0 -32
- package/decorators/Embeddable.d.ts +0 -8
- package/decorators/Embeddable.js +0 -11
- package/decorators/Embedded.d.ts +0 -18
- package/decorators/Embedded.js +0 -18
- package/decorators/Entity.d.ts +0 -18
- package/decorators/Entity.js +0 -13
- package/decorators/Enum.d.ts +0 -9
- package/decorators/Enum.js +0 -16
- package/decorators/Filter.d.ts +0 -2
- package/decorators/Filter.js +0 -8
- package/decorators/Formula.d.ts +0 -5
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -17
- package/decorators/Indexed.js +0 -20
- package/decorators/ManyToMany.d.ts +0 -40
- package/decorators/ManyToMany.js +0 -14
- package/decorators/ManyToOne.d.ts +0 -30
- package/decorators/ManyToOne.js +0 -14
- package/decorators/OneToMany.d.ts +0 -28
- package/decorators/OneToMany.js +0 -17
- package/decorators/OneToOne.d.ts +0 -24
- package/decorators/OneToOne.js +0 -7
- package/decorators/PrimaryKey.d.ts +0 -9
- package/decorators/PrimaryKey.js +0 -20
- package/decorators/Property.d.ts +0 -250
- package/decorators/Property.js +0 -32
- package/decorators/Transactional.d.ts +0 -13
- package/decorators/Transactional.js +0 -28
- package/decorators/hooks.d.ts +0 -16
- package/decorators/hooks.js +0 -47
- package/decorators/index.d.ts +0 -17
- package/decorators/index.js +0 -17
- package/entity/ArrayCollection.d.ts +0 -116
- package/entity/ArrayCollection.js +0 -395
- package/entity/EntityValidator.d.ts +0 -19
- package/entity/EntityValidator.js +0 -150
- package/metadata/ReflectMetadataProvider.d.ts +0 -8
- package/metadata/ReflectMetadataProvider.js +0 -44
- package/utils/resolveContextProvider.d.ts +0 -10
- package/utils/resolveContextProvider.js +0 -28
|
@@ -2,10 +2,13 @@ import { clone } from './clone.js';
|
|
|
2
2
|
import { ReferenceKind } from '../enums.js';
|
|
3
3
|
import { compareArrays, compareBooleans, compareBuffers, compareObjects, equals, parseJsonSafe, Utils } from './Utils.js';
|
|
4
4
|
import { JsonType } from '../types/JsonType.js';
|
|
5
|
-
import {
|
|
5
|
+
import { Raw } from './RawQueryFragment.js';
|
|
6
|
+
import { EntityIdentifier } from '../entity/EntityIdentifier.js';
|
|
7
|
+
import { PolymorphicRef } from '../entity/PolymorphicRef.js';
|
|
6
8
|
export class EntityComparator {
|
|
7
9
|
metadata;
|
|
8
10
|
platform;
|
|
11
|
+
config;
|
|
9
12
|
comparators = new Map();
|
|
10
13
|
mappers = new Map();
|
|
11
14
|
snapshotGenerators = new Map();
|
|
@@ -13,16 +16,17 @@ export class EntityComparator {
|
|
|
13
16
|
pkGettersConverted = new Map();
|
|
14
17
|
pkSerializers = new Map();
|
|
15
18
|
tmpIndex = 0;
|
|
16
|
-
constructor(metadata, platform) {
|
|
19
|
+
constructor(metadata, platform, config) {
|
|
17
20
|
this.metadata = metadata;
|
|
18
21
|
this.platform = platform;
|
|
22
|
+
this.config = config;
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
25
|
* Computes difference between two entities.
|
|
22
26
|
*/
|
|
23
|
-
diffEntities(entityName, a, b) {
|
|
27
|
+
diffEntities(entityName, a, b, options) {
|
|
24
28
|
const comparator = this.getEntityComparator(entityName);
|
|
25
|
-
return Utils.callCompiledFunction(comparator, a, b);
|
|
29
|
+
return Utils.callCompiledFunction(comparator, a, b, options);
|
|
26
30
|
}
|
|
27
31
|
matching(entityName, a, b) {
|
|
28
32
|
const diff = this.diffEntities(entityName, a, b);
|
|
@@ -33,22 +37,22 @@ export class EntityComparator {
|
|
|
33
37
|
* References will be mapped to primary keys, collections to arrays of primary keys.
|
|
34
38
|
*/
|
|
35
39
|
prepareEntity(entity) {
|
|
36
|
-
const generator = this.getSnapshotGenerator(entity.constructor
|
|
40
|
+
const generator = this.getSnapshotGenerator(entity.constructor);
|
|
37
41
|
return Utils.callCompiledFunction(generator, entity);
|
|
38
42
|
}
|
|
39
43
|
/**
|
|
40
44
|
* Maps database columns to properties.
|
|
41
45
|
*/
|
|
42
|
-
mapResult(
|
|
43
|
-
const mapper = this.getResultMapper(
|
|
46
|
+
mapResult(meta, result) {
|
|
47
|
+
const mapper = this.getResultMapper(meta);
|
|
44
48
|
return Utils.callCompiledFunction(mapper, result);
|
|
45
49
|
}
|
|
46
50
|
/**
|
|
47
51
|
* @internal Highly performance-sensitive method.
|
|
48
52
|
*/
|
|
49
53
|
getPkGetter(meta) {
|
|
50
|
-
const exists = this.pkGetters.get(meta
|
|
51
|
-
/* v8 ignore next
|
|
54
|
+
const exists = this.pkGetters.get(meta);
|
|
55
|
+
/* v8 ignore next */
|
|
52
56
|
if (exists) {
|
|
53
57
|
return exists;
|
|
54
58
|
}
|
|
@@ -74,7 +78,7 @@ export class EntityComparator {
|
|
|
74
78
|
lines.push(` if (entity${this.wrap(pk)} != null && (entity${this.wrap(pk)}.__entity || entity${this.wrap(pk)}.__reference)) {`);
|
|
75
79
|
lines.push(` const pk = entity${this.wrap(pk)}.__helper.getPrimaryKey();`);
|
|
76
80
|
if (meta.properties[pk].targetMeta.compositePK) {
|
|
77
|
-
lines.push(` if (typeof pk === 'object') {`);
|
|
81
|
+
lines.push(` if (typeof pk === 'object' && pk != null) {`);
|
|
78
82
|
lines.push(` return [`);
|
|
79
83
|
for (const childPK of meta.properties[pk].targetMeta.primaryKeys) {
|
|
80
84
|
lines.push(` pk${this.wrap(childPK)},`);
|
|
@@ -87,18 +91,19 @@ export class EntityComparator {
|
|
|
87
91
|
}
|
|
88
92
|
lines.push(` return entity${this.wrap(pk)};`);
|
|
89
93
|
}
|
|
90
|
-
const code = `// compiled pk
|
|
94
|
+
const code = `// compiled pk getter for entity ${meta.className}\n`
|
|
91
95
|
+ `return function(entity) {\n${lines.join('\n')}\n}`;
|
|
92
|
-
const
|
|
93
|
-
this.
|
|
96
|
+
const fnKey = `pkGetter-${meta.uniqueName}`;
|
|
97
|
+
const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
|
|
98
|
+
this.pkGetters.set(meta, pkSerializer);
|
|
94
99
|
return pkSerializer;
|
|
95
100
|
}
|
|
96
101
|
/**
|
|
97
102
|
* @internal Highly performance-sensitive method.
|
|
98
103
|
*/
|
|
99
104
|
getPkGetterConverted(meta) {
|
|
100
|
-
const exists = this.pkGettersConverted.get(meta
|
|
101
|
-
/* v8 ignore next
|
|
105
|
+
const exists = this.pkGettersConverted.get(meta);
|
|
106
|
+
/* v8 ignore next */
|
|
102
107
|
if (exists) {
|
|
103
108
|
return exists;
|
|
104
109
|
}
|
|
@@ -139,22 +144,24 @@ export class EntityComparator {
|
|
|
139
144
|
}
|
|
140
145
|
const code = `// compiled pk getter (with converted custom types) for entity ${meta.className}\n`
|
|
141
146
|
+ `return function(entity) {\n${lines.join('\n')}\n}`;
|
|
142
|
-
const
|
|
143
|
-
this.
|
|
147
|
+
const fnKey = `pkGetterConverted-${meta.uniqueName}`;
|
|
148
|
+
const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
|
|
149
|
+
this.pkGettersConverted.set(meta, pkSerializer);
|
|
144
150
|
return pkSerializer;
|
|
145
151
|
}
|
|
146
152
|
/**
|
|
147
153
|
* @internal Highly performance-sensitive method.
|
|
148
154
|
*/
|
|
149
155
|
getPkSerializer(meta) {
|
|
150
|
-
const exists = this.pkSerializers.get(meta
|
|
151
|
-
/* v8 ignore next
|
|
156
|
+
const exists = this.pkSerializers.get(meta);
|
|
157
|
+
/* v8 ignore next */
|
|
152
158
|
if (exists) {
|
|
153
159
|
return exists;
|
|
154
160
|
}
|
|
155
161
|
const lines = [];
|
|
156
162
|
const context = new Map();
|
|
157
163
|
context.set('getCompositeKeyValue', (val) => Utils.flatten(Utils.getCompositeKeyValue(val, meta, 'convertToDatabaseValue', this.platform)));
|
|
164
|
+
context.set('getPrimaryKeyHash', (val) => Utils.getPrimaryKeyHash(Utils.asArray(val)));
|
|
158
165
|
if (meta.primaryKeys.length > 1) {
|
|
159
166
|
lines.push(` const pks = entity.__helper.__pk ? getCompositeKeyValue(entity.__helper.__pk) : [`);
|
|
160
167
|
meta.primaryKeys.forEach(pk => {
|
|
@@ -170,35 +177,45 @@ export class EntityComparator {
|
|
|
170
177
|
}
|
|
171
178
|
else {
|
|
172
179
|
const pk = meta.primaryKeys[0];
|
|
173
|
-
|
|
180
|
+
const prop = meta.properties[pk];
|
|
181
|
+
if (prop.kind !== ReferenceKind.SCALAR) {
|
|
174
182
|
lines.push(` if (entity${this.wrap(pk)} != null && (entity${this.wrap(pk)}.__entity || entity${this.wrap(pk)}.__reference)) return entity${this.wrap(pk)}.__helper.getSerializedPrimaryKey();`);
|
|
175
183
|
}
|
|
176
184
|
const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
|
|
177
185
|
if (serializedPrimaryKey) {
|
|
178
186
|
lines.push(` return '' + entity.${serializedPrimaryKey.name};`);
|
|
179
187
|
}
|
|
180
|
-
|
|
188
|
+
else if (prop.customType) {
|
|
189
|
+
const convertorKey = this.registerCustomType(meta.properties[pk], context);
|
|
190
|
+
const idx = this.tmpIndex++;
|
|
191
|
+
lines.push(` const val_${idx} = convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)});`);
|
|
192
|
+
lines.push(` return getPrimaryKeyHash(val_${idx});`);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
lines.push(` return '' + entity${this.wrap(pk)};`);
|
|
196
|
+
}
|
|
181
197
|
}
|
|
182
198
|
const code = `// compiled pk serializer for entity ${meta.className}\n`
|
|
183
199
|
+ `return function(entity) {\n${lines.join('\n')}\n}`;
|
|
184
|
-
const
|
|
185
|
-
this.
|
|
200
|
+
const fnKey = `pkSerializer-${meta.uniqueName}`;
|
|
201
|
+
const pkSerializer = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
|
|
202
|
+
this.pkSerializers.set(meta, pkSerializer);
|
|
186
203
|
return pkSerializer;
|
|
187
204
|
}
|
|
188
205
|
/**
|
|
189
206
|
* @internal Highly performance-sensitive method.
|
|
190
207
|
*/
|
|
191
208
|
getSnapshotGenerator(entityName) {
|
|
192
|
-
const
|
|
209
|
+
const meta = this.metadata.find(entityName);
|
|
210
|
+
const exists = this.snapshotGenerators.get(meta);
|
|
193
211
|
if (exists) {
|
|
194
212
|
return exists;
|
|
195
213
|
}
|
|
196
|
-
const meta = this.metadata.find(entityName);
|
|
197
214
|
const lines = [];
|
|
198
215
|
const context = new Map();
|
|
199
216
|
context.set('clone', clone);
|
|
200
217
|
context.set('cloneEmbeddable', (o) => this.platform.cloneEmbeddable(o)); // do not clone prototypes
|
|
201
|
-
if (meta.discriminatorValue) {
|
|
218
|
+
if (meta.root.inheritanceType === 'sti' && meta.discriminatorValue) {
|
|
202
219
|
lines.push(` ret${this.wrap(meta.root.discriminatorColumn)} = '${meta.discriminatorValue}'`);
|
|
203
220
|
}
|
|
204
221
|
const getRootProperty = (prop) => prop.embedded ? getRootProperty(meta.properties[prop.embedded[0]]) : prop;
|
|
@@ -210,8 +227,9 @@ export class EntityComparator {
|
|
|
210
227
|
})
|
|
211
228
|
.forEach(prop => lines.push(this.getPropertySnapshot(meta, prop, context, this.wrap(prop.name), this.wrap(prop.name), [prop.name])));
|
|
212
229
|
const code = `return function(entity) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
|
|
213
|
-
const
|
|
214
|
-
this.
|
|
230
|
+
const fnKey = `snapshotGenerator-${meta.uniqueName}`;
|
|
231
|
+
const snapshotGenerator = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
|
|
232
|
+
this.snapshotGenerators.set(meta, snapshotGenerator);
|
|
215
233
|
return snapshotGenerator;
|
|
216
234
|
}
|
|
217
235
|
/**
|
|
@@ -261,23 +279,27 @@ export class EntityComparator {
|
|
|
261
279
|
/**
|
|
262
280
|
* @internal Highly performance-sensitive method.
|
|
263
281
|
*/
|
|
264
|
-
getResultMapper(
|
|
265
|
-
const exists = this.mappers.get(
|
|
282
|
+
getResultMapper(meta) {
|
|
283
|
+
const exists = this.mappers.get(meta);
|
|
266
284
|
if (exists) {
|
|
267
285
|
return exists;
|
|
268
286
|
}
|
|
269
|
-
const meta = this.metadata.get(entityName);
|
|
270
287
|
const lines = [];
|
|
271
288
|
const context = new Map();
|
|
289
|
+
context.set('PolymorphicRef', PolymorphicRef);
|
|
272
290
|
const tz = this.platform.getTimezone();
|
|
273
291
|
const parseDate = (key, value, padding = '') => {
|
|
274
292
|
lines.push(`${padding} if (${value} == null || ${value} instanceof Date) {`);
|
|
275
293
|
lines.push(`${padding} ${key} = ${value};`);
|
|
276
294
|
if (!tz || tz === 'local') {
|
|
295
|
+
lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
|
|
296
|
+
lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
|
|
277
297
|
lines.push(`${padding} } else {`);
|
|
278
298
|
lines.push(`${padding} ${key} = parseDate(${value});`);
|
|
279
299
|
}
|
|
280
300
|
else {
|
|
301
|
+
lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
|
|
302
|
+
lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
|
|
281
303
|
lines.push(`${padding} } else if (typeof ${value} === 'number' || ${value}.includes('+') || ${value}.lastIndexOf('-') > 10 || ${value}.endsWith('Z')) {`);
|
|
282
304
|
lines.push(`${padding} ${key} = parseDate(${value});`);
|
|
283
305
|
lines.push(`${padding} } else {`);
|
|
@@ -286,61 +308,94 @@ export class EntityComparator {
|
|
|
286
308
|
lines.push(`${padding} }`);
|
|
287
309
|
};
|
|
288
310
|
lines.push(` const mapped = {};`);
|
|
289
|
-
meta
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
if (prop.embedded && (meta.embeddable || meta.properties[prop.embedded[0]].object)) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
if (prop.runtimeType === 'boolean') {
|
|
306
|
-
lines.push(` if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
|
|
307
|
-
lines.push(` ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])} == null ? ${this.propName(prop.fieldNames[0])} : !!${this.propName(prop.fieldNames[0])};`);
|
|
308
|
-
lines.push(` ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
|
|
309
|
-
lines.push(` }`);
|
|
310
|
-
}
|
|
311
|
-
else if (prop.runtimeType === 'Date' && !this.platform.isNumericProperty(prop)) {
|
|
312
|
-
lines.push(` if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
|
|
313
|
-
context.set('parseDate', (value) => this.platform.parseDate(value));
|
|
314
|
-
parseDate('ret' + this.wrap(prop.name), this.propName(prop.fieldNames[0]));
|
|
315
|
-
lines.push(` ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
|
|
316
|
-
lines.push(` }`);
|
|
317
|
-
}
|
|
318
|
-
else if (prop.kind === ReferenceKind.EMBEDDED && (prop.object || meta.embeddable)) {
|
|
319
|
-
const idx = this.tmpIndex++;
|
|
320
|
-
context.set(`mapEmbeddedResult_${idx}`, (data) => {
|
|
321
|
-
const item = parseJsonSafe(data);
|
|
322
|
-
if (Array.isArray(item)) {
|
|
323
|
-
return item.map(row => row == null ? row : this.getResultMapper(prop.type)(row));
|
|
311
|
+
const mapEntityProperties = (meta, padding = '') => {
|
|
312
|
+
for (const prop of meta.props) {
|
|
313
|
+
if (!prop.fieldNames) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (prop.polymorphic && prop.fieldNames.length >= 2) {
|
|
317
|
+
const discriminatorField = prop.fieldNames[0];
|
|
318
|
+
const idFields = prop.fieldNames.slice(1);
|
|
319
|
+
lines.push(`${padding} if (${prop.fieldNames.map(field => `typeof ${this.propName(field)} === 'undefined'`).join(' && ')}) {`);
|
|
320
|
+
lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} != null`).join(' && ')}) {`);
|
|
321
|
+
if (idFields.length === 1) {
|
|
322
|
+
lines.push(`${padding} ret${this.wrap(prop.name)} = new PolymorphicRef(${this.propName(discriminatorField)}, ${this.propName(idFields[0])});`);
|
|
324
323
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
324
|
+
else {
|
|
325
|
+
lines.push(`${padding} ret${this.wrap(prop.name)} = new PolymorphicRef(${this.propName(discriminatorField)}, [${idFields.map(f => this.propName(f)).join(', ')}]);`);
|
|
326
|
+
}
|
|
327
|
+
lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`));
|
|
328
|
+
lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} == null`).join(' && ')}) {\n${padding} ret${this.wrap(prop.name)} = null;`);
|
|
329
|
+
lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`), ' }');
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
if (prop.targetMeta && prop.fieldNames.length > 1) {
|
|
333
|
+
lines.push(`${padding} if (${prop.fieldNames.map(field => `typeof ${this.propName(field)} === 'undefined'`).join(' && ')}) {`);
|
|
334
|
+
lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} != null`).join(' && ')}) {`);
|
|
335
|
+
lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.createCompositeKeyArray(prop)};`);
|
|
336
|
+
lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`));
|
|
337
|
+
lines.push(`${padding} } else if (${prop.fieldNames.map(field => `${this.propName(field)} == null`).join(' && ')}) {\n${padding} ret${this.wrap(prop.name)} = null;`);
|
|
338
|
+
lines.push(...prop.fieldNames.map(field => `${padding} ${this.propName(field, 'mapped')} = true;`), ' }');
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (prop.embedded && (meta.embeddable || meta.properties[prop.embedded[0]].object)) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (prop.runtimeType === 'boolean') {
|
|
345
|
+
lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
|
|
346
|
+
lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])} == null ? ${this.propName(prop.fieldNames[0])} : !!${this.propName(prop.fieldNames[0])};`);
|
|
347
|
+
lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
|
|
348
|
+
lines.push(`${padding} }`);
|
|
349
|
+
}
|
|
350
|
+
else if (prop.runtimeType === 'Date' && !this.platform.isNumericProperty(prop)) {
|
|
351
|
+
lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
|
|
352
|
+
context.set('parseDate', (value) => this.platform.parseDate(value));
|
|
353
|
+
parseDate('ret' + this.wrap(prop.name), this.propName(prop.fieldNames[0]), padding);
|
|
354
|
+
lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
|
|
355
|
+
lines.push(`${padding} }`);
|
|
356
|
+
}
|
|
357
|
+
else if (prop.kind === ReferenceKind.EMBEDDED && (prop.object || meta.embeddable)) {
|
|
358
|
+
const idx = this.tmpIndex++;
|
|
359
|
+
context.set(`mapEmbeddedResult_${idx}`, (data) => {
|
|
360
|
+
const item = parseJsonSafe(data);
|
|
361
|
+
if (Array.isArray(item)) {
|
|
362
|
+
return item.map(row => row == null ? row : this.getResultMapper(prop.targetMeta)(row));
|
|
363
|
+
}
|
|
364
|
+
return item == null ? item : this.getResultMapper(prop.targetMeta)(item);
|
|
365
|
+
});
|
|
366
|
+
lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
|
|
367
|
+
lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])} == null ? ${this.propName(prop.fieldNames[0])} : mapEmbeddedResult_${idx}(${this.propName(prop.fieldNames[0])});`);
|
|
368
|
+
lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
|
|
369
|
+
lines.push(`${padding} }`);
|
|
370
|
+
}
|
|
371
|
+
else if (prop.kind !== ReferenceKind.EMBEDDED) {
|
|
372
|
+
lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
|
|
373
|
+
lines.push(`${padding} ret${this.wrap(prop.name)} = ${this.propName(prop.fieldNames[0])};`);
|
|
374
|
+
lines.push(`${padding} ${this.propName(prop.fieldNames[0], 'mapped')} = true;`);
|
|
375
|
+
lines.push(`${padding} }`);
|
|
376
|
+
}
|
|
331
377
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
378
|
+
};
|
|
379
|
+
if (meta.polymorphs && meta.discriminatorColumn) {
|
|
380
|
+
for (const polymorph of meta.polymorphs) {
|
|
381
|
+
const first = polymorph === meta.polymorphs[0];
|
|
382
|
+
lines.push(` ${first ? '' : 'else '}if (${this.propName(meta.discriminatorColumn)} == '${polymorph.discriminatorValue}') {`);
|
|
383
|
+
mapEntityProperties(polymorph, ' ');
|
|
336
384
|
lines.push(` }`);
|
|
337
385
|
}
|
|
338
|
-
|
|
339
|
-
|
|
386
|
+
lines.push(` else {`);
|
|
387
|
+
mapEntityProperties(meta, ' ');
|
|
388
|
+
lines.push(` }`);
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
mapEntityProperties(meta);
|
|
392
|
+
}
|
|
393
|
+
lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k] && ret[k] === undefined) ret[k] = result[k]; }`);
|
|
340
394
|
const code = `// compiled mapper for entity ${meta.className}\n`
|
|
341
395
|
+ `return function(result) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
|
|
342
|
-
const
|
|
343
|
-
this.
|
|
396
|
+
const fnKey = `resultMapper-${meta.uniqueName}`;
|
|
397
|
+
const resultMapper = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
|
|
398
|
+
this.mappers.set(meta, resultMapper);
|
|
344
399
|
return resultMapper;
|
|
345
400
|
}
|
|
346
401
|
getPropertyCondition(path) {
|
|
@@ -391,11 +446,21 @@ export class EntityComparator {
|
|
|
391
446
|
}
|
|
392
447
|
getEmbeddedPropertySnapshot(meta, prop, context, level, path, dataKey, object = prop.object) {
|
|
393
448
|
const padding = ' '.repeat(level * 2);
|
|
449
|
+
const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
|
|
394
450
|
let ret = `${level === 1 ? '' : '\n'}`;
|
|
395
451
|
if (object) {
|
|
396
|
-
const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
|
|
397
452
|
ret += `${padding}if (${nullCond}) ret${dataKey} = null;\n`;
|
|
398
453
|
}
|
|
454
|
+
else {
|
|
455
|
+
ret += `${padding}if (${nullCond}) {\n`;
|
|
456
|
+
ret += meta.props.filter(p => p.embedded?.[0] === prop.name
|
|
457
|
+
// object for JSON embeddable
|
|
458
|
+
&& (p.object || (p.persist !== false))).map(childProp => {
|
|
459
|
+
const childDataKey = meta.embeddable || prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
|
|
460
|
+
return `${padding} ret${childDataKey} = null;`;
|
|
461
|
+
}).join('\n') + `\n`;
|
|
462
|
+
ret += `${padding}}\n`;
|
|
463
|
+
}
|
|
399
464
|
const cond = `entity${path.map(k => this.wrap(k)).join('')} != null`;
|
|
400
465
|
ret += `${padding}if (${cond}) {\n`;
|
|
401
466
|
if (object) {
|
|
@@ -440,8 +505,8 @@ export class EntityComparator {
|
|
|
440
505
|
registerCustomType(prop, context) {
|
|
441
506
|
const convertorKey = this.safeKey(prop.name);
|
|
442
507
|
context.set(`convertToDatabaseValue_${convertorKey}`, (val) => {
|
|
443
|
-
/* v8 ignore next
|
|
444
|
-
if (
|
|
508
|
+
/* v8 ignore next */
|
|
509
|
+
if (Raw.isKnownFragment(val)) {
|
|
445
510
|
return val;
|
|
446
511
|
}
|
|
447
512
|
return prop.customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' });
|
|
@@ -470,16 +535,51 @@ export class EntityComparator {
|
|
|
470
535
|
ret += ` ret${dataKey} = entity${entityKey};\n`;
|
|
471
536
|
}
|
|
472
537
|
}
|
|
538
|
+
else if (prop.polymorphic) {
|
|
539
|
+
const discriminatorMapKey = `discriminatorMapReverse_${prop.name}`;
|
|
540
|
+
const reverseMap = new Map();
|
|
541
|
+
for (const [key, value] of Object.entries(prop.discriminatorMap)) {
|
|
542
|
+
reverseMap.set(value, key);
|
|
543
|
+
}
|
|
544
|
+
context.set(discriminatorMapKey, reverseMap);
|
|
545
|
+
this.setToArrayHelper(context);
|
|
546
|
+
context.set('EntityIdentifier', EntityIdentifier);
|
|
547
|
+
context.set('PolymorphicRef', PolymorphicRef);
|
|
548
|
+
ret += ` if (entity${entityKey} === null) {\n`;
|
|
549
|
+
ret += ` ret${dataKey} = null;\n`;
|
|
550
|
+
ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
|
|
551
|
+
ret += ` const val${level} = entity${entityKey}${unwrap};\n`;
|
|
552
|
+
ret += ` const discriminator = ${discriminatorMapKey}.get(val${level}?.constructor);\n`;
|
|
553
|
+
ret += ` const pk = val${level}?.__helper?.__identifier && !val${level}?.__helper?.hasPrimaryKey()\n`;
|
|
554
|
+
ret += ` ? val${level}.__helper.__identifier\n`;
|
|
555
|
+
ret += ` : toArray(val${level}?.__helper?.getPrimaryKey(true));\n`;
|
|
556
|
+
ret += ` ret${dataKey} = new PolymorphicRef(discriminator, pk);\n`;
|
|
557
|
+
ret += ` }\n`;
|
|
558
|
+
}
|
|
559
|
+
else if (prop.targetKey) {
|
|
560
|
+
// When targetKey is set, extract that property value instead of the PK
|
|
561
|
+
const targetProp = prop.targetMeta?.properties[prop.targetKey];
|
|
562
|
+
ret += ` if (entity${entityKey} === null) {\n`;
|
|
563
|
+
ret += ` ret${dataKey} = null;\n`;
|
|
564
|
+
ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
|
|
565
|
+
ret += ` const val${level} = entity${entityKey}${unwrap};\n`;
|
|
566
|
+
if (targetProp?.customType) {
|
|
567
|
+
// If targetKey property has a custom type, convert to database value
|
|
568
|
+
const convertorKey = this.registerCustomType(targetProp, context);
|
|
569
|
+
ret += ` ret${dataKey} = convertToDatabaseValue_${convertorKey}(val${level}?.${prop.targetKey});\n`;
|
|
570
|
+
}
|
|
571
|
+
else {
|
|
572
|
+
ret += ` ret${dataKey} = val${level}?.${prop.targetKey};\n`;
|
|
573
|
+
}
|
|
574
|
+
ret += ` }\n`;
|
|
575
|
+
}
|
|
473
576
|
else {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
return Object.values(val).map(v => toArray(v));
|
|
477
|
-
}
|
|
478
|
-
return val;
|
|
479
|
-
};
|
|
480
|
-
context.set('toArray', toArray);
|
|
577
|
+
this.setToArrayHelper(context);
|
|
578
|
+
context.set('EntityIdentifier', EntityIdentifier);
|
|
481
579
|
ret += ` if (entity${entityKey} === null) {\n`;
|
|
482
580
|
ret += ` ret${dataKey} = null;\n`;
|
|
581
|
+
ret += ` } else if (entity${entityKey}?.__helper.__identifier && !entity${entityKey}.__helper.hasPrimaryKey()) {\n`;
|
|
582
|
+
ret += ` ret${dataKey} = entity${entityKey}?.__helper.__identifier;\n`;
|
|
483
583
|
ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
|
|
484
584
|
ret += ` ret${dataKey} = toArray(entity${entityKey}.__helper.getPrimaryKey(true));\n`;
|
|
485
585
|
ret += ` }\n`;
|
|
@@ -503,11 +603,11 @@ export class EntityComparator {
|
|
|
503
603
|
* @internal Highly performance-sensitive method.
|
|
504
604
|
*/
|
|
505
605
|
getEntityComparator(entityName) {
|
|
506
|
-
const
|
|
606
|
+
const meta = this.metadata.find(entityName);
|
|
607
|
+
const exists = this.comparators.get(meta);
|
|
507
608
|
if (exists) {
|
|
508
609
|
return exists;
|
|
509
610
|
}
|
|
510
|
-
const meta = this.metadata.find(entityName);
|
|
511
611
|
const lines = [];
|
|
512
612
|
const context = new Map();
|
|
513
613
|
context.set('compareArrays', compareArrays);
|
|
@@ -515,17 +615,28 @@ export class EntityComparator {
|
|
|
515
615
|
context.set('compareBuffers', compareBuffers);
|
|
516
616
|
context.set('compareObjects', compareObjects);
|
|
517
617
|
context.set('equals', equals);
|
|
518
|
-
meta.comparableProps
|
|
618
|
+
for (const prop of meta.comparableProps) {
|
|
519
619
|
lines.push(this.getPropertyComparator(prop, context));
|
|
520
|
-
}
|
|
620
|
+
}
|
|
621
|
+
// also compare 1:1 inverse sides, important for `factory.mergeData`
|
|
622
|
+
lines.push(`if (options?.includeInverseSides) {`);
|
|
623
|
+
for (const prop of meta.bidirectionalRelations) {
|
|
624
|
+
if (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner && prop.hydrate !== false) {
|
|
625
|
+
lines.push(this.getPropertyComparator(prop, context));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
lines.push(`}`);
|
|
521
629
|
const code = `// compiled comparator for entity ${meta.className}\n`
|
|
522
|
-
+ `return function(last, current) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
|
|
523
|
-
const
|
|
524
|
-
this.
|
|
630
|
+
+ `return function(last, current, options) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
|
|
631
|
+
const fnKey = `comparator-${meta.uniqueName}`;
|
|
632
|
+
const comparator = Utils.createFunction(context, code, this.config?.get('compiledFunctions'), fnKey);
|
|
633
|
+
this.comparators.set(meta, comparator);
|
|
525
634
|
return comparator;
|
|
526
635
|
}
|
|
527
636
|
getGenericComparator(prop, cond) {
|
|
528
|
-
return ` if (current${prop}
|
|
637
|
+
return ` if (current${prop} === null && last${prop} === undefined) {\n` +
|
|
638
|
+
` diff${prop} = current${prop};\n` +
|
|
639
|
+
` } else if (current${prop} == null && last${prop} == null) {\n\n` +
|
|
529
640
|
` } else if ((current${prop} != null && last${prop} == null) || (current${prop} == null && last${prop} != null)) {\n` +
|
|
530
641
|
` diff${prop} = current${prop};\n` +
|
|
531
642
|
` } else if (${cond}) {\n` +
|
|
@@ -535,18 +646,28 @@ export class EntityComparator {
|
|
|
535
646
|
getPropertyComparator(prop, context) {
|
|
536
647
|
let type = prop.type.toLowerCase();
|
|
537
648
|
if (prop.kind !== ReferenceKind.SCALAR && prop.kind !== ReferenceKind.EMBEDDED) {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
type = 'array';
|
|
649
|
+
if (prop.polymorphic) {
|
|
650
|
+
type = 'object';
|
|
541
651
|
}
|
|
542
652
|
else {
|
|
543
|
-
|
|
653
|
+
const meta2 = prop.targetMeta;
|
|
654
|
+
if (meta2.primaryKeys.length > 1) {
|
|
655
|
+
type = 'array';
|
|
656
|
+
}
|
|
657
|
+
else {
|
|
658
|
+
type = meta2.getPrimaryProp().type.toLowerCase();
|
|
659
|
+
}
|
|
544
660
|
}
|
|
545
661
|
}
|
|
546
662
|
if (prop.customType) {
|
|
547
663
|
if (prop.customType.compareValues) {
|
|
548
664
|
const idx = this.tmpIndex++;
|
|
549
|
-
context.set(`compareValues_${idx}`, (a, b) =>
|
|
665
|
+
context.set(`compareValues_${idx}`, (a, b) => {
|
|
666
|
+
if (Raw.isKnownFragment(a) || Raw.isKnownFragment(b)) {
|
|
667
|
+
return Raw.getKnownFragment(a) === Raw.getKnownFragment(b);
|
|
668
|
+
}
|
|
669
|
+
return prop.customType.compareValues(a, b);
|
|
670
|
+
});
|
|
550
671
|
return this.getGenericComparator(this.wrap(prop.name), `!compareValues_${idx}(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
|
|
551
672
|
}
|
|
552
673
|
type = prop.customType.compareAsType().toLowerCase();
|
|
@@ -566,10 +687,10 @@ export class EntityComparator {
|
|
|
566
687
|
if (['buffer', 'uint8array'].includes(type)) {
|
|
567
688
|
return this.getGenericComparator(this.wrap(prop.name), `!compareBuffers(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
|
|
568
689
|
}
|
|
569
|
-
if (
|
|
690
|
+
if (type === 'date') {
|
|
570
691
|
return this.getGenericComparator(this.wrap(prop.name), `last${this.wrap(prop.name)}.valueOf() !== current${this.wrap(prop.name)}.valueOf()`);
|
|
571
692
|
}
|
|
572
|
-
if (
|
|
693
|
+
if (type === 'objectid') {
|
|
573
694
|
// We might be comparing PK to object, in case we compare with cached data of populated entity
|
|
574
695
|
// in such case we just ignore the comparison and fallback to `equals()` (which will still mark
|
|
575
696
|
// it as not equal as we compare PK to plain object).
|
|
@@ -587,11 +708,27 @@ export class EntityComparator {
|
|
|
587
708
|
safeKey(key) {
|
|
588
709
|
return key.replace(/\W/g, '_');
|
|
589
710
|
}
|
|
711
|
+
/**
|
|
712
|
+
* Sets the toArray helper in the context if not already set.
|
|
713
|
+
* Used for converting composite PKs to arrays.
|
|
714
|
+
*/
|
|
715
|
+
setToArrayHelper(context) {
|
|
716
|
+
if (context.has('toArray')) {
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
const toArray = (val) => {
|
|
720
|
+
if (Utils.isPlainObject(val)) {
|
|
721
|
+
return Object.values(val).map(v => toArray(v));
|
|
722
|
+
}
|
|
723
|
+
return val;
|
|
724
|
+
};
|
|
725
|
+
context.set('toArray', toArray);
|
|
726
|
+
}
|
|
590
727
|
/**
|
|
591
728
|
* perf: used to generate list of comparable properties during discovery, so we speed up the runtime comparison
|
|
592
729
|
*/
|
|
593
730
|
static isComparable(prop, root) {
|
|
594
|
-
const virtual = prop.persist === false || prop.generated;
|
|
731
|
+
const virtual = prop.persist === false || (prop.generated && !prop.primary);
|
|
595
732
|
const inverse = prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner;
|
|
596
733
|
const discriminator = prop.name === root.discriminatorColumn;
|
|
597
734
|
const collection = prop.kind === ReferenceKind.ONE_TO_MANY || prop.kind === ReferenceKind.MANY_TO_MANY;
|
package/utils/QueryHelper.d.ts
CHANGED
|
@@ -1,27 +1,45 @@
|
|
|
1
|
-
import type { Dictionary, EntityMetadata, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
|
|
1
|
+
import type { Dictionary, EntityMetadata, EntityName, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
|
|
2
|
+
import { type QueryOrderMap } from '../enums.js';
|
|
2
3
|
import type { Platform } from '../platforms/Platform.js';
|
|
3
4
|
import type { MetadataStorage } from '../metadata/MetadataStorage.js';
|
|
5
|
+
import type { FilterOptions } from '../drivers/IDatabaseDriver.js';
|
|
6
|
+
/** @internal */
|
|
4
7
|
export declare class QueryHelper {
|
|
5
8
|
static readonly SUPPORTED_OPERATORS: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Finds the discriminator value (key) for a given entity class in a discriminator map.
|
|
11
|
+
*/
|
|
12
|
+
static findDiscriminatorValue<T>(discriminatorMap: Dictionary<T>, targetClass: T): string | undefined;
|
|
6
13
|
static processParams(params: unknown): any;
|
|
7
|
-
static processObjectParams<T extends
|
|
14
|
+
static processObjectParams<T extends Dictionary>(params?: T): T;
|
|
15
|
+
/**
|
|
16
|
+
* converts `{ account: { $or: [ [Object], [Object] ] } }`
|
|
17
|
+
* to `{ $or: [ { account: [Object] }, { account: [Object] } ] }`
|
|
18
|
+
*/
|
|
19
|
+
static liftGroupOperators<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): string | undefined;
|
|
8
20
|
static inlinePrimaryKeyObjects<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): boolean;
|
|
9
21
|
static processWhere<T extends object>(options: ProcessWhereOptions<T>): FilterQuery<T>;
|
|
10
|
-
static getActiveFilters(
|
|
11
|
-
static
|
|
22
|
+
static getActiveFilters<T>(meta: EntityMetadata<T>, options: FilterOptions | undefined, filters: Dictionary<FilterDef>): FilterDef[];
|
|
23
|
+
static mergePropertyFilters(propFilters: FilterOptions | undefined, options: FilterOptions | undefined): FilterOptions | undefined;
|
|
24
|
+
static isFilterActive<T>(meta: EntityMetadata<T>, filterName: string, filter: FilterDef, options: Dictionary<boolean | Dictionary>): boolean;
|
|
12
25
|
static processCustomType<T extends object>(prop: EntityProperty<T>, cond: FilterQuery<T>, platform: Platform, key?: string, fromQuery?: boolean): FilterQuery<T>;
|
|
13
26
|
private static isSupportedOperator;
|
|
14
27
|
private static processJsonCondition;
|
|
15
28
|
private static getValueType;
|
|
16
29
|
static findProperty<T>(fieldName: string, options: ProcessWhereOptions<T>): EntityProperty<T> | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Merges multiple orderBy sources with key-level deduplication (first-seen key wins).
|
|
32
|
+
* RawQueryFragment symbol keys are never deduped (each is unique).
|
|
33
|
+
*/
|
|
34
|
+
static mergeOrderBy<T>(...sources: (QueryOrderMap<T> | QueryOrderMap<T>[] | undefined)[]): QueryOrderMap<T>[];
|
|
17
35
|
}
|
|
18
36
|
interface ProcessWhereOptions<T> {
|
|
19
37
|
where: FilterQuery<T>;
|
|
20
|
-
entityName:
|
|
38
|
+
entityName: EntityName<T>;
|
|
21
39
|
metadata: MetadataStorage;
|
|
22
40
|
platform: Platform;
|
|
23
41
|
aliased?: boolean;
|
|
24
|
-
aliasMap?: Dictionary<
|
|
42
|
+
aliasMap?: Dictionary<EntityName>;
|
|
25
43
|
convertCustomTypes?: boolean;
|
|
26
44
|
root?: boolean;
|
|
27
45
|
type?: 'where' | 'orderBy';
|