@mikro-orm/knex 6.6.5-dev.4 → 6.6.5-dev.6
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 +2 -2
- package/AbstractSqlDriver.js +42 -18
- package/package.json +2 -2
- package/query/QueryBuilder.js +14 -9
- package/query/QueryBuilderHelper.d.ts +3 -2
- package/query/QueryBuilderHelper.js +20 -3
package/AbstractSqlDriver.d.ts
CHANGED
|
@@ -61,7 +61,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
61
61
|
/**
|
|
62
62
|
* @internal
|
|
63
63
|
*/
|
|
64
|
-
mapPropToFieldNames<T extends object>(qb: QueryBuilder<T, any, any, any>, prop: EntityProperty<T>, tableAlias?: string, explicitFields?: Field<T>[]): Field<T>[];
|
|
64
|
+
mapPropToFieldNames<T extends object>(qb: QueryBuilder<T, any, any, any>, prop: EntityProperty<T>, tableAlias: string | undefined, meta: EntityMetadata<T>, schema?: string, explicitFields?: readonly Field<T>[]): Field<T>[];
|
|
65
65
|
/** @internal */
|
|
66
66
|
createQueryBuilder<T extends object>(entityName: EntityName<T> | QueryBuilder<T, any, any, any>, ctx?: Transaction<Knex.Transaction>, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): QueryBuilder<T, any, any, any>;
|
|
67
67
|
protected resolveConnectionType(args: {
|
|
@@ -77,5 +77,5 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
77
77
|
protected buildJoinedPropsOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options?: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>, parentPath?: string): QueryOrderMap<T>[];
|
|
78
78
|
protected normalizeFields<T extends object>(fields: Field<T>[], prefix?: string): string[];
|
|
79
79
|
protected processField<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T> | undefined, field: string, ret: Field<T>[]): void;
|
|
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'
|
|
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'>, schema?: string): Field<T>[];
|
|
81
81
|
}
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -31,9 +31,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
31
31
|
}
|
|
32
32
|
const populate = this.autoJoinOneToOneOwner(meta, options.populate, options.fields);
|
|
33
33
|
const joinedProps = this.joinedProps(meta, populate, options);
|
|
34
|
+
const schema = this.getSchemaName(meta, options);
|
|
34
35
|
const qb = this.createQueryBuilder(entityName, options.ctx, options.connectionType, false, options.logging)
|
|
35
|
-
.withSchema(
|
|
36
|
-
const fields = this.buildFields(meta, populate, joinedProps, qb, qb.alias, options);
|
|
36
|
+
.withSchema(schema);
|
|
37
|
+
const fields = this.buildFields(meta, populate, joinedProps, qb, qb.alias, options, schema);
|
|
37
38
|
const orderBy = this.buildOrderBy(qb, meta, populate, options);
|
|
38
39
|
const populateWhere = this.buildPopulateWhere(meta, joinedProps, options);
|
|
39
40
|
core_1.Utils.asArray(options.flags).forEach(flag => qb.setFlag(flag));
|
|
@@ -250,7 +251,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
250
251
|
relationPojo[prop.name] = root[alias];
|
|
251
252
|
}
|
|
252
253
|
});
|
|
253
|
-
const mapToPk = !!(ref || prop.mapToPk);
|
|
254
|
+
const mapToPk = !hint.dataOnly && !!(ref || prop.mapToPk);
|
|
254
255
|
const targetProps = mapToPk
|
|
255
256
|
? meta2.getPrimaryProps()
|
|
256
257
|
: meta2.props.filter(prop => this.platform.shouldHaveColumn(prop, hint.children || []));
|
|
@@ -320,10 +321,11 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
320
321
|
options = { populate: [], ...options };
|
|
321
322
|
const populate = options.populate;
|
|
322
323
|
const joinedProps = this.joinedProps(meta, populate, options);
|
|
324
|
+
const schema = this.getSchemaName(meta, options);
|
|
323
325
|
const qb = this.createQueryBuilder(entityName, options.ctx, options.connectionType, false, options.logging);
|
|
324
326
|
const populateWhere = this.buildPopulateWhere(meta, joinedProps, options);
|
|
325
327
|
if (meta && !core_1.Utils.isEmpty(populate)) {
|
|
326
|
-
this.buildFields(meta, populate, joinedProps, qb, qb.alias, options);
|
|
328
|
+
this.buildFields(meta, populate, joinedProps, qb, qb.alias, options, schema);
|
|
327
329
|
}
|
|
328
330
|
qb.__populateWhere = options._populateWhere;
|
|
329
331
|
qb.indexHint(options.indexHint)
|
|
@@ -332,7 +334,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
332
334
|
.groupBy(options.groupBy)
|
|
333
335
|
.having(options.having)
|
|
334
336
|
.populate(populate, joinedProps.length > 0 ? populateWhere : undefined, joinedProps.length > 0 ? options.populateFilter : undefined)
|
|
335
|
-
.withSchema(
|
|
337
|
+
.withSchema(schema)
|
|
336
338
|
.where(where);
|
|
337
339
|
if (options.em) {
|
|
338
340
|
await qb.applyJoinedFilters(options.em, options.filters);
|
|
@@ -437,19 +439,21 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
437
439
|
}
|
|
438
440
|
if (prop.fieldNames.length > 1) {
|
|
439
441
|
const newFields = [];
|
|
440
|
-
const
|
|
442
|
+
const rawParam = core_1.Utils.asArray(row[prop.name]) ?? prop.fieldNames.map(() => null);
|
|
443
|
+
// Deep flatten nested arrays when needed (for deeply nested composite keys like Tag -> Comment -> Post -> User)
|
|
444
|
+
const needsFlatten = rawParam.length !== prop.fieldNames.length && rawParam.some(v => Array.isArray(v));
|
|
445
|
+
const allParam = needsFlatten ? core_1.Utils.flatten(rawParam, true) : rawParam;
|
|
441
446
|
// TODO(v7): instead of making this conditional here, the entity snapshot should respect `ownColumns`,
|
|
442
447
|
// but that means changing the compiled PK getters, which might be seen as breaking
|
|
443
448
|
const columns = allParam.length > 1 ? prop.fieldNames : prop.ownColumns;
|
|
444
|
-
const
|
|
449
|
+
const param = [];
|
|
445
450
|
columns.forEach((field, idx) => {
|
|
446
451
|
if (usedDups.includes(field)) {
|
|
447
452
|
return;
|
|
448
453
|
}
|
|
449
454
|
newFields.push(field);
|
|
450
|
-
|
|
455
|
+
param.push(allParam[idx]);
|
|
451
456
|
});
|
|
452
|
-
const param = core_1.Utils.flatten(newParam);
|
|
453
457
|
newFields.forEach((field, idx) => {
|
|
454
458
|
if (!duplicates.includes(field) || !usedDups.includes(field)) {
|
|
455
459
|
params.push(param[idx]);
|
|
@@ -801,7 +805,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
801
805
|
fields,
|
|
802
806
|
exclude: childExclude,
|
|
803
807
|
orderBy: this.getPivotOrderBy(prop, pivotProp1, orderBy, options?.orderBy),
|
|
804
|
-
populate: [{ field: populateField, strategy: core_1.LoadStrategy.JOINED, joinType: query_1.JoinType.innerJoin, children: populate }],
|
|
808
|
+
populate: [{ field: populateField, strategy: core_1.LoadStrategy.JOINED, joinType: query_1.JoinType.innerJoin, children: populate, dataOnly: pivotProp1.mapToPk && !pivotJoin }],
|
|
805
809
|
populateWhere: undefined,
|
|
806
810
|
// @ts-ignore
|
|
807
811
|
_populateWhere: 'infer',
|
|
@@ -950,7 +954,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
950
954
|
// alias all fields in the primary table
|
|
951
955
|
meta.props
|
|
952
956
|
.filter(prop => this.shouldHaveColumn(meta, prop, populate, explicitFields, exclude))
|
|
953
|
-
.forEach(prop => fields.push(...this.mapPropToFieldNames(qb, prop, parentTableAlias, explicitFields)));
|
|
957
|
+
.forEach(prop => fields.push(...this.mapPropToFieldNames(qb, prop, parentTableAlias, meta, undefined, explicitFields)));
|
|
954
958
|
}
|
|
955
959
|
for (const hint of joinedProps) {
|
|
956
960
|
const [propName, ref] = hint.field.split(':', 2);
|
|
@@ -989,10 +993,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
989
993
|
}
|
|
990
994
|
});
|
|
991
995
|
const childExclude = exclude ? core_1.Utils.extractChildElements(exclude, prop.name) : exclude;
|
|
992
|
-
if (!ref && !prop.mapToPk) {
|
|
996
|
+
if (!ref && (!prop.mapToPk || hint.dataOnly)) {
|
|
993
997
|
fields.push(...this.getFieldsForJoinedLoad(qb, meta2, childExplicitFields.length === 0 ? undefined : childExplicitFields, childExclude, hint.children, options, tableAlias, path));
|
|
994
998
|
}
|
|
995
|
-
else if (hint.filter || prop.mapToPk || (ref && [core_1.ReferenceKind.MANY_TO_ONE, core_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind))) {
|
|
999
|
+
else if (hint.filter || (prop.mapToPk && !hint.dataOnly) || (ref && [core_1.ReferenceKind.MANY_TO_ONE, core_1.ReferenceKind.ONE_TO_ONE].includes(prop.kind))) {
|
|
996
1000
|
fields.push(...prop.referencedColumnNames.map(col => qb.helper.mapper(`${tableAlias}.${col}`, qb.type, undefined, `${tableAlias}__${col}`)));
|
|
997
1001
|
}
|
|
998
1002
|
}
|
|
@@ -1001,14 +1005,14 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
1001
1005
|
/**
|
|
1002
1006
|
* @internal
|
|
1003
1007
|
*/
|
|
1004
|
-
mapPropToFieldNames(qb, prop, tableAlias, explicitFields) {
|
|
1008
|
+
mapPropToFieldNames(qb, prop, tableAlias, meta, schema, explicitFields) {
|
|
1005
1009
|
if (prop.kind === core_1.ReferenceKind.EMBEDDED && !prop.object) {
|
|
1006
1010
|
return Object.entries(prop.embeddedProps).flatMap(([name, childProp]) => {
|
|
1007
1011
|
const childFields = explicitFields ? core_1.Utils.extractChildElements(explicitFields, prop.name) : [];
|
|
1008
1012
|
if (!this.shouldHaveColumn(prop.targetMeta, { ...childProp, name }, [], childFields.length > 0 ? childFields : undefined)) {
|
|
1009
1013
|
return [];
|
|
1010
1014
|
}
|
|
1011
|
-
return this.mapPropToFieldNames(qb, childProp, tableAlias, childFields);
|
|
1015
|
+
return this.mapPropToFieldNames(qb, childProp, tableAlias, meta, schema, childFields);
|
|
1012
1016
|
});
|
|
1013
1017
|
}
|
|
1014
1018
|
const aliased = this.platform.quoteIdentifier(tableAlias ? `${tableAlias}__${prop.fieldNames[0]}` : prop.fieldNames[0]);
|
|
@@ -1028,7 +1032,17 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
1028
1032
|
}
|
|
1029
1033
|
if (prop.formula) {
|
|
1030
1034
|
const alias = this.platform.quoteIdentifier(tableAlias ?? qb.alias);
|
|
1031
|
-
|
|
1035
|
+
const effectiveSchema = schema ?? (meta.schema !== '*' ? meta.schema : undefined);
|
|
1036
|
+
const qualifiedName = effectiveSchema ? `${effectiveSchema}.${meta.tableName}` : meta.tableName;
|
|
1037
|
+
const table = {
|
|
1038
|
+
alias: alias.toString(),
|
|
1039
|
+
name: meta.tableName,
|
|
1040
|
+
schema: effectiveSchema,
|
|
1041
|
+
qualifiedName,
|
|
1042
|
+
toString: () => alias.toString(),
|
|
1043
|
+
};
|
|
1044
|
+
const columns = meta.createColumnMappingObject();
|
|
1045
|
+
return [(0, core_1.raw)(`${(prop.formula(table, columns))} as ${aliased}`)];
|
|
1032
1046
|
}
|
|
1033
1047
|
if (tableAlias) {
|
|
1034
1048
|
return prop.fieldNames.map(fieldName => {
|
|
@@ -1258,7 +1272,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
1258
1272
|
}
|
|
1259
1273
|
ret.push(prop.name);
|
|
1260
1274
|
}
|
|
1261
|
-
buildFields(meta, populate, joinedProps, qb, alias, options) {
|
|
1275
|
+
buildFields(meta, populate, joinedProps, qb, alias, options, schema) {
|
|
1262
1276
|
const lazyProps = meta.props.filter(prop => prop.lazy && !populate.some(p => this.isPopulated(meta, prop, p)));
|
|
1263
1277
|
const hasLazyFormulas = meta.props.some(p => p.lazy && p.formula);
|
|
1264
1278
|
const requiresSQLConversion = meta.props.some(p => p.customType?.convertToJSValueSQL && p.persist !== false);
|
|
@@ -1303,6 +1317,8 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
1303
1317
|
ret.push('*');
|
|
1304
1318
|
}
|
|
1305
1319
|
if (ret.length > 0 && !hasExplicitFields && addFormulas) {
|
|
1320
|
+
const columns = meta.createColumnMappingObject();
|
|
1321
|
+
const effectiveSchema = schema ?? (meta.schema !== '*' ? meta.schema : undefined);
|
|
1306
1322
|
for (const prop of meta.props) {
|
|
1307
1323
|
if (lazyProps.includes(prop)) {
|
|
1308
1324
|
continue;
|
|
@@ -1310,7 +1326,15 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
1310
1326
|
if (prop.formula) {
|
|
1311
1327
|
const a = this.platform.quoteIdentifier(alias);
|
|
1312
1328
|
const aliased = this.platform.quoteIdentifier(prop.fieldNames[0]);
|
|
1313
|
-
|
|
1329
|
+
const qualifiedName = effectiveSchema ? `${effectiveSchema}.${meta.tableName}` : meta.tableName;
|
|
1330
|
+
const table = {
|
|
1331
|
+
alias: a.toString(),
|
|
1332
|
+
name: meta.tableName,
|
|
1333
|
+
schema: effectiveSchema,
|
|
1334
|
+
qualifiedName,
|
|
1335
|
+
toString: () => a.toString(),
|
|
1336
|
+
};
|
|
1337
|
+
ret.push((0, core_1.raw)(`${(prop.formula(table, columns))} as ${aliased}`));
|
|
1314
1338
|
}
|
|
1315
1339
|
if (!prop.object && (prop.hasConvertToDatabaseValueSQL || prop.hasConvertToJSValueSQL)) {
|
|
1316
1340
|
ret.push(prop.name);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.6.5-dev.
|
|
3
|
+
"version": "6.6.5-dev.6",
|
|
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.6.4"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.6.5-dev.
|
|
69
|
+
"@mikro-orm/core": "6.6.5-dev.6",
|
|
70
70
|
"better-sqlite3": "*",
|
|
71
71
|
"libsql": "*",
|
|
72
72
|
"mariadb": "*"
|
package/query/QueryBuilder.js
CHANGED
|
@@ -222,6 +222,8 @@ class QueryBuilder {
|
|
|
222
222
|
const fields = [];
|
|
223
223
|
const populate = [];
|
|
224
224
|
const joinKey = Object.keys(this._joins).find(join => join.endsWith(`#${alias}`));
|
|
225
|
+
const targetMeta = prop.targetMeta;
|
|
226
|
+
const schema = this._schema ?? (targetMeta.schema !== '*' ? targetMeta.schema : undefined);
|
|
225
227
|
if (joinKey) {
|
|
226
228
|
const path = this._joins[joinKey].path.split('.').slice(1);
|
|
227
229
|
let children = this._populate;
|
|
@@ -234,29 +236,29 @@ class QueryBuilder {
|
|
|
234
236
|
}
|
|
235
237
|
populate.push(...children);
|
|
236
238
|
}
|
|
237
|
-
for (const p of
|
|
238
|
-
fields.push(...this.driver.mapPropToFieldNames(this, p, alias));
|
|
239
|
+
for (const p of targetMeta.getPrimaryProps()) {
|
|
240
|
+
fields.push(...this.driver.mapPropToFieldNames(this, p, alias, targetMeta, schema));
|
|
239
241
|
}
|
|
240
242
|
if (explicitFields) {
|
|
241
243
|
for (const field of explicitFields) {
|
|
242
244
|
const [a, f] = this.helper.splitField(field);
|
|
243
|
-
const p =
|
|
245
|
+
const p = targetMeta.properties[f];
|
|
244
246
|
if (p) {
|
|
245
|
-
fields.push(...this.driver.mapPropToFieldNames(this, p, alias));
|
|
247
|
+
fields.push(...this.driver.mapPropToFieldNames(this, p, alias, targetMeta, schema));
|
|
246
248
|
}
|
|
247
249
|
else {
|
|
248
250
|
fields.push(`${a}.${f} as ${a}__${f}`);
|
|
249
251
|
}
|
|
250
252
|
}
|
|
251
253
|
}
|
|
252
|
-
|
|
254
|
+
targetMeta.props
|
|
253
255
|
.filter(prop => {
|
|
254
256
|
if (!explicitFields) {
|
|
255
257
|
return this.platform.shouldHaveColumn(prop, populate);
|
|
256
258
|
}
|
|
257
259
|
return prop.primary && !explicitFields.includes(prop.name) && !explicitFields.includes(`${alias}.${prop.name}`);
|
|
258
260
|
})
|
|
259
|
-
.forEach(prop => fields.push(...this.driver.mapPropToFieldNames(this, prop, alias)));
|
|
261
|
+
.forEach(prop => fields.push(...this.driver.mapPropToFieldNames(this, prop, alias, targetMeta, schema)));
|
|
260
262
|
return fields;
|
|
261
263
|
}
|
|
262
264
|
/**
|
|
@@ -1164,12 +1166,15 @@ class QueryBuilder {
|
|
|
1164
1166
|
this.processPopulateHint();
|
|
1165
1167
|
this.processNestedJoins();
|
|
1166
1168
|
if (meta && (this._fields?.includes('*') || this._fields?.includes(`${this.mainAlias.aliasName}.*`))) {
|
|
1169
|
+
const schema = this.getSchema(this.mainAlias);
|
|
1170
|
+
const columns = meta.createColumnMappingObject();
|
|
1167
1171
|
meta.props
|
|
1168
1172
|
.filter(prop => prop.formula && (!prop.lazy || this.flags.has(core_1.QueryFlag.INCLUDE_LAZY_FORMULAS)))
|
|
1169
1173
|
.map(prop => {
|
|
1170
|
-
const alias = this.
|
|
1171
|
-
const aliased = this.
|
|
1172
|
-
|
|
1174
|
+
const alias = this.platform.quoteIdentifier(this.mainAlias.aliasName);
|
|
1175
|
+
const aliased = this.platform.quoteIdentifier(prop.fieldNames[0]);
|
|
1176
|
+
const table = this.helper.createFormulaTable(alias.toString(), meta, schema);
|
|
1177
|
+
return `${(prop.formula(table, columns))} as ${aliased}`;
|
|
1173
1178
|
})
|
|
1174
1179
|
.filter(field => !this._fields.some(f => {
|
|
1175
1180
|
if (f instanceof core_1.RawQueryFragment) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Knex } from 'knex';
|
|
2
|
-
import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery, RawQueryFragment } from '@mikro-orm/core';
|
|
2
|
+
import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, type FormulaTable, LockMode, type QBFilterQuery, RawQueryFragment } from '@mikro-orm/core';
|
|
3
3
|
import { JoinType, QueryType } from './enums';
|
|
4
4
|
import type { Field, JoinOptions } from '../typings';
|
|
5
5
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver';
|
|
@@ -17,7 +17,7 @@ export declare class QueryBuilderHelper {
|
|
|
17
17
|
private readonly metadata;
|
|
18
18
|
constructor(entityName: string, alias: string, aliasMap: Dictionary<Alias<any>>, subQueries: Dictionary<string>, knex: Knex, driver: AbstractSqlDriver);
|
|
19
19
|
mapper(field: string | Knex.Raw, type?: QueryType): string;
|
|
20
|
-
mapper(field: string | Knex.Raw, type?: QueryType, value?: any, alias?: string | null): string;
|
|
20
|
+
mapper(field: string | Knex.Raw, type?: QueryType, value?: any, alias?: string | null, schema?: string): string;
|
|
21
21
|
processData(data: Dictionary, convertCustomTypes: boolean, multi?: boolean): any;
|
|
22
22
|
joinOneToReference(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, cond?: Dictionary, schema?: string): JoinOptions;
|
|
23
23
|
joinManyToOneReference(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, cond?: Dictionary, schema?: string): JoinOptions;
|
|
@@ -60,6 +60,7 @@ export declare class QueryBuilderHelper {
|
|
|
60
60
|
getProperty(field: string, alias?: string): EntityProperty | undefined;
|
|
61
61
|
isTableNameAliasRequired(type?: QueryType): boolean;
|
|
62
62
|
processOnConflictCondition(cond: QBFilterQuery, schema?: string): QBFilterQuery;
|
|
63
|
+
createFormulaTable(alias: string, meta: EntityMetadata, schema?: string): FormulaTable;
|
|
63
64
|
}
|
|
64
65
|
export interface Alias<T> {
|
|
65
66
|
aliasName: string;
|
|
@@ -26,7 +26,7 @@ class QueryBuilderHelper {
|
|
|
26
26
|
this.platform = this.driver.getPlatform();
|
|
27
27
|
this.metadata = this.driver.getMetadata();
|
|
28
28
|
}
|
|
29
|
-
mapper(field, type = enums_1.QueryType.SELECT, value, alias) {
|
|
29
|
+
mapper(field, type = enums_1.QueryType.SELECT, value, alias, schema) {
|
|
30
30
|
if (core_1.Utils.isRawSql(field)) {
|
|
31
31
|
return this.knex.raw(field.sql, field.params);
|
|
32
32
|
}
|
|
@@ -87,7 +87,10 @@ class QueryBuilderHelper {
|
|
|
87
87
|
const alias2 = this.knex.ref(a).toString();
|
|
88
88
|
const aliased = this.knex.ref(prop.fieldNames[0]).toString();
|
|
89
89
|
const as = alias === null ? '' : ` as ${aliased}`;
|
|
90
|
-
|
|
90
|
+
const meta = this.aliasMap[a]?.metadata ?? this.metadata.get(this.entityName);
|
|
91
|
+
const table = this.createFormulaTable(alias2, meta, schema);
|
|
92
|
+
const columns = meta.createColumnMappingObject();
|
|
93
|
+
let value = prop.formula(table, columns);
|
|
91
94
|
if (!this.isTableNameAliasRequired(type)) {
|
|
92
95
|
value = value.replaceAll(alias2 + '.', '');
|
|
93
96
|
}
|
|
@@ -208,7 +211,10 @@ class QueryBuilderHelper {
|
|
|
208
211
|
const right = `${join.alias}.${join.joinColumns[idx]}`;
|
|
209
212
|
if (join.prop.formula) {
|
|
210
213
|
const alias = this.platform.quoteIdentifier(join.ownerAlias);
|
|
211
|
-
const
|
|
214
|
+
const ownerMeta = this.aliasMap[join.ownerAlias]?.metadata ?? this.metadata.get(this.entityName);
|
|
215
|
+
const table = this.createFormulaTable(alias.toString(), ownerMeta, schema);
|
|
216
|
+
const columns = ownerMeta.createColumnMappingObject();
|
|
217
|
+
const left = join.prop.formula(table, columns);
|
|
212
218
|
conditions.push(`${left} = ${this.knex.ref(right)}`);
|
|
213
219
|
return;
|
|
214
220
|
}
|
|
@@ -770,5 +776,16 @@ class QueryBuilderHelper {
|
|
|
770
776
|
}
|
|
771
777
|
return cond;
|
|
772
778
|
}
|
|
779
|
+
createFormulaTable(alias, meta, schema) {
|
|
780
|
+
const effectiveSchema = schema ?? (meta.schema !== '*' ? meta.schema : undefined);
|
|
781
|
+
const qualifiedName = effectiveSchema ? `${effectiveSchema}.${meta.tableName}` : meta.tableName;
|
|
782
|
+
return {
|
|
783
|
+
alias,
|
|
784
|
+
name: meta.tableName,
|
|
785
|
+
schema: effectiveSchema,
|
|
786
|
+
qualifiedName,
|
|
787
|
+
toString: () => alias,
|
|
788
|
+
};
|
|
789
|
+
}
|
|
773
790
|
}
|
|
774
791
|
exports.QueryBuilderHelper = QueryBuilderHelper;
|