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

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.
@@ -1,4 +1,4 @@
1
- import { helper, isRaw, LoadStrategy, LockMode, PopulateHint, QueryFlag, QueryHelper, raw, RawQueryFragment, Reference, ReferenceKind, serialize, Utils, ValidationError, inspect, } from '@mikro-orm/core';
1
+ import { helper, inspect, isRaw, LoadStrategy, LockMode, PopulateHint, QueryFlag, QueryHelper, raw, RawQueryFragment, Reference, ReferenceKind, serialize, Utils, ValidationError, } from '@mikro-orm/core';
2
2
  import { JoinType, QueryType } from './enums.js';
3
3
  import { QueryBuilderHelper } from './QueryBuilderHelper.js';
4
4
  import { CriteriaNodeFactory } from './CriteriaNodeFactory.js';
@@ -138,7 +138,7 @@ export class QueryBuilder {
138
138
  this._fields = Utils.asArray(field);
139
139
  }
140
140
  else if (distinct || this.hasToManyJoins()) {
141
- this._fields = this.mainAlias.metadata.primaryKeys;
141
+ this._fields = this.mainAlias.meta.primaryKeys;
142
142
  }
143
143
  else {
144
144
  this._fields = [raw('*')];
@@ -274,7 +274,7 @@ export class QueryBuilder {
274
274
  continue;
275
275
  }
276
276
  filterOptions = QueryHelper.mergePropertyFilters(join.prop.filters, filterOptions);
277
- const cond = await em.applyFilters(join.prop.type, join.cond, filterOptions, 'read');
277
+ const cond = await em.applyFilters(join.prop.targetMeta.class, join.cond, filterOptions, 'read');
278
278
  if (Utils.hasObjectKeys(cond) || RawQueryFragment.hasObjectFragments(cond)) {
279
279
  // remove nested filters, we only care about scalars here, nesting would require another join branch
280
280
  for (const key of Object.keys(cond)) {
@@ -331,7 +331,7 @@ export class QueryBuilder {
331
331
  if ([QueryType.UPDATE, QueryType.DELETE].includes(this.type) && criteriaNode.willAutoJoin(this, undefined, { ignoreBranching })) {
332
332
  // use sub-query to support joining
333
333
  this.setFlag(this.type === QueryType.UPDATE ? QueryFlag.UPDATE_SUB_QUERY : QueryFlag.DELETE_SUB_QUERY);
334
- this.select(this.mainAlias.metadata.primaryKeys, true);
334
+ this.select(this.mainAlias.meta.primaryKeys, true);
335
335
  }
336
336
  if (topLevel) {
337
337
  this._cond = criteriaNode.process(this, { ignoreBranching });
@@ -379,6 +379,7 @@ export class QueryBuilder {
379
379
  type: 'orderBy',
380
380
  });
381
381
  this._orderBy.push(CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, processed).process(this, { matchPopulateJoins: true, type: 'orderBy' }));
382
+ // this._orderBy.push(CriteriaNodeFactory.createNode<Entity>(this.metadata, Utils.className(this.mainAlias.entityName), processed).process(this, { matchPopulateJoins: true, type: 'orderBy' }));
382
383
  });
383
384
  return this;
384
385
  }
@@ -409,7 +410,7 @@ export class QueryBuilder {
409
410
  return this.having(cond, params, '$or');
410
411
  }
411
412
  onConflict(fields = []) {
412
- const meta = this.mainAlias.metadata;
413
+ const meta = this.mainAlias.meta;
413
414
  this.ensureNotFinalized();
414
415
  this._onConflict ??= [];
415
416
  this._onConflict.push({
@@ -536,11 +537,10 @@ export class QueryBuilder {
536
537
  this.fromSubQuery(target, aliasName);
537
538
  }
538
539
  else {
539
- const entityName = Utils.className(target);
540
- if (aliasName && this._mainAlias && entityName !== this._mainAlias.aliasName) {
540
+ if (aliasName && this._mainAlias && Utils.className(target) !== this._mainAlias.aliasName) {
541
541
  throw new Error(`Cannot override the alias to '${aliasName}' since a query already contains references to '${this._mainAlias.aliasName}'`);
542
542
  }
543
- this.fromEntityName(entityName, aliasName);
543
+ this.fromEntityName(target, aliasName);
544
544
  }
545
545
  return this;
546
546
  }
@@ -571,7 +571,7 @@ export class QueryBuilder {
571
571
  if (this.lockMode) {
572
572
  this.helper.getLockSQL(qb, this.lockMode, this.lockTables, this._joins);
573
573
  }
574
- this.helper.finalize(this.type, qb, this.mainAlias.metadata, this._data, this._returning);
574
+ this.helper.finalize(this.type, qb, this.mainAlias.meta, this._data, this._returning);
575
575
  return this._query.qb = qb;
576
576
  }
577
577
  /**
@@ -613,7 +613,7 @@ export class QueryBuilder {
613
613
  * @internal
614
614
  */
615
615
  getAliasForJoinPath(path, options) {
616
- if (!path || path === this.mainAlias.entityName) {
616
+ if (!path || path === Utils.className(this.mainAlias.entityName)) {
617
617
  return this.mainAlias.aliasName;
618
618
  }
619
619
  const join = typeof path === 'string' ? this.getJoinForPath(path, options) : path;
@@ -657,6 +657,7 @@ export class QueryBuilder {
657
657
  * @internal
658
658
  */
659
659
  getNextAlias(entityName = 'e') {
660
+ entityName = Utils.className(entityName);
660
661
  return this.driver.config.getNamingStrategy().aliasName(entityName, this.aliasCounter++);
661
662
  }
662
663
  /**
@@ -688,7 +689,7 @@ export class QueryBuilder {
688
689
  }
689
690
  const loggerContext = { id: this.em?.id, ...this.loggerContext };
690
691
  const res = await this.getConnection().execute(query.sql, query.params, method, this.context, loggerContext);
691
- const meta = this.mainAlias.metadata;
692
+ const meta = this.mainAlias.meta;
692
693
  if (!options.mapResults || !meta) {
693
694
  await this.em?.storeCache(this._cache, cached, res);
694
695
  return res;
@@ -702,7 +703,7 @@ export class QueryBuilder {
702
703
  const map = {};
703
704
  mapped = res.map(r => this.driver.mapResult(r, meta, this._populate, this, map));
704
705
  if (options.mergeResults && joinedProps.length > 0) {
705
- mapped = this.driver.mergeJoinedResult(mapped, this.mainAlias.metadata, joinedProps);
706
+ mapped = this.driver.mergeJoinedResult(mapped, this.mainAlias.meta, joinedProps);
706
707
  }
707
708
  }
708
709
  else {
@@ -743,7 +744,7 @@ export class QueryBuilder {
743
744
  const query = this.toQuery();
744
745
  const loggerContext = { id: this.em?.id, ...this.loggerContext };
745
746
  const res = this.getConnection().stream(query.sql, query.params, this.context, loggerContext);
746
- const meta = this.mainAlias.metadata;
747
+ const meta = this.mainAlias.meta;
747
748
  if (options.rawResults || !meta) {
748
749
  yield* res;
749
750
  return;
@@ -760,7 +761,7 @@ export class QueryBuilder {
760
761
  continue;
761
762
  }
762
763
  if (stack.length > 0 && hash(stack[stack.length - 1]) !== hash(mapped)) {
763
- const res = this.driver.mergeJoinedResult(stack, this.mainAlias.metadata, joinedProps);
764
+ const res = this.driver.mergeJoinedResult(stack, this.mainAlias.meta, joinedProps);
764
765
  for (const row of res) {
765
766
  yield this.mapResult(row, options.mapResults);
766
767
  }
@@ -769,7 +770,7 @@ export class QueryBuilder {
769
770
  stack.push(mapped);
770
771
  }
771
772
  if (stack.length > 0) {
772
- const merged = this.driver.mergeJoinedResult(stack, this.mainAlias.metadata, joinedProps);
773
+ const merged = this.driver.mergeJoinedResult(stack, this.mainAlias.meta, joinedProps);
773
774
  yield this.mapResult(merged[0], options.mapResults);
774
775
  }
775
776
  }
@@ -856,28 +857,25 @@ export class QueryBuilder {
856
857
  await this.clone().getCount(),
857
858
  ];
858
859
  }
859
- /**
860
- * Returns native query builder instance with sub-query aliased with given alias.
861
- * You can provide `EntityName.propName` as alias, then the field name will be used based on the metadata
862
- */
863
- as(alias) {
860
+ as(aliasOrTargetEntity, alias) {
864
861
  const qb = this.getNativeQuery();
865
- if (alias.includes('.')) {
866
- const [a, f] = alias.split('.');
867
- const meta = this.metadata.find(a);
862
+ let finalAlias = aliasOrTargetEntity;
863
+ /* v8 ignore next */
864
+ if (typeof aliasOrTargetEntity === 'string' && aliasOrTargetEntity.includes('.')) {
865
+ throw new Error('qb.as(alias) no longer supports target entity name prefix, use qb.as(TargetEntity, key) signature instead');
866
+ }
867
+ if (alias) {
868
+ const meta = this.metadata.get(aliasOrTargetEntity);
868
869
  /* v8 ignore next */
869
- alias = meta?.properties[f]?.fieldNames[0] ?? alias;
870
+ finalAlias = meta.properties[alias]?.fieldNames[0] ?? alias;
870
871
  }
871
- qb.as(alias);
872
+ qb.as(finalAlias);
872
873
  // tag the instance, so it is possible to detect it easily
873
- Object.defineProperty(qb, '__as', { enumerable: false, value: alias });
874
+ Object.defineProperty(qb, '__as', { enumerable: false, value: finalAlias });
874
875
  return qb;
875
876
  }
876
- clone(reset) {
877
+ clone(reset, preserve) {
877
878
  const qb = new QueryBuilder(this.mainAlias.entityName, this.metadata, this.driver, this.context, this.mainAlias.aliasName, this.connectionType, this.em);
878
- if (reset === true) {
879
- return qb;
880
- }
881
879
  reset = reset || [];
882
880
  // clone array/object properties
883
881
  const properties = [
@@ -886,13 +884,13 @@ export class QueryBuilder {
886
884
  '_comments', '_hintComments', 'aliasCounter',
887
885
  ];
888
886
  for (const prop of Object.keys(this)) {
889
- if (reset.includes(prop) || ['_helper', '_query'].includes(prop)) {
887
+ if (!preserve?.includes(prop) && (reset === true || reset.includes(prop) || ['_helper', '_query'].includes(prop))) {
890
888
  continue;
891
889
  }
892
890
  qb[prop] = properties.includes(prop) ? Utils.copy(this[prop]) : this[prop];
893
891
  }
894
892
  /* v8 ignore next */
895
- if (this._fields && !reset.includes('_fields')) {
893
+ if (this._fields && reset !== true && !reset.includes('_fields')) {
896
894
  qb._fields = [...this._fields];
897
895
  }
898
896
  qb._aliases = { ...this._aliases };
@@ -939,8 +937,8 @@ export class QueryBuilder {
939
937
  kind: ReferenceKind.MANY_TO_ONE,
940
938
  };
941
939
  if (field instanceof QueryBuilder) {
942
- prop.type = field.mainAlias.entityName;
943
- prop.targetMeta = field.mainAlias.metadata;
940
+ prop.type = Utils.className(field.mainAlias.entityName);
941
+ prop.targetMeta = field.mainAlias.meta;
944
942
  field = field.getNativeQuery();
945
943
  }
946
944
  if (isRaw(field)) {
@@ -972,7 +970,7 @@ export class QueryBuilder {
972
970
  if (!prop) {
973
971
  throw new Error(`Trying to join ${q(field)}, but ${q(fromField)} is not a defined relation on ${meta.className}.`);
974
972
  }
975
- this.createAlias(prop.type, alias);
973
+ this.createAlias(prop.targetMeta.class, alias);
976
974
  cond = QueryHelper.processWhere({
977
975
  where: cond,
978
976
  entityName: this.mainAlias.entityName,
@@ -981,10 +979,10 @@ export class QueryBuilder {
981
979
  aliasMap: this.getAliasMap(),
982
980
  aliased: [QueryType.SELECT, QueryType.COUNT].includes(this.type),
983
981
  });
984
- const criteriaNode = CriteriaNodeFactory.createNode(this.metadata, prop.targetMeta.className, cond);
982
+ const criteriaNode = CriteriaNodeFactory.createNode(this.metadata, prop.targetMeta.class, cond);
985
983
  cond = criteriaNode.process(this, { ignoreBranching: true, alias });
986
984
  let aliasedName = `${fromAlias}.${prop.name}#${alias}`;
987
- path ??= `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? entityName)}.${prop.name}`;
985
+ path ??= `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? Utils.className(entityName))}.${prop.name}`;
988
986
  if (prop.kind === ReferenceKind.ONE_TO_MANY) {
989
987
  this._joins[aliasedName] = this.helper.joinOneToReference(prop, fromAlias, alias, type, cond, schema);
990
988
  this._joins[aliasedName].path ??= path;
@@ -1062,9 +1060,7 @@ export class QueryBuilder {
1062
1060
  }
1063
1061
  ret.push(getFieldName(field));
1064
1062
  });
1065
- const meta = this.mainAlias.metadata;
1066
- /* v8 ignore next */
1067
- const requiresSQLConversion = meta?.props.filter(p => p.hasConvertToJSValueSQL && p.persist !== false) ?? [];
1063
+ const requiresSQLConversion = this.mainAlias.meta.props.filter(p => p.hasConvertToJSValueSQL && p.persist !== false);
1068
1064
  if (this.flags.has(QueryFlag.CONVERT_CUSTOM_TYPES) && (fields.includes('*') || fields.includes(`${this.mainAlias.aliasName}.*`)) && requiresSQLConversion.length > 0) {
1069
1065
  for (const p of requiresSQLConversion) {
1070
1066
  ret.push(this.helper.mapper(p.name, this.type));
@@ -1099,14 +1095,14 @@ export class QueryBuilder {
1099
1095
  }
1100
1096
  getQueryBase(processVirtualEntity) {
1101
1097
  const qb = this.platform.createNativeQueryBuilder().setFlags(this.flags);
1102
- const { subQuery, aliasName, entityName, metadata } = this.mainAlias;
1098
+ const { subQuery, aliasName, entityName, meta } = this.mainAlias;
1103
1099
  const requiresAlias = this.finalized && (this._explicitAlias || this.helper.isTableNameAliasRequired(this.type));
1104
1100
  const alias = requiresAlias ? aliasName : undefined;
1105
1101
  const schema = this.getSchema(this.mainAlias);
1106
1102
  const tableName = subQuery ? subQuery.as(aliasName) : this.helper.getTableName(entityName);
1107
1103
  const joinSchema = this._schema ?? this.em?.schema ?? schema;
1108
- if (metadata?.virtual && processVirtualEntity) {
1109
- qb.from(raw(this.fromVirtual(metadata)), { indexHint: this._indexHint });
1104
+ if (meta.virtual && processVirtualEntity) {
1105
+ qb.from(raw(this.fromVirtual(meta)), { indexHint: this._indexHint });
1110
1106
  }
1111
1107
  else {
1112
1108
  qb.from(tableName, {
@@ -1150,19 +1146,19 @@ export class QueryBuilder {
1150
1146
  return qb;
1151
1147
  }
1152
1148
  applyDiscriminatorCondition() {
1153
- const meta = this.mainAlias.metadata;
1154
- if (!meta?.discriminatorValue) {
1149
+ const meta = this.mainAlias.meta;
1150
+ if (!meta.discriminatorValue) {
1155
1151
  return;
1156
1152
  }
1157
- const types = Object.values(meta.root.discriminatorMap).map(cls => this.metadata.find(cls));
1153
+ const types = Object.values(meta.root.discriminatorMap).map(cls => this.metadata.get(cls));
1158
1154
  const children = [];
1159
1155
  const lookUpChildren = (ret, type) => {
1160
1156
  const children = types.filter(meta2 => meta2.extends === type);
1161
- children.forEach(m => lookUpChildren(ret, m.className));
1157
+ children.forEach(m => lookUpChildren(ret, m.class));
1162
1158
  ret.push(...children.filter(c => c.discriminatorValue));
1163
1159
  return children;
1164
1160
  };
1165
- lookUpChildren(children, meta.className);
1161
+ lookUpChildren(children, meta.class);
1166
1162
  this.andWhere({
1167
1163
  [meta.root.discriminatorColumn]: children.length > 0 ? { $in: [meta.discriminatorValue, ...children.map(c => c.discriminatorValue)] } : meta.discriminatorValue,
1168
1164
  });
@@ -1174,7 +1170,7 @@ export class QueryBuilder {
1174
1170
  if (!this._type) {
1175
1171
  this.select('*');
1176
1172
  }
1177
- const meta = this.mainAlias.metadata;
1173
+ const meta = this.mainAlias.meta;
1178
1174
  this.applyDiscriminatorCondition();
1179
1175
  this.processPopulateHint();
1180
1176
  this.processNestedJoins();
@@ -1214,7 +1210,7 @@ export class QueryBuilder {
1214
1210
  if (this.populateHintFinalized) {
1215
1211
  return;
1216
1212
  }
1217
- const meta = this.mainAlias.metadata;
1213
+ const meta = this.mainAlias.meta;
1218
1214
  if (meta && this.flags.has(QueryFlag.AUTO_JOIN_ONE_TO_ONE_OWNER)) {
1219
1215
  const relationsToPopulate = this._populate.map(({ field }) => field);
1220
1216
  meta.relations
@@ -1232,12 +1228,12 @@ export class QueryBuilder {
1232
1228
  }
1233
1229
  if (meta && this.helper.isOneToOneInverse(fromField)) {
1234
1230
  const prop = meta.properties[fromField];
1235
- const alias = this.getNextAlias(prop.pivotEntity ?? prop.type);
1231
+ const alias = this.getNextAlias(prop.pivotEntity ?? prop.targetMeta.class);
1236
1232
  const aliasedName = `${fromAlias}.${prop.name}#${alias}`;
1237
1233
  this._joins[aliasedName] = this.helper.joinOneToReference(prop, this.mainAlias.aliasName, alias, JoinType.leftJoin);
1238
1234
  this._joins[aliasedName].path = `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? meta.className)}.${prop.name}`;
1239
1235
  this._populateMap[aliasedName] = this._joins[aliasedName].alias;
1240
- this.createAlias(prop.type, alias);
1236
+ this.createAlias(prop.targetMeta.class, alias);
1241
1237
  }
1242
1238
  });
1243
1239
  this.processPopulateWhere(false);
@@ -1463,8 +1459,8 @@ export class QueryBuilder {
1463
1459
  });
1464
1460
  }
1465
1461
  getSchema(alias) {
1466
- const { metadata } = alias;
1467
- const metaSchema = metadata?.schema && metadata.schema !== '*' ? metadata.schema : undefined;
1462
+ const { meta } = alias;
1463
+ const metaSchema = meta.schema && meta.schema !== '*' ? meta.schema : undefined;
1468
1464
  const schema = this._schema ?? metaSchema ?? this.em?.schema ?? this.em?.config.getSchema(true);
1469
1465
  if (schema === this.platform.getDefaultSchemaName()) {
1470
1466
  return undefined;
@@ -1472,8 +1468,8 @@ export class QueryBuilder {
1472
1468
  return schema;
1473
1469
  }
1474
1470
  createAlias(entityName, aliasName, subQuery) {
1475
- const metadata = this.metadata.find(entityName);
1476
- const alias = { aliasName, entityName, metadata, subQuery };
1471
+ const meta = this.metadata.find(entityName);
1472
+ const alias = { aliasName, entityName, meta, subQuery };
1477
1473
  this._aliases[aliasName] = alias;
1478
1474
  return alias;
1479
1475
  }
@@ -1531,7 +1527,7 @@ export class QueryBuilder {
1531
1527
  if (!Utils.isEmpty(this._orderBy)) {
1532
1528
  object.orderBy = this._orderBy;
1533
1529
  }
1534
- const name = this._mainAlias ? `${prefix}QueryBuilder<${this._mainAlias?.entityName}>` : 'QueryBuilder';
1530
+ const name = this._mainAlias ? `${prefix}QueryBuilder<${Utils.className(this._mainAlias?.entityName)}>` : 'QueryBuilder';
1535
1531
  const ret = inspect(object, { depth });
1536
1532
  return ret === '[Object]' ? `[${name}]` : name + ' ' + ret;
1537
1533
  }
@@ -1,4 +1,4 @@
1
- import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery, type QBQueryOrderMap, Raw, type RawQueryFragmentSymbol } from '@mikro-orm/core';
1
+ import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityName, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery, type QBQueryOrderMap, Raw, type RawQueryFragmentSymbol } from '@mikro-orm/core';
2
2
  import { JoinType, QueryType } from './enums.js';
3
3
  import type { Field, JoinOptions } from '../typings.js';
4
4
  import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
@@ -14,7 +14,7 @@ export declare class QueryBuilderHelper {
14
14
  private readonly driver;
15
15
  private readonly platform;
16
16
  private readonly metadata;
17
- constructor(entityName: string, alias: string, aliasMap: Dictionary<Alias<any>>, subQueries: Dictionary<string>, driver: AbstractSqlDriver);
17
+ constructor(entityName: EntityName, alias: string, aliasMap: Dictionary<Alias<any>>, subQueries: Dictionary<string>, driver: AbstractSqlDriver);
18
18
  mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType): string;
19
19
  mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType, value?: any, alias?: string | null): string;
20
20
  processData(data: Dictionary, convertCustomTypes: boolean, multi?: boolean): any;
@@ -28,7 +28,7 @@ export declare class QueryBuilderHelper {
28
28
  };
29
29
  mapJoinColumns(type: QueryType, join: JoinOptions): (string | Raw)[];
30
30
  isOneToOneInverse(field: string, meta?: EntityMetadata): boolean;
31
- getTableName(entityName: string): string;
31
+ getTableName(entityName: EntityName): string;
32
32
  /**
33
33
  * Checks whether the RE can be rewritten to simple LIKE query
34
34
  */
@@ -62,8 +62,8 @@ export declare class QueryBuilderHelper {
62
62
  }
63
63
  export interface Alias<T> {
64
64
  aliasName: string;
65
- entityName: string;
66
- metadata?: EntityMetadata<T>;
65
+ entityName: EntityName<T>;
66
+ meta: EntityMetadata<T>;
67
67
  subQuery?: NativeQueryBuilder;
68
68
  }
69
69
  export interface OnConflictClause<T> {
@@ -128,7 +128,7 @@ export class QueryBuilderHelper {
128
128
  }
129
129
  joinOneToReference(prop, ownerAlias, alias, type, cond = {}, schema) {
130
130
  const prop2 = prop.targetMeta.properties[prop.mappedBy || prop.inversedBy];
131
- const table = this.getTableName(prop.type);
131
+ const table = this.getTableName(prop.targetMeta.class);
132
132
  const joinColumns = prop.owner ? prop.referencedColumnNames : prop2.joinColumns;
133
133
  const inverseJoinColumns = prop.referencedColumnNames;
134
134
  const primaryKeys = prop.owner ? prop.joinColumns : prop2.referencedColumnNames;
@@ -142,7 +142,7 @@ export class QueryBuilderHelper {
142
142
  joinManyToOneReference(prop, ownerAlias, alias, type, cond = {}, schema) {
143
143
  return {
144
144
  prop, type, cond, ownerAlias, alias,
145
- table: this.getTableName(prop.type),
145
+ table: this.getTableName(prop.targetMeta.class),
146
146
  schema: prop.targetMeta?.schema === '*' ? '*' : this.driver.getSchemaName(prop.targetMeta, { schema }),
147
147
  joinColumns: prop.referencedColumnNames,
148
148
  primaryKeys: prop.fieldNames,
@@ -167,7 +167,7 @@ export class QueryBuilderHelper {
167
167
  if (type === JoinType.pivotJoin) {
168
168
  return ret;
169
169
  }
170
- const prop2 = prop.owner ? pivotMeta.relations[1] : pivotMeta.relations[0];
170
+ const prop2 = pivotMeta.relations[prop.owner ? 1 : 0];
171
171
  ret[`${pivotAlias}.${prop2.name}#${alias}`] = this.joinManyToOneReference(prop2, pivotAlias, alias, type, cond, schema);
172
172
  ret[`${pivotAlias}.${prop2.name}#${alias}`].path = path;
173
173
  const tmp = prop2.referencedTableName.split('.');
@@ -264,7 +264,7 @@ export class QueryBuilderHelper {
264
264
  }
265
265
  getTableName(entityName) {
266
266
  const meta = this.metadata.find(entityName);
267
- return meta ? meta.collection : entityName;
267
+ return meta?.tableName ?? Utils.className(entityName);
268
268
  }
269
269
  /**
270
270
  * Checks whether the RE can be rewritten to simple LIKE query
@@ -644,7 +644,7 @@ export class QueryBuilderHelper {
644
644
  getLockSQL(qb, lockMode, lockTables = [], joinsMap) {
645
645
  const meta = this.metadata.find(this.entityName);
646
646
  if (lockMode === LockMode.OPTIMISTIC && meta && !meta.versionProperty) {
647
- throw OptimisticLockError.lockFailed(this.entityName);
647
+ throw OptimisticLockError.lockFailed(Utils.className(this.entityName));
648
648
  }
649
649
  if (lockMode !== LockMode.OPTIMISTIC && lockTables.length === 0 && joinsMap) {
650
650
  const joins = Object.values(joinsMap);
@@ -739,9 +739,9 @@ export class QueryBuilderHelper {
739
739
  }
740
740
  getProperty(field, alias) {
741
741
  const entityName = this.aliasMap[alias]?.entityName || this.entityName;
742
- const meta = this.metadata.find(entityName);
742
+ const meta = this.metadata.get(entityName);
743
743
  // check if `alias` is not matching an embedded property name instead of alias, e.g. `address.city`
744
- if (alias && meta) {
744
+ if (alias) {
745
745
  const prop = meta.properties[alias];
746
746
  if (prop?.kind === ReferenceKind.EMBEDDED) {
747
747
  // we want to select the full object property so hydration works as expected
@@ -753,13 +753,10 @@ export class QueryBuilderHelper {
753
753
  return nest(prop);
754
754
  }
755
755
  }
756
- if (meta) {
757
- if (meta.properties[field]) {
758
- return meta.properties[field];
759
- }
760
- return meta.relations.find(prop => prop.fieldNames?.some(name => field === name));
756
+ if (meta.properties[field]) {
757
+ return meta.properties[field];
761
758
  }
762
- return undefined;
759
+ return meta.relations.find(prop => prop.fieldNames?.some(name => field === name));
763
760
  }
764
761
  isTableNameAliasRequired(type) {
765
762
  return [QueryType.SELECT, QueryType.COUNT].includes(type);
@@ -12,7 +12,7 @@ export class ScalarCriteriaNode extends CriteriaNode {
12
12
  if (this.shouldJoin(qb, nestedAlias)) {
13
13
  const path = this.getPath();
14
14
  const parentPath = this.parent.getPath(); // the parent is always there, otherwise `shouldJoin` would return `false`
15
- const nestedAlias = qb.getAliasForJoinPath(path) || qb.getNextAlias(this.prop?.pivotTable ?? this.entityName);
15
+ const nestedAlias = qb.getAliasForJoinPath(path) || qb.getNextAlias(this.prop?.pivotEntity ?? this.entityName);
16
16
  const field = this.aliased(this.prop.name, options?.alias);
17
17
  const type = this.prop.kind === ReferenceKind.MANY_TO_MANY ? JoinType.pivotJoin : JoinType.leftJoin;
18
18
  qb.join(field, nestedAlias, undefined, type, path);
@@ -114,7 +114,7 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
114
114
  await this.execute(this.helper.disableForeignKeysSQL());
115
115
  const schema = options?.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
116
116
  for (const meta of this.getOrderedMetadata(schema).reverse()) {
117
- await this.driver.createQueryBuilder(meta.className, this.em?.getTransactionContext(), 'write', false)
117
+ await this.driver.createQueryBuilder(meta.class, this.em?.getTransactionContext(), 'write', false)
118
118
  .withSchema(schema)
119
119
  .truncate()
120
120
  .execute();
@@ -197,7 +197,7 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
197
197
  const toSchema = this.getTargetSchema(options.schema);
198
198
  const schemas = toSchema.getNamespaces();
199
199
  const fromSchema = options.fromSchema ?? (await DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas, undefined, this.options.skipTables));
200
- const wildcardSchemaTables = Object.values(this.metadata.getAll()).filter(meta => meta.schema === '*').map(meta => meta.tableName);
200
+ const wildcardSchemaTables = [...this.metadata.getAll().values()].filter(meta => meta.schema === '*').map(meta => meta.tableName);
201
201
  fromSchema.prune(options.schema, wildcardSchemaTables);
202
202
  toSchema.prune(options.schema, wildcardSchemaTables);
203
203
  return { fromSchema, toSchema };