@mikro-orm/knex 6.0.0-dev.305 → 6.0.0-dev.307
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.
package/AbstractSqlDriver.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
35
35
|
/**
|
|
36
36
|
* 1:1 owner side needs to be marked for population so QB auto-joins the owner id
|
|
37
37
|
*/
|
|
38
|
-
protected autoJoinOneToOneOwner<T extends object
|
|
38
|
+
protected autoJoinOneToOneOwner<T extends object>(meta: EntityMetadata<T>, populate: PopulateOptions<T>[], fields?: readonly EntityField<T, any>[]): PopulateOptions<T>[];
|
|
39
39
|
/**
|
|
40
40
|
* @internal
|
|
41
41
|
*/
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -766,7 +766,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
766
766
|
if (!this.config.get('autoJoinOneToOneOwner')) {
|
|
767
767
|
return populate;
|
|
768
768
|
}
|
|
769
|
-
const relationsToPopulate = populate.map(({ field }) => field);
|
|
769
|
+
const relationsToPopulate = populate.map(({ field }) => field.split(':')[0]);
|
|
770
770
|
const toPopulate = meta.relations
|
|
771
771
|
.filter(prop => prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner && !relationsToPopulate.includes(prop.name))
|
|
772
772
|
.filter(prop => fields.length === 0 || fields.some(f => prop.name === f || prop.name.startsWith(`${String(f)}.`)))
|
|
@@ -778,14 +778,14 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
778
778
|
*/
|
|
779
779
|
joinedProps(meta, populate, options) {
|
|
780
780
|
return populate.filter(hint => {
|
|
781
|
-
const [propName
|
|
781
|
+
const [propName] = hint.field.split(':', 2);
|
|
782
782
|
const prop = meta.properties[propName] || {};
|
|
783
|
+
if (hint.filter && hint.strategy === core_1.LoadStrategy.JOINED) {
|
|
784
|
+
return true;
|
|
785
|
+
}
|
|
783
786
|
if ((options?.strategy || hint.strategy || prop.strategy || this.config.get('loadStrategy')) !== core_1.LoadStrategy.JOINED) {
|
|
784
787
|
return false;
|
|
785
788
|
}
|
|
786
|
-
if (ref) {
|
|
787
|
-
return [core_1.ReferenceKind.MANY_TO_MANY, core_1.ReferenceKind.ONE_TO_MANY].includes(prop.kind);
|
|
788
|
-
}
|
|
789
789
|
return ![core_1.ReferenceKind.SCALAR, core_1.ReferenceKind.EMBEDDED].includes(prop.kind);
|
|
790
790
|
});
|
|
791
791
|
}
|
|
@@ -853,15 +853,23 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
853
853
|
joinedProps.forEach(hint => {
|
|
854
854
|
const [propName, ref] = hint.field.split(':', 2);
|
|
855
855
|
const prop = meta.properties[propName];
|
|
856
|
+
// ignore ref joins of known FKs unless it's a filter hint
|
|
857
|
+
if (ref && !hint.filter && (prop.kind === core_1.ReferenceKind.MANY_TO_ONE || (prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner))) {
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
856
860
|
const meta2 = this.metadata.find(prop.type);
|
|
857
861
|
const pivotRefJoin = prop.kind === core_1.ReferenceKind.MANY_TO_MANY && ref;
|
|
858
862
|
const tableAlias = qb.getNextAlias(prop.name);
|
|
859
863
|
const field = parentTableAlias ? `${parentTableAlias}.${prop.name}` : prop.name;
|
|
860
864
|
let path = parentJoinPath ? `${parentJoinPath}.${prop.name}` : `${meta.name}.${prop.name}`;
|
|
861
|
-
if (!parentJoinPath && populateWhereAll && !path.startsWith('[populate]')) {
|
|
865
|
+
if (!parentJoinPath && populateWhereAll && !hint.filter && !path.startsWith('[populate]')) {
|
|
862
866
|
path = '[populate]' + path;
|
|
863
867
|
}
|
|
864
|
-
const joinType = pivotRefJoin
|
|
868
|
+
const joinType = pivotRefJoin
|
|
869
|
+
? query_1.JoinType.pivotJoin
|
|
870
|
+
: hint.filter && !prop.nullable
|
|
871
|
+
? query_1.JoinType.innerJoin
|
|
872
|
+
: query_1.JoinType.leftJoin;
|
|
865
873
|
qb.join(field, tableAlias, {}, joinType, path);
|
|
866
874
|
if (pivotRefJoin) {
|
|
867
875
|
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}`)));
|
|
@@ -879,6 +887,9 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
879
887
|
if (!ref) {
|
|
880
888
|
fields.push(...this.getFieldsForJoinedLoad(qb, meta2, childExplicitFields.length === 0 ? undefined : childExplicitFields, childExclude, hint.children, options, tableAlias, path));
|
|
881
889
|
}
|
|
890
|
+
else if (hint.filter) {
|
|
891
|
+
fields.push(field);
|
|
892
|
+
}
|
|
882
893
|
});
|
|
883
894
|
return fields;
|
|
884
895
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.0.0-dev.
|
|
3
|
+
"version": "6.0.0-dev.307",
|
|
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,6 +66,6 @@
|
|
|
66
66
|
"@mikro-orm/core": "^5.0.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.0.0-dev.
|
|
69
|
+
"@mikro-orm/core": "6.0.0-dev.307"
|
|
70
70
|
}
|
|
71
71
|
}
|
package/query/QueryBuilder.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { inspect } from 'util';
|
|
3
3
|
import type { Knex } from 'knex';
|
|
4
4
|
import { type AnyEntity, type ConnectionType, type Dictionary, type EntityData, type EntityName, type EntityProperty, type FlushMode, type GroupOperator, LockMode, type LoggingOptions, type MetadataStorage, type ObjectQuery, PopulateHint, type PopulateOptions, type QBFilterQuery, type QBQueryOrderMap, QueryFlag, type QueryResult, type RequiredEntityData } from '@mikro-orm/core';
|
|
5
|
-
import {
|
|
5
|
+
import { JoinType, QueryType } from './enums';
|
|
6
6
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver';
|
|
7
7
|
import { type Alias, QueryBuilderHelper } from './QueryBuilderHelper';
|
|
8
8
|
import type { SqlEntityManager } from '../SqlEntityManager';
|
package/query/QueryBuilder.js
CHANGED
|
@@ -264,19 +264,20 @@ class QueryBuilder {
|
|
|
264
264
|
const op = operator || params;
|
|
265
265
|
const topLevel = !op || !core_1.Utils.hasObjectKeys(this._cond);
|
|
266
266
|
const criteriaNode = CriteriaNodeFactory_1.CriteriaNodeFactory.createNode(this.metadata, this.mainAlias.entityName, cond);
|
|
267
|
+
const ignoreBranching = this.__populateWhere === 'infer';
|
|
267
268
|
if ([enums_1.QueryType.UPDATE, enums_1.QueryType.DELETE].includes(this.type) && criteriaNode.willAutoJoin(this)) {
|
|
268
269
|
// use sub-query to support joining
|
|
269
270
|
this.setFlag(this.type === enums_1.QueryType.UPDATE ? core_1.QueryFlag.UPDATE_SUB_QUERY : core_1.QueryFlag.DELETE_SUB_QUERY);
|
|
270
271
|
this.select(this.mainAlias.metadata.primaryKeys, true);
|
|
271
272
|
}
|
|
272
273
|
if (topLevel) {
|
|
273
|
-
this._cond = criteriaNode.process(this);
|
|
274
|
+
this._cond = criteriaNode.process(this, { ignoreBranching });
|
|
274
275
|
}
|
|
275
276
|
else if (Array.isArray(this._cond[op])) {
|
|
276
|
-
this._cond[op].push(criteriaNode.process(this));
|
|
277
|
+
this._cond[op].push(criteriaNode.process(this, { ignoreBranching }));
|
|
277
278
|
}
|
|
278
279
|
else {
|
|
279
|
-
const cond1 = [this._cond, criteriaNode.process(this)];
|
|
280
|
+
const cond1 = [this._cond, criteriaNode.process(this, { ignoreBranching })];
|
|
280
281
|
this._cond = { [op]: cond1 };
|
|
281
282
|
}
|
|
282
283
|
if (this._onConflict) {
|
|
@@ -1060,18 +1061,24 @@ class QueryBuilder {
|
|
|
1060
1061
|
join.cond_ = join.cond;
|
|
1061
1062
|
join.cond = {};
|
|
1062
1063
|
});
|
|
1063
|
-
const replaceOnConditions = (cond) => {
|
|
1064
|
+
const replaceOnConditions = (cond, op) => {
|
|
1064
1065
|
Object.keys(cond).forEach(k => {
|
|
1065
1066
|
if (core_1.Utils.isOperator(k)) {
|
|
1066
1067
|
if (Array.isArray(cond[k])) {
|
|
1067
|
-
return cond[k].forEach((c) => replaceOnConditions(c));
|
|
1068
|
+
return cond[k].forEach((c) => replaceOnConditions(c, k));
|
|
1068
1069
|
}
|
|
1069
|
-
|
|
1070
|
+
/* istanbul ignore next */
|
|
1071
|
+
return replaceOnConditions(cond[k], k);
|
|
1070
1072
|
}
|
|
1071
1073
|
const [alias] = this.helper.splitField(k);
|
|
1072
1074
|
const join = joins.find(j => j.alias === alias);
|
|
1073
1075
|
if (join) {
|
|
1074
|
-
|
|
1076
|
+
if (join.cond[k]) {
|
|
1077
|
+
join.cond = { [op ?? '$and']: [join.cond, { [k]: cond[k] }] };
|
|
1078
|
+
}
|
|
1079
|
+
else {
|
|
1080
|
+
join.cond = { ...join.cond, [k]: cond[k] };
|
|
1081
|
+
}
|
|
1075
1082
|
}
|
|
1076
1083
|
});
|
|
1077
1084
|
};
|
|
@@ -288,9 +288,10 @@ class QueryBuilderHelper {
|
|
|
288
288
|
return `(${parts.join(` ${core_1.GroupOperator[operator]} `)})`;
|
|
289
289
|
}
|
|
290
290
|
mapJoinColumns(type, join) {
|
|
291
|
-
if (join.prop &&
|
|
291
|
+
if (join.prop && [core_1.ReferenceKind.MANY_TO_ONE, core_1.ReferenceKind.ONE_TO_ONE].includes(join.prop.kind)) {
|
|
292
292
|
return join.prop.fieldNames.map((fieldName, idx) => {
|
|
293
|
-
|
|
293
|
+
const columns = join.prop.owner ? join.joinColumns : join.inverseJoinColumns;
|
|
294
|
+
return this.mapper(`${join.alias}.${columns[idx]}`, type, undefined, fieldName);
|
|
294
295
|
});
|
|
295
296
|
}
|
|
296
297
|
return [
|