@mikro-orm/sql 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.
@@ -7,14 +7,7 @@ import type { NativeQueryBuilder } from './NativeQueryBuilder.js';
7
7
  * @internal
8
8
  */
9
9
  export declare class QueryBuilderHelper {
10
- private readonly entityName;
11
- private alias;
12
- private readonly aliasMap;
13
- private readonly subQueries;
14
- private readonly driver;
15
- private readonly tptAliasMap;
16
- private readonly platform;
17
- private readonly metadata;
10
+ #private;
18
11
  constructor(entityName: EntityName, alias: string, aliasMap: Dictionary<Alias<any>>, subQueries: Dictionary<string>, driver: AbstractSqlDriver, tptAliasMap?: Dictionary<string>);
19
12
  /**
20
13
  * For TPT inheritance, finds the correct alias for a property based on which entity owns it.
@@ -4,30 +4,30 @@ import { JoinType, QueryType } from './enums.js';
4
4
  * @internal
5
5
  */
6
6
  export class QueryBuilderHelper {
7
- entityName;
8
- alias;
9
- aliasMap;
10
- subQueries;
11
- driver;
12
- tptAliasMap;
13
- platform;
14
- metadata;
7
+ #platform;
8
+ #metadata;
9
+ #entityName;
10
+ #alias;
11
+ #aliasMap;
12
+ #subQueries;
13
+ #driver;
14
+ #tptAliasMap;
15
15
  constructor(entityName, alias, aliasMap, subQueries, driver, tptAliasMap = {}) {
16
- this.entityName = entityName;
17
- this.alias = alias;
18
- this.aliasMap = aliasMap;
19
- this.subQueries = subQueries;
20
- this.driver = driver;
21
- this.tptAliasMap = tptAliasMap;
22
- this.platform = this.driver.getPlatform();
23
- this.metadata = this.driver.getMetadata();
16
+ this.#entityName = entityName;
17
+ this.#alias = alias;
18
+ this.#aliasMap = aliasMap;
19
+ this.#subQueries = subQueries;
20
+ this.#driver = driver;
21
+ this.#tptAliasMap = tptAliasMap;
22
+ this.#platform = this.#driver.getPlatform();
23
+ this.#metadata = this.#driver.getMetadata();
24
24
  }
25
25
  /**
26
26
  * For TPT inheritance, finds the correct alias for a property based on which entity owns it.
27
27
  * Returns the main alias if not a TPT property or if the property belongs to the main entity.
28
28
  */
29
29
  getTPTAliasForProperty(propName, defaultAlias) {
30
- const meta = this.aliasMap[defaultAlias]?.meta ?? this.metadata.get(this.entityName);
30
+ const meta = this.#aliasMap[defaultAlias]?.meta ?? this.#metadata.get(this.#entityName);
31
31
  if (meta?.inheritanceType !== 'tpt' || !meta.tptParent) {
32
32
  return defaultAlias;
33
33
  }
@@ -38,7 +38,7 @@ export class QueryBuilderHelper {
38
38
  // Walk up the TPT hierarchy to find which parent owns this property
39
39
  let parentMeta = meta.tptParent;
40
40
  while (parentMeta) {
41
- const parentAlias = this.tptAliasMap[parentMeta.className];
41
+ const parentAlias = this.#tptAliasMap[parentMeta.className];
42
42
  if (parentAlias && parentMeta.ownProps?.some(p => p.name === propName || p.fieldNames?.includes(propName))) {
43
43
  return parentAlias;
44
44
  }
@@ -67,13 +67,13 @@ export class QueryBuilderHelper {
67
67
  const prop = this.getProperty(f, a);
68
68
  const fkIdx2 = prop?.fieldNames.findIndex(name => name === f) ?? -1;
69
69
  if (fkIdx2 !== -1) {
70
- parts.push(this.mapper(a !== this.alias ? `${a}.${prop.fieldNames[fkIdx2]}` : prop.fieldNames[fkIdx2], type, value, alias));
70
+ parts.push(this.mapper(a !== this.#alias ? `${a}.${prop.fieldNames[fkIdx2]}` : prop.fieldNames[fkIdx2], type, value, alias));
71
71
  }
72
72
  else if (prop) {
73
- parts.push(...prop.fieldNames.map(f => this.mapper(a !== this.alias ? `${a}.${f}` : f, type, value, alias)));
73
+ parts.push(...prop.fieldNames.map(f => this.mapper(a !== this.#alias ? `${a}.${f}` : f, type, value, alias)));
74
74
  }
75
75
  else {
76
- parts.push(this.mapper(a !== this.alias ? `${a}.${f}` : f, type, value, alias));
76
+ parts.push(this.mapper(a !== this.#alias ? `${a}.${f}` : f, type, value, alias));
77
77
  }
78
78
  }
79
79
  // flatten the value if we see we are expanding nested composite key
@@ -87,16 +87,16 @@ export class QueryBuilderHelper {
87
87
  }
88
88
  });
89
89
  }
90
- return raw('(' + parts.map(part => this.platform.quoteIdentifier(part)).join(', ') + ')');
90
+ return raw('(' + parts.map(part => this.#platform.quoteIdentifier(part)).join(', ') + ')');
91
91
  }
92
92
  const [a, f] = this.splitField(field);
93
93
  const prop = this.getProperty(f, a);
94
94
  // For TPT inheritance, resolve the correct alias for this property
95
95
  // Only apply TPT resolution when `a` is an actual table alias (in aliasMap),
96
96
  // not when it's an embedded property name like 'profile1.identity.links'
97
- const isTableAlias = !!this.aliasMap[a];
98
- const baseAlias = isTableAlias ? a : this.alias;
99
- const resolvedAlias = isTableAlias ? this.getTPTAliasForProperty(prop?.name ?? f, a) : this.alias;
97
+ const isTableAlias = !!this.#aliasMap[a];
98
+ const baseAlias = isTableAlias ? a : this.#alias;
99
+ const resolvedAlias = isTableAlias ? this.getTPTAliasForProperty(prop?.name ?? f, a) : this.#alias;
100
100
  const aliasPrefix = isTableNameAliasRequired ? resolvedAlias + '.' : '';
101
101
  const fkIdx2 = prop?.fieldNames.findIndex(name => name === f) ?? -1;
102
102
  const fkIdx = fkIdx2 === -1 ? 0 : fkIdx2;
@@ -108,13 +108,13 @@ export class QueryBuilderHelper {
108
108
  return raw(this.prefix(field, isTableNameAliasRequired));
109
109
  }
110
110
  if (prop?.formula) {
111
- const alias2 = this.platform.quoteIdentifier(a).toString();
111
+ const alias2 = this.#platform.quoteIdentifier(a).toString();
112
112
  const aliasName = alias === undefined ? prop.fieldNames[0] : alias;
113
- const as = aliasName === null ? '' : ` as ${this.platform.quoteIdentifier(aliasName)}`;
114
- const meta = this.aliasMap[a]?.meta ?? this.metadata.get(this.entityName);
113
+ const as = aliasName === null ? '' : ` as ${this.#platform.quoteIdentifier(aliasName)}`;
114
+ const meta = this.#aliasMap[a]?.meta ?? this.#metadata.get(this.#entityName);
115
115
  const table = this.createFormulaTable(alias2, meta, schema);
116
116
  const columns = meta.createColumnMappingObject(p => this.getTPTAliasForProperty(p.name, a), alias2);
117
- let value = this.driver.evaluateFormula(prop.formula, columns, table);
117
+ let value = this.#driver.evaluateFormula(prop.formula, columns, table);
118
118
  if (!this.isTableNameAliasRequired(type)) {
119
119
  value = value.replaceAll(alias2 + '.', '');
120
120
  }
@@ -125,16 +125,16 @@ export class QueryBuilderHelper {
125
125
  if (prop.fieldNames.length > 1 && fkIdx !== -1) {
126
126
  const fk = prop.targetMeta.getPrimaryProps()[fkIdx];
127
127
  const prefixed = this.prefix(field, isTableNameAliasRequired, true, fkIdx);
128
- valueSQL = fk.customType.convertToJSValueSQL(prefixed, this.platform);
128
+ valueSQL = fk.customType.convertToJSValueSQL(prefixed, this.#platform);
129
129
  }
130
130
  else {
131
131
  const prefixed = this.prefix(field, isTableNameAliasRequired, true);
132
- valueSQL = prop.customType.convertToJSValueSQL(prefixed, this.platform);
132
+ valueSQL = prop.customType.convertToJSValueSQL(prefixed, this.#platform);
133
133
  }
134
134
  if (alias === null) {
135
135
  return raw(valueSQL);
136
136
  }
137
- return raw(`${valueSQL} as ${this.platform.quoteIdentifier(alias ?? prop.fieldNames[fkIdx])}`);
137
+ return raw(`${valueSQL} as ${this.#platform.quoteIdentifier(alias ?? prop.fieldNames[fkIdx])}`);
138
138
  }
139
139
  let ret = this.prefix(field, false, false, fkIdx);
140
140
  if (alias) {
@@ -149,11 +149,11 @@ export class QueryBuilderHelper {
149
149
  if (Array.isArray(data)) {
150
150
  return data.map(d => this.processData(d, convertCustomTypes, true));
151
151
  }
152
- const meta = this.metadata.find(this.entityName);
153
- data = this.driver.mapDataToFieldNames(data, true, meta?.properties, convertCustomTypes);
152
+ const meta = this.#metadata.find(this.#entityName);
153
+ data = this.#driver.mapDataToFieldNames(data, true, meta?.properties, convertCustomTypes);
154
154
  if (!Utils.hasObjectKeys(data) && meta && multi) {
155
155
  /* v8 ignore next */
156
- data[meta.getPrimaryProps()[0].fieldNames[0]] = this.platform.usesDefaultKeyword() ? raw('default') : undefined;
156
+ data[meta.getPrimaryProps()[0].fieldNames[0]] = this.#platform.usesDefaultKeyword() ? raw('default') : undefined;
157
157
  }
158
158
  return data;
159
159
  }
@@ -163,11 +163,11 @@ export class QueryBuilderHelper {
163
163
  const joinColumns = prop.owner ? prop.referencedColumnNames : prop2.joinColumns;
164
164
  const inverseJoinColumns = prop.referencedColumnNames;
165
165
  const primaryKeys = prop.owner ? prop.joinColumns : prop2.referencedColumnNames;
166
- schema ??= prop.targetMeta?.schema === '*' ? '*' : this.driver.getSchemaName(prop.targetMeta);
166
+ schema ??= prop.targetMeta?.schema === '*' ? '*' : this.#driver.getSchemaName(prop.targetMeta);
167
167
  cond = Utils.merge(cond, prop.where);
168
168
  // For inverse side of polymorphic relations, add discriminator condition
169
169
  if (!prop.owner && prop2.polymorphic && prop2.discriminatorColumn && prop2.discriminatorMap) {
170
- const ownerMeta = this.aliasMap[ownerAlias]?.meta ?? this.metadata.get(this.entityName);
170
+ const ownerMeta = this.#aliasMap[ownerAlias]?.meta ?? this.#metadata.get(this.#entityName);
171
171
  const discriminatorValue = QueryHelper.findDiscriminatorValue(prop2.discriminatorMap, ownerMeta.class);
172
172
  if (discriminatorValue) {
173
173
  cond[`${alias}.${prop2.discriminatorColumn}`] = discriminatorValue;
@@ -194,7 +194,7 @@ export class QueryBuilderHelper {
194
194
  ownerAlias,
195
195
  alias,
196
196
  table: this.getTableName(prop.targetMeta.class),
197
- schema: prop.targetMeta?.schema === '*' ? '*' : this.driver.getSchemaName(prop.targetMeta, { schema }),
197
+ schema: prop.targetMeta?.schema === '*' ? '*' : this.#driver.getSchemaName(prop.targetMeta, { schema }),
198
198
  joinColumns: prop.referencedColumnNames,
199
199
  // For polymorphic relations, fieldNames includes the discriminator column which is not
200
200
  // part of the join condition - use joinColumns (the FK columns only) instead
@@ -202,7 +202,7 @@ export class QueryBuilderHelper {
202
202
  };
203
203
  }
204
204
  joinManyToManyReference(prop, ownerAlias, alias, pivotAlias, type, cond, path, schema) {
205
- const pivotMeta = this.metadata.find(prop.pivotEntity);
205
+ const pivotMeta = this.#metadata.find(prop.pivotEntity);
206
206
  const ret = {
207
207
  [`${ownerAlias}.${prop.name}#${pivotAlias}`]: {
208
208
  prop,
@@ -215,7 +215,7 @@ export class QueryBuilderHelper {
215
215
  primaryKeys: prop.referencedColumnNames,
216
216
  cond: {},
217
217
  table: pivotMeta.tableName,
218
- schema: prop.targetMeta?.schema === '*' ? '*' : this.driver.getSchemaName(pivotMeta, { schema }),
218
+ schema: prop.targetMeta?.schema === '*' ? '*' : this.#driver.getSchemaName(pivotMeta, { schema }),
219
219
  path: path.endsWith('[pivot]') ? path : `${path}[pivot]`,
220
220
  },
221
221
  };
@@ -248,25 +248,25 @@ export class QueryBuilderHelper {
248
248
  const conditions = [];
249
249
  const params = [];
250
250
  schema = join.schema === '*' ? schema : (join.schema ?? schemaOverride);
251
- if (schema && schema !== this.platform.getDefaultSchemaName()) {
251
+ if (schema && schema !== this.#platform.getDefaultSchemaName()) {
252
252
  table = `${schema}.${table}`;
253
253
  }
254
254
  if (join.prop.name !== '__subquery__') {
255
255
  join.primaryKeys.forEach((primaryKey, idx) => {
256
256
  const right = `${join.alias}.${join.joinColumns[idx]}`;
257
257
  if (join.prop.formula) {
258
- const quotedAlias = this.platform.quoteIdentifier(join.ownerAlias).toString();
259
- const ownerMeta = this.aliasMap[join.ownerAlias]?.meta ?? this.metadata.get(this.entityName);
258
+ const quotedAlias = this.#platform.quoteIdentifier(join.ownerAlias).toString();
259
+ const ownerMeta = this.#aliasMap[join.ownerAlias]?.meta ?? this.#metadata.get(this.#entityName);
260
260
  const table = this.createFormulaTable(quotedAlias, ownerMeta, schema);
261
261
  const columns = ownerMeta.createColumnMappingObject(p => this.getTPTAliasForProperty(p.name, join.ownerAlias), quotedAlias);
262
- const left = this.driver.evaluateFormula(join.prop.formula, columns, table);
263
- conditions.push(`${left} = ${this.platform.quoteIdentifier(right)}`);
262
+ const left = this.#driver.evaluateFormula(join.prop.formula, columns, table);
263
+ conditions.push(`${left} = ${this.#platform.quoteIdentifier(right)}`);
264
264
  return;
265
265
  }
266
266
  const left = join.prop.object && join.prop.fieldNameRaw
267
267
  ? join.prop.fieldNameRaw.replaceAll(ALIAS_REPLACEMENT, join.ownerAlias)
268
- : this.platform.quoteIdentifier(`${join.ownerAlias}.${primaryKey}`);
269
- conditions.push(`${left} = ${this.platform.quoteIdentifier(right)}`);
268
+ : this.#platform.quoteIdentifier(`${join.ownerAlias}.${primaryKey}`);
269
+ conditions.push(`${left} = ${this.#platform.quoteIdentifier(right)}`);
270
270
  });
271
271
  }
272
272
  if (join.prop.targetMeta?.root.inheritanceType === 'sti' &&
@@ -280,15 +280,15 @@ export class QueryBuilderHelper {
280
280
  if (join.prop.polymorphic && join.prop.discriminatorColumn && join.prop.discriminatorMap) {
281
281
  const discriminatorValue = QueryHelper.findDiscriminatorValue(join.prop.discriminatorMap, join.prop.targetMeta.class);
282
282
  if (discriminatorValue) {
283
- const discriminatorCol = this.platform.quoteIdentifier(`${join.ownerAlias}.${join.prop.discriminatorColumn}`);
283
+ const discriminatorCol = this.#platform.quoteIdentifier(`${join.ownerAlias}.${join.prop.discriminatorColumn}`);
284
284
  conditions.push(`${discriminatorCol} = ?`);
285
285
  params.push(discriminatorValue);
286
286
  }
287
287
  }
288
288
  let sql = method + ' ';
289
289
  if (join.nested) {
290
- const asKeyword = this.platform.usesAsKeyword() ? ' as ' : ' ';
291
- sql += `(${this.platform.quoteIdentifier(table)}${asKeyword}${this.platform.quoteIdentifier(join.alias)}`;
290
+ const asKeyword = this.#platform.usesAsKeyword() ? ' as ' : ' ';
291
+ sql += `(${this.#platform.quoteIdentifier(table)}${asKeyword}${this.#platform.quoteIdentifier(join.alias)}`;
292
292
  for (const nested of join.nested) {
293
293
  const { sql: nestedSql, params: nestedParams } = this.createJoinExpression(nested, joins, schema, schemaOverride);
294
294
  sql += ' ' + nestedSql;
@@ -297,19 +297,19 @@ export class QueryBuilderHelper {
297
297
  sql += `)`;
298
298
  }
299
299
  else if (join.subquery) {
300
- const asKeyword = this.platform.usesAsKeyword() ? ' as ' : ' ';
301
- sql += `(${join.subquery})${asKeyword}${this.platform.quoteIdentifier(join.alias)}`;
300
+ const asKeyword = this.#platform.usesAsKeyword() ? ' as ' : ' ';
301
+ sql += `(${join.subquery})${asKeyword}${this.#platform.quoteIdentifier(join.alias)}`;
302
302
  }
303
303
  else {
304
304
  sql +=
305
- this.platform.quoteIdentifier(table) +
306
- (this.platform.usesAsKeyword() ? ' as ' : ' ') +
307
- this.platform.quoteIdentifier(join.alias);
305
+ this.#platform.quoteIdentifier(table) +
306
+ (this.#platform.usesAsKeyword() ? ' as ' : ' ') +
307
+ this.#platform.quoteIdentifier(join.alias);
308
308
  }
309
- const oldAlias = this.alias;
310
- this.alias = join.alias;
309
+ const oldAlias = this.#alias;
310
+ this.#alias = join.alias;
311
311
  const subquery = this._appendQueryCondition(QueryType.SELECT, join.cond);
312
- this.alias = oldAlias;
312
+ this.#alias = oldAlias;
313
313
  if (subquery.sql) {
314
314
  conditions.push(subquery.sql);
315
315
  subquery.params.forEach(p => params.push(p));
@@ -332,12 +332,12 @@ export class QueryBuilderHelper {
332
332
  ];
333
333
  }
334
334
  isOneToOneInverse(field, meta) {
335
- meta ??= this.metadata.find(this.entityName);
335
+ meta ??= this.#metadata.find(this.#entityName);
336
336
  const prop = meta.properties[field.replace(/:ref$/, '')];
337
337
  return prop?.kind === ReferenceKind.ONE_TO_ONE && !prop.owner;
338
338
  }
339
339
  getTableName(entityName) {
340
- const meta = this.metadata.find(entityName);
340
+ const meta = this.#metadata.find(entityName);
341
341
  return meta?.tableName ?? Utils.className(entityName);
342
342
  }
343
343
  /**
@@ -432,7 +432,7 @@ export class QueryBuilderHelper {
432
432
  const parts = [];
433
433
  const params = [];
434
434
  if (this.isSimpleRegExp(cond[key])) {
435
- parts.push(`${this.platform.quoteIdentifier(this.mapper(key, type))} like ?`);
435
+ parts.push(`${this.#platform.quoteIdentifier(this.mapper(key, type))} like ?`);
436
436
  params.push(this.getRegExpParam(cond[key]));
437
437
  return { sql: parts.join(' and '), params };
438
438
  }
@@ -442,7 +442,7 @@ export class QueryBuilderHelper {
442
442
  const op = cond[key] === null ? 'is' : '=';
443
443
  if (Raw.isKnownFragmentSymbol(key)) {
444
444
  const raw = Raw.getKnownFragment(key);
445
- const sql = raw.sql.replaceAll(ALIAS_REPLACEMENT, this.alias);
445
+ const sql = raw.sql.replaceAll(ALIAS_REPLACEMENT, this.#alias);
446
446
  const value = Utils.asArray(cond[key]);
447
447
  params.push(...raw.params);
448
448
  if (value.length > 0) {
@@ -455,13 +455,13 @@ export class QueryBuilderHelper {
455
455
  return { sql: parts.join(' and '), params };
456
456
  }
457
457
  const fields = Utils.splitPrimaryKeys(key);
458
- if (this.subQueries[key]) {
458
+ if (this.#subQueries[key]) {
459
459
  const val = this.getValueReplacement(fields, cond[key], params, key);
460
- parts.push(`(${this.subQueries[key]}) ${op} ${val}`);
460
+ parts.push(`(${this.#subQueries[key]}) ${op} ${val}`);
461
461
  return { sql: parts.join(' and '), params };
462
462
  }
463
463
  const val = this.getValueReplacement(fields, cond[key], params, key);
464
- parts.push(`${this.platform.quoteIdentifier(this.mapper(key, type, cond[key], null))} ${op} ${val}`);
464
+ parts.push(`${this.#platform.quoteIdentifier(this.mapper(key, type, cond[key], null))} ${op} ${val}`);
465
465
  return { sql: parts.join(' and '), params };
466
466
  }
467
467
  processObjectSubCondition(cond, key, type) {
@@ -483,7 +483,7 @@ export class QueryBuilderHelper {
483
483
  return { sql: parts.join(' and '), params };
484
484
  }
485
485
  if (value instanceof RegExp) {
486
- value = this.platform.getRegExpValue(value);
486
+ value = this.#platform.getRegExpValue(value);
487
487
  }
488
488
  // operators
489
489
  const op = Object.keys(QueryOperator).find(op => op in value);
@@ -496,17 +496,17 @@ export class QueryBuilderHelper {
496
496
  const fields = rawField ? [key] : Utils.splitPrimaryKeys(key);
497
497
  if (fields.length > 1 && Array.isArray(value[op])) {
498
498
  const singleTuple = !value[op].every((v) => Array.isArray(v));
499
- if (!this.platform.allowsComparingTuples()) {
499
+ if (!this.#platform.allowsComparingTuples()) {
500
500
  const mapped = fields.map(f => this.mapper(f, type));
501
501
  if (op === '$in') {
502
502
  const conds = value[op].map(() => {
503
- return `(${mapped.map(field => `${this.platform.quoteIdentifier(field)} = ?`).join(' and ')})`;
503
+ return `(${mapped.map(field => `${this.#platform.quoteIdentifier(field)} = ?`).join(' and ')})`;
504
504
  });
505
505
  parts.push(`(${conds.join(' or ')})`);
506
506
  params.push(...Utils.flatten(value[op]));
507
507
  return { sql: parts.join(' and '), params };
508
508
  }
509
- parts.push(...mapped.map(field => `${this.platform.quoteIdentifier(field)} = ?`));
509
+ parts.push(...mapped.map(field => `${this.#platform.quoteIdentifier(field)} = ?`));
510
510
  params.push(...Utils.flatten(value[op]));
511
511
  return { sql: parts.join(' and '), params };
512
512
  }
@@ -516,9 +516,9 @@ export class QueryBuilderHelper {
516
516
  value[op] = raw(sql, tmp);
517
517
  }
518
518
  }
519
- if (this.subQueries[key]) {
519
+ if (this.#subQueries[key]) {
520
520
  const val = this.getValueReplacement(fields, value[op], params, op);
521
- parts.push(`(${this.subQueries[key]}) ${replacement} ${val}`);
521
+ parts.push(`(${this.#subQueries[key]}) ${replacement} ${val}`);
522
522
  return { sql: parts.join(' and '), params };
523
523
  }
524
524
  const [a, f] = rawField ? [] : this.splitField(key);
@@ -531,7 +531,7 @@ export class QueryBuilderHelper {
531
531
  if (!prop) {
532
532
  throw new Error(`Cannot use $fulltext operator on ${String(key)}, property not found`);
533
533
  }
534
- const { sql, params: params2 } = raw(this.platform.getFullTextWhereClause(prop), {
534
+ const { sql, params: params2 } = raw(this.#platform.getFullTextWhereClause(prop), {
535
535
  column: this.mapper(key, type, undefined, null),
536
536
  query: value[op],
537
537
  });
@@ -543,7 +543,7 @@ export class QueryBuilderHelper {
543
543
  }
544
544
  else if (op === '$re') {
545
545
  const mappedKey = this.mapper(key, type, value[op], null);
546
- const processed = this.platform.mapRegExpCondition(mappedKey, value);
546
+ const processed = this.#platform.mapRegExpCondition(mappedKey, value);
547
547
  parts.push(processed.sql);
548
548
  params.push(...processed.params);
549
549
  }
@@ -554,13 +554,13 @@ export class QueryBuilderHelper {
554
554
  if (['$in', '$nin'].includes(op)) {
555
555
  sql = `(${sql})`;
556
556
  }
557
- parts.push(`${this.platform.quoteIdentifier(mappedKey)} ${replacement} ${sql}`);
557
+ parts.push(`${this.#platform.quoteIdentifier(mappedKey)} ${replacement} ${sql}`);
558
558
  params.push(...query.params);
559
559
  }
560
560
  else {
561
561
  const mappedKey = this.mapper(key, type, value[op], null);
562
562
  const val = this.getValueReplacement(fields, value[op], params, op, prop);
563
- parts.push(`${this.platform.quoteIdentifier(mappedKey)} ${replacement} ${val}`);
563
+ parts.push(`${this.#platform.quoteIdentifier(mappedKey)} ${replacement} ${val}`);
564
564
  }
565
565
  return { sql: parts.join(' and '), params };
566
566
  }
@@ -575,7 +575,7 @@ export class QueryBuilderHelper {
575
575
  return `(${tmp.join(', ')})`;
576
576
  }
577
577
  if (prop?.customType instanceof ArrayType) {
578
- const item = prop.customType.convertToDatabaseValue(value, this.platform, {
578
+ const item = prop.customType.convertToDatabaseValue(value, this.#platform, {
579
579
  fromQuery: true,
580
580
  key,
581
581
  mode: 'query',
@@ -603,7 +603,7 @@ export class QueryBuilderHelper {
603
603
  replacement = op === '$eq' ? 'is' : 'is not';
604
604
  }
605
605
  if (op === '$re') {
606
- replacement = this.platform.getRegExpOperator(value[op], value.$flags);
606
+ replacement = this.#platform.getRegExpOperator(value[op], value.$flags);
607
607
  }
608
608
  if (replacement.includes('?')) {
609
609
  replacement = replacement.replaceAll('?', '\\?');
@@ -648,7 +648,7 @@ export class QueryBuilderHelper {
648
648
  const order = typeof direction === 'number' ? QueryOrderNumeric[direction] : direction;
649
649
  if (Raw.isKnownFragmentSymbol(key)) {
650
650
  const raw = Raw.getKnownFragment(key);
651
- ret.push(...this.platform.getOrderByExpression(this.platform.formatQuery(raw.sql, raw.params), order, collation));
651
+ ret.push(...this.#platform.getOrderByExpression(this.#platform.formatQuery(raw.sql, raw.params), order, collation));
652
652
  continue;
653
653
  }
654
654
  for (const f of Utils.splitPrimaryKeys(key)) {
@@ -662,19 +662,19 @@ export class QueryBuilderHelper {
662
662
  const rawColumn = typeof column === 'string'
663
663
  ? column
664
664
  .split('.')
665
- .map(e => this.platform.quoteIdentifier(e))
665
+ .map(e => this.#platform.quoteIdentifier(e))
666
666
  .join('.')
667
667
  : column;
668
668
  const customOrder = prop?.customOrder;
669
- let colPart = customOrder ? this.platform.generateCustomOrder(rawColumn, customOrder) : rawColumn;
669
+ let colPart = customOrder ? this.#platform.generateCustomOrder(rawColumn, customOrder) : rawColumn;
670
670
  if (isRaw(colPart)) {
671
- colPart = this.platform.formatQuery(colPart.sql, colPart.params);
671
+ colPart = this.#platform.formatQuery(colPart.sql, colPart.params);
672
672
  }
673
673
  if (Array.isArray(order)) {
674
674
  order.forEach(part => ret.push(...this.getQueryOrderFromObject(type, part, populate, collation)));
675
675
  }
676
676
  else {
677
- ret.push(...this.platform.getOrderByExpression(colPart, order, collation));
677
+ ret.push(...this.#platform.getOrderByExpression(colPart, order, collation));
678
678
  }
679
679
  }
680
680
  }
@@ -687,7 +687,7 @@ export class QueryBuilderHelper {
687
687
  parts[parts.length - 1] = parts[parts.length - 1].substring(0, parts[parts.length - 1].indexOf(':'));
688
688
  }
689
689
  if (parts.length === 1) {
690
- return [this.alias, parts[0], ref];
690
+ return [this.#alias, parts[0], ref];
691
691
  }
692
692
  if (greedyAlias) {
693
693
  const fromField = parts.pop();
@@ -699,28 +699,28 @@ export class QueryBuilderHelper {
699
699
  return [fromAlias, fromField, ref];
700
700
  }
701
701
  getLockSQL(qb, lockMode, lockTables = [], joinsMap) {
702
- const meta = this.metadata.find(this.entityName);
702
+ const meta = this.#metadata.find(this.#entityName);
703
703
  if (lockMode === LockMode.OPTIMISTIC && meta && !meta.versionProperty) {
704
- throw OptimisticLockError.lockFailed(Utils.className(this.entityName));
704
+ throw OptimisticLockError.lockFailed(Utils.className(this.#entityName));
705
705
  }
706
706
  if (lockMode !== LockMode.OPTIMISTIC && lockTables.length === 0 && joinsMap) {
707
707
  const joins = Object.values(joinsMap);
708
708
  const innerJoins = joins.filter(join => [JoinType.innerJoin, JoinType.innerJoinLateral, JoinType.nestedInnerJoin].includes(join.type));
709
709
  if (joins.length > innerJoins.length) {
710
- lockTables.push(this.alias, ...innerJoins.map(join => join.alias));
710
+ lockTables.push(this.#alias, ...innerJoins.map(join => join.alias));
711
711
  }
712
712
  }
713
713
  qb.lockMode(lockMode, lockTables);
714
714
  }
715
715
  updateVersionProperty(qb, data) {
716
- const meta = this.metadata.find(this.entityName);
716
+ const meta = this.#metadata.find(this.#entityName);
717
717
  if (!meta?.versionProperty || meta.versionProperty in data) {
718
718
  return;
719
719
  }
720
720
  const versionProperty = meta.properties[meta.versionProperty];
721
- let sql = this.platform.quoteIdentifier(versionProperty.fieldNames[0]) + ' + 1';
721
+ let sql = this.#platform.quoteIdentifier(versionProperty.fieldNames[0]) + ' + 1';
722
722
  if (versionProperty.runtimeType === 'Date') {
723
- sql = this.platform.getCurrentTimestampSQL(versionProperty.length);
723
+ sql = this.#platform.getCurrentTimestampSQL(versionProperty.length);
724
724
  }
725
725
  qb.update({ [versionProperty.fieldNames[0]]: raw(sql) });
726
726
  }
@@ -728,8 +728,8 @@ export class QueryBuilderHelper {
728
728
  let ret;
729
729
  if (!this.isPrefixed(field)) {
730
730
  // For TPT inheritance, resolve the correct alias for this property
731
- const tptAlias = this.getTPTAliasForProperty(field, this.alias);
732
- const alias = always ? (quote ? tptAlias : this.platform.quoteIdentifier(tptAlias)) + '.' : '';
731
+ const tptAlias = this.getTPTAliasForProperty(field, this.#alias);
732
+ const alias = always ? (quote ? tptAlias : this.#platform.quoteIdentifier(tptAlias)) + '.' : '';
733
733
  const fieldName = this.fieldName(field, tptAlias, always, idx);
734
734
  if (fieldName instanceof Raw) {
735
735
  return fieldName.sql;
@@ -742,7 +742,7 @@ export class QueryBuilderHelper {
742
742
  // For TPT inheritance, resolve the correct alias for this property
743
743
  // Only apply TPT resolution when `a` is an actual table alias (in aliasMap),
744
744
  // not when it's an embedded property name like 'profile1.identity.links'
745
- const isTableAlias = !!this.aliasMap[a];
745
+ const isTableAlias = !!this.#aliasMap[a];
746
746
  const resolvedAlias = isTableAlias ? this.getTPTAliasForProperty(f, a) : a;
747
747
  const fieldName = this.fieldName(f, resolvedAlias, always, idx);
748
748
  if (fieldName instanceof Raw) {
@@ -751,7 +751,7 @@ export class QueryBuilderHelper {
751
751
  ret = resolvedAlias + '.' + fieldName;
752
752
  }
753
753
  if (quote) {
754
- return this.platform.quoteIdentifier(ret);
754
+ return this.#platform.quoteIdentifier(ret);
755
755
  }
756
756
  return ret;
757
757
  }
@@ -792,7 +792,7 @@ export class QueryBuilderHelper {
792
792
  if (!always) {
793
793
  return raw(prop.fieldNameRaw
794
794
  .replace(new RegExp(ALIAS_REPLACEMENT_RE + '\\.?', 'g'), '')
795
- .replace(this.platform.quoteIdentifier('') + '.', ''));
795
+ .replace(this.#platform.quoteIdentifier('') + '.', ''));
796
796
  }
797
797
  if (alias) {
798
798
  return raw(prop.fieldNameRaw.replace(new RegExp(ALIAS_REPLACEMENT_RE, 'g'), alias));
@@ -804,8 +804,8 @@ export class QueryBuilderHelper {
804
804
  return prop.fieldNames?.[idx] ?? field;
805
805
  }
806
806
  getProperty(field, alias) {
807
- const entityName = this.aliasMap[alias]?.entityName || this.entityName;
808
- const meta = this.metadata.find(entityName);
807
+ const entityName = this.#aliasMap[alias]?.entityName || this.#entityName;
808
+ const meta = this.#metadata.find(entityName);
809
809
  // raw table name (e.g. CTE) — no metadata available
810
810
  if (!meta) {
811
811
  return undefined;
@@ -828,7 +828,7 @@ export class QueryBuilderHelper {
828
828
  return [QueryType.SELECT, QueryType.COUNT].includes(type);
829
829
  }
830
830
  processOnConflictCondition(cond, schema) {
831
- const meta = this.metadata.get(this.entityName);
831
+ const meta = this.#metadata.get(this.#entityName);
832
832
  const tableName = meta.tableName;
833
833
  for (const key of Object.keys(cond)) {
834
834
  const mapped = this.mapper(key, QueryType.UPSERT);
@@ -18,7 +18,9 @@ export class ScalarCriteriaNode extends CriteriaNode {
18
18
  const type = this.prop.kind === ReferenceKind.MANY_TO_MANY ? JoinType.pivotJoin : JoinType.leftJoin;
19
19
  qb.join(field, nestedAlias, undefined, type, path);
20
20
  // select the owner as virtual property when joining from 1:1 inverse side, but only if the parent is root entity
21
- if (this.prop.kind === ReferenceKind.ONE_TO_ONE && !parentPath.includes('.') && !qb._fields?.includes(field)) {
21
+ if (this.prop.kind === ReferenceKind.ONE_TO_ONE &&
22
+ !parentPath.includes('.') &&
23
+ !qb.state.fields?.includes(field)) {
22
24
  qb.addSelect(field);
23
25
  }
24
26
  }
@@ -7,19 +7,21 @@ import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
7
7
  * @internal
8
8
  */
9
9
  export declare class DatabaseSchema {
10
- private readonly platform;
10
+ #private;
11
11
  readonly name: string;
12
- private tables;
13
- private views;
14
- private namespaces;
15
- private nativeEnums;
16
12
  constructor(platform: AbstractSqlPlatform, name: string);
17
13
  addTable(name: string, schema: string | undefined | null, comment?: string): DatabaseTable;
18
14
  getTables(): DatabaseTable[];
15
+ /** @internal */
16
+ setTables(tables: DatabaseTable[]): void;
17
+ /** @internal */
18
+ setNamespaces(namespaces: Set<string>): void;
19
19
  getTable(name: string): DatabaseTable | undefined;
20
20
  hasTable(name: string): boolean;
21
21
  addView(name: string, schema: string | undefined | null, definition: string, materialized?: boolean, withData?: boolean): DatabaseView;
22
22
  getViews(): DatabaseView[];
23
+ /** @internal */
24
+ setViews(views: DatabaseView[]): void;
23
25
  getView(name: string): DatabaseView | undefined;
24
26
  hasView(name: string): boolean;
25
27
  setNativeEnums(nativeEnums: Dictionary<{