@mikro-orm/core 7.0.0-dev.320 → 7.0.0-dev.322
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 +2 -15
- package/EntityManager.js +155 -152
- package/MikroORM.d.ts +1 -3
- package/MikroORM.js +20 -20
- package/cache/FileCacheAdapter.d.ts +1 -5
- package/cache/FileCacheAdapter.js +22 -22
- package/cache/GeneratedCacheAdapter.d.ts +1 -1
- package/cache/GeneratedCacheAdapter.js +6 -6
- package/cache/MemoryCacheAdapter.d.ts +1 -2
- package/cache/MemoryCacheAdapter.js +8 -8
- package/entity/Collection.d.ts +2 -10
- package/entity/Collection.js +95 -105
- package/entity/EntityFactory.d.ts +1 -8
- package/entity/EntityFactory.js +48 -48
- package/entity/EntityLoader.d.ts +1 -3
- package/entity/EntityLoader.js +33 -34
- package/entity/Reference.d.ts +1 -2
- package/entity/Reference.js +11 -11
- package/events/EventManager.d.ts +1 -4
- package/events/EventManager.js +21 -21
- package/hydration/ObjectHydrator.d.ts +1 -2
- package/hydration/ObjectHydrator.js +11 -11
- package/metadata/MetadataDiscovery.d.ts +1 -9
- package/metadata/MetadataDiscovery.js +147 -144
- package/metadata/MetadataStorage.d.ts +1 -5
- package/metadata/MetadataStorage.js +36 -36
- package/package.json +1 -1
- package/serialization/SerializationContext.d.ts +2 -6
- package/serialization/SerializationContext.js +14 -14
- package/unit-of-work/ChangeSetComputer.d.ts +1 -6
- package/unit-of-work/ChangeSetComputer.js +21 -21
- package/unit-of-work/ChangeSetPersister.d.ts +1 -9
- package/unit-of-work/ChangeSetPersister.js +51 -51
- package/unit-of-work/CommitOrderCalculator.d.ts +1 -4
- package/unit-of-work/CommitOrderCalculator.js +13 -13
- package/unit-of-work/IdentityMap.d.ts +2 -5
- package/unit-of-work/IdentityMap.js +18 -18
- package/unit-of-work/UnitOfWork.d.ts +5 -19
- package/unit-of-work/UnitOfWork.js +181 -173
- package/utils/AbstractMigrator.d.ts +1 -1
- package/utils/AbstractMigrator.js +6 -6
- package/utils/Configuration.d.ts +1 -6
- package/utils/Configuration.js +78 -78
- package/utils/Cursor.d.ts +1 -1
- package/utils/Cursor.js +3 -3
- package/utils/EntityComparator.d.ts +2 -11
- package/utils/EntityComparator.js +44 -44
- package/utils/TransactionManager.js +1 -2
- package/utils/Utils.js +1 -1
- package/utils/clone.js +5 -0
|
@@ -12,72 +12,72 @@ import { colors } from '../logging/colors.js';
|
|
|
12
12
|
import { raw, Raw } from '../utils/RawQueryFragment.js';
|
|
13
13
|
import { BaseEntity } from '../entity/BaseEntity.js';
|
|
14
14
|
export class MetadataDiscovery {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
#namingStrategy;
|
|
16
|
+
#metadataProvider;
|
|
17
|
+
#logger;
|
|
18
|
+
#schemaHelper;
|
|
19
|
+
#validator = new MetadataValidator();
|
|
20
|
+
#discovered = [];
|
|
21
|
+
#metadata;
|
|
22
|
+
#platform;
|
|
23
|
+
#config;
|
|
24
24
|
constructor(metadata, platform, config) {
|
|
25
|
-
this
|
|
26
|
-
this
|
|
27
|
-
this
|
|
28
|
-
this
|
|
29
|
-
this
|
|
30
|
-
this
|
|
31
|
-
this
|
|
25
|
+
this.#metadata = metadata;
|
|
26
|
+
this.#platform = platform;
|
|
27
|
+
this.#config = config;
|
|
28
|
+
this.#namingStrategy = this.#config.getNamingStrategy();
|
|
29
|
+
this.#metadataProvider = this.#config.getMetadataProvider();
|
|
30
|
+
this.#logger = this.#config.getLogger();
|
|
31
|
+
this.#schemaHelper = this.#platform.getSchemaHelper();
|
|
32
32
|
}
|
|
33
33
|
async discover(preferTs = true) {
|
|
34
|
-
this
|
|
34
|
+
this.#discovered.length = 0;
|
|
35
35
|
const startTime = Date.now();
|
|
36
|
-
const suffix = this
|
|
36
|
+
const suffix = this.#metadataProvider.constructor === MetadataProvider
|
|
37
37
|
? ''
|
|
38
|
-
: `, using ${colors.cyan(this
|
|
39
|
-
this
|
|
38
|
+
: `, using ${colors.cyan(this.#metadataProvider.constructor.name)}`;
|
|
39
|
+
this.#logger.log('discovery', `ORM entity discovery started${suffix}`);
|
|
40
40
|
await this.findEntities(preferTs);
|
|
41
|
-
for (const meta of this
|
|
41
|
+
for (const meta of this.#discovered) {
|
|
42
42
|
/* v8 ignore next */
|
|
43
|
-
await this
|
|
43
|
+
await this.#config.get('discovery').onMetadata?.(meta, this.#platform);
|
|
44
44
|
}
|
|
45
|
-
this.processDiscoveredEntities(this
|
|
45
|
+
this.processDiscoveredEntities(this.#discovered);
|
|
46
46
|
const diff = Date.now() - startTime;
|
|
47
|
-
this
|
|
47
|
+
this.#logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.#discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
|
|
48
48
|
const storage = this.mapDiscoveredEntities();
|
|
49
49
|
/* v8 ignore next */
|
|
50
|
-
await this
|
|
50
|
+
await this.#config.get('discovery').afterDiscovered?.(storage, this.#platform);
|
|
51
51
|
return storage;
|
|
52
52
|
}
|
|
53
53
|
discoverSync() {
|
|
54
|
-
this
|
|
54
|
+
this.#discovered.length = 0;
|
|
55
55
|
const startTime = Date.now();
|
|
56
|
-
const suffix = this
|
|
56
|
+
const suffix = this.#metadataProvider.constructor === MetadataProvider
|
|
57
57
|
? ''
|
|
58
|
-
: `, using ${colors.cyan(this
|
|
59
|
-
this
|
|
60
|
-
const refs = this
|
|
58
|
+
: `, using ${colors.cyan(this.#metadataProvider.constructor.name)}`;
|
|
59
|
+
this.#logger.log('discovery', `ORM entity discovery started${suffix} in sync mode`);
|
|
60
|
+
const refs = this.#config.get('entities');
|
|
61
61
|
this.discoverReferences(refs);
|
|
62
|
-
for (const meta of this
|
|
62
|
+
for (const meta of this.#discovered) {
|
|
63
63
|
/* v8 ignore next */
|
|
64
|
-
void this
|
|
64
|
+
void this.#config.get('discovery').onMetadata?.(meta, this.#platform);
|
|
65
65
|
}
|
|
66
|
-
this.processDiscoveredEntities(this
|
|
66
|
+
this.processDiscoveredEntities(this.#discovered);
|
|
67
67
|
const diff = Date.now() - startTime;
|
|
68
|
-
this
|
|
68
|
+
this.#logger.log('discovery', `- entity discovery finished, found ${colors.green('' + this.#discovered.length)} entities, took ${colors.green(`${diff} ms`)}`);
|
|
69
69
|
const storage = this.mapDiscoveredEntities();
|
|
70
70
|
/* v8 ignore next */
|
|
71
|
-
void this
|
|
71
|
+
void this.#config.get('discovery').afterDiscovered?.(storage, this.#platform);
|
|
72
72
|
return storage;
|
|
73
73
|
}
|
|
74
74
|
mapDiscoveredEntities() {
|
|
75
75
|
const discovered = new MetadataStorage();
|
|
76
|
-
this
|
|
76
|
+
this.#discovered
|
|
77
77
|
.filter(meta => meta.root.name)
|
|
78
78
|
.sort((a, b) => b.root.name.localeCompare(a.root.name))
|
|
79
79
|
.forEach(meta => {
|
|
80
|
-
this
|
|
80
|
+
this.#platform.validateMetadata(meta);
|
|
81
81
|
discovered.set(meta.class, meta);
|
|
82
82
|
});
|
|
83
83
|
for (const meta of discovered) {
|
|
@@ -137,7 +137,7 @@ export class MetadataDiscovery {
|
|
|
137
137
|
filtered.forEach(meta => this.defineBaseEntityProperties(meta));
|
|
138
138
|
filtered.forEach(meta => {
|
|
139
139
|
const newMeta = EntitySchema.fromMetadata(meta).init().meta;
|
|
140
|
-
return this
|
|
140
|
+
return this.#metadata.set(newMeta.class, newMeta);
|
|
141
141
|
});
|
|
142
142
|
filtered.forEach(meta => this.initAutoincrement(meta));
|
|
143
143
|
const forEachProp = (cb) => {
|
|
@@ -167,9 +167,9 @@ export class MetadataDiscovery {
|
|
|
167
167
|
discovered.push(...this.processEntity(meta));
|
|
168
168
|
}
|
|
169
169
|
discovered.forEach(meta => meta.sync(true));
|
|
170
|
-
this
|
|
170
|
+
this.#metadataProvider.combineCache();
|
|
171
171
|
return discovered.map(meta => {
|
|
172
|
-
meta = this
|
|
172
|
+
meta = this.#metadata.get(meta.class);
|
|
173
173
|
meta.sync(true);
|
|
174
174
|
this.findReferencingProperties(meta, filtered);
|
|
175
175
|
if (meta.inheritanceType === 'tpt') {
|
|
@@ -179,7 +179,7 @@ export class MetadataDiscovery {
|
|
|
179
179
|
});
|
|
180
180
|
}
|
|
181
181
|
async findEntities(preferTs) {
|
|
182
|
-
const { entities, entitiesTs, baseDir } = this
|
|
182
|
+
const { entities, entitiesTs, baseDir } = this.#config.getAll();
|
|
183
183
|
const targets = preferTs && entitiesTs.length > 0 ? entitiesTs : entities;
|
|
184
184
|
const processed = [];
|
|
185
185
|
const paths = [];
|
|
@@ -203,13 +203,13 @@ export class MetadataDiscovery {
|
|
|
203
203
|
.replace(/\[]$/, '') // remove array suffix
|
|
204
204
|
.replace(/\((.*)\)/, '$1'); // unwrap union types
|
|
205
205
|
const missing = [];
|
|
206
|
-
this
|
|
206
|
+
this.#discovered.forEach(meta => Object.values(meta.properties).forEach(prop => {
|
|
207
207
|
if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.pivotEntity) {
|
|
208
208
|
const pivotEntity = prop.pivotEntity;
|
|
209
209
|
const target = typeof pivotEntity === 'function' && !pivotEntity.prototype
|
|
210
210
|
? pivotEntity()
|
|
211
211
|
: pivotEntity;
|
|
212
|
-
if (!this
|
|
212
|
+
if (!this.#discovered.find(m => m.className === Utils.className(target))) {
|
|
213
213
|
missing.push(target);
|
|
214
214
|
}
|
|
215
215
|
}
|
|
@@ -217,7 +217,7 @@ export class MetadataDiscovery {
|
|
|
217
217
|
const target = typeof prop.entity === 'function' && !prop.entity.prototype ? prop.entity() : prop.type;
|
|
218
218
|
if (!unwrap(prop.type)
|
|
219
219
|
.split(/ ?\| ?/)
|
|
220
|
-
.every(type => this
|
|
220
|
+
.every(type => this.#discovered.find(m => m.className === type))) {
|
|
221
221
|
missing.push(...Utils.asArray(target));
|
|
222
222
|
}
|
|
223
223
|
}
|
|
@@ -233,7 +233,7 @@ export class MetadataDiscovery {
|
|
|
233
233
|
if (isDiscoverable && target.name) {
|
|
234
234
|
// Get the actual class for EntitySchema, or use target directly for classes
|
|
235
235
|
const targetClass = schema ? schema.meta.class : target;
|
|
236
|
-
if (!this
|
|
236
|
+
if (!this.#metadata.has(targetClass)) {
|
|
237
237
|
this.discoverReferences([target], false);
|
|
238
238
|
this.discoverMissingTargets();
|
|
239
239
|
}
|
|
@@ -248,16 +248,16 @@ export class MetadataDiscovery {
|
|
|
248
248
|
}
|
|
249
249
|
const schema = this.getSchema(entity);
|
|
250
250
|
const meta = schema.init().meta;
|
|
251
|
-
this
|
|
251
|
+
this.#metadata.set(meta.class, meta);
|
|
252
252
|
found.push(schema);
|
|
253
253
|
}
|
|
254
254
|
// discover parents (base entities) automatically
|
|
255
|
-
for (const meta of this
|
|
255
|
+
for (const meta of this.#metadata) {
|
|
256
256
|
let parent = meta.extends;
|
|
257
|
-
if (parent instanceof EntitySchema && !this
|
|
257
|
+
if (parent instanceof EntitySchema && !this.#metadata.has(parent.init().meta.class)) {
|
|
258
258
|
this.discoverReferences([parent], false);
|
|
259
259
|
}
|
|
260
|
-
if (typeof parent === 'function' && parent.name && !this
|
|
260
|
+
if (typeof parent === 'function' && parent.name && !this.#metadata.has(parent)) {
|
|
261
261
|
this.discoverReferences([parent], false);
|
|
262
262
|
}
|
|
263
263
|
/* v8 ignore next */
|
|
@@ -266,7 +266,10 @@ export class MetadataDiscovery {
|
|
|
266
266
|
}
|
|
267
267
|
parent = Object.getPrototypeOf(meta.class);
|
|
268
268
|
// Skip if parent is the auto-generated base class for the same entity (from setClass usage)
|
|
269
|
-
if (parent.name !== '' &&
|
|
269
|
+
if (parent.name !== '' &&
|
|
270
|
+
parent.name !== meta.className &&
|
|
271
|
+
!this.#metadata.has(parent) &&
|
|
272
|
+
parent !== BaseEntity) {
|
|
270
273
|
this.discoverReferences([parent], false);
|
|
271
274
|
}
|
|
272
275
|
}
|
|
@@ -275,15 +278,15 @@ export class MetadataDiscovery {
|
|
|
275
278
|
}
|
|
276
279
|
this.discoverMissingTargets();
|
|
277
280
|
if (validate) {
|
|
278
|
-
this
|
|
281
|
+
this.#validator.validateDiscovered(this.#discovered, this.#config.get('discovery'));
|
|
279
282
|
}
|
|
280
|
-
return this
|
|
283
|
+
return this.#discovered.filter(meta => found.find(m => m.name === meta.className));
|
|
281
284
|
}
|
|
282
285
|
reset(entityName) {
|
|
283
|
-
const exists = this
|
|
286
|
+
const exists = this.#discovered.findIndex(m => m.class === entityName || m.className === Utils.className(entityName));
|
|
284
287
|
if (exists !== -1) {
|
|
285
|
-
this
|
|
286
|
-
this
|
|
288
|
+
this.#metadata.reset(this.#discovered[exists].class);
|
|
289
|
+
this.#discovered.splice(exists, 1);
|
|
287
290
|
}
|
|
288
291
|
}
|
|
289
292
|
getSchema(entity) {
|
|
@@ -298,17 +301,17 @@ export class MetadataDiscovery {
|
|
|
298
301
|
if (path) {
|
|
299
302
|
const meta = Utils.copy(MetadataStorage.getMetadata(entity.name, path), false);
|
|
300
303
|
meta.path = path;
|
|
301
|
-
this
|
|
304
|
+
this.#metadata.set(entity, meta);
|
|
302
305
|
}
|
|
303
|
-
const exists = this
|
|
304
|
-
const meta = this
|
|
306
|
+
const exists = this.#metadata.has(entity);
|
|
307
|
+
const meta = this.#metadata.get(entity, true);
|
|
305
308
|
meta.abstract ??= !(exists && meta.name);
|
|
306
309
|
const schema = EntitySchema.fromMetadata(meta);
|
|
307
310
|
schema.setClass(entity);
|
|
308
311
|
return schema;
|
|
309
312
|
}
|
|
310
313
|
getRootEntity(meta) {
|
|
311
|
-
const base = meta.extends && this
|
|
314
|
+
const base = meta.extends && this.#metadata.find(meta.extends);
|
|
312
315
|
if (!base || base === meta) {
|
|
313
316
|
// make sure we do not fall into infinite loop
|
|
314
317
|
return meta;
|
|
@@ -324,13 +327,13 @@ export class MetadataDiscovery {
|
|
|
324
327
|
discoverEntity(schema) {
|
|
325
328
|
const meta = schema.meta;
|
|
326
329
|
const path = meta.path;
|
|
327
|
-
this
|
|
330
|
+
this.#logger.log('discovery', `- processing entity ${colors.cyan(meta.className)}${colors.grey(path ? ` (${path})` : '')}`);
|
|
328
331
|
const root = this.getRootEntity(meta);
|
|
329
332
|
schema.meta.path = meta.path;
|
|
330
|
-
const cache = this
|
|
333
|
+
const cache = this.#metadataProvider.getCachedMetadata(meta, root);
|
|
331
334
|
if (cache) {
|
|
332
|
-
this
|
|
333
|
-
this
|
|
335
|
+
this.#logger.log('discovery', `- using cached metadata for entity ${colors.cyan(meta.className)}`);
|
|
336
|
+
this.#discovered.push(meta);
|
|
334
337
|
return;
|
|
335
338
|
}
|
|
336
339
|
// infer default value from property initializer early, as the metadata provider might use some defaults, e.g. string for reflect-metadata
|
|
@@ -338,14 +341,14 @@ export class MetadataDiscovery {
|
|
|
338
341
|
this.inferDefaultValue(meta, prop);
|
|
339
342
|
}
|
|
340
343
|
// if the definition is using EntitySchema we still want it to go through the metadata provider to validate no types are missing
|
|
341
|
-
this
|
|
344
|
+
this.#metadataProvider.loadEntityMetadata(meta);
|
|
342
345
|
if (!meta.tableName && meta.name) {
|
|
343
346
|
const entityName = root.discriminatorColumn ? root.name : meta.name;
|
|
344
|
-
meta.tableName = this
|
|
347
|
+
meta.tableName = this.#namingStrategy.classToTableName(entityName);
|
|
345
348
|
}
|
|
346
|
-
this
|
|
349
|
+
this.#metadataProvider.saveToCache(meta);
|
|
347
350
|
meta.root = root;
|
|
348
|
-
this
|
|
351
|
+
this.#discovered.push(meta);
|
|
349
352
|
}
|
|
350
353
|
initNullability(prop) {
|
|
351
354
|
if (prop.kind === ReferenceKind.ONE_TO_ONE) {
|
|
@@ -410,7 +413,7 @@ export class MetadataDiscovery {
|
|
|
410
413
|
return;
|
|
411
414
|
}
|
|
412
415
|
if (prop.kind === ReferenceKind.SCALAR || prop.kind === ReferenceKind.EMBEDDED) {
|
|
413
|
-
prop.fieldNames = [this
|
|
416
|
+
prop.fieldNames = [this.#namingStrategy.propertyToColumnName(prop.name, object)];
|
|
414
417
|
}
|
|
415
418
|
else if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && !prop.polymorphic) {
|
|
416
419
|
prop.fieldNames = this.initManyToOneFieldName(prop, prop.name);
|
|
@@ -425,19 +428,19 @@ export class MetadataDiscovery {
|
|
|
425
428
|
for (const primaryKey of meta2.primaryKeys) {
|
|
426
429
|
this.initFieldName(meta2.properties[primaryKey]);
|
|
427
430
|
for (const fieldName of meta2.properties[primaryKey].fieldNames) {
|
|
428
|
-
ret.push(this
|
|
431
|
+
ret.push(this.#namingStrategy.joinKeyColumnName(name, fieldName, meta2.compositePK, tableName));
|
|
429
432
|
}
|
|
430
433
|
}
|
|
431
434
|
return ret;
|
|
432
435
|
}
|
|
433
436
|
initManyToManyFieldName(prop, name) {
|
|
434
437
|
const meta2 = prop.targetMeta;
|
|
435
|
-
return meta2.primaryKeys.map(() => this
|
|
438
|
+
return meta2.primaryKeys.map(() => this.#namingStrategy.propertyToColumnName(name));
|
|
436
439
|
}
|
|
437
440
|
initManyToManyFields(meta, prop) {
|
|
438
441
|
const meta2 = prop.targetMeta;
|
|
439
442
|
Utils.defaultValue(prop, 'fixedOrder', !!prop.fixedOrderColumn);
|
|
440
|
-
const pivotMeta = this
|
|
443
|
+
const pivotMeta = this.#metadata.find(prop.pivotEntity);
|
|
441
444
|
const props = Object.values(pivotMeta?.properties ?? {});
|
|
442
445
|
const pks = props.filter(p => p.primary);
|
|
443
446
|
const fks = props.filter(p => p.kind === ReferenceKind.MANY_TO_ONE);
|
|
@@ -455,8 +458,8 @@ export class MetadataDiscovery {
|
|
|
455
458
|
prop.joinColumns ??= first.fieldNames;
|
|
456
459
|
prop.inverseJoinColumns ??= second.fieldNames;
|
|
457
460
|
}
|
|
458
|
-
if (!prop.pivotTable && prop.owner && this
|
|
459
|
-
prop.pivotTable = this
|
|
461
|
+
if (!prop.pivotTable && prop.owner && this.#platform.usesPivotTable()) {
|
|
462
|
+
prop.pivotTable = this.#namingStrategy.joinTableName(meta.className, meta2.tableName, prop.name, meta.tableName);
|
|
460
463
|
}
|
|
461
464
|
if (prop.mappedBy) {
|
|
462
465
|
const prop2 = meta2.properties[prop.mappedBy];
|
|
@@ -475,22 +478,22 @@ export class MetadataDiscovery {
|
|
|
475
478
|
prop.referencedColumnNames ??= Utils.flatten(meta.primaryKeys.map(primaryKey => meta.properties[primaryKey].fieldNames));
|
|
476
479
|
// For polymorphic M:N, use discriminator base name for FK column (e.g., taggable_id instead of post_id)
|
|
477
480
|
if (prop.polymorphic && prop.discriminator) {
|
|
478
|
-
prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this
|
|
481
|
+
prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this.#namingStrategy.joinKeyColumnName(prop.discriminator, referencedColumnName, prop.referencedColumnNames.length > 1));
|
|
479
482
|
}
|
|
480
483
|
else {
|
|
481
484
|
const ownerTableName = this.isExplicitTableName(meta.root) ? meta.root.tableName : undefined;
|
|
482
|
-
prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this
|
|
485
|
+
prop.joinColumns ??= prop.referencedColumnNames.map(referencedColumnName => this.#namingStrategy.joinKeyColumnName(meta.root.className, referencedColumnName, meta.compositePK, ownerTableName));
|
|
483
486
|
}
|
|
484
487
|
const inverseTableName = this.isExplicitTableName(meta2.root) ? meta2.root.tableName : undefined;
|
|
485
488
|
prop.inverseJoinColumns ??= this.initManyToOneFieldName(prop, meta2.root.className, inverseTableName);
|
|
486
489
|
}
|
|
487
490
|
isExplicitTableName(meta) {
|
|
488
|
-
return meta.tableName !== this
|
|
491
|
+
return meta.tableName !== this.#namingStrategy.classToTableName(meta.className);
|
|
489
492
|
}
|
|
490
493
|
initManyToOneFields(prop) {
|
|
491
494
|
if (prop.polymorphic && prop.polymorphTargets) {
|
|
492
495
|
const fieldNames1 = prop.targetMeta.getPrimaryProps().flatMap(pk => pk.fieldNames);
|
|
493
|
-
const idColumns = fieldNames1.map(fieldName => this
|
|
496
|
+
const idColumns = fieldNames1.map(fieldName => this.#namingStrategy.joinKeyColumnName(prop.discriminator, fieldName, fieldNames1.length > 1));
|
|
494
497
|
prop.fieldNames ??= [prop.discriminatorColumn, ...idColumns];
|
|
495
498
|
prop.joinColumns ??= idColumns;
|
|
496
499
|
prop.referencedColumnNames ??= fieldNames1;
|
|
@@ -509,7 +512,7 @@ export class MetadataDiscovery {
|
|
|
509
512
|
}
|
|
510
513
|
Utils.defaultValue(prop, 'referencedTableName', meta2.tableName);
|
|
511
514
|
if (!prop.joinColumns) {
|
|
512
|
-
prop.joinColumns = fieldNames.map(fieldName => this
|
|
515
|
+
prop.joinColumns = fieldNames.map(fieldName => this.#namingStrategy.joinKeyColumnName(prop.name, fieldName, fieldNames.length > 1));
|
|
513
516
|
}
|
|
514
517
|
if (!prop.referencedColumnNames) {
|
|
515
518
|
prop.referencedColumnNames = fieldNames;
|
|
@@ -528,7 +531,7 @@ export class MetadataDiscovery {
|
|
|
528
531
|
initOneToManyFields(prop) {
|
|
529
532
|
const meta2 = prop.targetMeta;
|
|
530
533
|
if (!prop.joinColumns) {
|
|
531
|
-
prop.joinColumns = [this
|
|
534
|
+
prop.joinColumns = [this.#namingStrategy.joinColumnName(prop.name)];
|
|
532
535
|
}
|
|
533
536
|
if (!prop.referencedColumnNames) {
|
|
534
537
|
meta2.getPrimaryProps().forEach(pk => this.applyNamingStrategy(meta2, pk));
|
|
@@ -549,7 +552,7 @@ export class MetadataDiscovery {
|
|
|
549
552
|
}
|
|
550
553
|
}
|
|
551
554
|
meta.forceConstructor ??= this.shouldForceConstructorUsage(meta);
|
|
552
|
-
this
|
|
555
|
+
this.#validator.validateEntityDefinition(this.#metadata, meta.class, this.#config.get('discovery'));
|
|
553
556
|
for (const prop of Object.values(meta.properties)) {
|
|
554
557
|
this.initNullability(prop);
|
|
555
558
|
this.applyNamingStrategy(meta, prop);
|
|
@@ -567,7 +570,7 @@ export class MetadataDiscovery {
|
|
|
567
570
|
if (meta.serializedPrimaryKey && meta.serializedPrimaryKey !== meta.primaryKeys[0]) {
|
|
568
571
|
meta.properties[meta.serializedPrimaryKey].persist ??= false;
|
|
569
572
|
}
|
|
570
|
-
if (this
|
|
573
|
+
if (this.#platform.usesPivotTable()) {
|
|
571
574
|
return Object.values(meta.properties)
|
|
572
575
|
.filter(prop => prop.kind === ReferenceKind.MANY_TO_MANY && prop.owner && prop.pivotTable)
|
|
573
576
|
.map(prop => {
|
|
@@ -594,7 +597,7 @@ export class MetadataDiscovery {
|
|
|
594
597
|
['mappedBy', 'inversedBy', 'pivotEntity'].forEach(type => {
|
|
595
598
|
const value = prop[type];
|
|
596
599
|
if (value instanceof Function) {
|
|
597
|
-
const meta2 = prop.targetMeta ?? this
|
|
600
|
+
const meta2 = prop.targetMeta ?? this.#metadata.get(prop.target);
|
|
598
601
|
prop[type] = value(meta2.properties)?.name;
|
|
599
602
|
if (type === 'pivotEntity' && value) {
|
|
600
603
|
prop[type] = value(meta2.properties);
|
|
@@ -631,8 +634,8 @@ export class MetadataDiscovery {
|
|
|
631
634
|
}
|
|
632
635
|
definePivotTableEntity(meta, prop) {
|
|
633
636
|
const pivotMeta = prop.pivotEntity
|
|
634
|
-
? this
|
|
635
|
-
: this
|
|
637
|
+
? this.#metadata.find(prop.pivotEntity)
|
|
638
|
+
: this.#metadata.getByClassName(prop.pivotTable, false);
|
|
636
639
|
// ensure inverse side exists so we can join it when populating via pivot tables
|
|
637
640
|
if (!prop.inversedBy && prop.targetMeta) {
|
|
638
641
|
const inverseName = `${meta.className}_${prop.name}__inverse`;
|
|
@@ -698,15 +701,15 @@ export class MetadataDiscovery {
|
|
|
698
701
|
prop.joinColumns.every((joinColumn, idx) => joinColumn === prop.inverseJoinColumns[idx])) {
|
|
699
702
|
// use tableName only when explicitly provided by user, otherwise use className for backwards compatibility
|
|
700
703
|
const baseName = this.isExplicitTableName(meta) ? meta.tableName : meta.className;
|
|
701
|
-
prop.joinColumns = prop.referencedColumnNames.map(name => this
|
|
702
|
-
prop.inverseJoinColumns = prop.referencedColumnNames.map(name => this
|
|
704
|
+
prop.joinColumns = prop.referencedColumnNames.map(name => this.#namingStrategy.joinKeyColumnName(baseName + '_1', name, meta.compositePK));
|
|
705
|
+
prop.inverseJoinColumns = prop.referencedColumnNames.map(name => this.#namingStrategy.joinKeyColumnName(baseName + '_2', name, meta.compositePK));
|
|
703
706
|
if (prop.inversedBy) {
|
|
704
707
|
const prop2 = targetMeta.properties[prop.inversedBy];
|
|
705
708
|
prop2.inverseJoinColumns = prop.joinColumns;
|
|
706
709
|
prop2.joinColumns = prop.inverseJoinColumns;
|
|
707
710
|
}
|
|
708
711
|
// propagate updated joinColumns to all child entities that inherit this property (STI)
|
|
709
|
-
for (const childMeta of this
|
|
712
|
+
for (const childMeta of this.#discovered.filter(m => m.root === meta && m !== meta)) {
|
|
710
713
|
const childProp = childMeta.properties[prop.name];
|
|
711
714
|
if (childProp) {
|
|
712
715
|
childProp.joinColumns = prop.joinColumns;
|
|
@@ -722,7 +725,7 @@ export class MetadataDiscovery {
|
|
|
722
725
|
pivotMeta2.properties[meta.name + '_owner'] = this.definePivotProperty(prop, meta.name + '_owner', meta.class, targetType + '_inverse', true, meta.className === targetType);
|
|
723
726
|
pivotMeta2.properties[targetType + '_inverse'] = this.definePivotProperty(prop, targetType + '_inverse', targetMeta.class, meta.name + '_owner', false, meta.className === targetType);
|
|
724
727
|
}
|
|
725
|
-
return this
|
|
728
|
+
return this.#metadata.set(pivotMeta2.class, EntitySchema.fromMetadata(pivotMeta2).init().meta);
|
|
726
729
|
}
|
|
727
730
|
/**
|
|
728
731
|
* Create a scalar property for a pivot table column.
|
|
@@ -778,7 +781,7 @@ export class MetadataDiscovery {
|
|
|
778
781
|
pivotMeta.properties[primaryProp.name] = primaryProp;
|
|
779
782
|
pivotMeta.compositePK = false;
|
|
780
783
|
}
|
|
781
|
-
const discriminatorProp = this.createPivotScalarProperty(discriminatorColumn, [this
|
|
784
|
+
const discriminatorProp = this.createPivotScalarProperty(discriminatorColumn, [this.#platform.getVarcharTypeDeclarationSQL(prop)], [discriminatorColumn], { type: 'string', primary: !isCompositePK, nullable: false });
|
|
782
785
|
this.initFieldName(discriminatorProp);
|
|
783
786
|
pivotMeta.properties[discriminatorColumn] = discriminatorProp;
|
|
784
787
|
const columnTypes = this.getPrimaryKeyColumnTypes(meta);
|
|
@@ -831,14 +834,14 @@ export class MetadataDiscovery {
|
|
|
831
834
|
ret.precision = pkProp.precision;
|
|
832
835
|
ret.scale = pkProp.scale;
|
|
833
836
|
}
|
|
834
|
-
const schema = targetMeta.schema ?? this
|
|
837
|
+
const schema = targetMeta.schema ?? this.#config.get('schema') ?? this.#platform.getDefaultSchemaName();
|
|
835
838
|
ret.referencedTableName = schema && schema !== '*' ? schema + '.' + targetMeta.tableName : targetMeta.tableName;
|
|
836
839
|
this.initColumnType(ret);
|
|
837
840
|
this.initRelation(ret);
|
|
838
841
|
return ret;
|
|
839
842
|
}
|
|
840
843
|
defineFixedOrderProperty(prop, targetMeta) {
|
|
841
|
-
const pk = prop.fixedOrderColumn || this
|
|
844
|
+
const pk = prop.fixedOrderColumn || this.#namingStrategy.referenceColumnName();
|
|
842
845
|
const primaryProp = {
|
|
843
846
|
name: pk,
|
|
844
847
|
type: 'number',
|
|
@@ -846,7 +849,7 @@ export class MetadataDiscovery {
|
|
|
846
849
|
kind: ReferenceKind.SCALAR,
|
|
847
850
|
primary: true,
|
|
848
851
|
autoincrement: true,
|
|
849
|
-
unsigned: this
|
|
852
|
+
unsigned: this.#platform.supportsUnsigned(),
|
|
850
853
|
};
|
|
851
854
|
this.initFieldName(primaryProp);
|
|
852
855
|
this.initColumnType(primaryProp);
|
|
@@ -867,21 +870,21 @@ export class MetadataDiscovery {
|
|
|
867
870
|
cascade: [Cascade.ALL],
|
|
868
871
|
fixedOrder: prop.fixedOrder,
|
|
869
872
|
fixedOrderColumn: prop.fixedOrderColumn,
|
|
870
|
-
index: this
|
|
873
|
+
index: this.#platform.indexForeignKeys(),
|
|
871
874
|
primary: !prop.fixedOrder,
|
|
872
875
|
autoincrement: false,
|
|
873
876
|
updateRule: prop.updateRule,
|
|
874
877
|
deleteRule: prop.deleteRule,
|
|
875
878
|
createForeignKeyConstraint: prop.createForeignKeyConstraint,
|
|
876
879
|
};
|
|
877
|
-
const defaultRule = selfReferencing && !this
|
|
880
|
+
const defaultRule = selfReferencing && !this.#platform.supportsMultipleCascadePaths() ? 'no action' : 'cascade';
|
|
878
881
|
ret.updateRule ??= defaultRule;
|
|
879
882
|
ret.deleteRule ??= defaultRule;
|
|
880
|
-
const meta = this
|
|
883
|
+
const meta = this.#metadata.get(type);
|
|
881
884
|
ret.targetMeta = meta;
|
|
882
885
|
ret.joinColumns = [];
|
|
883
886
|
ret.inverseJoinColumns = [];
|
|
884
|
-
const schema = meta.schema ?? this
|
|
887
|
+
const schema = meta.schema ?? this.#config.get('schema') ?? this.#platform.getDefaultSchemaName();
|
|
885
888
|
ret.referencedTableName = schema && schema !== '*' ? schema + '.' + meta.tableName : meta.tableName;
|
|
886
889
|
if (owner) {
|
|
887
890
|
ret.owner = true;
|
|
@@ -927,7 +930,7 @@ export class MetadataDiscovery {
|
|
|
927
930
|
});
|
|
928
931
|
}
|
|
929
932
|
defineBaseEntityProperties(meta) {
|
|
930
|
-
const base = meta.extends && this
|
|
933
|
+
const base = meta.extends && this.#metadata.get(meta.extends);
|
|
931
934
|
if (!base || base === meta) {
|
|
932
935
|
// make sure we do not fall into infinite loop
|
|
933
936
|
return 0;
|
|
@@ -974,8 +977,8 @@ export class MetadataDiscovery {
|
|
|
974
977
|
}
|
|
975
978
|
visited.add(embeddedProp);
|
|
976
979
|
const types = embeddedProp.type.split(/ ?\| ?/);
|
|
977
|
-
let embeddable = this
|
|
978
|
-
const polymorphs = this
|
|
980
|
+
let embeddable = this.#discovered.find(m => m.name === embeddedProp.type);
|
|
981
|
+
const polymorphs = this.#discovered.filter(m => types.includes(m.name));
|
|
979
982
|
// create virtual polymorphic entity
|
|
980
983
|
if (!embeddable && polymorphs.length > 0) {
|
|
981
984
|
const properties = {};
|
|
@@ -993,7 +996,7 @@ export class MetadataDiscovery {
|
|
|
993
996
|
});
|
|
994
997
|
};
|
|
995
998
|
const processExtensions = (meta) => {
|
|
996
|
-
const parent = this
|
|
999
|
+
const parent = this.#discovered.find(m => {
|
|
997
1000
|
return meta.extends && Utils.className(meta.extends) === m.className;
|
|
998
1001
|
});
|
|
999
1002
|
if (!parent) {
|
|
@@ -1031,7 +1034,7 @@ export class MetadataDiscovery {
|
|
|
1031
1034
|
}
|
|
1032
1035
|
prop.polymorphic = true;
|
|
1033
1036
|
prop.discriminator ??= prop.name;
|
|
1034
|
-
prop.discriminatorColumn ??= this
|
|
1037
|
+
prop.discriminatorColumn ??= this.#namingStrategy.discriminatorColumnName(prop.discriminator);
|
|
1035
1038
|
prop.createForeignKeyConstraint = false;
|
|
1036
1039
|
const isToOne = [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind);
|
|
1037
1040
|
if (isToOne) {
|
|
@@ -1043,7 +1046,7 @@ export class MetadataDiscovery {
|
|
|
1043
1046
|
if (prop.discriminatorMap) {
|
|
1044
1047
|
const normalizedMap = {};
|
|
1045
1048
|
for (const [key, value] of Object.entries(prop.discriminatorMap)) {
|
|
1046
|
-
const targetMeta = this
|
|
1049
|
+
const targetMeta = this.#metadata.getByClassName(value, false);
|
|
1047
1050
|
if (!targetMeta) {
|
|
1048
1051
|
throw MetadataError.fromUnknownEntity(value, `${meta.className}.${prop.name} discriminatorMap`);
|
|
1049
1052
|
}
|
|
@@ -1078,7 +1081,7 @@ export class MetadataDiscovery {
|
|
|
1078
1081
|
return;
|
|
1079
1082
|
}
|
|
1080
1083
|
visited.add(embeddedProp);
|
|
1081
|
-
const embeddable = this
|
|
1084
|
+
const embeddable = this.#discovered.find(m => m.name === embeddedProp.type);
|
|
1082
1085
|
if (!embeddable) {
|
|
1083
1086
|
throw MetadataError.fromUnknownEntity(embeddedProp.type, `${meta.className}.${embeddedProp.name}`);
|
|
1084
1087
|
}
|
|
@@ -1150,7 +1153,7 @@ export class MetadataDiscovery {
|
|
|
1150
1153
|
meta.properties[name].fieldNames = prop.fieldNames;
|
|
1151
1154
|
meta.properties[name].embeddedPath = path;
|
|
1152
1155
|
const targetProp = prop.targetMeta?.getPrimaryProp() ?? prop;
|
|
1153
|
-
const fieldName = raw(this
|
|
1156
|
+
const fieldName = raw(this.#platform.getSearchJsonPropertySQL(path.join('->'), targetProp.runtimeType ?? targetProp.type, true));
|
|
1154
1157
|
meta.properties[name].fieldNameRaw = fieldName.sql; // for querying in SQL drivers
|
|
1155
1158
|
meta.properties[name].persist = false; // only virtual as we store the whole object
|
|
1156
1159
|
meta.properties[name].userDefined = false; // mark this as a generated/internal property, so we can distinguish from user-defined non-persist properties
|
|
@@ -1192,7 +1195,7 @@ export class MetadataDiscovery {
|
|
|
1192
1195
|
const map = meta.root.discriminatorMap;
|
|
1193
1196
|
Object.keys(map)
|
|
1194
1197
|
.filter(key => typeof map[key] === 'string')
|
|
1195
|
-
.forEach(key => (map[key] = this
|
|
1198
|
+
.forEach(key => (map[key] = this.#metadata.getByClassName(map[key]).class));
|
|
1196
1199
|
}
|
|
1197
1200
|
else {
|
|
1198
1201
|
meta.root.discriminatorMap = {};
|
|
@@ -1200,7 +1203,7 @@ export class MetadataDiscovery {
|
|
|
1200
1203
|
.filter(m => m.root.class === meta.root.class && !m.abstract)
|
|
1201
1204
|
.sort((a, b) => a.className.localeCompare(b.className));
|
|
1202
1205
|
for (const m of children) {
|
|
1203
|
-
const name = m.discriminatorValue ?? this
|
|
1206
|
+
const name = m.discriminatorValue ?? this.#namingStrategy.classToTableName(m.className);
|
|
1204
1207
|
meta.root.discriminatorMap[name] = m.class;
|
|
1205
1208
|
}
|
|
1206
1209
|
}
|
|
@@ -1232,7 +1235,7 @@ export class MetadataDiscovery {
|
|
|
1232
1235
|
rootProp.stiFieldNameMap = {};
|
|
1233
1236
|
// Find which discriminator owns the original fieldNames
|
|
1234
1237
|
for (const [discValue, childClass] of Object.entries(meta.root.discriminatorMap)) {
|
|
1235
|
-
const childMeta = this
|
|
1238
|
+
const childMeta = this.#metadata.find(childClass);
|
|
1236
1239
|
if (childMeta?.properties[prop.name]?.fieldNames &&
|
|
1237
1240
|
compareArrays(childMeta.properties[prop.name].fieldNames, rootProp.fieldNames)) {
|
|
1238
1241
|
rootProp.stiFieldNameMap[discValue] = rootProp.fieldNames[0];
|
|
@@ -1300,11 +1303,11 @@ export class MetadataDiscovery {
|
|
|
1300
1303
|
if (meta.tptChildren) {
|
|
1301
1304
|
meta.tptChildren = meta.tptChildren.map(child => metadata.find(m => m.class === child.class) ?? child);
|
|
1302
1305
|
}
|
|
1303
|
-
const registryMeta = this
|
|
1306
|
+
const registryMeta = this.#metadata.get(meta.class);
|
|
1304
1307
|
if (registryMeta && registryMeta !== meta) {
|
|
1305
1308
|
registryMeta.inheritanceType = meta.inheritanceType;
|
|
1306
|
-
registryMeta.tptParent = meta.tptParent ? this
|
|
1307
|
-
registryMeta.tptChildren = meta.tptChildren?.map(child => this
|
|
1309
|
+
registryMeta.tptParent = meta.tptParent ? this.#metadata.get(meta.tptParent.class) : undefined;
|
|
1310
|
+
registryMeta.tptChildren = meta.tptChildren?.map(child => this.#metadata.get(child.class));
|
|
1308
1311
|
}
|
|
1309
1312
|
this.initTPTDiscriminator(meta, metadata);
|
|
1310
1313
|
}
|
|
@@ -1322,12 +1325,12 @@ export class MetadataDiscovery {
|
|
|
1322
1325
|
}
|
|
1323
1326
|
meta.root.discriminatorMap = {};
|
|
1324
1327
|
for (const m of allDescendants) {
|
|
1325
|
-
const name = this
|
|
1328
|
+
const name = this.#namingStrategy.classToTableName(m.className);
|
|
1326
1329
|
meta.root.discriminatorMap[name] = m.class;
|
|
1327
1330
|
m.discriminatorValue = name;
|
|
1328
1331
|
}
|
|
1329
1332
|
if (!meta.abstract) {
|
|
1330
|
-
const name = this
|
|
1333
|
+
const name = this.#namingStrategy.classToTableName(meta.className);
|
|
1331
1334
|
meta.root.discriminatorMap[name] = meta.class;
|
|
1332
1335
|
meta.discriminatorValue = name;
|
|
1333
1336
|
}
|
|
@@ -1440,7 +1443,7 @@ export class MetadataDiscovery {
|
|
|
1440
1443
|
}
|
|
1441
1444
|
initAutoincrement(meta) {
|
|
1442
1445
|
const pks = meta.getPrimaryProps();
|
|
1443
|
-
if (pks.length === 1 && this
|
|
1446
|
+
if (pks.length === 1 && this.#platform.isNumericProperty(pks[0])) {
|
|
1444
1447
|
/* v8 ignore next */
|
|
1445
1448
|
pks[0].autoincrement ??= true;
|
|
1446
1449
|
}
|
|
@@ -1459,12 +1462,12 @@ export class MetadataDiscovery {
|
|
|
1459
1462
|
const table = this.createSchemaTable(meta);
|
|
1460
1463
|
for (const check of meta.checks) {
|
|
1461
1464
|
const fieldNames = check.property ? meta.properties[check.property].fieldNames : [];
|
|
1462
|
-
check.name ??= this
|
|
1465
|
+
check.name ??= this.#namingStrategy.indexName(meta.tableName, fieldNames, 'check');
|
|
1463
1466
|
if (check.expression instanceof Function) {
|
|
1464
1467
|
check.expression = check.expression(columns, table);
|
|
1465
1468
|
}
|
|
1466
1469
|
}
|
|
1467
|
-
if (this
|
|
1470
|
+
if (this.#platform.usesEnumCheckConstraints() && !meta.embeddable) {
|
|
1468
1471
|
for (const prop of meta.props) {
|
|
1469
1472
|
if (prop.enum &&
|
|
1470
1473
|
prop.persist !== false &&
|
|
@@ -1472,9 +1475,9 @@ export class MetadataDiscovery {
|
|
|
1472
1475
|
prop.items?.every(item => typeof item === 'string')) {
|
|
1473
1476
|
this.initFieldName(prop);
|
|
1474
1477
|
meta.checks.push({
|
|
1475
|
-
name: this
|
|
1478
|
+
name: this.#namingStrategy.indexName(meta.tableName, prop.fieldNames, 'check'),
|
|
1476
1479
|
property: prop.name,
|
|
1477
|
-
expression: `${this
|
|
1480
|
+
expression: `${this.#platform.quoteIdentifier(prop.fieldNames[0])} in ('${prop.items.join("', '")}')`,
|
|
1478
1481
|
});
|
|
1479
1482
|
}
|
|
1480
1483
|
}
|
|
@@ -1505,13 +1508,13 @@ export class MetadataDiscovery {
|
|
|
1505
1508
|
}
|
|
1506
1509
|
/* v8 ignore next */
|
|
1507
1510
|
if (prop.default != null) {
|
|
1508
|
-
return '' + this
|
|
1511
|
+
return '' + this.#platform.convertVersionValue(prop.default, prop);
|
|
1509
1512
|
}
|
|
1510
1513
|
this.initCustomType(meta, prop, true);
|
|
1511
1514
|
const type = prop.customType?.runtimeType ?? prop.runtimeType ?? prop.type;
|
|
1512
1515
|
if (type === 'Date') {
|
|
1513
|
-
prop.length ??= this
|
|
1514
|
-
return this
|
|
1516
|
+
prop.length ??= this.#platform.getDefaultVersionLength();
|
|
1517
|
+
return this.#platform.getCurrentTimestampSQL(prop.length);
|
|
1515
1518
|
}
|
|
1516
1519
|
return '1';
|
|
1517
1520
|
}
|
|
@@ -1522,7 +1525,7 @@ export class MetadataDiscovery {
|
|
|
1522
1525
|
const entity1 = new meta.class();
|
|
1523
1526
|
const entity2 = new meta.class();
|
|
1524
1527
|
// we compare the two values by reference, this will discard things like `new Date()` or `Date.now()`
|
|
1525
|
-
if (this
|
|
1528
|
+
if (this.#config.get('discovery').inferDefaultValues &&
|
|
1526
1529
|
prop.default === undefined &&
|
|
1527
1530
|
entity1[prop.name] != null &&
|
|
1528
1531
|
entity1[prop.name] === entity2[prop.name] &&
|
|
@@ -1549,11 +1552,11 @@ export class MetadataDiscovery {
|
|
|
1549
1552
|
let val = prop.default;
|
|
1550
1553
|
const raw = Raw.getKnownFragment(val);
|
|
1551
1554
|
if (raw) {
|
|
1552
|
-
prop.defaultRaw = this
|
|
1555
|
+
prop.defaultRaw = this.#platform.formatQuery(raw.sql, raw.params);
|
|
1553
1556
|
return;
|
|
1554
1557
|
}
|
|
1555
1558
|
if (Array.isArray(prop.default) && prop.customType) {
|
|
1556
|
-
val = prop.customType.convertToDatabaseValue(prop.default, this
|
|
1559
|
+
val = prop.customType.convertToDatabaseValue(prop.default, this.#platform);
|
|
1557
1560
|
}
|
|
1558
1561
|
prop.defaultRaw = typeof val === 'string' ? `'${val}'` : '' + val;
|
|
1559
1562
|
}
|
|
@@ -1653,7 +1656,7 @@ export class MetadataDiscovery {
|
|
|
1653
1656
|
}
|
|
1654
1657
|
if (prop.customType && !prop.columnTypes) {
|
|
1655
1658
|
const mappedType = this.getMappedType({
|
|
1656
|
-
columnTypes: [prop.customType.getColumnType(prop, this
|
|
1659
|
+
columnTypes: [prop.customType.getColumnType(prop, this.#platform)],
|
|
1657
1660
|
});
|
|
1658
1661
|
if (prop.customType.compareAsType() === 'any' && ![t.json].some(t => prop.customType instanceof t)) {
|
|
1659
1662
|
prop.runtimeType ??= mappedType.runtimeType;
|
|
@@ -1669,15 +1672,15 @@ export class MetadataDiscovery {
|
|
|
1669
1672
|
prop.runtimeType ??= mappedType.runtimeType;
|
|
1670
1673
|
}
|
|
1671
1674
|
if (prop.customType) {
|
|
1672
|
-
prop.customType.platform = this
|
|
1675
|
+
prop.customType.platform = this.#platform;
|
|
1673
1676
|
prop.customType.meta = meta;
|
|
1674
1677
|
prop.customType.prop = prop;
|
|
1675
|
-
prop.columnTypes ??= [prop.customType.getColumnType(prop, this
|
|
1678
|
+
prop.columnTypes ??= [prop.customType.getColumnType(prop, this.#platform)];
|
|
1676
1679
|
prop.hasConvertToJSValueSQL =
|
|
1677
|
-
!!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this
|
|
1680
|
+
!!prop.customType.convertToJSValueSQL && prop.customType.convertToJSValueSQL('', this.#platform) !== '';
|
|
1678
1681
|
prop.hasConvertToDatabaseValueSQL =
|
|
1679
1682
|
!!prop.customType.convertToDatabaseValueSQL &&
|
|
1680
|
-
prop.customType.convertToDatabaseValueSQL('', this
|
|
1683
|
+
prop.customType.convertToDatabaseValueSQL('', this.#platform) !== '';
|
|
1681
1684
|
if (prop.customType instanceof t.bigint &&
|
|
1682
1685
|
['string', 'bigint', 'number'].includes(prop.runtimeType.toLowerCase())) {
|
|
1683
1686
|
prop.customType.mode = prop.runtimeType.toLowerCase();
|
|
@@ -1695,11 +1698,11 @@ export class MetadataDiscovery {
|
|
|
1695
1698
|
if (pk.customType) {
|
|
1696
1699
|
prop.customTypes.push(pk.customType);
|
|
1697
1700
|
prop.hasConvertToJSValueSQL ||=
|
|
1698
|
-
!!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this
|
|
1701
|
+
!!pk.customType.convertToJSValueSQL && pk.customType.convertToJSValueSQL('', this.#platform) !== '';
|
|
1699
1702
|
/* v8 ignore next */
|
|
1700
1703
|
prop.hasConvertToDatabaseValueSQL ||=
|
|
1701
1704
|
!!pk.customType.convertToDatabaseValueSQL &&
|
|
1702
|
-
pk.customType.convertToDatabaseValueSQL('', this
|
|
1705
|
+
pk.customType.convertToDatabaseValueSQL('', this.#platform) !== '';
|
|
1703
1706
|
}
|
|
1704
1707
|
else {
|
|
1705
1708
|
prop.customTypes.push(undefined);
|
|
@@ -1709,13 +1712,13 @@ export class MetadataDiscovery {
|
|
|
1709
1712
|
if (prop.kind === ReferenceKind.SCALAR && !(mappedType instanceof t.unknown)) {
|
|
1710
1713
|
if (!prop.columnTypes &&
|
|
1711
1714
|
prop.nativeEnumName &&
|
|
1712
|
-
meta.schema !== this
|
|
1715
|
+
meta.schema !== this.#platform.getDefaultSchemaName() &&
|
|
1713
1716
|
meta.schema &&
|
|
1714
1717
|
!prop.nativeEnumName.includes('.')) {
|
|
1715
1718
|
prop.columnTypes = [`${meta.schema}.${prop.nativeEnumName}`];
|
|
1716
1719
|
}
|
|
1717
1720
|
else {
|
|
1718
|
-
prop.columnTypes ??= [mappedType.getColumnType(prop, this
|
|
1721
|
+
prop.columnTypes ??= [mappedType.getColumnType(prop, this.#platform)];
|
|
1719
1722
|
}
|
|
1720
1723
|
// use only custom types provided by user, we don't need to use the ones provided by ORM,
|
|
1721
1724
|
// with exception for ArrayType and JsonType, those two are handled in
|
|
@@ -1729,7 +1732,7 @@ export class MetadataDiscovery {
|
|
|
1729
1732
|
return;
|
|
1730
1733
|
}
|
|
1731
1734
|
// when the target is a polymorphic embedded entity, `prop.target` is an array of classes, we need to get the metadata by the type name instead
|
|
1732
|
-
const meta2 = this
|
|
1735
|
+
const meta2 = this.#metadata.find(prop.target) ?? this.#metadata.getByClassName(prop.type);
|
|
1733
1736
|
// If targetKey is specified, use that property instead of PKs for referencedPKs
|
|
1734
1737
|
prop.referencedPKs = prop.targetKey ? [prop.targetKey] : meta2.primaryKeys;
|
|
1735
1738
|
prop.targetMeta = meta2;
|
|
@@ -1744,7 +1747,7 @@ export class MetadataDiscovery {
|
|
|
1744
1747
|
!prop.embedded) {
|
|
1745
1748
|
this.initFieldName(prop);
|
|
1746
1749
|
if (prop.fieldNames?.length === 1) {
|
|
1747
|
-
prop.formula = table => `${table}.${this
|
|
1750
|
+
prop.formula = table => `${table}.${this.#platform.quoteIdentifier(prop.fieldNames[0])}`;
|
|
1748
1751
|
}
|
|
1749
1752
|
}
|
|
1750
1753
|
}
|
|
@@ -1766,7 +1769,7 @@ export class MetadataDiscovery {
|
|
|
1766
1769
|
const mappedType = this.getMappedType(prop);
|
|
1767
1770
|
prop.type = mappedType.compareAsType();
|
|
1768
1771
|
}
|
|
1769
|
-
if (prop.columnTypes || !this
|
|
1772
|
+
if (prop.columnTypes || !this.#schemaHelper) {
|
|
1770
1773
|
return;
|
|
1771
1774
|
}
|
|
1772
1775
|
if (prop.kind === ReferenceKind.SCALAR) {
|
|
@@ -1781,13 +1784,13 @@ export class MetadataDiscovery {
|
|
|
1781
1784
|
prop.columnTypes = [type];
|
|
1782
1785
|
}
|
|
1783
1786
|
else {
|
|
1784
|
-
prop.columnTypes = [mappedType.getColumnType(prop, this
|
|
1787
|
+
prop.columnTypes = [mappedType.getColumnType(prop, this.#platform)];
|
|
1785
1788
|
}
|
|
1786
1789
|
return;
|
|
1787
1790
|
}
|
|
1788
1791
|
/* v8 ignore next */
|
|
1789
1792
|
if (prop.kind === ReferenceKind.EMBEDDED && prop.object) {
|
|
1790
|
-
prop.columnTypes = [this
|
|
1793
|
+
prop.columnTypes = [this.#platform.getJsonDeclarationSQL()];
|
|
1791
1794
|
return;
|
|
1792
1795
|
}
|
|
1793
1796
|
const targetMeta = prop.targetMeta;
|
|
@@ -1795,7 +1798,7 @@ export class MetadataDiscovery {
|
|
|
1795
1798
|
// Use targetKey property if specified, otherwise use primary key properties
|
|
1796
1799
|
const referencedProps = prop.targetKey ? [targetMeta.properties[prop.targetKey]] : targetMeta.getPrimaryProps();
|
|
1797
1800
|
if (prop.polymorphic && prop.polymorphTargets) {
|
|
1798
|
-
prop.columnTypes.push(this
|
|
1801
|
+
prop.columnTypes.push(this.#platform.getVarcharTypeDeclarationSQL(prop));
|
|
1799
1802
|
}
|
|
1800
1803
|
for (const referencedProp of referencedProps) {
|
|
1801
1804
|
this.initCustomType(targetMeta, referencedProp);
|
|
@@ -1803,7 +1806,7 @@ export class MetadataDiscovery {
|
|
|
1803
1806
|
const mappedType = this.getMappedType(referencedProp);
|
|
1804
1807
|
let columnTypes = referencedProp.columnTypes;
|
|
1805
1808
|
if (referencedProp.autoincrement) {
|
|
1806
|
-
columnTypes = [mappedType.getColumnType({ ...referencedProp, autoincrement: false }, this
|
|
1809
|
+
columnTypes = [mappedType.getColumnType({ ...referencedProp, autoincrement: false }, this.#platform)];
|
|
1807
1810
|
}
|
|
1808
1811
|
prop.columnTypes.push(...columnTypes);
|
|
1809
1812
|
if (!targetMeta.compositePK || prop.targetKey) {
|
|
@@ -1826,7 +1829,7 @@ export class MetadataDiscovery {
|
|
|
1826
1829
|
if (t === 'Date') {
|
|
1827
1830
|
t = 'datetime';
|
|
1828
1831
|
}
|
|
1829
|
-
return this
|
|
1832
|
+
return this.#platform.getMappedType(t);
|
|
1830
1833
|
}
|
|
1831
1834
|
getPrefix(prop, parent) {
|
|
1832
1835
|
const { embeddedPath = [], fieldNames, prefix = true, prefixMode } = prop;
|
|
@@ -1837,7 +1840,7 @@ export class MetadataDiscovery {
|
|
|
1837
1840
|
if (prefix === false) {
|
|
1838
1841
|
return prefixParent;
|
|
1839
1842
|
}
|
|
1840
|
-
const mode = prefixMode ?? this
|
|
1843
|
+
const mode = prefixMode ?? this.#config.get('embeddables').prefixMode;
|
|
1841
1844
|
return mode === 'absolute' ? prefix : prefixParent + prefix;
|
|
1842
1845
|
}
|
|
1843
1846
|
initUnsigned(prop) {
|
|
@@ -1852,16 +1855,16 @@ export class MetadataDiscovery {
|
|
|
1852
1855
|
return;
|
|
1853
1856
|
}
|
|
1854
1857
|
prop.unsigned ??=
|
|
1855
|
-
(prop.primary || prop.unsigned) && this
|
|
1858
|
+
(prop.primary || prop.unsigned) && this.#platform.isNumericProperty(prop) && this.#platform.supportsUnsigned();
|
|
1856
1859
|
}
|
|
1857
1860
|
initIndexes(meta, prop) {
|
|
1858
1861
|
const hasIndex = meta.indexes.some(idx => idx.properties?.length === 1 && idx.properties[0] === prop.name);
|
|
1859
|
-
if (prop.kind === ReferenceKind.MANY_TO_ONE && this
|
|
1862
|
+
if (prop.kind === ReferenceKind.MANY_TO_ONE && this.#platform.indexForeignKeys() && !hasIndex) {
|
|
1860
1863
|
prop.index ??= true;
|
|
1861
1864
|
}
|
|
1862
1865
|
}
|
|
1863
1866
|
shouldForceConstructorUsage(meta) {
|
|
1864
|
-
const forceConstructor = this
|
|
1867
|
+
const forceConstructor = this.#config.get('forceEntityConstructor');
|
|
1865
1868
|
if (Array.isArray(forceConstructor)) {
|
|
1866
1869
|
return forceConstructor.some(cls => Utils.className(cls) === meta.className);
|
|
1867
1870
|
}
|