@mikro-orm/knex 6.0.0-dev.5 → 6.0.0-dev.51

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.
Files changed (42) hide show
  1. package/AbstractSqlConnection.d.ts +3 -0
  2. package/AbstractSqlConnection.js +16 -8
  3. package/AbstractSqlDriver.d.ts +11 -11
  4. package/AbstractSqlDriver.js +107 -44
  5. package/AbstractSqlPlatform.d.ts +2 -4
  6. package/AbstractSqlPlatform.js +15 -21
  7. package/MonkeyPatchable.d.ts +1 -0
  8. package/MonkeyPatchable.js +3 -0
  9. package/README.md +63 -106
  10. package/SqlEntityManager.d.ts +0 -4
  11. package/SqlEntityManager.js +1 -9
  12. package/SqlEntityRepository.d.ts +0 -1
  13. package/SqlEntityRepository.js +0 -1
  14. package/index.d.ts +1 -0
  15. package/index.js +1 -0
  16. package/index.mjs +175 -0
  17. package/package.json +5 -39
  18. package/query/ArrayCriteriaNode.d.ts +3 -3
  19. package/query/CriteriaNode.d.ts +8 -8
  20. package/query/CriteriaNode.js +8 -8
  21. package/query/CriteriaNodeFactory.d.ts +6 -6
  22. package/query/CriteriaNodeFactory.js +11 -11
  23. package/query/ObjectCriteriaNode.d.ts +3 -3
  24. package/query/ObjectCriteriaNode.js +12 -8
  25. package/query/QueryBuilder.d.ts +17 -4
  26. package/query/QueryBuilder.js +188 -45
  27. package/query/QueryBuilderHelper.d.ts +3 -5
  28. package/query/QueryBuilderHelper.js +85 -71
  29. package/query/ScalarCriteriaNode.d.ts +3 -2
  30. package/query/ScalarCriteriaNode.js +9 -6
  31. package/schema/DatabaseSchema.js +3 -3
  32. package/schema/DatabaseTable.d.ts +9 -9
  33. package/schema/DatabaseTable.js +21 -22
  34. package/schema/SchemaComparator.d.ts +4 -4
  35. package/schema/SchemaComparator.js +4 -2
  36. package/schema/SchemaHelper.d.ts +11 -11
  37. package/schema/SchemaHelper.js +3 -3
  38. package/schema/{SchemaGenerator.d.ts → SqlSchemaGenerator.d.ts} +4 -8
  39. package/schema/{SchemaGenerator.js → SqlSchemaGenerator.js} +17 -24
  40. package/schema/index.d.ts +1 -1
  41. package/schema/index.js +1 -1
  42. package/typings.d.ts +14 -13
@@ -1,6 +1,19 @@
1
1
  "use strict";
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
+ };
13
+ var _QueryBuilder_query;
2
14
  Object.defineProperty(exports, "__esModule", { value: true });
3
15
  exports.QueryBuilder = void 0;
16
+ const util_1 = require("util");
4
17
  const core_1 = require("@mikro-orm/core");
5
18
  const enums_1 = require("./enums");
6
19
  const QueryBuilderHelper_1 = require("./QueryBuilderHelper");
@@ -63,6 +76,7 @@ class QueryBuilder {
63
76
  this._aliases = {};
64
77
  this.platform = this.driver.getPlatform();
65
78
  this.knex = this.driver.getConnection(this.connectionType).getKnex();
79
+ _QueryBuilder_query.set(this, void 0);
66
80
  if (alias) {
67
81
  this.aliasCounter++;
68
82
  this._explicitAlias = true;
@@ -115,7 +129,7 @@ class QueryBuilder {
115
129
  this._fields = this.mainAlias.metadata.primaryKeys;
116
130
  }
117
131
  else {
118
- this._fields = [this.raw('*')];
132
+ this._fields = [(0, core_1.raw)('*')];
119
133
  }
120
134
  if (distinct) {
121
135
  this.flags.add(core_1.QueryFlag.DISTINCT);
@@ -164,9 +178,15 @@ class QueryBuilder {
164
178
  }
165
179
  where(cond, params, operator) {
166
180
  this.ensureNotFinalized();
167
- if (core_1.Utils.isString(cond)) {
168
- cond = { [`(${cond})`]: core_1.Utils.asArray(params) };
169
- operator = operator || '$and';
181
+ const rawField = core_1.RawQueryFragment.getKnownFragment(cond);
182
+ if (rawField) {
183
+ const sql = this.platform.formatQuery(rawField.sql, rawField.params);
184
+ cond = { [(0, core_1.raw)(`(${sql})`)]: core_1.Utils.asArray(params) };
185
+ operator ??= '$and';
186
+ }
187
+ else if (core_1.Utils.isString(cond)) {
188
+ cond = { [(0, core_1.raw)(`(${cond})`, core_1.Utils.asArray(params))]: [] };
189
+ operator ??= '$and';
170
190
  }
171
191
  else {
172
192
  cond = core_1.QueryHelper.processWhere({
@@ -234,7 +254,7 @@ class QueryBuilder {
234
254
  having(cond = {}, params) {
235
255
  this.ensureNotFinalized();
236
256
  if (core_1.Utils.isString(cond)) {
237
- cond = { [`(${cond})`]: core_1.Utils.asArray(params) };
257
+ cond = { [(0, core_1.raw)(`(${cond})`, params)]: [] };
238
258
  }
239
259
  this._having = CriteriaNodeFactory_1.CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, cond).process(this);
240
260
  return this;
@@ -277,11 +297,6 @@ class QueryBuilder {
277
297
  ref(field) {
278
298
  return this.knex.ref(field);
279
299
  }
280
- raw(sql, bindings = []) {
281
- const raw = this.knex.raw(sql, bindings);
282
- raw.__raw = true; // tag it as there is now way to check via `instanceof`
283
- return raw;
284
- }
285
300
  limit(limit, offset = 0) {
286
301
  this.ensureNotFinalized();
287
302
  this._limit = limit;
@@ -360,7 +375,8 @@ class QueryBuilder {
360
375
  core_1.Utils.runIfNotEmpty(() => {
361
376
  const queryOrder = this.helper.getQueryOrder(this.type ?? enums_1.QueryType.SELECT, this._orderBy, this._populateMap);
362
377
  if (queryOrder) {
363
- return qb.orderByRaw(queryOrder);
378
+ qb.orderByRaw(queryOrder);
379
+ return;
364
380
  }
365
381
  }, this._orderBy);
366
382
  core_1.Utils.runIfNotEmpty(() => qb.limit(this._limit), this._limit != null);
@@ -372,26 +388,34 @@ class QueryBuilder {
372
388
  if (this.lockMode) {
373
389
  this.helper.getLockSQL(qb, this.lockMode, this.lockTables);
374
390
  }
375
- this.helper.finalize(this.type ?? enums_1.QueryType.SELECT, qb, this.mainAlias.metadata);
391
+ this.helper.finalize(this.type ?? enums_1.QueryType.SELECT, qb, this.mainAlias.metadata, this._data);
376
392
  return qb;
377
393
  }
378
394
  /**
379
395
  * Returns the query with parameters as wildcards.
380
396
  */
381
397
  getQuery() {
382
- return this.getKnexQuery().toSQL().toNative().sql;
398
+ return this.toQuery().sql;
399
+ }
400
+ toQuery() {
401
+ if (__classPrivateFieldGet(this, _QueryBuilder_query, "f")) {
402
+ return __classPrivateFieldGet(this, _QueryBuilder_query, "f");
403
+ }
404
+ const sql = this.getKnexQuery().toSQL();
405
+ const query = sql.toNative();
406
+ return __classPrivateFieldSet(this, _QueryBuilder_query, { sql: query.sql, params: query.bindings ?? [], _sql: sql }, "f");
383
407
  }
384
408
  /**
385
409
  * Returns the list of all parameters for this query.
386
410
  */
387
411
  getParams() {
388
- return this.getKnexQuery().toSQL().toNative().bindings;
412
+ return this.toQuery().params;
389
413
  }
390
414
  /**
391
415
  * Returns raw interpolated query string with all the parameters inlined.
392
416
  */
393
417
  getFormattedQuery() {
394
- const query = this.getKnexQuery().toSQL();
418
+ const query = this.toQuery()._sql;
395
419
  return this.platform.formatQuery(query.sql, query.bindings);
396
420
  }
397
421
  /**
@@ -464,7 +488,27 @@ class QueryBuilder {
464
488
  if (this._joinedProps.size > 0) {
465
489
  res = this.driver.mergeJoinedResult(res, this.mainAlias.metadata);
466
490
  }
467
- return res.map(r => this.em.map(this.mainAlias.entityName, r, { schema: this._schema }));
491
+ const entities = [];
492
+ function propagatePopulateHint(entity, hint) {
493
+ (0, core_1.helper)(entity).__serializationContext.populate ??= hint;
494
+ hint.forEach(pop => {
495
+ const value = entity[pop.field];
496
+ if (core_1.Utils.isEntity(value, true)) {
497
+ (0, core_1.helper)(value).populated();
498
+ propagatePopulateHint(value, pop.children ?? []);
499
+ }
500
+ else if (core_1.Utils.isCollection(value)) {
501
+ value.populated();
502
+ value.getItems(false).forEach(item => propagatePopulateHint(item, pop.children ?? []));
503
+ }
504
+ });
505
+ }
506
+ for (const r of res) {
507
+ const entity = this.em.map(this.mainAlias.entityName, r, { schema: this._schema });
508
+ propagatePopulateHint(entity, this._populate);
509
+ entities.push(entity);
510
+ }
511
+ return entities;
468
512
  }
469
513
  /**
470
514
  * Executes the query, returning the first result or null
@@ -488,11 +532,24 @@ class QueryBuilder {
488
532
  }
489
533
  return res ? +res.count : 0;
490
534
  }
535
+ /**
536
+ * Executes the query, returning both array of results and total count query (without offset and limit).
537
+ */
538
+ async getResultAndCount() {
539
+ return Promise.all([
540
+ this.getResultList(),
541
+ this.getCount(),
542
+ ]);
543
+ }
491
544
  /**
492
545
  * Provides promise-like interface so we can await the QB instance.
493
546
  */
494
547
  then(onfulfilled, onrejected) {
495
- switch (this.type ?? enums_1.QueryType.SELECT) {
548
+ let type = this.type ?? enums_1.QueryType.SELECT;
549
+ if (this.flags.has(core_1.QueryFlag.UPDATE_SUB_QUERY) || this.flags.has(core_1.QueryFlag.DELETE_SUB_QUERY)) {
550
+ type = enums_1.QueryType.UPDATE;
551
+ }
552
+ switch (type) {
496
553
  case enums_1.QueryType.INSERT:
497
554
  case enums_1.QueryType.UPDATE:
498
555
  case enums_1.QueryType.DELETE:
@@ -515,7 +572,10 @@ class QueryBuilder {
515
572
  /* istanbul ignore next */
516
573
  alias = meta?.properties[f]?.fieldNames[0] ?? alias;
517
574
  }
518
- return qb.as(alias);
575
+ const ret = qb.as(alias);
576
+ // tag the instance, so it is possible to detect it easily
577
+ Object.defineProperty(ret, '__as', { enumerable: false, value: alias });
578
+ return ret;
519
579
  }
520
580
  clone() {
521
581
  const qb = new QueryBuilder(this.mainAlias.entityName, this.metadata, this.driver, this.context, this.mainAlias.aliasName, this.connectionType, this.em);
@@ -570,11 +630,11 @@ class QueryBuilder {
570
630
  aliased: !this.type || [enums_1.QueryType.SELECT, enums_1.QueryType.COUNT].includes(this.type),
571
631
  });
572
632
  let aliasedName = `${fromAlias}.${prop.name}#${alias}`;
573
- path ?? (path = `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? entityName)}.${prop.name}`);
574
- if (prop.reference === core_1.ReferenceType.ONE_TO_MANY) {
633
+ path ??= `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? entityName)}.${prop.name}`;
634
+ if (prop.kind === core_1.ReferenceKind.ONE_TO_MANY) {
575
635
  this._joins[aliasedName] = this.helper.joinOneToReference(prop, fromAlias, alias, type, cond);
576
636
  }
577
- else if (prop.reference === core_1.ReferenceType.MANY_TO_MANY) {
637
+ else if (prop.kind === core_1.ReferenceKind.MANY_TO_MANY) {
578
638
  let pivotAlias = alias;
579
639
  if (type !== 'pivotJoin') {
580
640
  const oldPivotAlias = this.getAliasForJoinPath(path + '[pivot]');
@@ -585,7 +645,7 @@ class QueryBuilder {
585
645
  Object.assign(this._joins, joins);
586
646
  this.createAlias(prop.pivotEntity, pivotAlias);
587
647
  }
588
- else if (prop.reference === core_1.ReferenceType.ONE_TO_ONE) {
648
+ else if (prop.kind === core_1.ReferenceKind.ONE_TO_ONE) {
589
649
  this._joins[aliasedName] = this.helper.joinOneToReference(prop, fromAlias, alias, type, cond);
590
650
  }
591
651
  else { // MANY_TO_ONE
@@ -599,17 +659,25 @@ class QueryBuilder {
599
659
  prepareFields(fields, type = 'where') {
600
660
  const ret = [];
601
661
  fields.forEach(field => {
662
+ const rawField = core_1.RawQueryFragment.getKnownFragment(field);
663
+ if (rawField) {
664
+ const sql = this.platform.formatQuery(rawField.sql, rawField.params);
665
+ ret.push(this.knex.raw(sql));
666
+ return;
667
+ }
602
668
  if (!core_1.Utils.isString(field)) {
603
- return ret.push(field);
669
+ ret.push(field);
670
+ return;
604
671
  }
605
672
  const join = Object.keys(this._joins).find(k => field === k.substring(0, k.indexOf('#')));
606
673
  if (join && type === 'where') {
607
- return ret.push(...this.helper.mapJoinColumns(this.type ?? enums_1.QueryType.SELECT, this._joins[join]));
674
+ ret.push(...this.helper.mapJoinColumns(this.type ?? enums_1.QueryType.SELECT, this._joins[join]));
675
+ return;
608
676
  }
609
677
  const [a, f] = this.helper.splitField(field);
610
678
  const prop = this.helper.getProperty(f, a);
611
679
  /* istanbul ignore next */
612
- if (prop && [core_1.ReferenceType.ONE_TO_MANY, core_1.ReferenceType.MANY_TO_MANY].includes(prop.reference)) {
680
+ if (prop && [core_1.ReferenceKind.ONE_TO_MANY, core_1.ReferenceKind.MANY_TO_MANY].includes(prop.kind)) {
613
681
  return;
614
682
  }
615
683
  if (prop?.embedded) {
@@ -617,7 +685,7 @@ class QueryBuilder {
617
685
  ret.push(fieldName);
618
686
  return;
619
687
  }
620
- if (prop?.reference === core_1.ReferenceType.EMBEDDED) {
688
+ if (prop?.kind === core_1.ReferenceKind.EMBEDDED) {
621
689
  if (prop.object) {
622
690
  ret.push(this.helper.mapper(prop.fieldNames[0], this.type));
623
691
  }
@@ -649,7 +717,7 @@ class QueryBuilder {
649
717
  const cols = this.helper.mapJoinColumns(this.type ?? enums_1.QueryType.SELECT, this._joins[f]);
650
718
  ret.push(...cols);
651
719
  }
652
- if (this._joins[f].prop.reference !== core_1.ReferenceType.ONE_TO_ONE && this._joins[f].inverseJoinColumns) {
720
+ if (this._joins[f].prop.kind !== core_1.ReferenceKind.ONE_TO_ONE && this._joins[f].inverseJoinColumns) {
653
721
  this._joins[f].inverseJoinColumns.forEach(inverseJoinColumn => {
654
722
  core_1.Utils.renameKey(this._cond, inverseJoinColumn, `${this._joins[f].alias}.${inverseJoinColumn}`);
655
723
  });
@@ -668,7 +736,7 @@ class QueryBuilder {
668
736
  }
669
737
  if (data) {
670
738
  if (core_1.Utils.isEntity(data)) {
671
- data = (0, core_1.helper)(data).toJSON();
739
+ data = this.em?.getComparator().prepareEntity(data) ?? (0, core_1.serialize)(data);
672
740
  }
673
741
  this._data = this.helper.processData(data, this.flags.has(core_1.QueryFlag.CONVERT_CUSTOM_TYPES));
674
742
  }
@@ -733,7 +801,7 @@ class QueryBuilder {
733
801
  if (meta && this.flags.has(core_1.QueryFlag.AUTO_JOIN_ONE_TO_ONE_OWNER)) {
734
802
  const relationsToPopulate = this._populate.map(({ field }) => field);
735
803
  meta.relations
736
- .filter(prop => prop.reference === core_1.ReferenceType.ONE_TO_ONE && !prop.owner && !relationsToPopulate.includes(prop.name))
804
+ .filter(prop => prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner && !relationsToPopulate.includes(prop.name))
737
805
  .map(prop => ({ field: prop.name }))
738
806
  .forEach(item => this._populate.push(item));
739
807
  }
@@ -742,7 +810,8 @@ class QueryBuilder {
742
810
  const aliasedField = `${fromAlias}.${fromField}`;
743
811
  const join = Object.keys(this._joins).find(k => `${aliasedField}#${this._joins[k].alias}` === k);
744
812
  if (join && this._joins[join] && this.helper.isOneToOneInverse(fromField)) {
745
- return this._populateMap[join] = this._joins[join].alias;
813
+ this._populateMap[join] = this._joins[join].alias;
814
+ return;
746
815
  }
747
816
  if (this.metadata.find(field)?.pivotTable) { // pivot table entity
748
817
  this.autoJoinPivotTable(field);
@@ -763,9 +832,15 @@ class QueryBuilder {
763
832
  const aliased = this.knex.ref(prop.fieldNames[0]).toString();
764
833
  return `${prop.formula(alias)} as ${aliased}`;
765
834
  })
766
- .filter(field => !this._fields.includes(field))
767
- .forEach(field => this.addSelect(field));
835
+ .filter(field => !this._fields.some(f => {
836
+ if (f instanceof core_1.RawQueryFragment) {
837
+ return f.sql === field && f.params.length === 0;
838
+ }
839
+ return f === field;
840
+ }))
841
+ .forEach(field => this._fields.push((0, core_1.raw)(field)));
768
842
  }
843
+ this.processPopulateWhere();
769
844
  core_1.QueryHelper.processObjectParams(this._data);
770
845
  core_1.QueryHelper.processObjectParams(this._cond);
771
846
  core_1.QueryHelper.processObjectParams(this._having);
@@ -781,17 +856,54 @@ class QueryBuilder {
781
856
  }
782
857
  this.finalized = true;
783
858
  }
859
+ processPopulateWhere() {
860
+ if (this._populateWhere == null || this._populateWhere === core_1.PopulateHint.ALL) {
861
+ return;
862
+ }
863
+ const joins = Object.values(this._joins);
864
+ joins.forEach(join => {
865
+ join.cond_ = join.cond;
866
+ join.cond = {};
867
+ });
868
+ const replaceOnConditions = (cond) => {
869
+ Object.keys(cond).forEach(k => {
870
+ if (core_1.Utils.isOperator(k)) {
871
+ if (Array.isArray(cond[k])) {
872
+ return cond[k].forEach((c) => replaceOnConditions(c));
873
+ }
874
+ return replaceOnConditions(cond[k]);
875
+ }
876
+ const [a] = this.helper.splitField(k);
877
+ const join = joins.find(j => j.alias === a);
878
+ if (join) {
879
+ join.cond = { ...join.cond, [k]: cond[k] };
880
+ }
881
+ });
882
+ };
883
+ if (this._populateWhere === core_1.PopulateHint.INFER) {
884
+ replaceOnConditions(this._cond);
885
+ }
886
+ else if (typeof this._populateWhere === 'object') {
887
+ const cond = CriteriaNodeFactory_1.CriteriaNodeFactory
888
+ .createNode(this.metadata, this.mainAlias.entityName, this._populateWhere)
889
+ .process(this);
890
+ replaceOnConditions(cond);
891
+ }
892
+ }
784
893
  hasToManyJoins() {
785
894
  return Object.values(this._joins).some(join => {
786
- return [core_1.ReferenceType.ONE_TO_MANY, core_1.ReferenceType.MANY_TO_MANY].includes(join.prop.reference);
895
+ return [core_1.ReferenceKind.ONE_TO_MANY, core_1.ReferenceKind.MANY_TO_MANY].includes(join.prop.kind);
787
896
  });
788
897
  }
789
898
  wrapPaginateSubQuery(meta) {
790
899
  const pks = this.prepareFields(meta.primaryKeys, 'sub-query');
791
900
  const subQuery = this.clone().select(pks).groupBy(pks).limit(this._limit);
901
+ // revert the on conditions added via populateWhere, we want to apply those only once
902
+ Object.values(subQuery._joins).forEach(join => join.cond = join.cond_ ?? {});
792
903
  if (this._offset) {
793
904
  subQuery.offset(this._offset);
794
905
  }
906
+ const addToSelect = [];
795
907
  if (this._orderBy.length > 0) {
796
908
  const orderBy = [];
797
909
  for (const orderMap of this._orderBy) {
@@ -799,28 +911,37 @@ class QueryBuilder {
799
911
  const [a, f] = this.helper.splitField(field);
800
912
  const prop = this.helper.getProperty(f, a);
801
913
  const type = this.platform.castColumn(prop);
802
- orderBy.push({
803
- [`min(${this.ref(this.helper.mapper(field, this.type, undefined, null))}${type})`]: direction,
804
- });
914
+ const fieldName = this.helper.mapper(field, this.type, undefined, null);
915
+ if (!prop?.persist && !prop?.formula) {
916
+ addToSelect.push(fieldName);
917
+ }
918
+ orderBy.push({ [(0, core_1.raw)(`min(${this.ref(fieldName)}${type})`)]: direction });
805
919
  }
806
920
  }
807
921
  subQuery.orderBy(orderBy);
808
922
  }
809
923
  subQuery.finalized = true;
810
924
  const knexQuery = subQuery.as(this.mainAlias.aliasName).clearSelect().select(pks);
925
+ if (addToSelect.length > 0) {
926
+ addToSelect.forEach(prop => {
927
+ const field = this._fields.find(field => {
928
+ if (typeof field === 'object' && field && '__as' in field) {
929
+ return field.__as === prop;
930
+ }
931
+ // not perfect, but should work most of the time, ideally we should check only the alias (`... as alias`)
932
+ return field.toString().includes(prop);
933
+ });
934
+ if (field) {
935
+ knexQuery.select(field);
936
+ }
937
+ });
938
+ }
811
939
  // multiple sub-queries are needed to get around mysql limitations with order by + limit + where in + group by (o.O)
812
940
  // https://stackoverflow.com/questions/17892762/mysql-this-version-of-mysql-doesnt-yet-support-limit-in-all-any-some-subqu
813
941
  const subSubQuery = this.getKnex().select(pks).from(knexQuery);
814
942
  this._limit = undefined;
815
943
  this._offset = undefined;
816
- const cond = this._cond;
817
944
  this.select(this._fields).where({ [core_1.Utils.getPrimaryKeyHash(meta.primaryKeys)]: { $in: subSubQuery } });
818
- if (this._populateWhere === core_1.PopulateHint.INFER) {
819
- this.andWhere(cond);
820
- }
821
- else if (typeof this._populateWhere === 'object') {
822
- this.andWhere(this._populateWhere);
823
- }
824
945
  }
825
946
  wrapModifySubQuery(meta) {
826
947
  const subQuery = this.clone();
@@ -864,11 +985,11 @@ class QueryBuilder {
864
985
  fromSubQuery(target, aliasName) {
865
986
  const subQuery = target.getKnexQuery();
866
987
  const { entityName } = target.mainAlias;
867
- aliasName ?? (aliasName = this.getNextAlias(entityName));
988
+ aliasName ??= this.getNextAlias(entityName);
868
989
  this.createMainAlias(entityName, aliasName, subQuery);
869
990
  }
870
991
  fromEntityName(entityName, aliasName) {
871
- aliasName ?? (aliasName = this._mainAlias?.aliasName ?? this.getNextAlias(entityName));
992
+ aliasName ??= this._mainAlias?.aliasName ?? this.getNextAlias(entityName);
872
993
  this.createMainAlias(entityName, aliasName);
873
994
  }
874
995
  createQueryBuilderHelper() {
@@ -885,5 +1006,27 @@ class QueryBuilder {
885
1006
  throw new Error('This QueryBuilder instance is already finalized, clone it first if you want to modify it.');
886
1007
  }
887
1008
  }
1009
+ /* istanbul ignore next */
1010
+ [(_QueryBuilder_query = new WeakMap(), util_1.inspect.custom)](depth) {
1011
+ const object = { ...this };
1012
+ const hidden = ['metadata', 'driver', 'context', 'platform', 'knex', 'type'];
1013
+ Object.keys(object).filter(k => k.startsWith('_')).forEach(k => delete object[k]);
1014
+ Object.keys(object).filter(k => object[k] == null).forEach(k => delete object[k]);
1015
+ hidden.forEach(k => delete object[k]);
1016
+ let prefix = this.type ? this.type.substring(0, 1) + this.type.toLowerCase().substring(1) : '';
1017
+ if (this._data) {
1018
+ object.data = this._data;
1019
+ }
1020
+ if (!core_1.Utils.isEmpty(this._cond)) {
1021
+ object.where = this._cond;
1022
+ }
1023
+ if (this._onConflict?.[0]) {
1024
+ prefix = 'Upsert';
1025
+ object.onConflict = this._onConflict[0];
1026
+ }
1027
+ const name = this._mainAlias ? `${prefix}QueryBuilder<${this._mainAlias?.entityName}>` : 'QueryBuilder';
1028
+ const ret = (0, util_1.inspect)(object, { depth });
1029
+ return ret === '[Object]' ? `[${name}]` : name + ' ' + ret;
1030
+ }
888
1031
  }
889
1032
  exports.QueryBuilder = QueryBuilder;
@@ -1,5 +1,5 @@
1
1
  import type { Knex } from 'knex';
2
- import type { Dictionary, EntityData, EntityMetadata, EntityProperty, FlatQueryOrderMap, QBFilterQuery } from '@mikro-orm/core';
2
+ import type { Dictionary, EntityData, EntityKey, EntityMetadata, EntityProperty, FlatQueryOrderMap, QBFilterQuery } from '@mikro-orm/core';
3
3
  import { LockMode } from '@mikro-orm/core';
4
4
  import { QueryType } from './enums';
5
5
  import type { Field, JoinOptions } from '../typings';
@@ -43,16 +43,14 @@ export declare class QueryBuilderHelper {
43
43
  }[], qb: Knex.QueryBuilder): void;
44
44
  appendQueryCondition(type: QueryType, cond: any, qb: Knex.QueryBuilder, operator?: '$and' | '$or', method?: 'where' | 'having'): void;
45
45
  private appendQuerySubCondition;
46
- private processCustomExpression;
47
46
  private processObjectSubCondition;
48
47
  private getOperatorReplacement;
49
48
  getQueryOrder(type: QueryType, orderBy: FlatQueryOrderMap | FlatQueryOrderMap[], populate: Dictionary<string>): string;
50
49
  getQueryOrderFromObject(type: QueryType, orderBy: FlatQueryOrderMap, populate: Dictionary<string>): string;
51
- finalize(type: QueryType, qb: Knex.QueryBuilder, meta?: EntityMetadata): void;
52
- splitField(field: string, greedyAlias?: boolean): [string, string];
50
+ finalize(type: QueryType, qb: Knex.QueryBuilder, meta?: EntityMetadata, data?: Dictionary): void;
51
+ splitField<T>(field: EntityKey<T>, greedyAlias?: boolean): [string, EntityKey<T>];
53
52
  getLockSQL(qb: Knex.QueryBuilder, lockMode: LockMode, lockTables?: string[]): void;
54
53
  updateVersionProperty(qb: Knex.QueryBuilder, data: Dictionary): void;
55
- static isCustomExpression(field: string, hasAlias?: boolean): boolean;
56
54
  private prefix;
57
55
  private appendGroupCondition;
58
56
  private isPrefixed;