@mikro-orm/sql 7.0.0-dev.114 → 7.0.0-dev.115

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.
@@ -15,23 +15,23 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
15
15
  getPlatform(): Platform;
16
16
  createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
17
17
  private createQueryBuilderFromOptions;
18
- find<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: string, where: ObjectQuery<T>, options?: FindOptions<T, P, F, E>): Promise<EntityData<T>[]>;
19
- findOne<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: string, where: ObjectQuery<T>, options?: FindOneOptions<T, P, F, E>): Promise<EntityData<T> | null>;
18
+ find<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: EntityName<T>, where: ObjectQuery<T>, options?: FindOptions<T, P, F, E>): Promise<EntityData<T>[]>;
19
+ findOne<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: EntityName<T>, where: ObjectQuery<T>, options?: FindOneOptions<T, P, F, E>): Promise<EntityData<T> | null>;
20
20
  protected hasToManyJoins<T extends object>(hint: PopulateOptions<T>, meta: EntityMetadata<T>): boolean;
21
- findVirtual<T extends object>(entityName: string, where: ObjectQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
22
- countVirtual<T extends object>(entityName: string, where: ObjectQuery<T>, options: CountOptions<T, any>): Promise<number>;
23
- protected findFromVirtual<T extends object>(entityName: string, where: ObjectQuery<T>, options: FindOptions<T, any> | CountOptions<T, any>, type: QueryType): Promise<EntityData<T>[] | number>;
21
+ findVirtual<T extends object>(entityName: EntityName<T>, where: ObjectQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
22
+ countVirtual<T extends object>(entityName: EntityName<T>, where: ObjectQuery<T>, options: CountOptions<T, any>): Promise<number>;
23
+ protected findFromVirtual<T extends object>(entityName: EntityName<T>, where: ObjectQuery<T>, options: FindOptions<T, any> | CountOptions<T, any>, type: QueryType): Promise<EntityData<T>[] | number>;
24
24
  protected streamFromVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: StreamOptions<T, any>): AsyncIterableIterator<EntityData<T>>;
25
25
  protected wrapVirtualExpressionInSubquery<T extends object>(meta: EntityMetadata<T>, expression: string, where: FilterQuery<T>, options: FindOptions<T, any>, type: QueryType): Promise<T[] | number>;
26
26
  protected wrapVirtualExpressionInSubqueryStream<T extends object>(meta: EntityMetadata<T>, expression: string, where: FilterQuery<T>, options: FindOptions<T, any, any, any>, type: QueryType.SELECT): AsyncIterableIterator<T>;
27
27
  mapResult<T extends object>(result: EntityData<T>, meta: EntityMetadata<T>, populate?: PopulateOptions<T>[], qb?: QueryBuilder<T, any, any, any>, map?: Dictionary): EntityData<T> | null;
28
28
  private mapJoinedProps;
29
- count<T extends object>(entityName: string, where: any, options?: CountOptions<T>): Promise<number>;
30
- nativeInsert<T extends object>(entityName: string, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
31
- nativeInsertMany<T extends object>(entityName: string, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>, transform?: (sql: string) => string): Promise<QueryResult<T>>;
32
- nativeUpdate<T extends object>(entityName: string, where: FilterQuery<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T> & UpsertOptions<T>): Promise<QueryResult<T>>;
33
- nativeUpdateMany<T extends object>(entityName: string, where: FilterQuery<T>[], data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T> & UpsertManyOptions<T>): Promise<QueryResult<T>>;
34
- nativeDelete<T extends object>(entityName: string, where: FilterQuery<T> | string | any, options?: DeleteOptions<T>): Promise<QueryResult<T>>;
29
+ count<T extends object>(entityName: EntityName<T>, where: any, options?: CountOptions<T>): Promise<number>;
30
+ nativeInsert<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
31
+ nativeInsertMany<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>, transform?: (sql: string) => string): Promise<QueryResult<T>>;
32
+ nativeUpdate<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T> & UpsertOptions<T>): Promise<QueryResult<T>>;
33
+ nativeUpdateMany<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>[], data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T> & UpsertManyOptions<T>): Promise<QueryResult<T>>;
34
+ nativeDelete<T extends object>(entityName: EntityName<T>, where: FilterQuery<T> | string | any, options?: DeleteOptions<T>): Promise<QueryResult<T>>;
35
35
  /**
36
36
  * Fast comparison for collection snapshots that are represented by PK arrays.
37
37
  * Compares scalars via `===` and fallbacks to Utils.equals()` for more complex types like Buffer.
@@ -69,8 +69,8 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
69
69
  ctx?: Transaction;
70
70
  connectionType?: ConnectionType;
71
71
  }): ConnectionType;
72
- protected extractManyToMany<T>(entityName: string, data: EntityDictionary<T>): EntityData<T>;
73
- protected processManyToMany<T extends object>(meta: EntityMetadata<T> | undefined, pks: Primary<T>[], collections: EntityData<T>, clear: boolean, options?: DriverMethodOptions): Promise<void>;
72
+ protected extractManyToMany<T>(meta: EntityMetadata<T>, data: EntityDictionary<T>): EntityData<T>;
73
+ protected processManyToMany<T extends object>(meta: EntityMetadata<T>, pks: Primary<T>[], collections: EntityData<T>, clear: boolean, options?: DriverMethodOptions): Promise<void>;
74
74
  lockPessimistic<T extends object>(entity: T, options: LockOptions): Promise<void>;
75
75
  protected buildPopulateWhere<T extends object>(meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'populateWhere'>): ObjectQuery<T>;
76
76
  protected buildOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>): QueryOrderMap<T>[];
@@ -25,7 +25,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
25
25
  const connectionType = this.resolveConnectionType({ ctx: options.ctx, connectionType: options.connectionType });
26
26
  const populate = this.autoJoinOneToOneOwner(meta, options.populate, options.fields);
27
27
  const joinedProps = this.joinedProps(meta, populate, options);
28
- const qb = this.createQueryBuilder(meta.className, options.ctx, connectionType, false, options.logging, undefined, options.em);
28
+ const qb = this.createQueryBuilder(meta.class, options.ctx, connectionType, false, options.logging, undefined, options.em);
29
29
  const fields = this.buildFields(meta, populate, joinedProps, qb, qb.alias, options);
30
30
  const orderBy = this.buildOrderBy(qb, meta, populate, options);
31
31
  const populateWhere = this.buildPopulateWhere(meta, joinedProps, options);
@@ -66,8 +66,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
66
66
  }
67
67
  async find(entityName, where, options = {}) {
68
68
  options = { populate: [], orderBy: [], ...options };
69
- const meta = this.metadata.find(entityName);
70
- if (meta?.virtual) {
69
+ const meta = this.metadata.get(entityName);
70
+ if (meta.virtual) {
71
71
  return this.findVirtual(entityName, where, options);
72
72
  }
73
73
  const qb = await this.createQueryBuilderFromOptions(meta, where, options);
@@ -226,7 +226,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
226
226
  return;
227
227
  }
228
228
  const pivotRefJoin = prop.kind === ReferenceKind.MANY_TO_MANY && ref;
229
- const meta2 = this.metadata.find(prop.type);
229
+ const meta2 = prop.targetMeta;
230
230
  let path = parentJoinPath ? `${parentJoinPath}.${prop.name}` : `${meta.name}.${prop.name}`;
231
231
  if (!parentJoinPath) {
232
232
  path = '[populate]' + path;
@@ -322,10 +322,10 @@ export class AbstractSqlDriver extends DatabaseDriver {
322
322
  if (prop.kind === ReferenceKind.EMBEDDED && (prop.object || meta.embeddable)) {
323
323
  const item = parseJsonSafe(relationPojo[prop.name]);
324
324
  if (Array.isArray(item)) {
325
- relationPojo[prop.name] = item.map(row => row == null ? row : this.comparator.mapResult(prop.type, row));
325
+ relationPojo[prop.name] = item.map(row => row == null ? row : this.comparator.mapResult(prop.targetMeta, row));
326
326
  }
327
327
  else {
328
- relationPojo[prop.name] = item == null ? item : this.comparator.mapResult(prop.type, item);
328
+ relationPojo[prop.name] = item == null ? item : this.comparator.mapResult(prop.targetMeta, item);
329
329
  }
330
330
  }
331
331
  }
@@ -382,19 +382,18 @@ export class AbstractSqlDriver extends DatabaseDriver {
382
382
  }
383
383
  async nativeInsert(entityName, data, options = {}) {
384
384
  options.convertCustomTypes ??= true;
385
- const meta = this.metadata.find(entityName);
386
- const collections = this.extractManyToMany(entityName, data);
387
- const pks = meta?.primaryKeys ?? [this.config.getNamingStrategy().referenceColumnName()];
385
+ const meta = this.metadata.get(entityName);
386
+ const collections = this.extractManyToMany(meta, data);
388
387
  const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes, options.loggerContext).withSchema(this.getSchemaName(meta, options));
389
388
  const res = await this.rethrow(qb.insert(data).execute('run', false));
390
389
  res.row = res.row || {};
391
390
  let pk;
392
- if (pks.length > 1) { // owner has composite pk
393
- pk = Utils.getPrimaryKeyCond(data, pks);
391
+ if (meta.primaryKeys.length > 1) { // owner has composite pk
392
+ pk = Utils.getPrimaryKeyCond(data, meta.primaryKeys);
394
393
  }
395
394
  else {
396
395
  /* v8 ignore next */
397
- res.insertId = data[pks[0]] ?? res.insertId ?? res.row[pks[0]];
396
+ res.insertId = data[meta.primaryKeys[0]] ?? res.insertId ?? res.row[meta.primaryKeys[0]];
398
397
  pk = [res.insertId];
399
398
  }
400
399
  await this.processManyToMany(meta, pk, collections, false, options);
@@ -403,23 +402,22 @@ export class AbstractSqlDriver extends DatabaseDriver {
403
402
  async nativeInsertMany(entityName, data, options = {}, transform) {
404
403
  options.processCollections ??= true;
405
404
  options.convertCustomTypes ??= true;
406
- const meta = this.metadata.find(entityName)?.root;
407
- const collections = options.processCollections ? data.map(d => this.extractManyToMany(entityName, d)) : [];
408
- const pks = this.getPrimaryKeyFields(entityName);
405
+ const meta = this.metadata.get(entityName).root;
406
+ const collections = options.processCollections ? data.map(d => this.extractManyToMany(meta, d)) : [];
407
+ const pks = this.getPrimaryKeyFields(meta);
409
408
  const set = new Set();
410
409
  data.forEach(row => Utils.keys(row).forEach(k => set.add(k)));
411
- const props = [...set].map(name => meta?.properties[name] ?? { name, fieldNames: [name] });
410
+ const props = [...set].map(name => meta.properties[name] ?? { name, fieldNames: [name] });
412
411
  let fields = Utils.flatten(props.map(prop => prop.fieldNames));
413
412
  const duplicates = Utils.findDuplicates(fields);
414
413
  const params = [];
415
414
  if (duplicates.length) {
416
415
  fields = Utils.unique(fields);
417
416
  }
418
- /* v8 ignore next */
419
- const tableName = meta ? this.getTableName(meta, options) : this.platform.quoteIdentifier(entityName);
417
+ const tableName = this.getTableName(meta, options);
420
418
  let sql = `insert into ${tableName} `;
421
419
  sql += fields.length > 0 ? '(' + fields.map(k => this.platform.quoteIdentifier(k)).join(', ') + ')' : `(${this.platform.quoteIdentifier(pks[0])})`;
422
- if (meta && this.platform.usesOutputStatement()) {
420
+ if (this.platform.usesOutputStatement()) {
423
421
  const returningProps = meta.props
424
422
  .filter(prop => prop.persist !== false && prop.defaultRaw || prop.autoincrement || prop.generated)
425
423
  .filter(prop => !(prop.name in data[0]) || isRaw(data[0][prop.name]));
@@ -536,13 +534,13 @@ export class AbstractSqlDriver extends DatabaseDriver {
536
534
  }
537
535
  async nativeUpdate(entityName, where, data, options = {}) {
538
536
  options.convertCustomTypes ??= true;
539
- const meta = this.metadata.find(entityName);
540
- const pks = this.getPrimaryKeyFields(entityName);
541
- const collections = this.extractManyToMany(entityName, data);
537
+ const meta = this.metadata.get(entityName);
538
+ const pks = this.getPrimaryKeyFields(meta);
539
+ const collections = this.extractManyToMany(meta, data);
542
540
  let res = { affectedRows: 0, insertId: 0, row: {} };
543
541
  if (Utils.isPrimaryKey(where) && pks.length === 1) {
544
542
  /* v8 ignore next */
545
- where = { [meta?.primaryKeys[0] ?? pks[0]]: where };
543
+ where = { [meta.primaryKeys[0] ?? pks[0]]: where };
546
544
  }
547
545
  if (Utils.hasObjectKeys(data)) {
548
546
  const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes, options.loggerContext)
@@ -566,7 +564,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
566
564
  qb.update(data).where(where);
567
565
  // reload generated columns and version fields
568
566
  const returning = [];
569
- meta?.props
567
+ meta.props
570
568
  .filter(prop => (prop.generated && !prop.primary) || prop.version)
571
569
  .forEach(prop => returning.push(prop.name));
572
570
  qb.returning(returning);
@@ -598,7 +596,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
598
596
  }
599
597
  return this.rethrow(qb.execute('run', false));
600
598
  }
601
- const collections = options.processCollections ? data.map(d => this.extractManyToMany(entityName, d)) : [];
599
+ const collections = options.processCollections ? data.map(d => this.extractManyToMany(meta, d)) : [];
602
600
  const keys = new Set();
603
601
  const fields = new Set();
604
602
  const returning = new Set();
@@ -611,7 +609,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
611
609
  }
612
610
  }
613
611
  // reload generated columns and version fields
614
- meta?.props
612
+ meta.props
615
613
  .filter(prop => prop.generated || prop.version || prop.primary)
616
614
  .forEach(prop => returning.add(prop.name));
617
615
  const pkCond = Utils.flatten(meta.primaryKeys.map(pk => meta.properties[pk].fieldNames)).map(pk => `${this.platform.quoteIdentifier(pk)} = ?`).join(' and ');
@@ -704,8 +702,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
704
702
  return res;
705
703
  }
706
704
  async nativeDelete(entityName, where, options = {}) {
707
- const meta = this.metadata.find(entityName);
708
- const pks = this.getPrimaryKeyFields(entityName);
705
+ const meta = this.metadata.get(entityName);
706
+ const pks = this.getPrimaryKeyFields(meta);
709
707
  if (Utils.isPrimaryKey(where) && pks.length === 1) {
710
708
  where = { [pks[0]]: where };
711
709
  }
@@ -758,7 +756,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
758
756
  }
759
757
  if (coll.property.kind === ReferenceKind.ONE_TO_MANY) {
760
758
  const cols = coll.property.referencedColumnNames;
761
- const qb = this.createQueryBuilder(coll.property.type, options?.ctx, 'write')
759
+ const qb = this.createQueryBuilder(coll.property.targetMeta.class, options?.ctx, 'write')
762
760
  .withSchema(this.getSchemaName(meta, options));
763
761
  if (coll.getSnapshot() === undefined) {
764
762
  if (coll.property.orphanRemoval) {
@@ -779,7 +777,6 @@ export class AbstractSqlDriver extends DatabaseDriver {
779
777
  await this.rethrow(query.execute());
780
778
  continue;
781
779
  }
782
- /* v8 ignore next */
783
780
  const pivotMeta = this.metadata.find(coll.property.pivotEntity);
784
781
  let schema = pivotMeta.schema;
785
782
  if (schema === '*') {
@@ -807,10 +804,10 @@ export class AbstractSqlDriver extends DatabaseDriver {
807
804
  if (owners.length === 0) {
808
805
  return {};
809
806
  }
810
- const pivotMeta = this.metadata.find(prop.pivotEntity);
807
+ const pivotMeta = this.metadata.get(prop.pivotEntity);
811
808
  const pivotProp1 = pivotMeta.relations[prop.owner ? 1 : 0];
812
809
  const pivotProp2 = pivotMeta.relations[prop.owner ? 0 : 1];
813
- const ownerMeta = this.metadata.find(pivotProp2.type);
810
+ const ownerMeta = pivotProp2.targetMeta;
814
811
  const cond = {
815
812
  [pivotProp2.name]: { $in: ownerMeta.compositePK ? owners : owners.map(o => o[0]) },
816
813
  };
@@ -825,7 +822,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
825
822
  const fields = pivotJoin
826
823
  ? [pivotProp1.name, pivotProp2.name]
827
824
  : [pivotProp1.name, pivotProp2.name, ...childFields];
828
- const res = await this.find(pivotMeta.className, where, {
825
+ const res = await this.find(pivotMeta.class, where, {
829
826
  ctx,
830
827
  ...options,
831
828
  fields,
@@ -870,8 +867,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
870
867
  }
871
868
  async *stream(entityName, where, options) {
872
869
  options = { populate: [], orderBy: [], ...options };
873
- const meta = this.metadata.find(entityName);
874
- if (meta?.virtual) {
870
+ const meta = this.metadata.get(entityName);
871
+ if (meta.virtual) {
875
872
  yield* this.streamFromVirtual(entityName, where, options);
876
873
  return;
877
874
  }
@@ -1008,7 +1005,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
1008
1005
  if (ref && !hint.filter && (prop.kind === ReferenceKind.MANY_TO_ONE || (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner))) {
1009
1006
  continue;
1010
1007
  }
1011
- const meta2 = this.metadata.find(prop.type);
1008
+ const meta2 = prop.targetMeta;
1012
1009
  const pivotRefJoin = prop.kind === ReferenceKind.MANY_TO_MANY && ref;
1013
1010
  const tableAlias = qb.getNextAlias(prop.name);
1014
1011
  const field = `${options.parentTableAlias}.${prop.name}`;
@@ -1119,26 +1116,20 @@ export class AbstractSqlDriver extends DatabaseDriver {
1119
1116
  }
1120
1117
  return 'write';
1121
1118
  }
1122
- extractManyToMany(entityName, data) {
1123
- if (!this.metadata.has(entityName)) {
1124
- return {};
1125
- }
1119
+ extractManyToMany(meta, data) {
1126
1120
  const ret = {};
1127
- this.metadata.find(entityName).relations.forEach(prop => {
1121
+ for (const prop of meta.relations) {
1128
1122
  if (prop.kind === ReferenceKind.MANY_TO_MANY && data[prop.name]) {
1129
1123
  ret[prop.name] = data[prop.name].map((item) => Utils.asArray(item));
1130
1124
  delete data[prop.name];
1131
1125
  }
1132
- });
1126
+ }
1133
1127
  return ret;
1134
1128
  }
1135
1129
  async processManyToMany(meta, pks, collections, clear, options) {
1136
- if (!meta) {
1137
- return;
1138
- }
1139
1130
  for (const prop of meta.relations) {
1140
1131
  if (collections[prop.name]) {
1141
- const pivotMeta = this.metadata.find(prop.pivotEntity);
1132
+ const pivotMeta = this.metadata.get(prop.pivotEntity);
1142
1133
  const persister = new PivotCollectionPersister(pivotMeta, this, options?.ctx, options?.schema, options?.loggerContext);
1143
1134
  persister.enqueueUpdate(prop, collections[prop.name], clear, pks);
1144
1135
  await this.rethrow(persister.execute());
@@ -1147,7 +1138,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
1147
1138
  }
1148
1139
  async lockPessimistic(entity, options) {
1149
1140
  const meta = helper(entity).__meta;
1150
- const qb = this.createQueryBuilder(entity.constructor.name, options.ctx, undefined, undefined, options.logging).withSchema(options.schema ?? meta.schema);
1141
+ const qb = this.createQueryBuilder(meta.class, options.ctx, undefined, undefined, options.logging).withSchema(options.schema ?? meta.schema);
1151
1142
  const cond = Utils.getPrimaryKeyCond(entity, meta.primaryKeys);
1152
1143
  qb.select(raw('1')).where(cond).setLockMode(options.lockMode, options.lockTableAliases);
1153
1144
  await this.rethrow(qb.execute());
@@ -1205,7 +1196,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
1205
1196
  throw new Error(`Trying to order by not existing property ${meta.className}.${field}`);
1206
1197
  }
1207
1198
  let path = parentPath;
1208
- const meta2 = this.metadata.find(prop.type);
1199
+ const meta2 = prop.targetMeta;
1209
1200
  if (prop.kind !== ReferenceKind.SCALAR && (![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) || !prop.owner || Utils.isPlainObject(childOrder))) {
1210
1201
  path += `.${field}`;
1211
1202
  }
@@ -1254,7 +1245,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
1254
1245
  }
1255
1246
  const join = qb.getJoinForPath(path, { matchPopulateJoins: true });
1256
1247
  const propAlias = qb.getAliasForJoinPath(join ?? path, { matchPopulateJoins: true });
1257
- const meta2 = this.metadata.find(prop.type);
1248
+ const meta2 = prop.targetMeta;
1258
1249
  if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.fixedOrder && join) {
1259
1250
  const alias = ref ? propAlias : join.ownerAlias;
1260
1251
  orderBy.push({ [`${alias}.${prop.fixedOrderColumn}`]: QueryOrder.ASC });
@@ -1338,7 +1329,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
1338
1329
  const prop = QueryHelper.findProperty(rootPropName, {
1339
1330
  metadata: this.metadata,
1340
1331
  platform: this.platform,
1341
- entityName: meta.className,
1332
+ entityName: meta.class,
1342
1333
  where: {},
1343
1334
  aliasMap: qb.getAliasMap(),
1344
1335
  });
@@ -120,7 +120,7 @@ export class PivotCollectionPersister {
120
120
  for (const item of chunk) {
121
121
  cond.$or.push(item.getCondition());
122
122
  }
123
- await this.driver.nativeDelete(this.meta.className, cond, {
123
+ await this.driver.nativeDelete(this.meta.class, cond, {
124
124
  ctx: this.ctx,
125
125
  schema: this.schema,
126
126
  loggerContext: this.loggerContext,
@@ -131,7 +131,7 @@ export class PivotCollectionPersister {
131
131
  const filtered = this.collectStatements(this.inserts);
132
132
  for (let i = 0; i < filtered.length; i += this.batchSize) {
133
133
  const chunk = filtered.slice(i, i + this.batchSize);
134
- await this.driver.nativeInsertMany(this.meta.className, chunk, {
134
+ await this.driver.nativeInsertMany(this.meta.class, chunk, {
135
135
  ctx: this.ctx,
136
136
  schema: this.schema,
137
137
  convertCustomTypes: false,
@@ -144,7 +144,7 @@ export class PivotCollectionPersister {
144
144
  const filtered = this.collectStatements(this.upserts);
145
145
  for (let i = 0; i < filtered.length; i += this.batchSize) {
146
146
  const chunk = filtered.slice(i, i + this.batchSize);
147
- await this.driver.nativeUpdateMany(this.meta.className, [], chunk, {
147
+ await this.driver.nativeUpdateMany(this.meta.class, [], chunk, {
148
148
  ctx: this.ctx,
149
149
  schema: this.schema,
150
150
  convertCustomTypes: false,
@@ -27,7 +27,7 @@ export declare class SqlEntityManager<Driver extends AbstractSqlDriver = Abstrac
27
27
  getKysely<TDB = undefined, TOptions extends GetKyselyOptions = GetKyselyOptions>(options?: TOptions): Kysely<TDB extends undefined ? InferKyselyDB<EntitiesFromManager<this>, TOptions> : TDB>;
28
28
  execute<T extends QueryResult | EntityData<AnyEntity> | EntityData<AnyEntity>[] = EntityData<AnyEntity>[]>(query: string | NativeQueryBuilder | RawQueryFragment, params?: any[], method?: 'all' | 'get' | 'run', loggerContext?: LoggingOptions): Promise<T>;
29
29
  getRepository<T extends object, U extends EntityRepository<T> = SqlEntityRepository<T>>(entityName: EntityName<T>): GetRepository<T, U>;
30
- protected applyDiscriminatorCondition<Entity extends object>(entityName: string, where: FilterQuery<Entity>): FilterQuery<Entity>;
30
+ protected applyDiscriminatorCondition<Entity extends object>(entityName: EntityName<Entity>, where: FilterQuery<Entity>): FilterQuery<Entity>;
31
31
  }
32
32
  type EntitiesFromManager<TEntityManager extends EntityManager<any>> = NonNullable<TEntityManager['~entities']> extends any[] ? (Extract<NonNullable<TEntityManager['~entities']>[number], EntitySchemaWithMeta>) : never;
33
33
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/sql",
3
- "version": "7.0.0-dev.114",
3
+ "version": "7.0.0-dev.115",
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
  "type": "module",
6
6
  "exports": {
@@ -56,6 +56,6 @@
56
56
  "@mikro-orm/core": "^6.6.2"
57
57
  },
58
58
  "peerDependencies": {
59
- "@mikro-orm/core": "7.0.0-dev.114"
59
+ "@mikro-orm/core": "7.0.0-dev.115"
60
60
  }
61
61
  }
@@ -706,7 +706,7 @@ export class MikroTransformer extends OperationNodeTransformer {
706
706
  * Find entity metadata by table name or entity name
707
707
  */
708
708
  findEntityMetadata(name) {
709
- const byEntity = this.metadata.find(name);
709
+ const byEntity = this.metadata.getByClassName(name, false);
710
710
  if (byEntity) {
711
711
  return byEntity;
712
712
  }
@@ -1,4 +1,4 @@
1
- import { type EntityKey, type EntityProperty, type MetadataStorage, type RawQueryFragmentSymbol } from '@mikro-orm/core';
1
+ import { type EntityKey, type EntityProperty, type MetadataStorage, type RawQueryFragmentSymbol, type EntityName } from '@mikro-orm/core';
2
2
  import type { ICriteriaNode, ICriteriaNodeProcessOptions, IQueryBuilder } from '../typings.js';
3
3
  /**
4
4
  * Helper for working with deeply nested where/orderBy/having criteria. Uses composite pattern to build tree from the payload.
@@ -7,14 +7,14 @@ import type { ICriteriaNode, ICriteriaNodeProcessOptions, IQueryBuilder } from '
7
7
  */
8
8
  export declare class CriteriaNode<T extends object> implements ICriteriaNode<T> {
9
9
  protected readonly metadata: MetadataStorage;
10
- readonly entityName: string;
10
+ readonly entityName: EntityName<T>;
11
11
  readonly parent?: ICriteriaNode<T> | undefined;
12
12
  readonly key?: (EntityKey<T> | RawQueryFragmentSymbol) | undefined;
13
13
  readonly strict: boolean;
14
14
  payload: any;
15
15
  prop?: EntityProperty<T>;
16
16
  index?: number;
17
- constructor(metadata: MetadataStorage, entityName: string, parent?: ICriteriaNode<T> | undefined, key?: (EntityKey<T> | RawQueryFragmentSymbol) | undefined, validate?: boolean, strict?: boolean);
17
+ constructor(metadata: MetadataStorage, entityName: EntityName<T>, parent?: ICriteriaNode<T> | undefined, key?: (EntityKey<T> | RawQueryFragmentSymbol) | undefined, validate?: boolean, strict?: boolean);
18
18
  process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
19
19
  unwrap(): any;
20
20
  shouldInline(payload: any): boolean;
@@ -30,7 +30,7 @@ export class CriteriaNode {
30
30
  const isProp = this.prop || meta.props.find(prop => (prop.fieldNames || []).includes(k));
31
31
  // do not validate if the key is prefixed or type casted (e.g. `k::text`)
32
32
  if (validate && !isProp && !k.includes('.') && !k.includes('::') && !Utils.isOperator(k)) {
33
- throw new Error(`Trying to query by not existing property ${entityName}.${k}`);
33
+ throw new Error(`Trying to query by not existing property ${Utils.className(entityName)}.${k}`);
34
34
  }
35
35
  }
36
36
  }
@@ -79,7 +79,7 @@ export class CriteriaNode {
79
79
  getPath(addIndex = false) {
80
80
  // use index on parent only if we are processing to-many relation
81
81
  const addParentIndex = this.prop && [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(this.prop.kind);
82
- const parentPath = this.parent?.getPath(addParentIndex) ?? this.entityName;
82
+ const parentPath = this.parent?.getPath(addParentIndex) ?? Utils.className(this.entityName);
83
83
  const index = addIndex && this.index != null ? `[${this.index}]` : '';
84
84
  // ignore group operators to allow easier mapping (e.g. for orderBy)
85
85
  const key = this.key && !RawQueryFragment.isKnownFragmentSymbol(this.key) && !['$and', '$or', '$not'].includes(this.key) ? '.' + this.key : '';
@@ -109,6 +109,7 @@ export class CriteriaNode {
109
109
  return this.strict;
110
110
  }
111
111
  /** @ignore */
112
+ /* v8 ignore next */
112
113
  [Symbol.for('nodejs.util.inspect.custom')]() {
113
114
  const o = {};
114
115
  ['entityName', 'key', 'index', 'payload']
@@ -1,12 +1,12 @@
1
- import { type Dictionary, type EntityKey, type EntityMetadata, type MetadataStorage, type RawQueryFragmentSymbol } from '@mikro-orm/core';
1
+ import { type Dictionary, type EntityKey, type EntityMetadata, type EntityName, type MetadataStorage, type RawQueryFragmentSymbol } from '@mikro-orm/core';
2
2
  import type { ICriteriaNode } from '../typings.js';
3
3
  /**
4
4
  * @internal
5
5
  */
6
6
  export declare class CriteriaNodeFactory {
7
- static createNode<T extends object>(metadata: MetadataStorage, entityName: string, payload: any, parent?: ICriteriaNode<T>, key?: EntityKey<T> | RawQueryFragmentSymbol): ICriteriaNode<T>;
8
- static createScalarNode<T extends object>(metadata: MetadataStorage, entityName: string, payload: any, parent?: ICriteriaNode<T>, key?: EntityKey<T> | RawQueryFragmentSymbol): ICriteriaNode<T>;
9
- static createArrayNode<T extends object>(metadata: MetadataStorage, entityName: string, payload: any[], parent?: ICriteriaNode<T>, key?: EntityKey<T>): ICriteriaNode<T>;
10
- static createObjectNode<T extends object>(metadata: MetadataStorage, entityName: string, payload: Dictionary, parent?: ICriteriaNode<T>, key?: EntityKey<T>): ICriteriaNode<T>;
11
- static createObjectItemNode<T extends object>(metadata: MetadataStorage, entityName: string, node: ICriteriaNode<T>, payload: Dictionary, key: EntityKey<T> | RawQueryFragmentSymbol, meta?: EntityMetadata<T>): ICriteriaNode<T>;
7
+ static createNode<T extends object>(metadata: MetadataStorage, entityName: EntityName<T>, payload: any, parent?: ICriteriaNode<T>, key?: EntityKey<T> | RawQueryFragmentSymbol): ICriteriaNode<T>;
8
+ static createScalarNode<T extends object>(metadata: MetadataStorage, entityName: EntityName<T>, payload: any, parent?: ICriteriaNode<T>, key?: EntityKey<T> | RawQueryFragmentSymbol): ICriteriaNode<T>;
9
+ static createArrayNode<T extends object>(metadata: MetadataStorage, entityName: EntityName<T>, payload: any[], parent?: ICriteriaNode<T>, key?: EntityKey<T>): ICriteriaNode<T>;
10
+ static createObjectNode<T extends object>(metadata: MetadataStorage, entityName: EntityName<T>, payload: Dictionary, parent?: ICriteriaNode<T>, key?: EntityKey<T>): ICriteriaNode<T>;
11
+ static createObjectItemNode<T extends object>(metadata: MetadataStorage, entityName: EntityName<T>, node: ICriteriaNode<T>, payload: Dictionary, key: EntityKey<T> | RawQueryFragmentSymbol, meta?: EntityMetadata<T>): ICriteriaNode<T>;
12
12
  }
@@ -46,7 +46,7 @@ export class CriteriaNodeFactory {
46
46
  static createObjectItemNode(metadata, entityName, node, payload, key, meta) {
47
47
  const rawField = RawQueryFragment.isKnownFragmentSymbol(key);
48
48
  const prop = rawField ? null : meta?.properties[key];
49
- const childEntity = prop && prop.kind !== ReferenceKind.SCALAR ? prop.type : entityName;
49
+ const childEntity = prop && prop.kind !== ReferenceKind.SCALAR ? prop.targetMeta.class : entityName;
50
50
  const isNotEmbedded = rawField || prop?.kind !== ReferenceKind.EMBEDDED;
51
51
  const val = payload[key];
52
52
  if (isNotEmbedded && prop?.customType instanceof JsonType) {
@@ -37,8 +37,8 @@ export class ObjectCriteriaNode extends CriteriaNode {
37
37
  const payload = this.payload[key].unwrap();
38
38
  const qb2 = qb.clone(true);
39
39
  const sub = qb2
40
- .from(parentMeta.className)
41
- .innerJoin(this.key, qb2.getNextAlias(this.prop.type))
40
+ .from(parentMeta.class)
41
+ .innerJoin(this.key, qb2.getNextAlias(this.prop.targetMeta.class))
42
42
  .select(parentMeta.primaryKeys);
43
43
  if (key === '$every') {
44
44
  sub.where({ $not: { [this.key]: payload } });
@@ -100,7 +100,7 @@ export class ObjectCriteriaNode extends CriteriaNode {
100
100
  this.inlineCondition(field.replaceAll(ALIAS_REPLACEMENT, alias), o, payload);
101
101
  }
102
102
  else {
103
- this.inlineCondition(`${alias}.${field}`, o, payload);
103
+ this.inlineCondition(`${alias ?? qb.alias}.${field}`, o, payload);
104
104
  }
105
105
  return o;
106
106
  }, {});
@@ -217,7 +217,7 @@ export class ObjectCriteriaNode extends CriteriaNode {
217
217
  return !primaryKeys && !nestedAlias && !operatorKeys && !embeddable;
218
218
  }
219
219
  autoJoin(qb, alias, options) {
220
- const nestedAlias = qb.getNextAlias(this.prop?.pivotTable ?? this.entityName);
220
+ const nestedAlias = qb.getNextAlias(this.prop?.pivotEntity ?? this.entityName);
221
221
  const rawField = RawQueryFragment.isKnownFragmentSymbol(this.key);
222
222
  const scalar = Utils.isPrimaryKey(this.payload) || this.payload instanceof RegExp || this.payload instanceof Date || rawField;
223
223
  const operator = Utils.isPlainObject(this.payload) && Utils.getObjectQueryKeys(this.payload).every(k => Utils.isOperator(k, false));
@@ -220,8 +220,8 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
220
220
  * Specifies FROM which entity's table select/update/delete will be executed, removing all previously set FROM-s.
221
221
  * Allows setting a main string alias of the selection data.
222
222
  */
223
- from<Entity extends AnyEntity<Entity> = AnyEntity>(target: QueryBuilder<Entity>, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
224
- from<Entity extends AnyEntity<Entity> = AnyEntity>(target: EntityName<Entity>): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
223
+ from<Entity extends object>(target: QueryBuilder<Entity>, aliasName?: string): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
224
+ from<Entity extends object>(target: EntityName<Entity>): SelectQueryBuilder<Entity, RootAlias, Hint, Context>;
225
225
  getNativeQuery(processVirtualEntity?: boolean): NativeQueryBuilder;
226
226
  /**
227
227
  * Returns the query with parameters as wildcards.
@@ -254,11 +254,11 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
254
254
  /**
255
255
  * @internal
256
256
  */
257
- getNextAlias(entityName?: string): string;
257
+ getNextAlias(entityName?: string | EntityName): string;
258
258
  /**
259
259
  * @internal
260
260
  */
261
- getAliasMap(): Dictionary<string>;
261
+ getAliasMap(): Dictionary<EntityName>;
262
262
  /**
263
263
  * Executes this QB and returns the raw results, mapped to the property names (unless disabled via last parameter).
264
264
  * Use `method` to specify what kind of result you want to get (array/single/meta).
@@ -307,9 +307,13 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
307
307
  getResultAndCount(): Promise<[Entity[], number]>;
308
308
  /**
309
309
  * Returns native query builder instance with sub-query aliased with given alias.
310
- * You can provide `EntityName.propName` as alias, then the field name will be used based on the metadata
311
310
  */
312
311
  as(alias: string): NativeQueryBuilder;
312
+ /**
313
+ * Returns native query builder instance with sub-query aliased with given alias.
314
+ * You can provide the target entity name as the first parameter and use the second parameter to point to an existing property to infer its field name.
315
+ */
316
+ as<T>(targetEntity: EntityName<T>, alias: EntityKey<T>): NativeQueryBuilder;
313
317
  clone(reset?: boolean | string[]): QueryBuilder<Entity>;
314
318
  /**
315
319
  * Sets logger context for this query builder.