@mikro-orm/core 7.0.0-dev.12 → 7.0.0-dev.120
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 +85 -56
- package/EntityManager.js +332 -293
- package/MikroORM.d.ts +41 -32
- package/MikroORM.js +100 -140
- package/README.md +3 -2
- package/cache/FileCacheAdapter.d.ts +1 -1
- package/cache/FileCacheAdapter.js +8 -7
- 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 +35 -19
- package/drivers/IDatabaseDriver.d.ts +38 -17
- package/entity/BaseEntity.d.ts +0 -1
- package/entity/BaseEntity.js +0 -3
- package/entity/Collection.d.ts +95 -30
- package/entity/Collection.js +439 -99
- package/entity/EntityAssigner.d.ts +1 -1
- package/entity/EntityAssigner.js +26 -18
- package/entity/EntityFactory.d.ts +7 -0
- package/entity/EntityFactory.js +72 -53
- package/entity/EntityHelper.d.ts +2 -2
- package/entity/EntityHelper.js +30 -15
- package/entity/EntityLoader.d.ts +7 -6
- package/entity/EntityLoader.js +84 -72
- package/entity/EntityRepository.d.ts +1 -1
- package/entity/EntityRepository.js +2 -2
- package/entity/Reference.d.ts +6 -5
- package/entity/Reference.js +34 -9
- package/entity/WrappedEntity.d.ts +2 -7
- package/entity/WrappedEntity.js +3 -8
- package/entity/defineEntity.d.ts +568 -0
- package/entity/defineEntity.js +529 -0
- package/entity/index.d.ts +3 -2
- package/entity/index.js +3 -2
- package/entity/utils.d.ts +7 -0
- package/entity/utils.js +16 -4
- package/entity/validators.d.ts +11 -0
- package/entity/validators.js +65 -0
- package/enums.d.ts +21 -6
- package/enums.js +14 -1
- package/errors.d.ts +17 -9
- package/errors.js +41 -21
- package/events/EventManager.d.ts +2 -1
- package/events/EventManager.js +19 -11
- package/hydration/Hydrator.js +1 -2
- package/hydration/ObjectHydrator.d.ts +4 -4
- package/hydration/ObjectHydrator.js +50 -33
- 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 +13 -17
- package/metadata/EntitySchema.js +67 -51
- package/metadata/MetadataDiscovery.d.ts +6 -10
- package/metadata/MetadataDiscovery.js +289 -298
- package/metadata/MetadataProvider.d.ts +11 -2
- package/metadata/MetadataProvider.js +46 -2
- package/metadata/MetadataStorage.d.ts +13 -11
- package/metadata/MetadataStorage.js +70 -37
- package/metadata/MetadataValidator.d.ts +2 -9
- package/metadata/MetadataValidator.js +22 -38
- 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 +480 -0
- package/metadata/types.js +1 -0
- package/naming-strategy/AbstractNamingStrategy.d.ts +8 -4
- package/naming-strategy/AbstractNamingStrategy.js +8 -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 +14 -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 +19 -11
- package/platforms/ExceptionConverter.js +1 -1
- package/platforms/Platform.d.ts +6 -13
- package/platforms/Platform.js +17 -43
- package/serialization/EntitySerializer.d.ts +5 -0
- package/serialization/EntitySerializer.js +47 -27
- package/serialization/EntityTransformer.js +28 -18
- 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 +8 -6
- package/types/BigIntType.js +1 -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 +124 -86
- package/typings.js +50 -42
- package/unit-of-work/ChangeSet.d.ts +2 -6
- package/unit-of-work/ChangeSet.js +4 -5
- package/unit-of-work/ChangeSetComputer.d.ts +1 -3
- package/unit-of-work/ChangeSetComputer.js +14 -12
- package/unit-of-work/ChangeSetPersister.d.ts +5 -4
- package/unit-of-work/ChangeSetPersister.js +65 -33
- package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/UnitOfWork.d.ts +10 -3
- package/unit-of-work/UnitOfWork.js +139 -96
- package/utils/AbstractSchemaGenerator.d.ts +5 -5
- package/utils/AbstractSchemaGenerator.js +18 -16
- package/utils/AsyncContext.d.ts +6 -0
- package/utils/AsyncContext.js +42 -0
- package/utils/Configuration.d.ts +753 -207
- package/utils/Configuration.js +145 -190
- package/utils/ConfigurationLoader.d.ts +1 -54
- package/utils/ConfigurationLoader.js +1 -352
- package/utils/Cursor.d.ts +0 -3
- package/utils/Cursor.js +9 -6
- package/utils/DataloaderUtils.d.ts +15 -5
- package/utils/DataloaderUtils.js +65 -17
- package/utils/EntityComparator.d.ts +13 -9
- package/utils/EntityComparator.js +85 -43
- package/utils/QueryHelper.d.ts +14 -6
- package/utils/QueryHelper.js +87 -25
- package/utils/RawQueryFragment.d.ts +48 -25
- package/utils/RawQueryFragment.js +66 -70
- 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 +12 -119
- package/utils/Utils.js +97 -373
- 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 +32 -0
- package/utils/fs-utils.js +178 -0
- package/utils/index.d.ts +2 -1
- package/utils/index.js +2 -1
- 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 -12
- 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 -4
- package/decorators/Formula.js +0 -15
- package/decorators/Indexed.d.ts +0 -19
- 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 -8
- 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 -402
- 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
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { EntityData, EntityDictionary, EntityMetadata, EntityProperty, IMetadataStorage } from '../typings.js';
|
|
1
|
+
import type { EntityData, EntityDictionary, EntityMetadata, EntityName, EntityProperty, IMetadataStorage } from '../typings.js';
|
|
2
2
|
import type { Platform } from '../platforms/Platform.js';
|
|
3
|
-
type Comparator<T> = (a: T, b: T
|
|
3
|
+
type Comparator<T> = (a: T, b: T, options?: {
|
|
4
|
+
includeInverseSides?: boolean;
|
|
5
|
+
}) => EntityData<T>;
|
|
4
6
|
type ResultMapper<T> = (result: EntityData<T>) => EntityData<T> | null;
|
|
5
7
|
type SnapshotGenerator<T> = (entity: T) => EntityData<T>;
|
|
6
8
|
type CompositeKeyPart = string | CompositeKeyPart[];
|
|
@@ -18,17 +20,19 @@ export declare class EntityComparator {
|
|
|
18
20
|
/**
|
|
19
21
|
* Computes difference between two entities.
|
|
20
22
|
*/
|
|
21
|
-
diffEntities<T>(entityName:
|
|
22
|
-
|
|
23
|
+
diffEntities<T extends object>(entityName: EntityName<T>, a: EntityData<T>, b: EntityData<T>, options?: {
|
|
24
|
+
includeInverseSides?: boolean;
|
|
25
|
+
}): EntityData<T>;
|
|
26
|
+
matching<T extends object>(entityName: EntityName<T>, a: EntityData<T>, b: EntityData<T>): boolean;
|
|
23
27
|
/**
|
|
24
28
|
* Removes ORM specific code from entities and prepares it for serializing. Used before change set computation.
|
|
25
29
|
* References will be mapped to primary keys, collections to arrays of primary keys.
|
|
26
30
|
*/
|
|
27
|
-
prepareEntity<T>(entity: T): EntityData<T>;
|
|
31
|
+
prepareEntity<T extends object>(entity: T): EntityData<T>;
|
|
28
32
|
/**
|
|
29
33
|
* Maps database columns to properties.
|
|
30
34
|
*/
|
|
31
|
-
mapResult<T>(
|
|
35
|
+
mapResult<T>(meta: EntityMetadata<T>, result: EntityDictionary<T>): EntityData<T>;
|
|
32
36
|
/**
|
|
33
37
|
* @internal Highly performance-sensitive method.
|
|
34
38
|
*/
|
|
@@ -44,7 +48,7 @@ export declare class EntityComparator {
|
|
|
44
48
|
/**
|
|
45
49
|
* @internal Highly performance-sensitive method.
|
|
46
50
|
*/
|
|
47
|
-
getSnapshotGenerator<T>(entityName:
|
|
51
|
+
getSnapshotGenerator<T>(entityName: EntityName<T>): SnapshotGenerator<T>;
|
|
48
52
|
/**
|
|
49
53
|
* @internal
|
|
50
54
|
*/
|
|
@@ -60,7 +64,7 @@ export declare class EntityComparator {
|
|
|
60
64
|
/**
|
|
61
65
|
* @internal Highly performance-sensitive method.
|
|
62
66
|
*/
|
|
63
|
-
getResultMapper<T>(
|
|
67
|
+
getResultMapper<T>(meta: EntityMetadata<T>): ResultMapper<T>;
|
|
64
68
|
private getPropertyCondition;
|
|
65
69
|
private getEmbeddedArrayPropertySnapshot;
|
|
66
70
|
/**
|
|
@@ -74,7 +78,7 @@ export declare class EntityComparator {
|
|
|
74
78
|
/**
|
|
75
79
|
* @internal Highly performance-sensitive method.
|
|
76
80
|
*/
|
|
77
|
-
getEntityComparator<T extends object>(entityName:
|
|
81
|
+
getEntityComparator<T extends object>(entityName: EntityName<T>): Comparator<T>;
|
|
78
82
|
private getGenericComparator;
|
|
79
83
|
private getPropertyComparator;
|
|
80
84
|
private wrap;
|
|
@@ -2,7 +2,8 @@ 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';
|
|
6
7
|
export class EntityComparator {
|
|
7
8
|
metadata;
|
|
8
9
|
platform;
|
|
@@ -20,9 +21,9 @@ export class EntityComparator {
|
|
|
20
21
|
/**
|
|
21
22
|
* Computes difference between two entities.
|
|
22
23
|
*/
|
|
23
|
-
diffEntities(entityName, a, b) {
|
|
24
|
+
diffEntities(entityName, a, b, options) {
|
|
24
25
|
const comparator = this.getEntityComparator(entityName);
|
|
25
|
-
return Utils.callCompiledFunction(comparator, a, b);
|
|
26
|
+
return Utils.callCompiledFunction(comparator, a, b, options);
|
|
26
27
|
}
|
|
27
28
|
matching(entityName, a, b) {
|
|
28
29
|
const diff = this.diffEntities(entityName, a, b);
|
|
@@ -33,22 +34,22 @@ export class EntityComparator {
|
|
|
33
34
|
* References will be mapped to primary keys, collections to arrays of primary keys.
|
|
34
35
|
*/
|
|
35
36
|
prepareEntity(entity) {
|
|
36
|
-
const generator = this.getSnapshotGenerator(entity.constructor
|
|
37
|
+
const generator = this.getSnapshotGenerator(entity.constructor);
|
|
37
38
|
return Utils.callCompiledFunction(generator, entity);
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Maps database columns to properties.
|
|
41
42
|
*/
|
|
42
|
-
mapResult(
|
|
43
|
-
const mapper = this.getResultMapper(
|
|
43
|
+
mapResult(meta, result) {
|
|
44
|
+
const mapper = this.getResultMapper(meta);
|
|
44
45
|
return Utils.callCompiledFunction(mapper, result);
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
47
48
|
* @internal Highly performance-sensitive method.
|
|
48
49
|
*/
|
|
49
50
|
getPkGetter(meta) {
|
|
50
|
-
const exists = this.pkGetters.get(meta
|
|
51
|
-
/* v8 ignore next
|
|
51
|
+
const exists = this.pkGetters.get(meta);
|
|
52
|
+
/* v8 ignore next */
|
|
52
53
|
if (exists) {
|
|
53
54
|
return exists;
|
|
54
55
|
}
|
|
@@ -90,15 +91,15 @@ export class EntityComparator {
|
|
|
90
91
|
const code = `// compiled pk serializer for entity ${meta.className}\n`
|
|
91
92
|
+ `return function(entity) {\n${lines.join('\n')}\n}`;
|
|
92
93
|
const pkSerializer = Utils.createFunction(context, code);
|
|
93
|
-
this.pkGetters.set(meta
|
|
94
|
+
this.pkGetters.set(meta, pkSerializer);
|
|
94
95
|
return pkSerializer;
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
98
|
* @internal Highly performance-sensitive method.
|
|
98
99
|
*/
|
|
99
100
|
getPkGetterConverted(meta) {
|
|
100
|
-
const exists = this.pkGettersConverted.get(meta
|
|
101
|
-
/* v8 ignore next
|
|
101
|
+
const exists = this.pkGettersConverted.get(meta);
|
|
102
|
+
/* v8 ignore next */
|
|
102
103
|
if (exists) {
|
|
103
104
|
return exists;
|
|
104
105
|
}
|
|
@@ -140,21 +141,22 @@ export class EntityComparator {
|
|
|
140
141
|
const code = `// compiled pk getter (with converted custom types) for entity ${meta.className}\n`
|
|
141
142
|
+ `return function(entity) {\n${lines.join('\n')}\n}`;
|
|
142
143
|
const pkSerializer = Utils.createFunction(context, code);
|
|
143
|
-
this.pkGettersConverted.set(meta
|
|
144
|
+
this.pkGettersConverted.set(meta, pkSerializer);
|
|
144
145
|
return pkSerializer;
|
|
145
146
|
}
|
|
146
147
|
/**
|
|
147
148
|
* @internal Highly performance-sensitive method.
|
|
148
149
|
*/
|
|
149
150
|
getPkSerializer(meta) {
|
|
150
|
-
const exists = this.pkSerializers.get(meta
|
|
151
|
-
/* v8 ignore next
|
|
151
|
+
const exists = this.pkSerializers.get(meta);
|
|
152
|
+
/* v8 ignore next */
|
|
152
153
|
if (exists) {
|
|
153
154
|
return exists;
|
|
154
155
|
}
|
|
155
156
|
const lines = [];
|
|
156
157
|
const context = new Map();
|
|
157
158
|
context.set('getCompositeKeyValue', (val) => Utils.flatten(Utils.getCompositeKeyValue(val, meta, 'convertToDatabaseValue', this.platform)));
|
|
159
|
+
context.set('getPrimaryKeyHash', (val) => Utils.getPrimaryKeyHash(Utils.asArray(val)));
|
|
158
160
|
if (meta.primaryKeys.length > 1) {
|
|
159
161
|
lines.push(` const pks = entity.__helper.__pk ? getCompositeKeyValue(entity.__helper.__pk) : [`);
|
|
160
162
|
meta.primaryKeys.forEach(pk => {
|
|
@@ -170,30 +172,39 @@ export class EntityComparator {
|
|
|
170
172
|
}
|
|
171
173
|
else {
|
|
172
174
|
const pk = meta.primaryKeys[0];
|
|
173
|
-
|
|
175
|
+
const prop = meta.properties[pk];
|
|
176
|
+
if (prop.kind !== ReferenceKind.SCALAR) {
|
|
174
177
|
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
178
|
}
|
|
176
179
|
const serializedPrimaryKey = meta.props.find(p => p.serializedPrimaryKey);
|
|
177
180
|
if (serializedPrimaryKey) {
|
|
178
181
|
lines.push(` return '' + entity.${serializedPrimaryKey.name};`);
|
|
179
182
|
}
|
|
180
|
-
|
|
183
|
+
else if (prop.customType) {
|
|
184
|
+
const convertorKey = this.registerCustomType(meta.properties[pk], context);
|
|
185
|
+
const idx = this.tmpIndex++;
|
|
186
|
+
lines.push(` const val_${idx} = convertToDatabaseValue_${convertorKey}(entity${this.wrap(pk)});`);
|
|
187
|
+
lines.push(` return getPrimaryKeyHash(val_${idx});`);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
lines.push(` return '' + entity${this.wrap(pk)};`);
|
|
191
|
+
}
|
|
181
192
|
}
|
|
182
193
|
const code = `// compiled pk serializer for entity ${meta.className}\n`
|
|
183
194
|
+ `return function(entity) {\n${lines.join('\n')}\n}`;
|
|
184
195
|
const pkSerializer = Utils.createFunction(context, code);
|
|
185
|
-
this.pkSerializers.set(meta
|
|
196
|
+
this.pkSerializers.set(meta, pkSerializer);
|
|
186
197
|
return pkSerializer;
|
|
187
198
|
}
|
|
188
199
|
/**
|
|
189
200
|
* @internal Highly performance-sensitive method.
|
|
190
201
|
*/
|
|
191
202
|
getSnapshotGenerator(entityName) {
|
|
192
|
-
const
|
|
203
|
+
const meta = this.metadata.find(entityName);
|
|
204
|
+
const exists = this.snapshotGenerators.get(meta);
|
|
193
205
|
if (exists) {
|
|
194
206
|
return exists;
|
|
195
207
|
}
|
|
196
|
-
const meta = this.metadata.find(entityName);
|
|
197
208
|
const lines = [];
|
|
198
209
|
const context = new Map();
|
|
199
210
|
context.set('clone', clone);
|
|
@@ -211,7 +222,7 @@ export class EntityComparator {
|
|
|
211
222
|
.forEach(prop => lines.push(this.getPropertySnapshot(meta, prop, context, this.wrap(prop.name), this.wrap(prop.name), [prop.name])));
|
|
212
223
|
const code = `return function(entity) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
|
|
213
224
|
const snapshotGenerator = Utils.createFunction(context, code);
|
|
214
|
-
this.snapshotGenerators.set(
|
|
225
|
+
this.snapshotGenerators.set(meta, snapshotGenerator);
|
|
215
226
|
return snapshotGenerator;
|
|
216
227
|
}
|
|
217
228
|
/**
|
|
@@ -261,12 +272,11 @@ export class EntityComparator {
|
|
|
261
272
|
/**
|
|
262
273
|
* @internal Highly performance-sensitive method.
|
|
263
274
|
*/
|
|
264
|
-
getResultMapper(
|
|
265
|
-
const exists = this.mappers.get(
|
|
275
|
+
getResultMapper(meta) {
|
|
276
|
+
const exists = this.mappers.get(meta);
|
|
266
277
|
if (exists) {
|
|
267
278
|
return exists;
|
|
268
279
|
}
|
|
269
|
-
const meta = this.metadata.get(entityName);
|
|
270
280
|
const lines = [];
|
|
271
281
|
const context = new Map();
|
|
272
282
|
const tz = this.platform.getTimezone();
|
|
@@ -274,10 +284,14 @@ export class EntityComparator {
|
|
|
274
284
|
lines.push(`${padding} if (${value} == null || ${value} instanceof Date) {`);
|
|
275
285
|
lines.push(`${padding} ${key} = ${value};`);
|
|
276
286
|
if (!tz || tz === 'local') {
|
|
287
|
+
lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
|
|
288
|
+
lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
|
|
277
289
|
lines.push(`${padding} } else {`);
|
|
278
290
|
lines.push(`${padding} ${key} = parseDate(${value});`);
|
|
279
291
|
}
|
|
280
292
|
else {
|
|
293
|
+
lines.push(`${padding} } else if (typeof ${value} === 'bigint') {`);
|
|
294
|
+
lines.push(`${padding} ${key} = parseDate(Number(${value}));`);
|
|
281
295
|
lines.push(`${padding} } else if (typeof ${value} === 'number' || ${value}.includes('+') || ${value}.lastIndexOf('-') > 10 || ${value}.endsWith('Z')) {`);
|
|
282
296
|
lines.push(`${padding} ${key} = parseDate(${value});`);
|
|
283
297
|
lines.push(`${padding} } else {`);
|
|
@@ -321,9 +335,9 @@ export class EntityComparator {
|
|
|
321
335
|
context.set(`mapEmbeddedResult_${idx}`, (data) => {
|
|
322
336
|
const item = parseJsonSafe(data);
|
|
323
337
|
if (Array.isArray(item)) {
|
|
324
|
-
return item.map(row => row == null ? row : this.getResultMapper(prop.
|
|
338
|
+
return item.map(row => row == null ? row : this.getResultMapper(prop.targetMeta)(row));
|
|
325
339
|
}
|
|
326
|
-
return item == null ? item : this.getResultMapper(prop.
|
|
340
|
+
return item == null ? item : this.getResultMapper(prop.targetMeta)(item);
|
|
327
341
|
});
|
|
328
342
|
lines.push(`${padding} if (typeof ${this.propName(prop.fieldNames[0])} !== 'undefined') {`);
|
|
329
343
|
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])});`);
|
|
@@ -352,11 +366,11 @@ export class EntityComparator {
|
|
|
352
366
|
else {
|
|
353
367
|
mapEntityProperties(meta);
|
|
354
368
|
}
|
|
355
|
-
lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k]) ret[k] = result[k]; }`);
|
|
369
|
+
lines.push(` for (let k in result) { if (Object.hasOwn(result, k) && !mapped[k] && ret[k] === undefined) ret[k] = result[k]; }`);
|
|
356
370
|
const code = `// compiled mapper for entity ${meta.className}\n`
|
|
357
371
|
+ `return function(result) {\n const ret = {};\n${lines.join('\n')}\n return ret;\n}`;
|
|
358
372
|
const resultMapper = Utils.createFunction(context, code);
|
|
359
|
-
this.mappers.set(
|
|
373
|
+
this.mappers.set(meta, resultMapper);
|
|
360
374
|
return resultMapper;
|
|
361
375
|
}
|
|
362
376
|
getPropertyCondition(path) {
|
|
@@ -407,11 +421,21 @@ export class EntityComparator {
|
|
|
407
421
|
}
|
|
408
422
|
getEmbeddedPropertySnapshot(meta, prop, context, level, path, dataKey, object = prop.object) {
|
|
409
423
|
const padding = ' '.repeat(level * 2);
|
|
424
|
+
const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
|
|
410
425
|
let ret = `${level === 1 ? '' : '\n'}`;
|
|
411
426
|
if (object) {
|
|
412
|
-
const nullCond = `entity${path.map(k => this.wrap(k)).join('')} === null`;
|
|
413
427
|
ret += `${padding}if (${nullCond}) ret${dataKey} = null;\n`;
|
|
414
428
|
}
|
|
429
|
+
else {
|
|
430
|
+
ret += `${padding}if (${nullCond}) {\n`;
|
|
431
|
+
ret += meta.props.filter(p => p.embedded?.[0] === prop.name
|
|
432
|
+
// object for JSON embeddable
|
|
433
|
+
&& (p.object || (p.persist !== false))).map(childProp => {
|
|
434
|
+
const childDataKey = meta.embeddable || prop.object ? dataKey + this.wrap(childProp.embedded[1]) : this.wrap(childProp.name);
|
|
435
|
+
return `${padding} ret${childDataKey} = null;`;
|
|
436
|
+
}).join('\n') + `\n`;
|
|
437
|
+
ret += `${padding}}\n`;
|
|
438
|
+
}
|
|
415
439
|
const cond = `entity${path.map(k => this.wrap(k)).join('')} != null`;
|
|
416
440
|
ret += `${padding}if (${cond}) {\n`;
|
|
417
441
|
if (object) {
|
|
@@ -456,8 +480,8 @@ export class EntityComparator {
|
|
|
456
480
|
registerCustomType(prop, context) {
|
|
457
481
|
const convertorKey = this.safeKey(prop.name);
|
|
458
482
|
context.set(`convertToDatabaseValue_${convertorKey}`, (val) => {
|
|
459
|
-
/* v8 ignore next
|
|
460
|
-
if (
|
|
483
|
+
/* v8 ignore next */
|
|
484
|
+
if (Raw.isKnownFragment(val)) {
|
|
461
485
|
return val;
|
|
462
486
|
}
|
|
463
487
|
return prop.customType.convertToDatabaseValue(val, this.platform, { mode: 'serialization' });
|
|
@@ -494,8 +518,11 @@ export class EntityComparator {
|
|
|
494
518
|
return val;
|
|
495
519
|
};
|
|
496
520
|
context.set('toArray', toArray);
|
|
521
|
+
context.set('EntityIdentifier', EntityIdentifier);
|
|
497
522
|
ret += ` if (entity${entityKey} === null) {\n`;
|
|
498
523
|
ret += ` ret${dataKey} = null;\n`;
|
|
524
|
+
ret += ` } else if (entity${entityKey}?.__helper.__identifier && !entity${entityKey}.__helper.hasPrimaryKey()) {\n`;
|
|
525
|
+
ret += ` ret${dataKey} = entity${entityKey}?.__helper.__identifier;\n`;
|
|
499
526
|
ret += ` } else if (typeof entity${entityKey} !== 'undefined') {\n`;
|
|
500
527
|
ret += ` ret${dataKey} = toArray(entity${entityKey}.__helper.getPrimaryKey(true));\n`;
|
|
501
528
|
ret += ` }\n`;
|
|
@@ -519,11 +546,11 @@ export class EntityComparator {
|
|
|
519
546
|
* @internal Highly performance-sensitive method.
|
|
520
547
|
*/
|
|
521
548
|
getEntityComparator(entityName) {
|
|
522
|
-
const
|
|
549
|
+
const meta = this.metadata.find(entityName);
|
|
550
|
+
const exists = this.comparators.get(meta);
|
|
523
551
|
if (exists) {
|
|
524
552
|
return exists;
|
|
525
553
|
}
|
|
526
|
-
const meta = this.metadata.find(entityName);
|
|
527
554
|
const lines = [];
|
|
528
555
|
const context = new Map();
|
|
529
556
|
context.set('compareArrays', compareArrays);
|
|
@@ -531,17 +558,27 @@ export class EntityComparator {
|
|
|
531
558
|
context.set('compareBuffers', compareBuffers);
|
|
532
559
|
context.set('compareObjects', compareObjects);
|
|
533
560
|
context.set('equals', equals);
|
|
534
|
-
meta.comparableProps
|
|
561
|
+
for (const prop of meta.comparableProps) {
|
|
535
562
|
lines.push(this.getPropertyComparator(prop, context));
|
|
536
|
-
}
|
|
563
|
+
}
|
|
564
|
+
// also compare 1:1 inverse sides, important for `factory.mergeData`
|
|
565
|
+
lines.push(`if (options?.includeInverseSides) {`);
|
|
566
|
+
for (const prop of meta.bidirectionalRelations) {
|
|
567
|
+
if (prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner && prop.hydrate !== false) {
|
|
568
|
+
lines.push(this.getPropertyComparator(prop, context));
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
lines.push(`}`);
|
|
537
572
|
const code = `// compiled comparator for entity ${meta.className}\n`
|
|
538
|
-
+ `return function(last, current) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
|
|
573
|
+
+ `return function(last, current, options) {\n const diff = {};\n${lines.join('\n')}\n return diff;\n}`;
|
|
539
574
|
const comparator = Utils.createFunction(context, code);
|
|
540
|
-
this.comparators.set(
|
|
575
|
+
this.comparators.set(meta, comparator);
|
|
541
576
|
return comparator;
|
|
542
577
|
}
|
|
543
578
|
getGenericComparator(prop, cond) {
|
|
544
|
-
return ` if (current${prop}
|
|
579
|
+
return ` if (current${prop} === null && last${prop} === undefined) {\n` +
|
|
580
|
+
` diff${prop} = current${prop};\n` +
|
|
581
|
+
` } else if (current${prop} == null && last${prop} == null) {\n\n` +
|
|
545
582
|
` } else if ((current${prop} != null && last${prop} == null) || (current${prop} == null && last${prop} != null)) {\n` +
|
|
546
583
|
` diff${prop} = current${prop};\n` +
|
|
547
584
|
` } else if (${cond}) {\n` +
|
|
@@ -551,18 +588,23 @@ export class EntityComparator {
|
|
|
551
588
|
getPropertyComparator(prop, context) {
|
|
552
589
|
let type = prop.type.toLowerCase();
|
|
553
590
|
if (prop.kind !== ReferenceKind.SCALAR && prop.kind !== ReferenceKind.EMBEDDED) {
|
|
554
|
-
const meta2 =
|
|
591
|
+
const meta2 = prop.targetMeta;
|
|
555
592
|
if (meta2.primaryKeys.length > 1) {
|
|
556
593
|
type = 'array';
|
|
557
594
|
}
|
|
558
595
|
else {
|
|
559
|
-
type = meta2.
|
|
596
|
+
type = meta2.getPrimaryProp().type.toLowerCase();
|
|
560
597
|
}
|
|
561
598
|
}
|
|
562
599
|
if (prop.customType) {
|
|
563
600
|
if (prop.customType.compareValues) {
|
|
564
601
|
const idx = this.tmpIndex++;
|
|
565
|
-
context.set(`compareValues_${idx}`, (a, b) =>
|
|
602
|
+
context.set(`compareValues_${idx}`, (a, b) => {
|
|
603
|
+
if (Raw.isKnownFragment(a) || Raw.isKnownFragment(b)) {
|
|
604
|
+
return Raw.getKnownFragment(a) === Raw.getKnownFragment(b);
|
|
605
|
+
}
|
|
606
|
+
return prop.customType.compareValues(a, b);
|
|
607
|
+
});
|
|
566
608
|
return this.getGenericComparator(this.wrap(prop.name), `!compareValues_${idx}(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
|
|
567
609
|
}
|
|
568
610
|
type = prop.customType.compareAsType().toLowerCase();
|
|
@@ -582,10 +624,10 @@ export class EntityComparator {
|
|
|
582
624
|
if (['buffer', 'uint8array'].includes(type)) {
|
|
583
625
|
return this.getGenericComparator(this.wrap(prop.name), `!compareBuffers(last${this.wrap(prop.name)}, current${this.wrap(prop.name)})`);
|
|
584
626
|
}
|
|
585
|
-
if (
|
|
627
|
+
if (type === 'date') {
|
|
586
628
|
return this.getGenericComparator(this.wrap(prop.name), `last${this.wrap(prop.name)}.valueOf() !== current${this.wrap(prop.name)}.valueOf()`);
|
|
587
629
|
}
|
|
588
|
-
if (
|
|
630
|
+
if (type === 'objectid') {
|
|
589
631
|
// We might be comparing PK to object, in case we compare with cached data of populated entity
|
|
590
632
|
// in such case we just ignore the comparison and fallback to `equals()` (which will still mark
|
|
591
633
|
// it as not equal as we compare PK to plain object).
|
|
@@ -607,7 +649,7 @@ export class EntityComparator {
|
|
|
607
649
|
* perf: used to generate list of comparable properties during discovery, so we speed up the runtime comparison
|
|
608
650
|
*/
|
|
609
651
|
static isComparable(prop, root) {
|
|
610
|
-
const virtual = prop.persist === false || prop.generated;
|
|
652
|
+
const virtual = prop.persist === false || (prop.generated && !prop.primary);
|
|
611
653
|
const inverse = prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner;
|
|
612
654
|
const discriminator = prop.name === root.discriminatorColumn;
|
|
613
655
|
const collection = prop.kind === ReferenceKind.ONE_TO_MANY || prop.kind === ReferenceKind.MANY_TO_MANY;
|
package/utils/QueryHelper.d.ts
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import type { Dictionary, EntityMetadata, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
|
|
1
|
+
import type { Dictionary, EntityMetadata, EntityName, EntityProperty, FilterDef, FilterQuery } from '../typings.js';
|
|
2
2
|
import type { Platform } from '../platforms/Platform.js';
|
|
3
3
|
import type { MetadataStorage } from '../metadata/MetadataStorage.js';
|
|
4
|
+
import type { FilterOptions } from '../drivers/IDatabaseDriver.js';
|
|
5
|
+
/** @internal */
|
|
4
6
|
export declare class QueryHelper {
|
|
5
7
|
static readonly SUPPORTED_OPERATORS: string[];
|
|
6
8
|
static processParams(params: unknown): any;
|
|
7
|
-
static processObjectParams<T extends
|
|
9
|
+
static processObjectParams<T extends Dictionary>(params?: T): T;
|
|
10
|
+
/**
|
|
11
|
+
* converts `{ account: { $or: [ [Object], [Object] ] } }`
|
|
12
|
+
* to `{ $or: [ { account: [Object] }, { account: [Object] } ] }`
|
|
13
|
+
*/
|
|
14
|
+
static liftGroupOperators<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): string | undefined;
|
|
8
15
|
static inlinePrimaryKeyObjects<T extends object>(where: Dictionary, meta: EntityMetadata<T>, metadata: MetadataStorage, key?: string): boolean;
|
|
9
16
|
static processWhere<T extends object>(options: ProcessWhereOptions<T>): FilterQuery<T>;
|
|
10
|
-
static getActiveFilters(
|
|
11
|
-
static
|
|
17
|
+
static getActiveFilters<T>(meta: EntityMetadata<T>, options: FilterOptions | undefined, filters: Dictionary<FilterDef>): FilterDef[];
|
|
18
|
+
static mergePropertyFilters(propFilters: FilterOptions | undefined, options: FilterOptions | undefined): FilterOptions | undefined;
|
|
19
|
+
static isFilterActive<T>(meta: EntityMetadata<T>, filterName: string, filter: FilterDef, options: Dictionary<boolean | Dictionary>): boolean;
|
|
12
20
|
static processCustomType<T extends object>(prop: EntityProperty<T>, cond: FilterQuery<T>, platform: Platform, key?: string, fromQuery?: boolean): FilterQuery<T>;
|
|
13
21
|
private static isSupportedOperator;
|
|
14
22
|
private static processJsonCondition;
|
|
@@ -17,11 +25,11 @@ export declare class QueryHelper {
|
|
|
17
25
|
}
|
|
18
26
|
interface ProcessWhereOptions<T> {
|
|
19
27
|
where: FilterQuery<T>;
|
|
20
|
-
entityName:
|
|
28
|
+
entityName: EntityName<T>;
|
|
21
29
|
metadata: MetadataStorage;
|
|
22
30
|
platform: Platform;
|
|
23
31
|
aliased?: boolean;
|
|
24
|
-
aliasMap?: Dictionary<
|
|
32
|
+
aliasMap?: Dictionary<EntityName>;
|
|
25
33
|
convertCustomTypes?: boolean;
|
|
26
34
|
root?: boolean;
|
|
27
35
|
type?: 'where' | 'orderBy';
|