@mikro-orm/sql 7.0.0-dev.321 → 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.
@@ -1,3 +1,4 @@
1
+ var _a;
1
2
  import { EntityMetadata, helper, inspect, isRaw, LoadStrategy, LockMode, PopulateHint, QueryFlag, QueryHelper, raw, RawQueryFragment, Reference, ReferenceKind, serialize, Utils, ValidationError, } from '@mikro-orm/core';
2
3
  import { JoinType, QueryType } from './enums.js';
3
4
  import { QueryBuilderHelper } from './QueryBuilderHelper.js';
@@ -31,61 +32,54 @@ export class QueryBuilder {
31
32
  connectionType;
32
33
  em;
33
34
  loggerContext;
35
+ #state = _a.createDefaultState();
36
+ #helper;
37
+ #query;
38
+ /** @internal */
39
+ static createDefaultState() {
40
+ return {
41
+ aliasCounter: 0,
42
+ explicitAlias: false,
43
+ populateHintFinalized: false,
44
+ joins: {},
45
+ cond: {},
46
+ orderBy: [],
47
+ groupBy: [],
48
+ having: {},
49
+ comments: [],
50
+ hintComments: [],
51
+ subQueries: {},
52
+ aliases: {},
53
+ tptAlias: {},
54
+ ctes: [],
55
+ tptJoinsApplied: false,
56
+ autoJoinedPaths: [],
57
+ populate: [],
58
+ populateMap: {},
59
+ flags: new Set([QueryFlag.CONVERT_CUSTOM_TYPES]),
60
+ finalized: false,
61
+ joinedProps: new Map(),
62
+ };
63
+ }
34
64
  get mainAlias() {
35
65
  this.ensureFromClause();
36
- return this._mainAlias;
66
+ return this.#state.mainAlias;
37
67
  }
38
68
  get alias() {
39
69
  return this.mainAlias.aliasName;
40
70
  }
41
71
  get helper() {
42
72
  this.ensureFromClause();
43
- return this._helper;
73
+ return this.#helper;
44
74
  }
45
75
  get type() {
46
- return this._type ?? QueryType.SELECT;
76
+ return this.#state.type ?? QueryType.SELECT;
47
77
  }
48
78
  /** @internal */
49
- _populate = [];
50
- /** @internal */
51
- _populateMap = {};
52
- aliasCounter = 0;
53
- flags = new Set([QueryFlag.CONVERT_CUSTOM_TYPES]);
54
- finalized = false;
55
- populateHintFinalized = false;
56
- _joins = {};
57
- _explicitAlias = false;
58
- _schema;
59
- _cond = {};
60
- _data;
61
- _orderBy = [];
62
- _groupBy = [];
63
- _having = {};
64
- _returning;
65
- _onConflict;
66
- _limit;
67
- _offset;
68
- _distinctOn;
69
- _joinedProps = new Map();
70
- _cache;
71
- _indexHint;
72
- _collation;
73
- _comments = [];
74
- _hintComments = [];
75
- flushMode;
76
- lockMode;
77
- lockTables;
78
- subQueries = {};
79
- _mainAlias;
80
- _aliases = {};
81
- _tptAlias = {}; // maps entity className to alias for TPT parent tables
82
- _helper;
83
- _query;
84
- _unionQuery;
85
- _ctes = [];
79
+ get state() {
80
+ return this.#state;
81
+ }
86
82
  platform;
87
- tptJoinsApplied = false;
88
- autoJoinedPaths = [];
89
83
  /**
90
84
  * @internal
91
85
  */
@@ -98,15 +92,15 @@ export class QueryBuilder {
98
92
  this.loggerContext = loggerContext;
99
93
  this.platform = this.driver.getPlatform();
100
94
  if (alias) {
101
- this.aliasCounter++;
102
- this._explicitAlias = true;
95
+ this.#state.aliasCounter++;
96
+ this.#state.explicitAlias = true;
103
97
  }
104
98
  // @ts-expect-error union type does not match the overloaded method signature
105
99
  this.from(entityName, alias);
106
100
  }
107
101
  select(fields, distinct = false) {
108
102
  this.ensureNotFinalized();
109
- this._fields = Utils.asArray(fields).flatMap(f => {
103
+ this.#state.fields = Utils.asArray(fields).flatMap(f => {
110
104
  if (typeof f !== 'string') {
111
105
  // Normalize sql.ref('prop') and sql.ref('prop').as('alias') to string form
112
106
  if (isRaw(f) && f.sql === '??' && f.params.length === 1) {
@@ -124,7 +118,7 @@ export class QueryBuilder {
124
118
  return this.resolveNestedPath(f);
125
119
  });
126
120
  if (distinct) {
127
- this.flags.add(QueryFlag.DISTINCT);
121
+ this.#state.flags.add(QueryFlag.DISTINCT);
128
122
  }
129
123
  return this.init(QueryType.SELECT);
130
124
  }
@@ -133,10 +127,10 @@ export class QueryBuilder {
133
127
  */
134
128
  addSelect(fields) {
135
129
  this.ensureNotFinalized();
136
- if (this._type && this._type !== QueryType.SELECT) {
130
+ if (this.#state.type && this.#state.type !== QueryType.SELECT) {
137
131
  return this;
138
132
  }
139
- return this.select([...Utils.asArray(this._fields), ...Utils.asArray(fields)]);
133
+ return this.select([...Utils.asArray(this.#state.fields), ...Utils.asArray(fields)]);
140
134
  }
141
135
  distinct() {
142
136
  this.ensureNotFinalized();
@@ -144,7 +138,7 @@ export class QueryBuilder {
144
138
  }
145
139
  distinctOn(fields) {
146
140
  this.ensureNotFinalized();
147
- this._distinctOn = Utils.asArray(fields);
141
+ this.#state.distinctOn = Utils.asArray(fields);
148
142
  return this;
149
143
  }
150
144
  /**
@@ -219,16 +213,16 @@ export class QueryBuilder {
219
213
  */
220
214
  count(field, distinct = false) {
221
215
  if (field) {
222
- this._fields = Utils.asArray(field);
216
+ this.#state.fields = Utils.asArray(field);
223
217
  }
224
218
  else if (distinct || this.hasToManyJoins()) {
225
- this._fields = this.mainAlias.meta.primaryKeys;
219
+ this.#state.fields = this.mainAlias.meta.primaryKeys;
226
220
  }
227
221
  else {
228
- this._fields = [raw('*')];
222
+ this.#state.fields = [raw('*')];
229
223
  }
230
224
  if (distinct) {
231
- this.flags.add(QueryFlag.DISTINCT);
225
+ this.#state.flags.add(QueryFlag.DISTINCT);
232
226
  }
233
227
  return this.init(QueryType.COUNT);
234
228
  }
@@ -262,30 +256,30 @@ export class QueryBuilder {
262
256
  * ```
263
257
  */
264
258
  joinAndSelect(field, alias, cond = {}, type = JoinType.innerJoin, path, fields, schema) {
265
- if (!this._type) {
259
+ if (!this.#state.type) {
266
260
  this.select('*');
267
261
  }
268
262
  let subquery;
269
263
  if (Array.isArray(field)) {
270
- const rawFragment = field[1] instanceof QueryBuilder ? field[1].toRaw() : field[1];
264
+ const rawFragment = field[1] instanceof _a ? field[1].toRaw() : field[1];
271
265
  subquery = this.platform.formatQuery(rawFragment.sql, rawFragment.params);
272
266
  field = field[0];
273
267
  }
274
268
  const { prop, key } = this.joinReference(field, alias, cond, type, path, schema, subquery);
275
269
  const [fromAlias] = this.helper.splitField(field);
276
270
  if (subquery) {
277
- this._joins[key].subquery = subquery;
271
+ this.#state.joins[key].subquery = subquery;
278
272
  }
279
- const populate = this._joinedProps.get(fromAlias);
273
+ const populate = this.#state.joinedProps.get(fromAlias);
280
274
  const item = { field: prop.name, strategy: LoadStrategy.JOINED, children: [] };
281
275
  if (populate) {
282
276
  populate.children.push(item);
283
277
  }
284
278
  else {
285
279
  // root entity
286
- this._populate.push(item);
280
+ this.#state.populate.push(item);
287
281
  }
288
- this._joinedProps.set(alias, item);
282
+ this.#state.joinedProps.set(alias, item);
289
283
  this.addSelect(this.getFieldsForJoinedLoad(prop, alias, fields));
290
284
  return this;
291
285
  }
@@ -306,12 +300,12 @@ export class QueryBuilder {
306
300
  getFieldsForJoinedLoad(prop, alias, explicitFields) {
307
301
  const fields = [];
308
302
  const populate = [];
309
- const joinKey = Object.keys(this._joins).find(join => join.endsWith(`#${alias}`));
303
+ const joinKey = Object.keys(this.#state.joins).find(join => join.endsWith(`#${alias}`));
310
304
  const targetMeta = prop.targetMeta;
311
- const schema = this._schema ?? (targetMeta.schema !== '*' ? targetMeta.schema : undefined);
305
+ const schema = this.#state.schema ?? (targetMeta.schema !== '*' ? targetMeta.schema : undefined);
312
306
  if (joinKey) {
313
- const path = this._joins[joinKey].path.split('.').slice(1);
314
- let children = this._populate;
307
+ const path = this.#state.joins[joinKey].path.split('.').slice(1);
308
+ let children = this.#state.populate;
315
309
  for (let i = 0; i < path.length; i++) {
316
310
  const child = children.filter(hint => {
317
311
  const [propName] = hint.field.split(':', 2);
@@ -361,13 +355,13 @@ export class QueryBuilder {
361
355
  * @internal
362
356
  */
363
357
  scheduleFilterCheck(path) {
364
- this.autoJoinedPaths.push(path);
358
+ this.#state.autoJoinedPaths.push(path);
365
359
  }
366
360
  /**
367
361
  * @internal
368
362
  */
369
363
  async applyJoinedFilters(em, filterOptions) {
370
- for (const path of this.autoJoinedPaths) {
364
+ for (const path of this.#state.autoJoinedPaths) {
371
365
  const join = this.getJoinForPath(path);
372
366
  if (join.type === JoinType.pivotJoin) {
373
367
  continue;
@@ -403,10 +397,10 @@ export class QueryBuilder {
403
397
  withSubQuery(subQuery, alias) {
404
398
  this.ensureNotFinalized();
405
399
  if (isRaw(subQuery)) {
406
- this.subQueries[alias] = this.platform.formatQuery(subQuery.sql, subQuery.params);
400
+ this.#state.subQueries[alias] = this.platform.formatQuery(subQuery.sql, subQuery.params);
407
401
  }
408
402
  else {
409
- this.subQueries[alias] = subQuery.toString();
403
+ this.#state.subQueries[alias] = subQuery.toString();
410
404
  }
411
405
  return this;
412
406
  }
@@ -430,13 +424,13 @@ export class QueryBuilder {
430
424
  platform: this.platform,
431
425
  aliasMap: this.getAliasMap(),
432
426
  aliased: [QueryType.SELECT, QueryType.COUNT].includes(this.type),
433
- convertCustomTypes: this.flags.has(QueryFlag.CONVERT_CUSTOM_TYPES),
427
+ convertCustomTypes: this.#state.flags.has(QueryFlag.CONVERT_CUSTOM_TYPES),
434
428
  });
435
429
  }
436
430
  const op = operator || params;
437
- const topLevel = !op || !(Utils.hasObjectKeys(this._cond) || RawQueryFragment.hasObjectFragments(this._cond));
431
+ const topLevel = !op || !(Utils.hasObjectKeys(this.#state.cond) || RawQueryFragment.hasObjectFragments(this.#state.cond));
438
432
  const criteriaNode = CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, processedCond);
439
- const ignoreBranching = this.__populateWhere === 'infer';
433
+ const ignoreBranching = this.#state.resolvedPopulateWhere === 'infer';
440
434
  if ([QueryType.UPDATE, QueryType.DELETE].includes(this.type) &&
441
435
  criteriaNode.willAutoJoin(this, undefined, { ignoreBranching })) {
442
436
  // use sub-query to support joining
@@ -444,18 +438,18 @@ export class QueryBuilder {
444
438
  this.select(this.mainAlias.meta.primaryKeys, true);
445
439
  }
446
440
  if (topLevel) {
447
- this._cond = criteriaNode.process(this, { ignoreBranching });
441
+ this.#state.cond = criteriaNode.process(this, { ignoreBranching });
448
442
  }
449
- else if (Array.isArray(this._cond[op])) {
450
- this._cond[op].push(criteriaNode.process(this, { ignoreBranching }));
443
+ else if (Array.isArray(this.#state.cond[op])) {
444
+ this.#state.cond[op].push(criteriaNode.process(this, { ignoreBranching }));
451
445
  }
452
446
  else {
453
- const cond1 = [this._cond, criteriaNode.process(this, { ignoreBranching })];
454
- this._cond = { [op]: cond1 };
447
+ const cond1 = [this.#state.cond, criteriaNode.process(this, { ignoreBranching })];
448
+ this.#state.cond = { [op]: cond1 };
455
449
  }
456
- if (this._onConflict) {
457
- this._onConflict[this._onConflict.length - 1].where = this.helper.processOnConflictCondition(this._cond, this._schema);
458
- this._cond = {};
450
+ if (this.#state.onConflict) {
451
+ this.#state.onConflict[this.#state.onConflict.length - 1].where = this.helper.processOnConflictCondition(this.#state.cond, this.#state.schema);
452
+ this.#state.cond = {};
459
453
  }
460
454
  return this;
461
455
  }
@@ -474,7 +468,7 @@ export class QueryBuilder {
474
468
  processOrderBy(orderBy, reset = true) {
475
469
  this.ensureNotFinalized();
476
470
  if (reset) {
477
- this._orderBy = [];
471
+ this.#state.orderBy = [];
478
472
  }
479
473
  const selectAliases = this.getSelectAliases();
480
474
  Utils.asArray(orderBy).forEach(orig => {
@@ -499,7 +493,7 @@ export class QueryBuilder {
499
493
  convertCustomTypes: false,
500
494
  type: 'orderBy',
501
495
  });
502
- this._orderBy.push(CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, processed).process(this, {
496
+ this.#state.orderBy.push(CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, processed).process(this, {
503
497
  matchPopulateJoins: true,
504
498
  type: 'orderBy',
505
499
  }));
@@ -509,7 +503,7 @@ export class QueryBuilder {
509
503
  /** Collect custom aliases from select fields (stored as 'resolved as alias' strings by select()). */
510
504
  getSelectAliases() {
511
505
  const aliases = new Set();
512
- for (const field of this._fields ?? []) {
506
+ for (const field of this.#state.fields ?? []) {
513
507
  if (typeof field === 'string') {
514
508
  const m = FIELD_ALIAS_RE.exec(field);
515
509
  if (m) {
@@ -521,7 +515,7 @@ export class QueryBuilder {
521
515
  }
522
516
  groupBy(fields) {
523
517
  this.ensureNotFinalized();
524
- this._groupBy = Utils.asArray(fields).flatMap(f => {
518
+ this.#state.groupBy = Utils.asArray(fields).flatMap(f => {
525
519
  if (typeof f !== 'string') {
526
520
  // Normalize sql.ref('prop') to string for proper formula resolution
527
521
  if (isRaw(f) && f.sql === '??' && f.params.length === 1) {
@@ -549,12 +543,12 @@ export class QueryBuilder {
549
543
  cond = { [raw(`(${cond})`, params)]: [] };
550
544
  }
551
545
  const processed = CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, cond, undefined, undefined, false).process(this, { type: 'having' });
552
- if (!this._having || !operator) {
553
- this._having = processed;
546
+ if (!this.#state.having || !operator) {
547
+ this.#state.having = processed;
554
548
  }
555
549
  else {
556
- const cond1 = [this._having, processed];
557
- this._having = { [operator]: cond1 };
550
+ const cond1 = [this.#state.having, processed];
551
+ this.#state.having = { [operator]: cond1 };
558
552
  }
559
553
  return this;
560
554
  }
@@ -567,8 +561,8 @@ export class QueryBuilder {
567
561
  onConflict(fields = []) {
568
562
  const meta = this.mainAlias.meta;
569
563
  this.ensureNotFinalized();
570
- this._onConflict ??= [];
571
- this._onConflict.push({
564
+ this.#state.onConflict ??= [];
565
+ this.#state.onConflict.push({
572
566
  fields: isRaw(fields)
573
567
  ? fields
574
568
  : Utils.asArray(fields).flatMap(f => {
@@ -580,24 +574,24 @@ export class QueryBuilder {
580
574
  return this;
581
575
  }
582
576
  ignore() {
583
- if (!this._onConflict) {
577
+ if (!this.#state.onConflict) {
584
578
  throw new Error('You need to call `qb.onConflict()` first to use `qb.ignore()`');
585
579
  }
586
- this._onConflict[this._onConflict.length - 1].ignore = true;
580
+ this.#state.onConflict[this.#state.onConflict.length - 1].ignore = true;
587
581
  return this;
588
582
  }
589
583
  merge(data) {
590
- if (!this._onConflict) {
584
+ if (!this.#state.onConflict) {
591
585
  throw new Error('You need to call `qb.onConflict()` first to use `qb.merge()`');
592
586
  }
593
587
  if (Array.isArray(data) && data.length === 0) {
594
588
  return this.ignore();
595
589
  }
596
- this._onConflict[this._onConflict.length - 1].merge = data;
590
+ this.#state.onConflict[this.#state.onConflict.length - 1].merge = data;
597
591
  return this;
598
592
  }
599
593
  returning(fields) {
600
- this._returning = Utils.asArray(fields);
594
+ this.#state.returning = Utils.asArray(fields);
601
595
  return this;
602
596
  }
603
597
  /**
@@ -605,9 +599,9 @@ export class QueryBuilder {
605
599
  */
606
600
  populate(populate, populateWhere, populateFilter) {
607
601
  this.ensureNotFinalized();
608
- this._populate = populate;
609
- this._populateWhere = populateWhere;
610
- this._populateFilter = populateFilter;
602
+ this.#state.populate = populate;
603
+ this.#state.populateWhere = populateWhere;
604
+ this.#state.populateFilter = populateFilter;
611
605
  return this;
612
606
  }
613
607
  /**
@@ -621,7 +615,7 @@ export class QueryBuilder {
621
615
  */
622
616
  limit(limit, offset = 0) {
623
617
  this.ensureNotFinalized();
624
- this._limit = limit;
618
+ this.#state.limit = limit;
625
619
  if (offset) {
626
620
  this.offset(offset);
627
621
  }
@@ -637,12 +631,12 @@ export class QueryBuilder {
637
631
  */
638
632
  offset(offset) {
639
633
  this.ensureNotFinalized();
640
- this._offset = offset;
634
+ this.#state.offset = offset;
641
635
  return this;
642
636
  }
643
637
  withSchema(schema) {
644
638
  this.ensureNotFinalized();
645
- this._schema = schema;
639
+ this.#state.schema = schema;
646
640
  return this;
647
641
  }
648
642
  setLockMode(mode, tables) {
@@ -650,31 +644,31 @@ export class QueryBuilder {
650
644
  if (mode != null && ![LockMode.OPTIMISTIC, LockMode.NONE].includes(mode) && !this.context) {
651
645
  throw ValidationError.transactionRequired();
652
646
  }
653
- this.lockMode = mode;
654
- this.lockTables = tables;
647
+ this.#state.lockMode = mode;
648
+ this.#state.lockTables = tables;
655
649
  return this;
656
650
  }
657
651
  setFlushMode(flushMode) {
658
652
  this.ensureNotFinalized();
659
- this.flushMode = flushMode;
653
+ this.#state.flushMode = flushMode;
660
654
  return this;
661
655
  }
662
656
  setFlag(flag) {
663
657
  this.ensureNotFinalized();
664
- this.flags.add(flag);
658
+ this.#state.flags.add(flag);
665
659
  return this;
666
660
  }
667
661
  unsetFlag(flag) {
668
662
  this.ensureNotFinalized();
669
- this.flags.delete(flag);
663
+ this.#state.flags.delete(flag);
670
664
  return this;
671
665
  }
672
666
  hasFlag(flag) {
673
- return this.flags.has(flag);
667
+ return this.#state.flags.has(flag);
674
668
  }
675
669
  cache(config = true) {
676
670
  this.ensureNotFinalized();
677
- this._cache = config;
671
+ this.#state.cache = config;
678
672
  return this;
679
673
  }
680
674
  /**
@@ -682,7 +676,7 @@ export class QueryBuilder {
682
676
  */
683
677
  indexHint(sql) {
684
678
  this.ensureNotFinalized();
685
- this._indexHint = sql;
679
+ this.#state.indexHint = sql;
686
680
  return this;
687
681
  }
688
682
  /**
@@ -690,7 +684,7 @@ export class QueryBuilder {
690
684
  */
691
685
  collation(collation) {
692
686
  this.ensureNotFinalized();
693
- this._collation = collation;
687
+ this.#state.collation = collation;
694
688
  return this;
695
689
  }
696
690
  /**
@@ -698,7 +692,7 @@ export class QueryBuilder {
698
692
  */
699
693
  comment(comment) {
700
694
  this.ensureNotFinalized();
701
- this._comments.push(...Utils.asArray(comment));
695
+ this.#state.comments.push(...Utils.asArray(comment));
702
696
  return this;
703
697
  }
704
698
  /**
@@ -708,43 +702,43 @@ export class QueryBuilder {
708
702
  */
709
703
  hintComment(comment) {
710
704
  this.ensureNotFinalized();
711
- this._hintComments.push(...Utils.asArray(comment));
705
+ this.#state.hintComments.push(...Utils.asArray(comment));
712
706
  return this;
713
707
  }
714
708
  from(target, aliasName) {
715
709
  this.ensureNotFinalized();
716
- if (target instanceof QueryBuilder) {
710
+ if (target instanceof _a) {
717
711
  this.fromSubQuery(target, aliasName);
718
712
  }
719
713
  else if (typeof target === 'string' && !this.metadata.find(target)) {
720
714
  this.fromRawTable(target, aliasName);
721
715
  }
722
716
  else {
723
- if (aliasName && this._mainAlias && Utils.className(target) !== this._mainAlias.aliasName) {
724
- throw new Error(`Cannot override the alias to '${aliasName}' since a query already contains references to '${this._mainAlias.aliasName}'`);
717
+ if (aliasName && this.#state.mainAlias && Utils.className(target) !== this.#state.mainAlias.aliasName) {
718
+ throw new Error(`Cannot override the alias to '${aliasName}' since a query already contains references to '${this.#state.mainAlias.aliasName}'`);
725
719
  }
726
720
  this.fromEntityName(target, aliasName);
727
721
  }
728
722
  return this;
729
723
  }
730
724
  getNativeQuery(processVirtualEntity = true) {
731
- if (this._unionQuery) {
732
- if (!this._query?.qb) {
733
- this._query = {};
725
+ if (this.#state.unionQuery) {
726
+ if (!this.#query?.qb) {
727
+ this.#query = {};
734
728
  const nqb = this.platform.createNativeQueryBuilder();
735
729
  nqb.select('*');
736
- nqb.from(raw(`(${this._unionQuery.sql})`, this._unionQuery.params));
737
- this._query.qb = nqb;
730
+ nqb.from(raw(`(${this.#state.unionQuery.sql})`, this.#state.unionQuery.params));
731
+ this.#query.qb = nqb;
738
732
  }
739
- return this._query.qb;
733
+ return this.#query.qb;
740
734
  }
741
- if (this._query?.qb) {
742
- return this._query.qb;
735
+ if (this.#query?.qb) {
736
+ return this.#query.qb;
743
737
  }
744
- this._query = {};
738
+ this.#query = {};
745
739
  this.finalize();
746
740
  const qb = this.getQueryBase(processVirtualEntity);
747
- for (const cte of this._ctes) {
741
+ for (const cte of this.#state.ctes) {
748
742
  const query = cte.query;
749
743
  const opts = { columns: cte.columns, materialized: cte.materialized };
750
744
  if (cte.recursive) {
@@ -756,27 +750,27 @@ export class QueryBuilder {
756
750
  }
757
751
  const schema = this.getSchema(this.mainAlias);
758
752
  const isNotEmptyObject = (obj) => Utils.hasObjectKeys(obj) || RawQueryFragment.hasObjectFragments(obj);
759
- Utils.runIfNotEmpty(() => this.helper.appendQueryCondition(this.type, this._cond, qb), this._cond && !this._onConflict);
760
- Utils.runIfNotEmpty(() => qb.groupBy(this.prepareFields(this._groupBy, 'groupBy', schema)), isNotEmptyObject(this._groupBy));
761
- Utils.runIfNotEmpty(() => this.helper.appendQueryCondition(this.type, this._having, qb, undefined, 'having'), isNotEmptyObject(this._having));
753
+ Utils.runIfNotEmpty(() => this.helper.appendQueryCondition(this.type, this.#state.cond, qb), this.#state.cond && !this.#state.onConflict);
754
+ Utils.runIfNotEmpty(() => qb.groupBy(this.prepareFields(this.#state.groupBy, 'groupBy', schema)), isNotEmptyObject(this.#state.groupBy));
755
+ Utils.runIfNotEmpty(() => this.helper.appendQueryCondition(this.type, this.#state.having, qb, undefined, 'having'), isNotEmptyObject(this.#state.having));
762
756
  Utils.runIfNotEmpty(() => {
763
- const queryOrder = this.helper.getQueryOrder(this.type, this._orderBy, this._populateMap, this._collation);
757
+ const queryOrder = this.helper.getQueryOrder(this.type, this.#state.orderBy, this.#state.populateMap, this.#state.collation);
764
758
  if (queryOrder.length > 0) {
765
759
  const sql = Utils.unique(queryOrder).join(', ');
766
760
  qb.orderBy(sql);
767
761
  return;
768
762
  }
769
- }, isNotEmptyObject(this._orderBy));
770
- Utils.runIfNotEmpty(() => qb.limit(this._limit), this._limit != null);
771
- Utils.runIfNotEmpty(() => qb.offset(this._offset), this._offset);
772
- Utils.runIfNotEmpty(() => qb.comment(this._comments), this._comments);
773
- Utils.runIfNotEmpty(() => qb.hintComment(this._hintComments), this._hintComments);
774
- Utils.runIfNotEmpty(() => this.helper.appendOnConflictClause(QueryType.UPSERT, this._onConflict, qb), this._onConflict);
775
- if (this.lockMode) {
776
- this.helper.getLockSQL(qb, this.lockMode, this.lockTables, this._joins);
777
- }
778
- this.processReturningStatement(qb, this.mainAlias.meta, this._data, this._returning);
779
- return (this._query.qb = qb);
763
+ }, isNotEmptyObject(this.#state.orderBy));
764
+ Utils.runIfNotEmpty(() => qb.limit(this.#state.limit), this.#state.limit != null);
765
+ Utils.runIfNotEmpty(() => qb.offset(this.#state.offset), this.#state.offset);
766
+ Utils.runIfNotEmpty(() => qb.comment(this.#state.comments), this.#state.comments);
767
+ Utils.runIfNotEmpty(() => qb.hintComment(this.#state.hintComments), this.#state.hintComments);
768
+ Utils.runIfNotEmpty(() => this.helper.appendOnConflictClause(QueryType.UPSERT, this.#state.onConflict, qb), this.#state.onConflict);
769
+ if (this.#state.lockMode) {
770
+ this.helper.getLockSQL(qb, this.#state.lockMode, this.#state.lockTables, this.#state.joins);
771
+ }
772
+ this.processReturningStatement(qb, this.mainAlias.meta, this.#state.data, this.#state.returning);
773
+ return (this.#query.qb = qb);
780
774
  }
781
775
  processReturningStatement(qb, meta, data, returning) {
782
776
  const usesReturningStatement = this.platform.usesReturningStatement() || this.platform.usesOutputStatement();
@@ -827,16 +821,16 @@ export class QueryBuilder {
827
821
  return raw(sql, params);
828
822
  }
829
823
  toQuery() {
830
- if (this._unionQuery) {
831
- return this._unionQuery;
824
+ if (this.#state.unionQuery) {
825
+ return this.#state.unionQuery;
832
826
  }
833
- if (this._query?.sql) {
834
- return { sql: this._query.sql, params: this._query.params };
827
+ if (this.#query?.sql) {
828
+ return { sql: this.#query.sql, params: this.#query.params };
835
829
  }
836
830
  const query = this.getNativeQuery().compile();
837
- this._query.sql = query.sql;
838
- this._query.params = query.params;
839
- return { sql: this._query.sql, params: this._query.params };
831
+ this.#query.sql = query.sql;
832
+ this.#query.params = query.params;
833
+ return { sql: this.#query.sql, params: this.#query.params };
840
834
  }
841
835
  /**
842
836
  * Returns the list of all parameters for this query.
@@ -868,7 +862,7 @@ export class QueryBuilder {
868
862
  * @internal
869
863
  */
870
864
  getJoinForPath(path, options) {
871
- const joins = Object.values(this._joins);
865
+ const joins = Object.values(this.#state.joins);
872
866
  if (joins.length === 0) {
873
867
  return undefined;
874
868
  }
@@ -900,7 +894,7 @@ export class QueryBuilder {
900
894
  */
901
895
  getNextAlias(entityName = 'e') {
902
896
  entityName = Utils.className(entityName);
903
- return this.driver.config.getNamingStrategy().aliasName(entityName, this.aliasCounter++);
897
+ return this.driver.config.getNamingStrategy().aliasName(entityName, this.#state.aliasCounter++);
904
898
  }
905
899
  /**
906
900
  * Registers a join for a specific polymorphic target type.
@@ -913,15 +907,15 @@ export class QueryBuilder {
913
907
  const referencedColumnNames = targetMeta.getPrimaryProps().flatMap(pk => pk.fieldNames);
914
908
  const targetProp = { ...prop, targetMeta, referencedColumnNames };
915
909
  const aliasedName = `${ownerAlias}.${prop.name}[${targetMeta.className}]#${alias}`;
916
- this._joins[aliasedName] = this.helper.joinManyToOneReference(targetProp, ownerAlias, alias, type, {}, schema);
917
- this._joins[aliasedName].path = path;
910
+ this.#state.joins[aliasedName] = this.helper.joinManyToOneReference(targetProp, ownerAlias, alias, type, {}, schema);
911
+ this.#state.joins[aliasedName].path = path;
918
912
  this.createAlias(targetMeta.class, alias);
919
913
  }
920
914
  /**
921
915
  * @internal
922
916
  */
923
917
  getAliasMap() {
924
- return Object.fromEntries(Object.entries(this._aliases).map(([key, value]) => [key, value.entityName]));
918
+ return Object.fromEntries(Object.entries(this.#state.aliases).map(([key, value]) => [key, value.entityName]));
925
919
  }
926
920
  /**
927
921
  * Executes this QB and returns the raw results, mapped to the property names (unless disabled via last parameter).
@@ -936,11 +930,11 @@ export class QueryBuilder {
936
930
  if (!this.connectionType && (isRunType || this.context)) {
937
931
  this.connectionType = 'write';
938
932
  }
939
- if (!this.finalized && method === 'get' && this.type === QueryType.SELECT) {
933
+ if (!this.#state.finalized && method === 'get' && this.type === QueryType.SELECT) {
940
934
  this.limit(1);
941
935
  }
942
936
  const query = this.toQuery();
943
- const cached = await this.em?.tryCache(this.mainAlias.entityName, this._cache, [
937
+ const cached = await this.em?.tryCache(this.mainAlias.entityName, this.#state.cache, [
944
938
  'qb.execute',
945
939
  query.sql,
946
940
  query.params,
@@ -953,17 +947,17 @@ export class QueryBuilder {
953
947
  const res = await this.getConnection().execute(query.sql, query.params, method, this.context, loggerContext);
954
948
  const meta = this.mainAlias.meta;
955
949
  if (!options.mapResults || !meta) {
956
- await this.em?.storeCache(this._cache, cached, res);
950
+ await this.em?.storeCache(this.#state.cache, cached, res);
957
951
  return res;
958
952
  }
959
953
  if (method === 'run') {
960
954
  return res;
961
955
  }
962
- const joinedProps = this.driver.joinedProps(meta, this._populate);
956
+ const joinedProps = this.driver.joinedProps(meta, this.#state.populate);
963
957
  let mapped;
964
958
  if (Array.isArray(res)) {
965
959
  const map = {};
966
- mapped = res.map(r => this.driver.mapResult(r, meta, this._populate, this, map));
960
+ mapped = res.map(r => this.driver.mapResult(r, meta, this.#state.populate, this, map));
967
961
  if (options.mergeResults && joinedProps.length > 0) {
968
962
  mapped = this.driver.mergeJoinedResult(mapped, this.mainAlias.meta, joinedProps);
969
963
  }
@@ -972,10 +966,10 @@ export class QueryBuilder {
972
966
  mapped = [this.driver.mapResult(res, meta, joinedProps, this)];
973
967
  }
974
968
  if (method === 'get') {
975
- await this.em?.storeCache(this._cache, cached, mapped[0]);
969
+ await this.em?.storeCache(this.#state.cache, cached, mapped[0]);
976
970
  return mapped[0];
977
971
  }
978
- await this.em?.storeCache(this._cache, cached, mapped);
972
+ await this.em?.storeCache(this.#state.cache, cached, mapped);
979
973
  return mapped;
980
974
  }
981
975
  getConnection() {
@@ -1011,13 +1005,13 @@ export class QueryBuilder {
1011
1005
  yield* res;
1012
1006
  return;
1013
1007
  }
1014
- const joinedProps = this.driver.joinedProps(meta, this._populate);
1008
+ const joinedProps = this.driver.joinedProps(meta, this.#state.populate);
1015
1009
  const stack = [];
1016
1010
  const hash = (data) => {
1017
1011
  return Utils.getPrimaryKeyHash(meta.primaryKeys.map(pk => data[pk]));
1018
1012
  };
1019
1013
  for await (const row of res) {
1020
- const mapped = this.driver.mapResult(row, meta, this._populate, this);
1014
+ const mapped = this.driver.mapResult(row, meta, this.#state.populate, this);
1021
1015
  if (!options.mergeResults || joinedProps.length === 0) {
1022
1016
  yield this.mapResult(mapped, options.mapResults);
1023
1017
  continue;
@@ -1046,7 +1040,7 @@ export class QueryBuilder {
1046
1040
  * Executes the query, returning array of results mapped to entity instances.
1047
1041
  */
1048
1042
  async getResultList(limit) {
1049
- await this.em.tryFlush(this.mainAlias.entityName, { flushMode: this.flushMode });
1043
+ await this.em.tryFlush(this.mainAlias.entityName, { flushMode: this.#state.flushMode });
1050
1044
  const res = await this.execute('all', true);
1051
1045
  return this.mapResults(res, limit);
1052
1046
  }
@@ -1068,15 +1062,15 @@ export class QueryBuilder {
1068
1062
  if (!map) {
1069
1063
  return row;
1070
1064
  }
1071
- const entity = this.em.map(this.mainAlias.entityName, row, { schema: this._schema });
1072
- this.propagatePopulateHint(entity, this._populate);
1065
+ const entity = this.em.map(this.mainAlias.entityName, row, { schema: this.#state.schema });
1066
+ this.propagatePopulateHint(entity, this.#state.populate);
1073
1067
  return entity;
1074
1068
  }
1075
1069
  mapResults(res, limit) {
1076
1070
  const entities = [];
1077
1071
  for (const row of res) {
1078
1072
  const entity = this.mapResult(row);
1079
- this.propagatePopulateHint(entity, this._populate);
1073
+ this.propagatePopulateHint(entity, this.#state.populate);
1080
1074
  entities.push(entity);
1081
1075
  if (limit != null && --limit === 0) {
1082
1076
  break;
@@ -1088,7 +1082,7 @@ export class QueryBuilder {
1088
1082
  * Executes the query, returning the first result or null
1089
1083
  */
1090
1084
  async getSingleResult() {
1091
- if (!this.finalized) {
1085
+ if (!this.#state.finalized) {
1092
1086
  this.limit(1);
1093
1087
  }
1094
1088
  const [res] = await this.getResultList(1);
@@ -1100,7 +1094,7 @@ export class QueryBuilder {
1100
1094
  res = await this.execute('get', false);
1101
1095
  }
1102
1096
  else {
1103
- const qb = (this._type === undefined ? this : this.clone());
1097
+ const qb = (this.#state.type === undefined ? this : this.clone());
1104
1098
  qb.processPopulateHint(); // needs to happen sooner so `qb.hasToManyJoins()` reports correctly
1105
1099
  qb.count(field, distinct ?? qb.hasToManyJoins())
1106
1100
  .limit(undefined)
@@ -1173,12 +1167,12 @@ export class QueryBuilder {
1173
1167
  const parts = [];
1174
1168
  const params = [];
1175
1169
  for (const qb of all) {
1176
- const compiled = qb instanceof QueryBuilder ? qb.toQuery() : qb.compile();
1170
+ const compiled = qb instanceof _a ? qb.toQuery() : qb.compile();
1177
1171
  parts.push(`(${compiled.sql})`);
1178
1172
  params.push(...compiled.params);
1179
1173
  }
1180
1174
  const result = this.clone(true);
1181
- result._unionQuery = { sql: parts.join(` ${separator} `), params };
1175
+ result.#state.unionQuery = { sql: parts.join(` ${separator} `), params };
1182
1176
  return result;
1183
1177
  }
1184
1178
  with(name, query, options) {
@@ -1189,12 +1183,12 @@ export class QueryBuilder {
1189
1183
  }
1190
1184
  addCte(name, query, options, recursive) {
1191
1185
  this.ensureNotFinalized();
1192
- if (this._ctes.some(cte => cte.name === name)) {
1186
+ if (this.#state.ctes.some(cte => cte.name === name)) {
1193
1187
  throw new Error(`CTE with name '${name}' already exists`);
1194
1188
  }
1195
1189
  // Eagerly compile QueryBuilder to RawQueryFragment — later mutations to the sub-query won't be reflected
1196
- const compiled = query instanceof QueryBuilder ? query.toRaw() : query;
1197
- this._ctes.push({
1190
+ const compiled = query instanceof _a ? query.toRaw() : query;
1191
+ this.#state.ctes.push({
1198
1192
  name,
1199
1193
  query: compiled,
1200
1194
  recursive,
@@ -1204,53 +1198,26 @@ export class QueryBuilder {
1204
1198
  return this;
1205
1199
  }
1206
1200
  clone(reset, preserve) {
1207
- const qb = new QueryBuilder(this.mainAlias.entityName, this.metadata, this.driver, this.context, this.mainAlias.aliasName, this.connectionType, this.em);
1208
- reset = reset || [];
1209
- // clone array/object properties
1210
- const properties = [
1211
- 'flags',
1212
- '_populate',
1213
- '_populateWhere',
1214
- '_populateFilter',
1215
- '__populateWhere',
1216
- '_populateMap',
1217
- '_joins',
1218
- '_joinedProps',
1219
- '_cond',
1220
- '_data',
1221
- '_orderBy',
1222
- '_schema',
1223
- '_indexHint',
1224
- '_collation',
1225
- '_cache',
1226
- 'subQueries',
1227
- 'lockMode',
1228
- 'lockTables',
1229
- '_groupBy',
1230
- '_having',
1231
- '_returning',
1232
- '_comments',
1233
- '_hintComments',
1234
- 'aliasCounter',
1235
- '_unionQuery',
1236
- ];
1237
- for (const prop of Object.keys(this)) {
1238
- if (!preserve?.includes(prop) &&
1239
- (reset === true || reset.includes(prop) || ['_helper', '_query'].includes(prop))) {
1240
- continue;
1201
+ const qb = new _a(this.#state.mainAlias.entityName, this.metadata, this.driver, this.context, this.#state.mainAlias.aliasName, this.connectionType, this.em);
1202
+ if (reset !== true) {
1203
+ qb.#state = Utils.copy(this.#state);
1204
+ // CTEs contain NativeQueryBuilder instances that should not be deep-cloned
1205
+ qb.#state.ctes = this.#state.ctes.map(cte => ({ ...cte }));
1206
+ if (Array.isArray(reset)) {
1207
+ const fresh = _a.createDefaultState();
1208
+ for (const key of reset) {
1209
+ qb.#state[key] = fresh[key];
1210
+ }
1241
1211
  }
1242
- qb[prop] = properties.includes(prop) ? Utils.copy(this[prop]) : this[prop];
1243
- }
1244
- /* v8 ignore next */
1245
- if (this._fields && reset !== true && !reset.includes('_fields')) {
1246
- qb._fields = [...this._fields];
1247
1212
  }
1248
- if (this._ctes.length && reset !== true && !reset.includes('_ctes')) {
1249
- qb._ctes = this._ctes.map(cte => ({ ...cte }));
1213
+ else if (preserve) {
1214
+ for (const key of preserve) {
1215
+ qb.#state[key] = Utils.copy(this.#state[key]);
1216
+ }
1250
1217
  }
1251
- qb._aliases = { ...this._aliases };
1252
- qb._helper.aliasMap = qb._aliases;
1253
- qb.finalized = false;
1218
+ qb.#state.finalized = false;
1219
+ qb.#query = undefined;
1220
+ qb.#helper = qb.createQueryBuilderHelper();
1254
1221
  return qb;
1255
1222
  }
1256
1223
  /**
@@ -1270,11 +1237,11 @@ export class QueryBuilder {
1270
1237
  if (typeof meta.expression === 'string') {
1271
1238
  return `(${meta.expression}) as ${this.platform.quoteIdentifier(this.alias)}`;
1272
1239
  }
1273
- const res = meta.expression(this.em, this._cond, {});
1240
+ const res = meta.expression(this.em, this.#state.cond, {});
1274
1241
  if (typeof res === 'string') {
1275
1242
  return `(${res}) as ${this.platform.quoteIdentifier(this.alias)}`;
1276
1243
  }
1277
- if (res instanceof QueryBuilder) {
1244
+ if (res instanceof _a) {
1278
1245
  return `(${res.getFormattedQuery()}) as ${this.platform.quoteIdentifier(this.alias)}`;
1279
1246
  }
1280
1247
  if (isRaw(res)) {
@@ -1293,11 +1260,11 @@ export class QueryBuilder {
1293
1260
  addPropertyJoin(prop, ownerAlias, alias, type, path, schema) {
1294
1261
  schema ??= prop.targetMeta?.schema === '*' ? '*' : this.driver.getSchemaName(prop.targetMeta);
1295
1262
  const key = `[tpt]${ownerAlias}#${alias}`;
1296
- this._joins[key] =
1263
+ this.#state.joins[key] =
1297
1264
  prop.kind === ReferenceKind.MANY_TO_ONE
1298
1265
  ? this.helper.joinManyToOneReference(prop, ownerAlias, alias, type, {}, schema)
1299
1266
  : this.helper.joinOneToReference(prop, ownerAlias, alias, type, {}, schema);
1300
- this._joins[key].path = path;
1267
+ this.#state.joins[key].path = path;
1301
1268
  return key;
1302
1269
  }
1303
1270
  joinReference(field, alias, cond, type, path, schema, subquery) {
@@ -1307,7 +1274,7 @@ export class QueryBuilder {
1307
1274
  name: '__subquery__',
1308
1275
  kind: ReferenceKind.MANY_TO_ONE,
1309
1276
  };
1310
- if (field instanceof QueryBuilder) {
1277
+ if (field instanceof _a) {
1311
1278
  prop.type = Utils.className(field.mainAlias.entityName);
1312
1279
  prop.targetMeta = field.mainAlias.meta;
1313
1280
  field = field.getNativeQuery();
@@ -1316,7 +1283,7 @@ export class QueryBuilder {
1316
1283
  field = this.platform.formatQuery(field.sql, field.params);
1317
1284
  }
1318
1285
  const key = `${this.alias}.${prop.name}#${alias}`;
1319
- this._joins[key] = {
1286
+ this.#state.joins[key] = {
1320
1287
  prop,
1321
1288
  alias,
1322
1289
  type,
@@ -1332,10 +1299,10 @@ export class QueryBuilder {
1332
1299
  }
1333
1300
  const [fromAlias, fromField] = this.helper.splitField(field);
1334
1301
  const q = (str) => `'${str}'`;
1335
- if (!this._aliases[fromAlias]) {
1336
- throw new Error(`Trying to join ${q(fromField)} with alias ${q(fromAlias)}, but ${q(fromAlias)} is not a known alias. Available aliases are: ${Object.keys(this._aliases).map(q).join(', ')}.`);
1302
+ if (!this.#state.aliases[fromAlias]) {
1303
+ throw new Error(`Trying to join ${q(fromField)} with alias ${q(fromAlias)}, but ${q(fromAlias)} is not a known alias. Available aliases are: ${Object.keys(this.#state.aliases).map(q).join(', ')}.`);
1337
1304
  }
1338
- const entityName = this._aliases[fromAlias].entityName;
1305
+ const entityName = this.#state.aliases[fromAlias].entityName;
1339
1306
  const meta = this.metadata.get(entityName);
1340
1307
  const prop = meta.properties[fromField];
1341
1308
  if (!prop) {
@@ -1358,10 +1325,10 @@ export class QueryBuilder {
1358
1325
  const criteriaNode = CriteriaNodeFactory.createNode(this.metadata, prop.targetMeta.class, cond);
1359
1326
  cond = criteriaNode.process(this, { ignoreBranching: true, alias });
1360
1327
  let aliasedName = `${fromAlias}.${prop.name}#${alias}`;
1361
- path ??= `${Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? Utils.className(entityName)}.${prop.name}`;
1328
+ path ??= `${Object.values(this.#state.joins).find(j => j.alias === fromAlias)?.path ?? Utils.className(entityName)}.${prop.name}`;
1362
1329
  if (prop.kind === ReferenceKind.ONE_TO_MANY) {
1363
- this._joins[aliasedName] = this.helper.joinOneToReference(prop, fromAlias, alias, type, cond, schema);
1364
- this._joins[aliasedName].path ??= path;
1330
+ this.#state.joins[aliasedName] = this.helper.joinOneToReference(prop, fromAlias, alias, type, cond, schema);
1331
+ this.#state.joins[aliasedName].path ??= path;
1365
1332
  }
1366
1333
  else if (prop.kind === ReferenceKind.MANY_TO_MANY) {
1367
1334
  let pivotAlias = alias;
@@ -1371,19 +1338,19 @@ export class QueryBuilder {
1371
1338
  aliasedName = `${fromAlias}.${prop.name}#${pivotAlias}`;
1372
1339
  }
1373
1340
  const joins = this.helper.joinManyToManyReference(prop, fromAlias, alias, pivotAlias, type, cond, path, schema);
1374
- Object.assign(this._joins, joins);
1341
+ Object.assign(this.#state.joins, joins);
1375
1342
  this.createAlias(prop.pivotEntity, pivotAlias);
1376
- this._joins[aliasedName].path ??= path;
1343
+ this.#state.joins[aliasedName].path ??= path;
1377
1344
  aliasedName = Object.keys(joins)[1];
1378
1345
  }
1379
1346
  else if (prop.kind === ReferenceKind.ONE_TO_ONE) {
1380
- this._joins[aliasedName] = this.helper.joinOneToReference(prop, ownerAlias, alias, type, cond, schema);
1381
- this._joins[aliasedName].path ??= path;
1347
+ this.#state.joins[aliasedName] = this.helper.joinOneToReference(prop, ownerAlias, alias, type, cond, schema);
1348
+ this.#state.joins[aliasedName].path ??= path;
1382
1349
  }
1383
1350
  else {
1384
1351
  // MANY_TO_ONE
1385
- this._joins[aliasedName] = this.helper.joinManyToOneReference(prop, ownerAlias, alias, type, cond, schema);
1386
- this._joins[aliasedName].path ??= path;
1352
+ this.#state.joins[aliasedName] = this.helper.joinManyToOneReference(prop, ownerAlias, alias, type, cond, schema);
1353
+ this.#state.joins[aliasedName].path ??= path;
1387
1354
  }
1388
1355
  return { prop, key: aliasedName };
1389
1356
  }
@@ -1406,9 +1373,9 @@ export class QueryBuilder {
1406
1373
  field = asMatch[1].trim();
1407
1374
  customAlias = asMatch[2];
1408
1375
  }
1409
- const join = Object.keys(this._joins).find(k => field === k.substring(0, k.indexOf('#')));
1376
+ const join = Object.keys(this.#state.joins).find(k => field === k.substring(0, k.indexOf('#')));
1410
1377
  if (join && type === 'where') {
1411
- ret.push(...this.helper.mapJoinColumns(this.type, this._joins[join]));
1378
+ ret.push(...this.helper.mapJoinColumns(this.type, this.#state.joins[join]));
1412
1379
  return;
1413
1380
  }
1414
1381
  const [a, f] = this.helper.splitField(field);
@@ -1422,7 +1389,7 @@ export class QueryBuilder {
1422
1389
  }
1423
1390
  if (prop?.embedded || (prop?.kind === ReferenceKind.EMBEDDED && prop.object)) {
1424
1391
  const name = prop.embeddedPath?.join('.') ?? prop.fieldNames[0];
1425
- const aliased = this._aliases[a] ? `${a}.${name}` : name;
1392
+ const aliased = this.#state.aliases[a] ? `${a}.${name}` : name;
1426
1393
  ret.push(getFieldName(aliased, customAlias));
1427
1394
  return;
1428
1395
  }
@@ -1455,16 +1422,16 @@ export class QueryBuilder {
1455
1422
  ret.push(getFieldName(field, customAlias));
1456
1423
  });
1457
1424
  const requiresSQLConversion = this.mainAlias.meta.props.filter(p => p.hasConvertToJSValueSQL && p.persist !== false);
1458
- if (this.flags.has(QueryFlag.CONVERT_CUSTOM_TYPES) &&
1425
+ if (this.#state.flags.has(QueryFlag.CONVERT_CUSTOM_TYPES) &&
1459
1426
  (fields.includes('*') || fields.includes(`${this.mainAlias.aliasName}.*`)) &&
1460
1427
  requiresSQLConversion.length > 0) {
1461
1428
  for (const p of requiresSQLConversion) {
1462
1429
  ret.push(this.helper.mapper(p.name, this.type));
1463
1430
  }
1464
1431
  }
1465
- for (const f of Object.keys(this._populateMap)) {
1466
- if (type === 'where' && this._joins[f]) {
1467
- ret.push(...this.helper.mapJoinColumns(this.type, this._joins[f]));
1432
+ for (const f of Object.keys(this.#state.populateMap)) {
1433
+ if (type === 'where' && this.#state.joins[f]) {
1434
+ ret.push(...this.helper.mapJoinColumns(this.type, this.#state.joins[f]));
1468
1435
  }
1469
1436
  }
1470
1437
  return Utils.unique(ret);
@@ -1480,16 +1447,16 @@ export class QueryBuilder {
1480
1447
  }
1481
1448
  const parts = field.split('.');
1482
1449
  // Simple alias.property case - let prepareFields handle it
1483
- if (parts.length === 2 && this._aliases[parts[0]]) {
1450
+ if (parts.length === 2 && this.#state.aliases[parts[0]]) {
1484
1451
  return field;
1485
1452
  }
1486
1453
  // Start with root alias
1487
1454
  let currentAlias = parts[0];
1488
- let currentMeta = this._aliases[currentAlias]
1489
- ? this.metadata.get(this._aliases[currentAlias].entityName)
1455
+ let currentMeta = this.#state.aliases[currentAlias]
1456
+ ? this.metadata.get(this.#state.aliases[currentAlias].entityName)
1490
1457
  : this.mainAlias.meta;
1491
1458
  // If first part is not an alias, it's a property of the main entity
1492
- if (!this._aliases[currentAlias]) {
1459
+ if (!this.#state.aliases[currentAlias]) {
1493
1460
  currentAlias = this.mainAlias.aliasName;
1494
1461
  parts.unshift(currentAlias);
1495
1462
  }
@@ -1527,14 +1494,14 @@ export class QueryBuilder {
1527
1494
  }
1528
1495
  // Find existing join or create new one
1529
1496
  const joinPath = parts.slice(0, i + 1).join('.');
1530
- const existingJoinKey = Object.keys(this._joins).find(k => {
1531
- const join = this._joins[k];
1497
+ const existingJoinKey = Object.keys(this.#state.joins).find(k => {
1498
+ const join = this.#state.joins[k];
1532
1499
  // Check by path or by key prefix (key format is `alias.field#joinAlias`)
1533
1500
  return join.path === joinPath || k.startsWith(`${currentAlias}.${propName}#`);
1534
1501
  });
1535
1502
  let joinAlias;
1536
1503
  if (existingJoinKey) {
1537
- joinAlias = this._joins[existingJoinKey].alias;
1504
+ joinAlias = this.#state.joins[existingJoinKey].alias;
1538
1505
  }
1539
1506
  else {
1540
1507
  joinAlias = this.getNextAlias(prop.targetMeta?.className ?? propName);
@@ -1551,18 +1518,18 @@ export class QueryBuilder {
1551
1518
  }
1552
1519
  init(type, data, cond) {
1553
1520
  this.ensureNotFinalized();
1554
- this._type = type;
1555
- if ([QueryType.UPDATE, QueryType.DELETE].includes(type) && Utils.hasObjectKeys(this._cond)) {
1521
+ this.#state.type = type;
1522
+ if ([QueryType.UPDATE, QueryType.DELETE].includes(type) && Utils.hasObjectKeys(this.#state.cond)) {
1556
1523
  throw new Error(`You are trying to call \`qb.where().${type.toLowerCase()}()\`. Calling \`qb.${type.toLowerCase()}()\` before \`qb.where()\` is required.`);
1557
1524
  }
1558
1525
  if (!this.helper.isTableNameAliasRequired(type)) {
1559
- delete this._fields;
1526
+ this.#state.fields = undefined;
1560
1527
  }
1561
1528
  if (data) {
1562
1529
  if (Utils.isEntity(data)) {
1563
1530
  data = this.em?.getComparator().prepareEntity(data) ?? serialize(data);
1564
1531
  }
1565
- this._data = this.helper.processData(data, this.flags.has(QueryFlag.CONVERT_CUSTOM_TYPES), false);
1532
+ this.#state.data = this.helper.processData(data, this.#state.flags.has(QueryFlag.CONVERT_CUSTOM_TYPES), false);
1566
1533
  }
1567
1534
  if (cond) {
1568
1535
  this.where(cond);
@@ -1570,9 +1537,9 @@ export class QueryBuilder {
1570
1537
  return this;
1571
1538
  }
1572
1539
  getQueryBase(processVirtualEntity) {
1573
- const qb = this.platform.createNativeQueryBuilder().setFlags(this.flags);
1540
+ const qb = this.platform.createNativeQueryBuilder().setFlags(this.#state.flags);
1574
1541
  const { subQuery, aliasName, entityName, meta, rawTableName } = this.mainAlias;
1575
- const requiresAlias = this.finalized && (this._explicitAlias || this.helper.isTableNameAliasRequired(this.type));
1542
+ const requiresAlias = this.#state.finalized && (this.#state.explicitAlias || this.helper.isTableNameAliasRequired(this.type));
1576
1543
  const alias = requiresAlias ? aliasName : undefined;
1577
1544
  const schema = this.getSchema(this.mainAlias);
1578
1545
  const tableName = rawTableName
@@ -1582,42 +1549,42 @@ export class QueryBuilder {
1582
1549
  : subQuery
1583
1550
  ? raw(`(${subQuery.sql}) as ${this.platform.quoteIdentifier(aliasName)}`, subQuery.params)
1584
1551
  : this.helper.getTableName(entityName);
1585
- const joinSchema = this._schema ?? this.em?.schema ?? schema;
1586
- const schemaOverride = this._schema ?? this.em?.schema;
1552
+ const joinSchema = this.#state.schema ?? this.em?.schema ?? schema;
1553
+ const schemaOverride = this.#state.schema ?? this.em?.schema;
1587
1554
  if (meta.virtual && processVirtualEntity) {
1588
- qb.from(raw(this.fromVirtual(meta)), { indexHint: this._indexHint });
1555
+ qb.from(raw(this.fromVirtual(meta)), { indexHint: this.#state.indexHint });
1589
1556
  }
1590
1557
  else {
1591
1558
  qb.from(tableName, {
1592
1559
  schema: rawTableName ? undefined : schema,
1593
1560
  alias,
1594
- indexHint: this._indexHint,
1561
+ indexHint: this.#state.indexHint,
1595
1562
  });
1596
1563
  }
1597
1564
  switch (this.type) {
1598
1565
  case QueryType.SELECT:
1599
- qb.select(this.prepareFields(this._fields, 'where', schema));
1600
- if (this._distinctOn) {
1601
- qb.distinctOn(this.prepareFields(this._distinctOn, 'where', schema));
1566
+ qb.select(this.prepareFields(this.#state.fields, 'where', schema));
1567
+ if (this.#state.distinctOn) {
1568
+ qb.distinctOn(this.prepareFields(this.#state.distinctOn, 'where', schema));
1602
1569
  }
1603
- else if (this.flags.has(QueryFlag.DISTINCT)) {
1570
+ else if (this.#state.flags.has(QueryFlag.DISTINCT)) {
1604
1571
  qb.distinct();
1605
1572
  }
1606
- this.helper.processJoins(qb, this._joins, joinSchema, schemaOverride);
1573
+ this.helper.processJoins(qb, this.#state.joins, joinSchema, schemaOverride);
1607
1574
  break;
1608
1575
  case QueryType.COUNT: {
1609
- const fields = this._fields.map(f => this.helper.mapper(f, this.type, undefined, undefined, schema));
1610
- qb.count(fields, this.flags.has(QueryFlag.DISTINCT));
1611
- this.helper.processJoins(qb, this._joins, joinSchema, schemaOverride);
1576
+ const fields = this.#state.fields.map(f => this.helper.mapper(f, this.type, undefined, undefined, schema));
1577
+ qb.count(fields, this.#state.flags.has(QueryFlag.DISTINCT));
1578
+ this.helper.processJoins(qb, this.#state.joins, joinSchema, schemaOverride);
1612
1579
  break;
1613
1580
  }
1614
1581
  case QueryType.INSERT:
1615
- qb.insert(this._data);
1582
+ qb.insert(this.#state.data);
1616
1583
  break;
1617
1584
  case QueryType.UPDATE:
1618
- qb.update(this._data);
1619
- this.helper.processJoins(qb, this._joins, joinSchema, schemaOverride);
1620
- this.helper.updateVersionProperty(qb, this._data);
1585
+ qb.update(this.#state.data);
1586
+ this.helper.processJoins(qb, this.#state.joins, joinSchema, schemaOverride);
1587
+ this.helper.updateVersionProperty(qb, this.#state.data);
1621
1588
  break;
1622
1589
  case QueryType.DELETE:
1623
1590
  qb.delete();
@@ -1668,17 +1635,17 @@ export class QueryBuilder {
1668
1635
  ![QueryType.SELECT, QueryType.COUNT].includes(this.type)) {
1669
1636
  return;
1670
1637
  }
1671
- if (this.tptJoinsApplied) {
1638
+ if (this.#state.tptJoinsApplied) {
1672
1639
  return;
1673
1640
  }
1674
- this.tptJoinsApplied = true;
1641
+ this.#state.tptJoinsApplied = true;
1675
1642
  let childMeta = meta;
1676
1643
  let childAlias = this.mainAlias.aliasName;
1677
1644
  while (childMeta.tptParent) {
1678
1645
  const parentMeta = childMeta.tptParent;
1679
1646
  const parentAlias = this.getNextAlias(parentMeta.className);
1680
1647
  this.createAlias(parentMeta.class, parentAlias);
1681
- this._tptAlias[parentMeta.className] = parentAlias;
1648
+ this.#state.tptAlias[parentMeta.className] = parentAlias;
1682
1649
  this.addPropertyJoin(childMeta.tptParentProp, childAlias, parentAlias, JoinType.innerJoin, `[tpt]${childMeta.className}`);
1683
1650
  childMeta = parentMeta;
1684
1651
  childAlias = parentAlias;
@@ -1694,17 +1661,17 @@ export class QueryBuilder {
1694
1661
  ![QueryType.SELECT, QueryType.COUNT].includes(this.type)) {
1695
1662
  return;
1696
1663
  }
1697
- if (!this._fields?.includes('*') && !this._fields?.includes(`${this.mainAlias.aliasName}.*`)) {
1664
+ if (!this.#state.fields?.includes('*') && !this.#state.fields?.includes(`${this.mainAlias.aliasName}.*`)) {
1698
1665
  return;
1699
1666
  }
1700
1667
  let parentMeta = meta.tptParent;
1701
1668
  while (parentMeta) {
1702
- const parentAlias = this._tptAlias[parentMeta.className];
1669
+ const parentAlias = this.#state.tptAlias[parentMeta.className];
1703
1670
  if (parentAlias) {
1704
1671
  const schema = parentMeta.schema === '*' ? '*' : this.driver.getSchemaName(parentMeta);
1705
1672
  parentMeta
1706
1673
  .ownProps.filter(prop => this.platform.shouldHaveColumn(prop, []))
1707
- .forEach(prop => this._fields.push(...this.driver.mapPropToFieldNames(this, prop, parentAlias, parentMeta, schema)));
1674
+ .forEach(prop => this.#state.fields.push(...this.driver.mapPropToFieldNames(this, prop, parentAlias, parentMeta, schema)));
1708
1675
  }
1709
1676
  parentMeta = parentMeta.tptParent;
1710
1677
  }
@@ -1719,32 +1686,32 @@ export class QueryBuilder {
1719
1686
  if (!descendants?.length || ![QueryType.SELECT, QueryType.COUNT].includes(this.type)) {
1720
1687
  return;
1721
1688
  }
1722
- if (!this._fields?.includes('*') && !this._fields?.includes(`${this.mainAlias.aliasName}.*`)) {
1689
+ if (!this.#state.fields?.includes('*') && !this.#state.fields?.includes(`${this.mainAlias.aliasName}.*`)) {
1723
1690
  return;
1724
1691
  }
1725
1692
  // LEFT JOIN each descendant table and add their fields
1726
1693
  for (const childMeta of descendants) {
1727
1694
  const childAlias = this.getNextAlias(childMeta.className);
1728
1695
  this.createAlias(childMeta.class, childAlias);
1729
- this._tptAlias[childMeta.className] = childAlias;
1696
+ this.#state.tptAlias[childMeta.className] = childAlias;
1730
1697
  this.addPropertyJoin(childMeta.tptInverseProp, this.mainAlias.aliasName, childAlias, JoinType.leftJoin, `[tpt]${meta.className}`);
1731
1698
  // Add child fields
1732
1699
  const schema = childMeta.schema === '*' ? '*' : this.driver.getSchemaName(childMeta);
1733
1700
  childMeta
1734
1701
  .ownProps.filter(prop => !prop.primary && this.platform.shouldHaveColumn(prop, []))
1735
- .forEach(prop => this._fields.push(...this.driver.mapPropToFieldNames(this, prop, childAlias, childMeta, schema)));
1702
+ .forEach(prop => this.#state.fields.push(...this.driver.mapPropToFieldNames(this, prop, childAlias, childMeta, schema)));
1736
1703
  }
1737
1704
  // Add computed discriminator (CASE WHEN to determine concrete type)
1738
1705
  // descendants is pre-sorted by depth (deepest first) during discovery
1739
1706
  if (meta.tptDiscriminatorColumn) {
1740
- this._fields.push(this.driver.buildTPTDiscriminatorExpression(meta, descendants, this._tptAlias, this.mainAlias.aliasName));
1707
+ this.#state.fields.push(this.driver.buildTPTDiscriminatorExpression(meta, descendants, this.#state.tptAlias, this.mainAlias.aliasName));
1741
1708
  }
1742
1709
  }
1743
1710
  finalize() {
1744
- if (this.finalized) {
1711
+ if (this.#state.finalized) {
1745
1712
  return;
1746
1713
  }
1747
- if (!this._type) {
1714
+ if (!this.#state.type) {
1748
1715
  this.select('*');
1749
1716
  }
1750
1717
  const meta = this.mainAlias.meta;
@@ -1754,99 +1721,102 @@ export class QueryBuilder {
1754
1721
  this.applyTPTPolymorphicJoins();
1755
1722
  this.processPopulateHint();
1756
1723
  this.processNestedJoins();
1757
- if (meta && (this._fields?.includes('*') || this._fields?.includes(`${this.mainAlias.aliasName}.*`))) {
1724
+ if (meta && (this.#state.fields?.includes('*') || this.#state.fields?.includes(`${this.mainAlias.aliasName}.*`))) {
1758
1725
  const schema = this.getSchema(this.mainAlias);
1759
1726
  // Create a column mapping with unquoted aliases - quoting should be handled by the user via `quote` helper
1760
1727
  // For TPT, use helper to resolve correct alias per property (inherited props use parent alias)
1761
1728
  const quotedMainAlias = this.platform.quoteIdentifier(this.mainAlias.aliasName).toString();
1762
1729
  const columns = meta.createColumnMappingObject(prop => this.helper.getTPTAliasForProperty(prop.name, this.mainAlias.aliasName), quotedMainAlias);
1763
1730
  meta.props
1764
- .filter(prop => prop.formula && (!prop.lazy || this.flags.has(QueryFlag.INCLUDE_LAZY_FORMULAS)))
1731
+ .filter(prop => prop.formula && (!prop.lazy || this.#state.flags.has(QueryFlag.INCLUDE_LAZY_FORMULAS)))
1765
1732
  .map(prop => {
1766
1733
  const aliased = this.platform.quoteIdentifier(prop.fieldNames[0]);
1767
1734
  const table = this.helper.createFormulaTable(quotedMainAlias, meta, schema);
1768
1735
  return `${this.driver.evaluateFormula(prop.formula, columns, table)} as ${aliased}`;
1769
1736
  })
1770
- .filter(field => !this._fields.some(f => {
1737
+ .filter(field => !this.#state.fields.some(f => {
1771
1738
  if (isRaw(f)) {
1772
1739
  return f.sql === field && f.params.length === 0;
1773
1740
  }
1774
1741
  return f === field;
1775
1742
  }))
1776
- .forEach(field => this._fields.push(raw(field)));
1743
+ .forEach(field => this.#state.fields.push(raw(field)));
1777
1744
  }
1778
- QueryHelper.processObjectParams(this._data);
1779
- QueryHelper.processObjectParams(this._cond);
1780
- QueryHelper.processObjectParams(this._having);
1745
+ QueryHelper.processObjectParams(this.#state.data);
1746
+ QueryHelper.processObjectParams(this.#state.cond);
1747
+ QueryHelper.processObjectParams(this.#state.having);
1781
1748
  // automatically enable paginate flag when we detect to-many joins, but only if there is no `group by` clause
1782
- if (!this.flags.has(QueryFlag.DISABLE_PAGINATE) && this._groupBy.length === 0 && this.hasToManyJoins()) {
1783
- this.flags.add(QueryFlag.PAGINATE);
1749
+ if (!this.#state.flags.has(QueryFlag.DISABLE_PAGINATE) &&
1750
+ this.#state.groupBy.length === 0 &&
1751
+ this.hasToManyJoins()) {
1752
+ this.#state.flags.add(QueryFlag.PAGINATE);
1784
1753
  }
1785
1754
  if (meta &&
1786
1755
  !meta.virtual &&
1787
- this.flags.has(QueryFlag.PAGINATE) &&
1788
- !this.flags.has(QueryFlag.DISABLE_PAGINATE) &&
1789
- (this._limit > 0 || this._offset > 0)) {
1756
+ this.#state.flags.has(QueryFlag.PAGINATE) &&
1757
+ !this.#state.flags.has(QueryFlag.DISABLE_PAGINATE) &&
1758
+ (this.#state.limit > 0 || this.#state.offset > 0)) {
1790
1759
  this.wrapPaginateSubQuery(meta);
1791
1760
  }
1792
- if (meta && (this.flags.has(QueryFlag.UPDATE_SUB_QUERY) || this.flags.has(QueryFlag.DELETE_SUB_QUERY))) {
1761
+ if (meta &&
1762
+ (this.#state.flags.has(QueryFlag.UPDATE_SUB_QUERY) || this.#state.flags.has(QueryFlag.DELETE_SUB_QUERY))) {
1793
1763
  this.wrapModifySubQuery(meta);
1794
1764
  }
1795
- this.finalized = true;
1765
+ this.#state.finalized = true;
1796
1766
  }
1797
1767
  /** @internal */
1798
1768
  processPopulateHint() {
1799
- if (this.populateHintFinalized) {
1769
+ if (this.#state.populateHintFinalized) {
1800
1770
  return;
1801
1771
  }
1802
1772
  const meta = this.mainAlias.meta;
1803
- if (meta && this.flags.has(QueryFlag.AUTO_JOIN_ONE_TO_ONE_OWNER)) {
1804
- const relationsToPopulate = this._populate.map(({ field }) => field);
1773
+ if (meta && this.#state.flags.has(QueryFlag.AUTO_JOIN_ONE_TO_ONE_OWNER)) {
1774
+ const relationsToPopulate = this.#state.populate.map(({ field }) => field);
1805
1775
  meta.relations
1806
1776
  .filter(prop => prop.kind === ReferenceKind.ONE_TO_ONE &&
1807
1777
  !prop.owner &&
1808
1778
  !relationsToPopulate.includes(prop.name) &&
1809
1779
  !relationsToPopulate.includes(`${prop.name}:ref`))
1810
1780
  .map(prop => ({ field: `${prop.name}:ref` }))
1811
- .forEach(item => this._populate.push(item));
1781
+ .forEach(item => this.#state.populate.push(item));
1812
1782
  }
1813
- this._populate.forEach(({ field }) => {
1783
+ this.#state.populate.forEach(({ field }) => {
1814
1784
  const [fromAlias, fromField] = this.helper.splitField(field);
1815
1785
  const aliasedField = `${fromAlias}.${fromField}`;
1816
- const join = Object.keys(this._joins).find(k => `${aliasedField}#${this._joins[k].alias}` === k);
1817
- if (join && this._joins[join] && this.helper.isOneToOneInverse(fromField)) {
1818
- this._populateMap[join] = this._joins[join].alias;
1786
+ const join = Object.keys(this.#state.joins).find(k => `${aliasedField}#${this.#state.joins[k].alias}` === k);
1787
+ if (join && this.#state.joins[join] && this.helper.isOneToOneInverse(fromField)) {
1788
+ this.#state.populateMap[join] = this.#state.joins[join].alias;
1819
1789
  return;
1820
1790
  }
1821
1791
  if (meta && this.helper.isOneToOneInverse(fromField)) {
1822
1792
  const prop = meta.properties[fromField];
1823
1793
  const alias = this.getNextAlias(prop.pivotEntity ?? prop.targetMeta.class);
1824
1794
  const aliasedName = `${fromAlias}.${prop.name}#${alias}`;
1825
- this._joins[aliasedName] = this.helper.joinOneToReference(prop, this.mainAlias.aliasName, alias, JoinType.leftJoin);
1826
- this._joins[aliasedName].path =
1827
- `${Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? meta.className}.${prop.name}`;
1828
- this._populateMap[aliasedName] = this._joins[aliasedName].alias;
1795
+ this.#state.joins[aliasedName] = this.helper.joinOneToReference(prop, this.mainAlias.aliasName, alias, JoinType.leftJoin);
1796
+ this.#state.joins[aliasedName].path =
1797
+ `${Object.values(this.#state.joins).find(j => j.alias === fromAlias)?.path ?? meta.className}.${prop.name}`;
1798
+ this.#state.populateMap[aliasedName] = this.#state.joins[aliasedName].alias;
1829
1799
  this.createAlias(prop.targetMeta.class, alias);
1830
1800
  }
1831
1801
  });
1832
1802
  this.processPopulateWhere(false);
1833
1803
  this.processPopulateWhere(true);
1834
- this.populateHintFinalized = true;
1804
+ this.#state.populateHintFinalized = true;
1835
1805
  }
1836
1806
  processPopulateWhere(filter) {
1837
- const key = filter ? '_populateFilter' : '_populateWhere';
1838
- if (this[key] == null || this[key] === PopulateHint.ALL) {
1807
+ const value = filter ? this.#state.populateFilter : this.#state.populateWhere;
1808
+ if (value == null || value === PopulateHint.ALL) {
1839
1809
  return;
1840
1810
  }
1841
- let joins = Object.values(this._joins);
1811
+ let joins = Object.values(this.#state.joins);
1842
1812
  for (const join of joins) {
1843
1813
  join.cond_ ??= join.cond;
1844
1814
  join.cond = { ...join.cond };
1845
1815
  }
1846
- if (typeof this[key] === 'object') {
1847
- const cond = CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, this[key]).process(this, { matchPopulateJoins: true, ignoreBranching: true, preferNoBranch: true, filter });
1816
+ if (typeof value === 'object') {
1817
+ const cond = CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, value).process(this, { matchPopulateJoins: true, ignoreBranching: true, preferNoBranch: true, filter });
1848
1818
  // there might be new joins created by processing the `populateWhere` object
1849
- joins = Object.values(this._joins);
1819
+ joins = Object.values(this.#state.joins);
1850
1820
  this.mergeOnConditions(joins, cond, filter);
1851
1821
  }
1852
1822
  }
@@ -1892,10 +1862,10 @@ export class QueryBuilder {
1892
1862
  * otherwise the inner join could discard rows of the root table.
1893
1863
  */
1894
1864
  processNestedJoins() {
1895
- if (this.flags.has(QueryFlag.DISABLE_NESTED_INNER_JOIN)) {
1865
+ if (this.#state.flags.has(QueryFlag.DISABLE_NESTED_INNER_JOIN)) {
1896
1866
  return;
1897
1867
  }
1898
- const joins = Object.values(this._joins);
1868
+ const joins = Object.values(this.#state.joins);
1899
1869
  const lookupParentGroup = (j) => {
1900
1870
  return j.nested ?? (j.parent ? lookupParentGroup(j.parent) : undefined);
1901
1871
  };
@@ -1918,30 +1888,30 @@ export class QueryBuilder {
1918
1888
  }
1919
1889
  }
1920
1890
  hasToManyJoins() {
1921
- return Object.values(this._joins).some(join => {
1891
+ return Object.values(this.#state.joins).some(join => {
1922
1892
  return [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(join.prop.kind);
1923
1893
  });
1924
1894
  }
1925
1895
  wrapPaginateSubQuery(meta) {
1926
1896
  const schema = this.getSchema(this.mainAlias);
1927
1897
  const pks = this.prepareFields(meta.primaryKeys, 'sub-query', schema);
1928
- const subQuery = this.clone(['_orderBy', '_fields', 'lockMode', 'lockTableAliases'])
1898
+ const subQuery = this.clone(['orderBy', 'fields', 'lockMode', 'lockTables'])
1929
1899
  .select(pks)
1930
1900
  .groupBy(pks)
1931
- .limit(this._limit);
1901
+ .limit(this.#state.limit);
1932
1902
  // revert the on conditions added via populateWhere, we want to apply those only once
1933
- for (const join of Object.values(subQuery._joins)) {
1903
+ for (const join of Object.values(subQuery.#state.joins)) {
1934
1904
  if (join.cond_) {
1935
1905
  join.cond = join.cond_;
1936
1906
  }
1937
1907
  }
1938
- if (this._offset) {
1939
- subQuery.offset(this._offset);
1908
+ if (this.#state.offset) {
1909
+ subQuery.offset(this.#state.offset);
1940
1910
  }
1941
1911
  const addToSelect = [];
1942
- if (this._orderBy.length > 0) {
1912
+ if (this.#state.orderBy.length > 0) {
1943
1913
  const orderBy = [];
1944
- for (const orderMap of this._orderBy) {
1914
+ for (const orderMap of this.#state.orderBy) {
1945
1915
  for (const field of Utils.getObjectQueryKeys(orderMap)) {
1946
1916
  const direction = orderMap[field];
1947
1917
  if (RawQueryFragment.isKnownFragmentSymbol(field)) {
@@ -1962,11 +1932,11 @@ export class QueryBuilder {
1962
1932
  }
1963
1933
  subQuery.orderBy(orderBy);
1964
1934
  }
1965
- subQuery.finalized = true;
1935
+ subQuery.#state.finalized = true;
1966
1936
  const innerQuery = subQuery.as(this.mainAlias.aliasName).clear('select').select(pks);
1967
1937
  if (addToSelect.length > 0) {
1968
1938
  addToSelect.forEach(prop => {
1969
- const field = this._fields.find(field => {
1939
+ const field = this.#state.fields.find(field => {
1970
1940
  if (typeof field === 'object' && field && '__as' in field) {
1971
1941
  return field.__as === prop;
1972
1942
  }
@@ -1992,18 +1962,18 @@ export class QueryBuilder {
1992
1962
  // https://stackoverflow.com/questions/17892762/mysql-this-version-of-mysql-doesnt-yet-support-limit-in-all-any-some-subqu
1993
1963
  const subSubQuery = this.platform.createNativeQueryBuilder();
1994
1964
  subSubQuery.select(pks).from(innerQuery);
1995
- this._limit = undefined;
1996
- this._offset = undefined;
1965
+ this.#state.limit = undefined;
1966
+ this.#state.offset = undefined;
1997
1967
  // Save the original WHERE conditions before pruning joins
1998
- const originalCond = this._cond;
1968
+ const originalCond = this.#state.cond;
1999
1969
  const populatePaths = this.getPopulatePaths();
2000
- if (!this._fields.some(field => isRaw(field))) {
1970
+ if (!this.#state.fields.some(field => isRaw(field))) {
2001
1971
  this.pruneJoinsForPagination(meta, populatePaths);
2002
1972
  }
2003
1973
  // Transfer WHERE conditions to ORDER BY joins (GH #6160)
2004
1974
  this.transferConditionsForOrderByJoins(meta, originalCond, populatePaths);
2005
1975
  const { sql, params } = subSubQuery.compile();
2006
- this.select(this._fields).where({
1976
+ this.select(this.#state.fields).where({
2007
1977
  [Utils.getPrimaryKeyHash(meta.primaryKeys)]: { $in: raw(sql, params) },
2008
1978
  });
2009
1979
  }
@@ -2022,7 +1992,7 @@ export class QueryBuilder {
2022
1992
  }
2023
1993
  }
2024
1994
  }
2025
- addPath(this._populate);
1995
+ addPath(this.#state.populate);
2026
1996
  return paths;
2027
1997
  }
2028
1998
  normalizeJoinPath(join, meta) {
@@ -2034,14 +2004,14 @@ export class QueryBuilder {
2034
2004
  * GH #6160
2035
2005
  */
2036
2006
  transferConditionsForOrderByJoins(meta, cond, populatePaths) {
2037
- if (!cond || this._orderBy.length === 0) {
2007
+ if (!cond || this.#state.orderBy.length === 0) {
2038
2008
  return;
2039
2009
  }
2040
- const orderByAliases = new Set(this._orderBy
2010
+ const orderByAliases = new Set(this.#state.orderBy
2041
2011
  .flatMap(hint => Object.keys(hint))
2042
2012
  .filter(k => !RawQueryFragment.isKnownFragmentSymbol(k))
2043
2013
  .map(k => k.split('.')[0]));
2044
- for (const join of Object.values(this._joins)) {
2014
+ for (const join of Object.values(this.#state.joins)) {
2045
2015
  const joinPath = this.normalizeJoinPath(join, meta);
2046
2016
  const isPopulateJoin = populatePaths.has(joinPath);
2047
2017
  // Only transfer conditions for joins used for ORDER BY but not for population
@@ -2054,8 +2024,8 @@ export class QueryBuilder {
2054
2024
  * Removes joins that are not used for population or ordering to improve performance.
2055
2025
  */
2056
2026
  pruneJoinsForPagination(meta, populatePaths) {
2057
- const orderByAliases = this._orderBy.flatMap(hint => Object.keys(hint)).map(k => k.split('.')[0]);
2058
- const joins = Object.entries(this._joins);
2027
+ const orderByAliases = this.#state.orderBy.flatMap(hint => Object.keys(hint)).map(k => k.split('.')[0]);
2028
+ const joins = Object.entries(this.#state.joins);
2059
2029
  const rootAlias = this.alias;
2060
2030
  function addParentAlias(alias) {
2061
2031
  const join = joins.find(j => j[1].alias === alias);
@@ -2070,7 +2040,7 @@ export class QueryBuilder {
2070
2040
  for (const [key, join] of joins) {
2071
2041
  const path = this.normalizeJoinPath(join, meta);
2072
2042
  if (!populatePaths.has(path) && !orderByAliases.includes(join.alias)) {
2073
- delete this._joins[key];
2043
+ delete this.#state.joins[key];
2074
2044
  }
2075
2045
  }
2076
2046
  }
@@ -2102,25 +2072,25 @@ export class QueryBuilder {
2102
2072
  }
2103
2073
  wrapModifySubQuery(meta) {
2104
2074
  const subQuery = this.clone();
2105
- subQuery.finalized = true;
2075
+ subQuery.#state.finalized = true;
2106
2076
  // wrap one more time to get around MySQL limitations
2107
2077
  // https://stackoverflow.com/questions/45494/mysql-error-1093-cant-specify-target-table-for-update-in-from-clause
2108
2078
  const subSubQuery = this.platform.createNativeQueryBuilder();
2109
- const method = this.flags.has(QueryFlag.UPDATE_SUB_QUERY) ? 'update' : 'delete';
2079
+ const method = this.#state.flags.has(QueryFlag.UPDATE_SUB_QUERY) ? 'update' : 'delete';
2110
2080
  const schema = this.getSchema(this.mainAlias);
2111
2081
  const pks = this.prepareFields(meta.primaryKeys, 'sub-query', schema);
2112
- this._cond = {}; // otherwise we would trigger validation error
2113
- this._joins = {}; // included in the subquery
2082
+ this.#state.cond = {}; // otherwise we would trigger validation error
2083
+ this.#state.joins = {}; // included in the subquery
2114
2084
  subSubQuery.select(pks).from(subQuery.as(this.mainAlias.aliasName));
2115
2085
  const { sql, params } = subSubQuery.compile();
2116
- this[method](this._data).where({
2086
+ this[method](this.#state.data).where({
2117
2087
  [Utils.getPrimaryKeyHash(meta.primaryKeys)]: { $in: raw(sql, params) },
2118
2088
  });
2119
2089
  }
2120
2090
  getSchema(alias) {
2121
2091
  const { meta } = alias;
2122
2092
  const metaSchema = meta.schema && meta.schema !== '*' ? meta.schema : undefined;
2123
- const schema = this._schema ?? metaSchema ?? this.em?.schema ?? this.em?.config.getSchema(true);
2093
+ const schema = this.#state.schema ?? metaSchema ?? this.em?.schema ?? this.em?.config.getSchema(true);
2124
2094
  if (schema === this.platform.getDefaultSchemaName()) {
2125
2095
  return undefined;
2126
2096
  }
@@ -2130,51 +2100,51 @@ export class QueryBuilder {
2130
2100
  createAlias(entityName, aliasName, subQuery) {
2131
2101
  const meta = this.metadata.find(entityName);
2132
2102
  const alias = { aliasName, entityName, meta, subQuery };
2133
- this._aliases[aliasName] = alias;
2103
+ this.#state.aliases[aliasName] = alias;
2134
2104
  return alias;
2135
2105
  }
2136
2106
  createMainAlias(entityName, aliasName, subQuery) {
2137
- this._mainAlias = this.createAlias(entityName, aliasName, subQuery);
2138
- this._helper = this.createQueryBuilderHelper();
2139
- return this._mainAlias;
2107
+ this.#state.mainAlias = this.createAlias(entityName, aliasName, subQuery);
2108
+ this.#helper = this.createQueryBuilderHelper();
2109
+ return this.#state.mainAlias;
2140
2110
  }
2141
2111
  fromSubQuery(target, aliasName) {
2142
2112
  const { entityName } = target.mainAlias;
2143
2113
  aliasName ??= this.getNextAlias(entityName);
2144
- const subQuery = target._unionQuery ? target.toRaw() : target.getNativeQuery();
2114
+ const subQuery = target.#state.unionQuery ? target.toRaw() : target.getNativeQuery();
2145
2115
  this.createMainAlias(entityName, aliasName, subQuery);
2146
2116
  }
2147
2117
  fromEntityName(entityName, aliasName) {
2148
- aliasName ??= this._mainAlias?.aliasName ?? this.getNextAlias(entityName);
2118
+ aliasName ??= this.#state.mainAlias?.aliasName ?? this.getNextAlias(entityName);
2149
2119
  this.createMainAlias(entityName, aliasName);
2150
2120
  }
2151
2121
  fromRawTable(tableName, aliasName) {
2152
- aliasName ??= this._mainAlias?.aliasName ?? this.getNextAlias(tableName);
2122
+ aliasName ??= this.#state.mainAlias?.aliasName ?? this.getNextAlias(tableName);
2153
2123
  const meta = new EntityMetadata({
2154
2124
  className: tableName,
2155
2125
  collection: tableName,
2156
2126
  });
2157
2127
  meta.root = meta;
2158
- this._mainAlias = {
2128
+ this.#state.mainAlias = {
2159
2129
  aliasName,
2160
2130
  entityName: tableName,
2161
2131
  meta,
2162
2132
  rawTableName: tableName,
2163
2133
  };
2164
- this._aliases[aliasName] = this._mainAlias;
2165
- this._helper = this.createQueryBuilderHelper();
2134
+ this.#state.aliases[aliasName] = this.#state.mainAlias;
2135
+ this.#helper = this.createQueryBuilderHelper();
2166
2136
  }
2167
2137
  createQueryBuilderHelper() {
2168
- return new QueryBuilderHelper(this.mainAlias.entityName, this.mainAlias.aliasName, this._aliases, this.subQueries, this.driver, this._tptAlias);
2138
+ return new QueryBuilderHelper(this.mainAlias.entityName, this.mainAlias.aliasName, this.#state.aliases, this.#state.subQueries, this.driver, this.#state.tptAlias);
2169
2139
  }
2170
2140
  ensureFromClause() {
2171
2141
  /* v8 ignore next */
2172
- if (!this._mainAlias) {
2142
+ if (!this.#state.mainAlias) {
2173
2143
  throw new Error(`Cannot proceed to build a query because the main alias is not set.`);
2174
2144
  }
2175
2145
  }
2176
2146
  ensureNotFinalized() {
2177
- if (this.finalized) {
2147
+ if (this.#state.finalized) {
2178
2148
  throw new Error('This QueryBuilder instance is already finalized, clone it first if you want to modify it.');
2179
2149
  }
2180
2150
  }
@@ -2191,26 +2161,27 @@ export class QueryBuilder {
2191
2161
  .forEach(k => delete object[k]);
2192
2162
  hidden.forEach(k => delete object[k]);
2193
2163
  let prefix = this.type ? this.type.substring(0, 1) + this.type.toLowerCase().substring(1) : '';
2194
- if (this._data) {
2195
- object.data = this._data;
2164
+ if (this.#state.data) {
2165
+ object.data = this.#state.data;
2196
2166
  }
2197
- if (this._schema) {
2198
- object.schema = this._schema;
2167
+ if (this.#state.schema) {
2168
+ object.schema = this.#state.schema;
2199
2169
  }
2200
- if (!Utils.isEmpty(this._cond)) {
2201
- object.where = this._cond;
2170
+ if (!Utils.isEmpty(this.#state.cond)) {
2171
+ object.where = this.#state.cond;
2202
2172
  }
2203
- if (this._onConflict?.[0]) {
2173
+ if (this.#state.onConflict?.[0]) {
2204
2174
  prefix = 'Upsert';
2205
- object.onConflict = this._onConflict[0];
2175
+ object.onConflict = this.#state.onConflict[0];
2206
2176
  }
2207
- if (!Utils.isEmpty(this._orderBy)) {
2208
- object.orderBy = this._orderBy;
2177
+ if (!Utils.isEmpty(this.#state.orderBy)) {
2178
+ object.orderBy = this.#state.orderBy;
2209
2179
  }
2210
- const name = this._mainAlias
2211
- ? `${prefix}QueryBuilder<${Utils.className(this._mainAlias?.entityName)}>`
2180
+ const name = this.#state.mainAlias
2181
+ ? `${prefix}QueryBuilder<${Utils.className(this.#state.mainAlias?.entityName)}>`
2212
2182
  : 'QueryBuilder';
2213
2183
  const ret = inspect(object, { depth });
2214
2184
  return ret === '[Object]' ? `[${name}]` : name + ' ' + ret;
2215
2185
  }
2216
2186
  }
2187
+ _a = QueryBuilder;