@mikro-orm/core 7.0.16-dev.1 → 7.0.16-dev.11
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.js +1 -1
- package/entity/EntityLoader.js +5 -2
- package/index.d.ts +1 -1
- package/metadata/MetadataDiscovery.js +9 -5
- package/package.json +1 -1
- package/platforms/Platform.d.ts +10 -2
- package/platforms/Platform.js +18 -2
- package/typings.d.ts +26 -4
- package/typings.js +29 -9
- package/unit-of-work/UnitOfWork.js +1 -1
- package/utils/Utils.js +1 -1
package/EntityManager.js
CHANGED
|
@@ -659,7 +659,7 @@ export class EntityManager {
|
|
|
659
659
|
where = await em.processWhere(entityName, where, options, 'read');
|
|
660
660
|
validateEmptyWhere(where);
|
|
661
661
|
em.checkLockRequirements(options.lockMode, meta);
|
|
662
|
-
const isOptimisticLocking = options.lockMode == null || options.lockMode === LockMode.OPTIMISTIC;
|
|
662
|
+
const isOptimisticLocking = options.lockMode == null || options.lockMode === LockMode.NONE || options.lockMode === LockMode.OPTIMISTIC;
|
|
663
663
|
if (entity && !em.shouldRefresh(meta, entity, options) && isOptimisticLocking) {
|
|
664
664
|
return em.lockAndPopulate(meta, entity, where, options);
|
|
665
665
|
}
|
package/entity/EntityLoader.js
CHANGED
|
@@ -665,8 +665,11 @@ export class EntityLoader {
|
|
|
665
665
|
}
|
|
666
666
|
return ret;
|
|
667
667
|
}, []);
|
|
668
|
-
// we need to automatically select the FKs too, e.g. for 1:m
|
|
669
|
-
|
|
668
|
+
// we need to automatically select the FKs too, e.g. for 1:m and inverse 1:1 relations
|
|
669
|
+
// to be able to wire them with the items
|
|
670
|
+
if (prop.kind === ReferenceKind.ONE_TO_MANY ||
|
|
671
|
+
prop.kind === ReferenceKind.MANY_TO_MANY ||
|
|
672
|
+
(prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner)) {
|
|
670
673
|
const owner = prop.targetMeta.properties[prop.mappedBy];
|
|
671
674
|
// when the owning FK is lazy, we need to explicitly select it even without user-provided fields,
|
|
672
675
|
// otherwise the driver will exclude it and we won't be able to map children to their parent collections
|
package/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module core
|
|
4
4
|
*/
|
|
5
5
|
export { EntityMetadata, PrimaryKeyProp, EntityRepositoryType, OptionalProps, EagerProps, HiddenProps, Config, EntityName, } from './typings.js';
|
|
6
|
-
export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IMigrationRunner, IEntityGenerator, ISeedManager, SeederObject, IMigratorStorage, RequiredEntityData, CheckCallback, IndexCallback, FormulaCallback, FormulaColumns, FormulaTable, SchemaTable, SchemaColumns, EntityDataPropValue, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
|
|
6
|
+
export type { CompiledFunctions, Constructor, ConnectionType, Dictionary, Primary, IPrimaryKey, ObjectQuery, FilterQuery, IWrappedEntity, InferEntityName, EntityData, Highlighter, MaybePromise, AnyEntity, EntityClass, EntityProperty, PopulateOptions, Populate, Loaded, New, LoadedReference, LoadedCollection, IMigrator, IMigrationGenerator, MigratorEvent, GetRepository, MigrationObject, DeepPartial, PrimaryProperty, Cast, IsUnknown, EntityDictionary, EntityDTO, EntityDTOFlat, EntityDTOProp, SerializeDTO, MigrationDiff, GenerateOptions, FilterObject, IMigrationRunner, IEntityGenerator, ISeedManager, SeederObject, IMigratorStorage, RequiredEntityData, CheckCallback, IndexCallback, FormulaCallback, FormulaColumns, FormulaTable, SchemaTable, SchemaColumns, SchemaColumnRef, EntityDataPropValue, SimpleColumnMeta, Rel, Ref, ScalarRef, EntityRef, ISchemaGenerator, MigrationInfo, MigrateOptions, MigrationResult, MigrationRow, EntityKey, EntityValue, EntityDataValue, FilterKey, EntityType, FromEntityType, Selected, IsSubset, EntityProps, ExpandProperty, ExpandScalar, FilterItemValue, ExpandQuery, Scalar, ExpandHint, FilterValue, MergeLoaded, MergeSelected, TypeConfig, AnyString, ClearDatabaseOptions, CreateSchemaOptions, EnsureDatabaseOptions, UpdateSchemaOptions, DropSchemaOptions, RefreshDatabaseOptions, AutoPath, UnboxArray, MetadataProcessor, ImportsResolver, RequiredNullable, DefineConfig, Opt, Hidden, EntitySchemaWithMeta, InferEntity, CheckConstraint, GeneratedColumnCallback, FilterDef, EntityCtor, Subquery, PopulateHintOptions, Prefixes, } from './typings.js';
|
|
7
7
|
export * from './enums.js';
|
|
8
8
|
export * from './errors.js';
|
|
9
9
|
export * from './exceptions.js';
|
|
@@ -963,9 +963,13 @@ export class MetadataDiscovery {
|
|
|
963
963
|
meta.propertyOrder.set(prop.name, (order += 0.01));
|
|
964
964
|
});
|
|
965
965
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
meta.
|
|
966
|
+
// TPT children have their own tables that don't contain the parent's columns,
|
|
967
|
+
// so propagating parent indexes/uniques/checks would target missing columns.
|
|
968
|
+
if (meta.inheritanceType !== 'tpt' || !meta.tptParent) {
|
|
969
|
+
meta.indexes = Utils.unique([...base.indexes, ...meta.indexes]);
|
|
970
|
+
meta.uniques = Utils.unique([...base.uniques, ...meta.uniques]);
|
|
971
|
+
meta.checks = Utils.unique([...base.checks, ...meta.checks]);
|
|
972
|
+
}
|
|
969
973
|
const pks = Object.values(meta.properties)
|
|
970
974
|
.filter(p => p.primary)
|
|
971
975
|
.map(p => p.name);
|
|
@@ -1531,7 +1535,7 @@ export class MetadataDiscovery {
|
|
|
1531
1535
|
const table = this.createSchemaTable(meta);
|
|
1532
1536
|
for (const check of meta.checks) {
|
|
1533
1537
|
const fieldNames = check.property ? meta.properties[check.property].fieldNames : [];
|
|
1534
|
-
check.name ??= this.#
|
|
1538
|
+
check.name ??= this.#platform.getIndexName(meta.tableName, fieldNames, 'check');
|
|
1535
1539
|
if (check.expression instanceof Function) {
|
|
1536
1540
|
check.expression = check.expression(columns, table);
|
|
1537
1541
|
}
|
|
@@ -1556,7 +1560,7 @@ export class MetadataDiscovery {
|
|
|
1556
1560
|
}
|
|
1557
1561
|
if (expression) {
|
|
1558
1562
|
meta.checks.push({
|
|
1559
|
-
name: this.#
|
|
1563
|
+
name: this.#platform.getIndexName(meta.tableName, prop.fieldNames, 'check'),
|
|
1560
1564
|
property: prop.name,
|
|
1561
1565
|
expression,
|
|
1562
1566
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.0.16-dev.
|
|
3
|
+
"version": "7.0.16-dev.11",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"data-mapper",
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -271,9 +271,17 @@ export declare abstract class Platform {
|
|
|
271
271
|
/** Whether the platform supports unsigned integer columns. */
|
|
272
272
|
supportsUnsigned(): boolean;
|
|
273
273
|
/**
|
|
274
|
-
*
|
|
274
|
+
* Maximum length of identifiers (table, column, index, constraint, …) the platform supports.
|
|
275
|
+
* Names produced by {@link getIndexName} above this limit are hash-truncated. Defaults to
|
|
276
|
+
* `Infinity` (no truncation); SQL platforms override with their engine's limit
|
|
277
|
+
* (PG 63, MySQL/MariaDB 64, MSSQL/Oracle 128).
|
|
275
278
|
*/
|
|
276
|
-
|
|
279
|
+
getMaxIdentifierLength(): number;
|
|
280
|
+
/**
|
|
281
|
+
* Returns the default name of index for the given columns, hash-truncated if it would
|
|
282
|
+
* exceed {@link getMaxIdentifierLength}.
|
|
283
|
+
*/
|
|
284
|
+
getIndexName(tableName: string, columns: string[], type: 'index' | 'unique' | 'foreign' | 'primary' | 'sequence' | 'check'): string;
|
|
277
285
|
/** Returns the default primary key constraint name. */
|
|
278
286
|
getDefaultPrimaryName(tableName: string, columns: string[]): string;
|
|
279
287
|
/** Whether the platform supports custom names for primary key constraints. */
|
package/platforms/Platform.js
CHANGED
|
@@ -618,10 +618,26 @@ export class Platform {
|
|
|
618
618
|
return false;
|
|
619
619
|
}
|
|
620
620
|
/**
|
|
621
|
-
*
|
|
621
|
+
* Maximum length of identifiers (table, column, index, constraint, …) the platform supports.
|
|
622
|
+
* Names produced by {@link getIndexName} above this limit are hash-truncated. Defaults to
|
|
623
|
+
* `Infinity` (no truncation); SQL platforms override with their engine's limit
|
|
624
|
+
* (PG 63, MySQL/MariaDB 64, MSSQL/Oracle 128).
|
|
625
|
+
*/
|
|
626
|
+
getMaxIdentifierLength() {
|
|
627
|
+
return Infinity;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Returns the default name of index for the given columns, hash-truncated if it would
|
|
631
|
+
* exceed {@link getMaxIdentifierLength}.
|
|
622
632
|
*/
|
|
623
633
|
getIndexName(tableName, columns, type) {
|
|
624
|
-
|
|
634
|
+
const indexName = this.namingStrategy.indexName(tableName, columns, type);
|
|
635
|
+
const max = this.getMaxIdentifierLength();
|
|
636
|
+
if (indexName.length > max) {
|
|
637
|
+
const suffix = type === 'primary' ? 'pkey' : type;
|
|
638
|
+
return `${indexName.substring(0, max - 8 - type.length)}_${Utils.hash(indexName, 5)}_${suffix}`;
|
|
639
|
+
}
|
|
640
|
+
return indexName;
|
|
625
641
|
}
|
|
626
642
|
/** Returns the default primary key constraint name. */
|
|
627
643
|
getDefaultPrimaryName(tableName, columns) {
|
package/typings.d.ts
CHANGED
|
@@ -579,19 +579,37 @@ export type SchemaTable = {
|
|
|
579
579
|
export type FormulaColumns<T> = Record<PropertyName<T>, string> & {
|
|
580
580
|
toString(): string;
|
|
581
581
|
};
|
|
582
|
+
/**
|
|
583
|
+
* Column reference for schema callbacks. Behaves like a string (coercible via `toString()`),
|
|
584
|
+
* with arbitrary nested property access for embedded sub-columns (e.g. `cols.address.city`).
|
|
585
|
+
*/
|
|
586
|
+
export type SchemaColumnRef = string & {
|
|
587
|
+
readonly [key: string]: SchemaColumnRef;
|
|
588
|
+
};
|
|
582
589
|
/**
|
|
583
590
|
* Column mapping for schema callbacks (indexes, checks, generated columns).
|
|
584
591
|
* Maps property names to field names. For TPT entities, only includes properties
|
|
585
592
|
* that belong to the current table (not inherited properties from parent tables).
|
|
593
|
+
* Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
|
|
594
|
+
* while coercing to the embedded property's own column name via `toString()` (matches the
|
|
595
|
+
* pre-7712 behaviour, regardless of any custom `prefix`).
|
|
596
|
+
*/
|
|
597
|
+
export type SchemaColumns<T> = Record<PropertyName<T>, SchemaColumnRef>;
|
|
598
|
+
/**
|
|
599
|
+
* Callback for custom index expressions. Receives column mappings, table info, and the index name.
|
|
600
|
+
* The runtime `columns` object includes nested entries for embedded properties (see `SchemaColumnRef`);
|
|
601
|
+
* cast to `SchemaColumns<T>` if you need typed nested access.
|
|
586
602
|
*/
|
|
587
|
-
export type SchemaColumns<T> = Record<PropertyName<T>, string>;
|
|
588
|
-
/** Callback for custom index expressions. Receives column mappings, table info, and the index name. */
|
|
589
603
|
export type IndexCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable, indexName: string) => string | Raw;
|
|
590
604
|
/** Callback for computed (formula) properties. Receives column mappings and table info, returns a SQL expression. */
|
|
591
605
|
export type FormulaCallback<T> = (columns: FormulaColumns<T>, table: FormulaTable) => string | Raw;
|
|
592
606
|
/** Callback for CHECK constraint expressions. Receives column mappings and table info. */
|
|
593
|
-
export type CheckCallback<T> = (columns:
|
|
594
|
-
/**
|
|
607
|
+
export type CheckCallback<T> = (columns: SchemaColumns<T>, table: SchemaTable) => string | Raw;
|
|
608
|
+
/**
|
|
609
|
+
* Callback for generated (computed) column expressions. Receives column mappings and table info.
|
|
610
|
+
* The runtime `columns` object includes nested entries for embedded properties (see `SchemaColumnRef`);
|
|
611
|
+
* cast to `SchemaColumns<T>` if you need typed nested access.
|
|
612
|
+
*/
|
|
595
613
|
export type GeneratedColumnCallback<T> = (columns: Record<PropertyName<T>, string>, table: SchemaTable) => string | Raw;
|
|
596
614
|
/** Definition of a CHECK constraint on a table or property. */
|
|
597
615
|
export interface CheckConstraint<T = any> {
|
|
@@ -728,8 +746,12 @@ export declare class EntityMetadata<Entity = any, Class extends EntityCtor<Entit
|
|
|
728
746
|
/**
|
|
729
747
|
* Creates a column mapping for schema callbacks (indexes, checks, generated columns).
|
|
730
748
|
* For TPT entities, only includes properties that belong to the current table (ownProps).
|
|
749
|
+
* Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
|
|
750
|
+
* while still coercing to the embedded column prefix when used as a string (GH #7712).
|
|
731
751
|
*/
|
|
732
752
|
createSchemaColumnMappingObject(): SchemaColumns<Entity>;
|
|
753
|
+
/** @internal Recursively builds a column mapping for an embedded property's sub-columns. */
|
|
754
|
+
private static buildEmbeddedColumnMapping;
|
|
733
755
|
get tableName(): string;
|
|
734
756
|
set tableName(name: string);
|
|
735
757
|
get uniqueName(): string;
|
package/typings.js
CHANGED
|
@@ -116,16 +116,37 @@ export class EntityMetadata {
|
|
|
116
116
|
/**
|
|
117
117
|
* Creates a column mapping for schema callbacks (indexes, checks, generated columns).
|
|
118
118
|
* For TPT entities, only includes properties that belong to the current table (ownProps).
|
|
119
|
+
* Embedded properties expose their sub-columns via nested access (e.g. `cols.address.city`),
|
|
120
|
+
* while still coercing to the embedded column prefix when used as a string (GH #7712).
|
|
119
121
|
*/
|
|
120
122
|
createSchemaColumnMappingObject() {
|
|
121
123
|
// For TPT entities, only include properties that belong to this entity's table
|
|
122
124
|
const props = this.inheritanceType === 'tpt' && this.ownProps ? this.ownProps : Object.values(this.properties);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
const result = {};
|
|
126
|
+
for (const prop of props) {
|
|
127
|
+
if (!prop.fieldNames) {
|
|
128
|
+
continue;
|
|
126
129
|
}
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
if (prop.kind === ReferenceKind.EMBEDDED && prop.embeddedProps) {
|
|
131
|
+
result[prop.name] = EntityMetadata.buildEmbeddedColumnMapping(prop);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
result[prop.name] = prop.fieldNames[0];
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
/** @internal Recursively builds a column mapping for an embedded property's sub-columns. */
|
|
139
|
+
static buildEmbeddedColumnMapping(embeddedProp) {
|
|
140
|
+
const result = {};
|
|
141
|
+
for (const [name, sub] of Object.entries(embeddedProp.embeddedProps)) {
|
|
142
|
+
result[name] =
|
|
143
|
+
sub.kind === ReferenceKind.EMBEDDED && sub.embeddedProps
|
|
144
|
+
? EntityMetadata.buildEmbeddedColumnMapping(sub)
|
|
145
|
+
: sub.fieldNames[0];
|
|
146
|
+
}
|
|
147
|
+
const prefix = embeddedProp.fieldNames[0];
|
|
148
|
+
Object.defineProperty(result, 'toString', { value: () => prefix, enumerable: false });
|
|
149
|
+
return result;
|
|
129
150
|
}
|
|
130
151
|
get tableName() {
|
|
131
152
|
return this.collection;
|
|
@@ -176,9 +197,10 @@ export class EntityMetadata {
|
|
|
176
197
|
// Virtual entities evaluate expressions at query time, view entities create actual database views.
|
|
177
198
|
this.virtual = !!this.expression && !this.view;
|
|
178
199
|
if (config) {
|
|
200
|
+
const platform = config.getPlatform();
|
|
179
201
|
for (const prop of this.props) {
|
|
180
202
|
if (prop.enum && !prop.nativeEnumName && prop.items?.every(item => typeof item === 'string')) {
|
|
181
|
-
const name =
|
|
203
|
+
const name = platform.getIndexName(this.tableName, prop.fieldNames, 'check');
|
|
182
204
|
const exists = this.checks.findIndex(check => check.name === name);
|
|
183
205
|
if (exists !== -1) {
|
|
184
206
|
this.checks.splice(exists, 1);
|
|
@@ -186,9 +208,7 @@ export class EntityMetadata {
|
|
|
186
208
|
this.checks.push({
|
|
187
209
|
name,
|
|
188
210
|
property: prop.name,
|
|
189
|
-
expression:
|
|
190
|
-
.getPlatform()
|
|
191
|
-
.getEnumCheckConstraintExpression(prop.fieldNames[0], prop.items),
|
|
211
|
+
expression: platform.getEnumCheckConstraintExpression(prop.fieldNames[0], prop.items),
|
|
192
212
|
});
|
|
193
213
|
}
|
|
194
214
|
}
|
|
@@ -463,7 +463,7 @@ export class UnitOfWork {
|
|
|
463
463
|
if (options.lockMode === LockMode.OPTIMISTIC) {
|
|
464
464
|
await this.lockOptimistic(entity, meta, options.lockVersion);
|
|
465
465
|
}
|
|
466
|
-
else if (options.lockMode != null) {
|
|
466
|
+
else if (options.lockMode != null && options.lockMode !== LockMode.NONE) {
|
|
467
467
|
await this.lockPessimistic(entity, options);
|
|
468
468
|
}
|
|
469
469
|
}
|
package/utils/Utils.js
CHANGED
|
@@ -141,7 +141,7 @@ export function parseJsonSafe(value) {
|
|
|
141
141
|
/** Collection of general-purpose utility methods used throughout the ORM. */
|
|
142
142
|
export class Utils {
|
|
143
143
|
static PK_SEPARATOR = '~~~';
|
|
144
|
-
static #ORM_VERSION = '7.0.16-dev.
|
|
144
|
+
static #ORM_VERSION = '7.0.16-dev.11';
|
|
145
145
|
/**
|
|
146
146
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
147
147
|
*/
|