@mikro-orm/knex 6.3.13-dev.12 → 6.3.13-dev.13

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.
@@ -55,7 +55,8 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
55
55
  protected getFieldsForJoinedLoad<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, explicitFields?: Field<T>[], exclude?: Field<T>[], populate?: PopulateOptions<T>[], options?: {
56
56
  strategy?: Options['loadStrategy'];
57
57
  populateWhere?: FindOptions<any>['populateWhere'];
58
- }, parentTableAlias?: string, parentJoinPath?: string): Field<T>[];
58
+ populateFilter?: FindOptions<any>['populateFilter'];
59
+ }, parentTableAlias?: string, parentJoinPath?: string, count?: boolean): Field<T>[];
59
60
  /**
60
61
  * @internal
61
62
  */
@@ -76,5 +77,5 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
76
77
  protected normalizeFields<T extends object>(fields: Field<T>[], prefix?: string): string[];
77
78
  protected processField<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T> | undefined, field: string, ret: Field<T>[], populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T, any, any, any>): void;
78
79
  protected isPopulated<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T>, hint: PopulateOptions<T>, name?: string): boolean;
79
- protected buildFields<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T, any, any, any>, alias: string, options: Pick<FindOptions<T, any, any, any>, 'strategy' | 'fields' | 'exclude'>): Field<T>[];
80
+ protected buildFields<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], joinedProps: PopulateOptions<T>[], qb: QueryBuilder<T, any, any, any>, alias: string, options: Pick<FindOptions<T, any, any, any>, 'strategy' | 'fields' | 'exclude'>, count?: boolean): Field<T>[];
80
81
  }
@@ -311,15 +311,21 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
311
311
  if (meta?.virtual) {
312
312
  return this.countVirtual(entityName, where, options);
313
313
  }
314
+ const joinedProps = meta ? this.joinedProps(meta, options.populate ?? []) : [];
315
+ const populateWhere = meta ? this.buildPopulateWhere(meta, joinedProps, options) : undefined;
316
+ const populate = options.populate ?? [];
314
317
  const qb = this.createQueryBuilder(entityName, options.ctx, options.connectionType, false, options.logging)
315
318
  .indexHint(options.indexHint)
316
319
  .comment(options.comments)
317
320
  .hintComment(options.hintComments)
318
321
  .groupBy(options.groupBy)
319
322
  .having(options.having)
320
- .populate(options.populate ?? [])
323
+ .populate(populate, joinedProps.length > 0 ? populateWhere : undefined, joinedProps.length > 0 ? options.populateFilter : undefined)
321
324
  .withSchema(this.getSchemaName(meta, options))
322
325
  .where(where);
326
+ if (meta && !core_1.Utils.isEmpty(populate)) {
327
+ this.buildFields(meta, populate, joinedProps, qb, qb.alias, options, true);
328
+ }
323
329
  return this.rethrow(qb.getCount());
324
330
  }
325
331
  async nativeInsert(entityName, data, options = {}) {
@@ -909,7 +915,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
909
915
  }
910
916
  return res;
911
917
  }
912
- getFieldsForJoinedLoad(qb, meta, explicitFields, exclude, populate = [], options, parentTableAlias, parentJoinPath) {
918
+ getFieldsForJoinedLoad(qb, meta, explicitFields, exclude, populate = [], options, parentTableAlias, parentJoinPath, count) {
913
919
  const fields = [];
914
920
  const joinedProps = this.joinedProps(meta, populate, options);
915
921
  const shouldHaveColumn = (prop, populate, fields) => {
@@ -929,12 +935,15 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
929
935
  .filter(prop => shouldHaveColumn(prop, populate, explicitFields))
930
936
  .forEach(prop => fields.push(...this.mapPropToFieldNames(qb, prop, parentTableAlias)));
931
937
  }
932
- joinedProps.forEach(hint => {
938
+ for (const hint of joinedProps) {
933
939
  const [propName, ref] = hint.field.split(':', 2);
934
940
  const prop = meta.properties[propName];
935
941
  // ignore ref joins of known FKs unless it's a filter hint
936
942
  if (ref && !hint.filter && (prop.kind === core_1.ReferenceKind.MANY_TO_ONE || (prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner))) {
937
- return;
943
+ continue;
944
+ }
945
+ if (count && (!options?.populateFilter || !options.populateFilter[prop.name])) {
946
+ continue;
938
947
  }
939
948
  const meta2 = this.metadata.find(prop.type);
940
949
  const pivotRefJoin = prop.kind === core_1.ReferenceKind.MANY_TO_MANY && ref;
@@ -954,7 +963,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
954
963
  fields.push(...prop.joinColumns.map(col => qb.helper.mapper(`${tableAlias}.${col}`, qb.type, undefined, `${tableAlias}__${col}`)), ...prop.inverseJoinColumns.map(col => qb.helper.mapper(`${tableAlias}.${col}`, qb.type, undefined, `${tableAlias}__${col}`)));
955
964
  }
956
965
  if (prop.kind === core_1.ReferenceKind.ONE_TO_MANY && ref) {
957
- fields.push(...this.getFieldsForJoinedLoad(qb, meta2, prop.referencedColumnNames, undefined, hint.children, options, tableAlias, path));
966
+ fields.push(...this.getFieldsForJoinedLoad(qb, meta2, prop.referencedColumnNames, undefined, hint.children, options, tableAlias, path, count));
958
967
  }
959
968
  const childExplicitFields = explicitFields?.filter(f => core_1.Utils.isPlainObject(f)).map(o => o[prop.name])[0] || [];
960
969
  explicitFields?.forEach(f => {
@@ -964,12 +973,12 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
964
973
  });
965
974
  const childExclude = exclude ? core_1.Utils.extractChildElements(exclude, prop.name) : exclude;
966
975
  if (!ref) {
967
- fields.push(...this.getFieldsForJoinedLoad(qb, meta2, childExplicitFields.length === 0 ? undefined : childExplicitFields, childExclude, hint.children, options, tableAlias, path));
976
+ fields.push(...this.getFieldsForJoinedLoad(qb, meta2, childExplicitFields.length === 0 ? undefined : childExplicitFields, childExclude, hint.children, options, tableAlias, path, count));
968
977
  }
969
978
  else if (hint.filter) {
970
979
  fields.push(...prop.referencedColumnNames.map(col => qb.helper.mapper(`${tableAlias}.${col}`, qb.type, undefined, `${tableAlias}__${col}`)));
971
980
  }
972
- });
981
+ }
973
982
  return fields;
974
983
  }
975
984
  /**
@@ -1232,7 +1241,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
1232
1241
  }
1233
1242
  return false;
1234
1243
  }
1235
- buildFields(meta, populate, joinedProps, qb, alias, options) {
1244
+ buildFields(meta, populate, joinedProps, qb, alias, options, count = false) {
1236
1245
  const lazyProps = meta.props.filter(prop => prop.lazy && !populate.some(p => this.isPopulated(meta, prop, p)));
1237
1246
  const hasLazyFormulas = meta.props.some(p => p.lazy && p.formula);
1238
1247
  const requiresSQLConversion = meta.props.some(p => p.customType?.convertToJSValueSQL && p.persist !== false);
@@ -1287,7 +1296,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
1287
1296
  }
1288
1297
  // add joined relations after the root entity fields
1289
1298
  if (joinedProps.length > 0) {
1290
- ret.push(...this.getFieldsForJoinedLoad(qb, meta, options.fields, options.exclude, populate, options, alias));
1299
+ ret.push(...this.getFieldsForJoinedLoad(qb, meta, options.fields, options.exclude, populate, options, alias, undefined, count));
1291
1300
  }
1292
1301
  return core_1.Utils.unique(ret);
1293
1302
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/knex",
3
- "version": "6.3.13-dev.12",
3
+ "version": "6.3.13-dev.13",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",
@@ -66,7 +66,7 @@
66
66
  "@mikro-orm/core": "^6.3.12"
67
67
  },
68
68
  "peerDependencies": {
69
- "@mikro-orm/core": "6.3.13-dev.12",
69
+ "@mikro-orm/core": "6.3.13-dev.13",
70
70
  "better-sqlite3": "*",
71
71
  "libsql": "*",
72
72
  "mariadb": "*"
@@ -1172,7 +1172,6 @@ class QueryBuilder {
1172
1172
  let joins = Object.values(this._joins);
1173
1173
  for (const join of joins) {
1174
1174
  join.cond_ ??= join.cond;
1175
- // join.cond = {};
1176
1175
  join.cond = filter ? { ...join.cond } : {};
1177
1176
  }
1178
1177
  if (typeof this[key] === 'object') {