@mikro-orm/knex 6.3.3-dev.3 → 6.3.3-dev.4
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/package.json +2 -2
- package/query/QueryBuilder.d.ts +1 -1
- package/query/QueryBuilder.js +11 -1
- package/query/QueryBuilderHelper.d.ts +4 -0
- package/query/QueryBuilderHelper.js +64 -45
- package/query/enums.d.ts +2 -0
- package/query/enums.js +2 -0
- package/typings.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.3.3-dev.
|
|
3
|
+
"version": "6.3.3-dev.4",
|
|
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.2"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.3.3-dev.
|
|
69
|
+
"@mikro-orm/core": "6.3.3-dev.4",
|
|
70
70
|
"better-sqlite3": "*",
|
|
71
71
|
"libsql": "*",
|
|
72
72
|
"mariadb": "*"
|
package/query/QueryBuilder.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { inspect } from 'node:util';
|
|
2
2
|
import type { Knex } from 'knex';
|
|
3
|
-
import { type AnyEntity, type ConnectionType, type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityName, type EntityProperty, type FlushMode, type GroupOperator, type Loaded, LockMode, type LoggingOptions, type MetadataStorage, type ObjectQuery, PopulateHint, type PopulateOptions, type QBFilterQuery, type QBQueryOrderMap, QueryFlag, type QueryOrderMap, type QueryResult, RawQueryFragment, type RequiredEntityData
|
|
3
|
+
import { type AnyEntity, type ConnectionType, type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityName, type EntityProperty, type ExpandProperty, type FlushMode, type GroupOperator, type Loaded, LockMode, type LoggingOptions, type MetadataStorage, type ObjectQuery, PopulateHint, type PopulateOptions, type QBFilterQuery, type QBQueryOrderMap, QueryFlag, type QueryOrderMap, type QueryResult, RawQueryFragment, type RequiredEntityData } from '@mikro-orm/core';
|
|
4
4
|
import { JoinType, QueryType } from './enums';
|
|
5
5
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver';
|
|
6
6
|
import { type Alias, QueryBuilderHelper } from './QueryBuilderHelper';
|
package/query/QueryBuilder.js
CHANGED
|
@@ -1155,7 +1155,7 @@ class QueryBuilder {
|
|
|
1155
1155
|
if (this._populateWhere == null || this._populateWhere === core_1.PopulateHint.ALL) {
|
|
1156
1156
|
return;
|
|
1157
1157
|
}
|
|
1158
|
-
|
|
1158
|
+
let joins = Object.values(this._joins);
|
|
1159
1159
|
joins.forEach(join => {
|
|
1160
1160
|
join.cond_ = join.cond;
|
|
1161
1161
|
join.cond = {};
|
|
@@ -1172,6 +1172,15 @@ class QueryBuilder {
|
|
|
1172
1172
|
const [alias] = this.helper.splitField(k);
|
|
1173
1173
|
const join = joins.find(j => j.alias === alias);
|
|
1174
1174
|
if (join) {
|
|
1175
|
+
const parentJoin = joins.find(j => j.alias === join.ownerAlias);
|
|
1176
|
+
// https://stackoverflow.com/a/56815807/3665878
|
|
1177
|
+
if (parentJoin) {
|
|
1178
|
+
const nested = (parentJoin.nested ??= new Set());
|
|
1179
|
+
join.type = join.type === enums_1.JoinType.innerJoin || [core_1.ReferenceKind.ONE_TO_MANY, core_1.ReferenceKind.MANY_TO_MANY].includes(parentJoin.prop.kind)
|
|
1180
|
+
? enums_1.JoinType.nestedInnerJoin
|
|
1181
|
+
: enums_1.JoinType.nestedLeftJoin;
|
|
1182
|
+
nested.add(join);
|
|
1183
|
+
}
|
|
1175
1184
|
if (join.cond[k]) {
|
|
1176
1185
|
join.cond = { [op ?? '$and']: [join.cond, { [k]: cond[k] }] };
|
|
1177
1186
|
}
|
|
@@ -1189,6 +1198,7 @@ class QueryBuilder {
|
|
|
1189
1198
|
const cond = CriteriaNodeFactory_1.CriteriaNodeFactory
|
|
1190
1199
|
.createNode(this.metadata, this.mainAlias.entityName, this._populateWhere)
|
|
1191
1200
|
.process(this, { matchPopulateJoins: true, ignoreBranching: true, preferNoBranch: true });
|
|
1201
|
+
joins = Object.values(this._joins); // there might be new joins created by processing the `populateWhere` object
|
|
1192
1202
|
replaceOnConditions(cond);
|
|
1193
1203
|
}
|
|
1194
1204
|
}
|
|
@@ -23,6 +23,10 @@ export declare class QueryBuilderHelper {
|
|
|
23
23
|
joinManyToOneReference(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, cond?: Dictionary, schema?: string): JoinOptions;
|
|
24
24
|
joinManyToManyReference(prop: EntityProperty, ownerAlias: string, alias: string, pivotAlias: string, type: JoinType, cond: Dictionary, path: string, schema?: string): Dictionary<JoinOptions>;
|
|
25
25
|
processJoins(qb: Knex.QueryBuilder, joins: Dictionary<JoinOptions>, schema?: string): void;
|
|
26
|
+
createJoinExpression(join: JoinOptions, joins: Dictionary<JoinOptions>, schema?: string): {
|
|
27
|
+
sql: string;
|
|
28
|
+
params: Knex.Value[];
|
|
29
|
+
};
|
|
26
30
|
private processJoinClause;
|
|
27
31
|
private wrapQueryGroup;
|
|
28
32
|
mapJoinColumns(type: QueryType, join: JoinOptions): (string | Knex.Raw)[];
|
|
@@ -183,56 +183,75 @@ class QueryBuilderHelper {
|
|
|
183
183
|
}
|
|
184
184
|
processJoins(qb, joins, schema) {
|
|
185
185
|
Object.values(joins).forEach(join => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const conditions = [];
|
|
189
|
-
const params = [];
|
|
190
|
-
schema = join.schema && join.schema !== '*' ? join.schema : schema;
|
|
191
|
-
if (schema) {
|
|
192
|
-
table = `${schema}.${table}`;
|
|
186
|
+
if ([enums_1.JoinType.nestedInnerJoin, enums_1.JoinType.nestedLeftJoin].includes(join.type)) {
|
|
187
|
+
return;
|
|
193
188
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
189
|
+
const { sql, params } = this.createJoinExpression(join, joins, schema);
|
|
190
|
+
qb.joinRaw(sql, params);
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
createJoinExpression(join, joins, schema) {
|
|
194
|
+
let table = join.table;
|
|
195
|
+
const method = {
|
|
196
|
+
[enums_1.JoinType.nestedInnerJoin]: 'inner join',
|
|
197
|
+
[enums_1.JoinType.nestedLeftJoin]: 'left join',
|
|
198
|
+
[enums_1.JoinType.pivotJoin]: 'left join',
|
|
199
|
+
}[join.type] ?? join.type;
|
|
200
|
+
const conditions = [];
|
|
201
|
+
const params = [];
|
|
202
|
+
schema = join.schema && join.schema !== '*' ? join.schema : schema;
|
|
203
|
+
if (schema) {
|
|
204
|
+
table = `${schema}.${table}`;
|
|
205
|
+
}
|
|
206
|
+
if (join.prop.name !== '__subquery__') {
|
|
207
|
+
join.primaryKeys.forEach((primaryKey, idx) => {
|
|
208
|
+
const right = `${join.alias}.${join.joinColumns[idx]}`;
|
|
209
|
+
if (join.prop.formula) {
|
|
210
|
+
const alias = this.platform.quoteIdentifier(join.ownerAlias);
|
|
211
|
+
const left = join.prop.formula(alias);
|
|
206
212
|
conditions.push(`${left} = ${this.knex.ref(right)}`);
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
if (join.prop.targetMeta?.discriminatorValue && !join.path?.endsWith('[pivot]')) {
|
|
210
|
-
const typeProperty = join.prop.targetMeta.root.discriminatorColumn;
|
|
211
|
-
const alias = join.inverseAlias ?? join.alias;
|
|
212
|
-
join.cond[`${alias}.${typeProperty}`] = join.prop.targetMeta.discriminatorValue;
|
|
213
|
-
}
|
|
214
|
-
for (const key of Object.keys(join.cond)) {
|
|
215
|
-
const hasPrefix = key.includes('.') || core_1.Utils.isOperator(key) || core_1.RawQueryFragment.isKnownFragment(key);
|
|
216
|
-
const newKey = hasPrefix ? key : `${join.alias}.${key}`;
|
|
217
|
-
const clause = this.processJoinClause(newKey, join.cond[key], join.alias, params);
|
|
218
|
-
/* istanbul ignore else */
|
|
219
|
-
if (clause !== '()') {
|
|
220
|
-
conditions.push(clause);
|
|
213
|
+
return;
|
|
221
214
|
}
|
|
215
|
+
const left = join.prop.object && join.prop.fieldNameRaw
|
|
216
|
+
? join.prop.fieldNameRaw.replaceAll(core_1.ALIAS_REPLACEMENT, join.ownerAlias)
|
|
217
|
+
: this.knex.ref(`${join.ownerAlias}.${primaryKey}`);
|
|
218
|
+
conditions.push(`${left} = ${this.knex.ref(right)}`);
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
if (join.prop.targetMeta?.discriminatorValue && !join.path?.endsWith('[pivot]')) {
|
|
222
|
+
const typeProperty = join.prop.targetMeta.root.discriminatorColumn;
|
|
223
|
+
const alias = join.inverseAlias ?? join.alias;
|
|
224
|
+
join.cond[`${alias}.${typeProperty}`] = join.prop.targetMeta.discriminatorValue;
|
|
225
|
+
}
|
|
226
|
+
for (const key of Object.keys(join.cond)) {
|
|
227
|
+
const hasPrefix = key.includes('.') || core_1.Utils.isOperator(key) || core_1.RawQueryFragment.isKnownFragment(key);
|
|
228
|
+
const newKey = hasPrefix ? key : `${join.alias}.${key}`;
|
|
229
|
+
const clause = this.processJoinClause(newKey, join.cond[key], join.alias, params);
|
|
230
|
+
/* istanbul ignore else */
|
|
231
|
+
if (clause !== '()') {
|
|
232
|
+
conditions.push(clause);
|
|
222
233
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
sql
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (conditions.length > 0) {
|
|
232
|
-
sql += ` on ${conditions.join(' and ')}`;
|
|
234
|
+
}
|
|
235
|
+
let sql = method + ' ';
|
|
236
|
+
if (join.nested) {
|
|
237
|
+
sql += `(${this.knex.ref(table)} as ${this.knex.ref(join.alias)}`;
|
|
238
|
+
for (const nested of join.nested) {
|
|
239
|
+
const { sql: nestedSql, params: nestedParams } = this.createJoinExpression(nested, joins, schema);
|
|
240
|
+
sql += ' ' + nestedSql;
|
|
241
|
+
params.unshift(...nestedParams);
|
|
233
242
|
}
|
|
234
|
-
|
|
235
|
-
}
|
|
243
|
+
sql += `)`;
|
|
244
|
+
}
|
|
245
|
+
else if (join.subquery) {
|
|
246
|
+
sql += `(${join.subquery}) as ${this.knex.ref(join.alias)}`;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
sql += `${this.knex.ref(table)} as ${this.knex.ref(join.alias)}`;
|
|
250
|
+
}
|
|
251
|
+
if (conditions.length > 0) {
|
|
252
|
+
sql += ` on ${conditions.join(' and ')}`;
|
|
253
|
+
}
|
|
254
|
+
return { sql, params };
|
|
236
255
|
}
|
|
237
256
|
processJoinClause(key, value, alias, params, operator = '$eq') {
|
|
238
257
|
if (core_1.Utils.isGroupOperator(key) && Array.isArray(value)) {
|
package/query/enums.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export declare enum QueryType {
|
|
|
9
9
|
export declare enum JoinType {
|
|
10
10
|
leftJoin = "left join",
|
|
11
11
|
innerJoin = "inner join",
|
|
12
|
+
nestedLeftJoin = "nested left join",
|
|
13
|
+
nestedInnerJoin = "nested inner join",
|
|
12
14
|
pivotJoin = "pivot join",
|
|
13
15
|
innerJoinLateral = "inner join lateral",
|
|
14
16
|
leftJoinLateral = "left join lateral"
|
package/query/enums.js
CHANGED
|
@@ -14,6 +14,8 @@ var JoinType;
|
|
|
14
14
|
(function (JoinType) {
|
|
15
15
|
JoinType["leftJoin"] = "left join";
|
|
16
16
|
JoinType["innerJoin"] = "inner join";
|
|
17
|
+
JoinType["nestedLeftJoin"] = "nested left join";
|
|
18
|
+
JoinType["nestedInnerJoin"] = "nested inner join";
|
|
17
19
|
JoinType["pivotJoin"] = "pivot join";
|
|
18
20
|
JoinType["innerJoinLateral"] = "inner join lateral";
|
|
19
21
|
JoinType["leftJoinLateral"] = "left join lateral";
|