@mikro-orm/sql 7.0.0-dev.153 → 7.0.0-dev.155
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
|
@@ -62,7 +62,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
62
62
|
/**
|
|
63
63
|
* @internal
|
|
64
64
|
*/
|
|
65
|
-
mapPropToFieldNames<T extends object>(qb: QueryBuilder<T, any, any, any>, prop: EntityProperty<T>, tableAlias: string, explicitFields?: readonly Field<T>[]): Field<T>[];
|
|
65
|
+
mapPropToFieldNames<T extends object>(qb: QueryBuilder<T, any, any, any>, prop: EntityProperty<T>, tableAlias: string, meta: EntityMetadata<T>, schema?: string, explicitFields?: readonly Field<T>[]): Field<T>[];
|
|
66
66
|
/** @internal */
|
|
67
67
|
createQueryBuilder<T extends object>(entityName: EntityName<T> | QueryBuilder<T, any, any, any>, ctx?: Transaction, preferredConnectionType?: ConnectionType, convertCustomTypes?: boolean, loggerContext?: LoggingOptions, alias?: string, em?: SqlEntityManager): QueryBuilder<T, any, any, any>;
|
|
68
68
|
protected resolveConnectionType(args: {
|
|
@@ -78,7 +78,7 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
78
78
|
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>[];
|
|
79
79
|
protected normalizeFields<T extends object>(fields: Field<T>[], prefix?: string): string[];
|
|
80
80
|
protected processField<T extends object>(meta: EntityMetadata<T>, prop: EntityProperty<T> | undefined, field: string, ret: Field<T>[]): void;
|
|
81
|
-
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'
|
|
81
|
+
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>[];
|
|
82
82
|
}
|
|
83
83
|
interface FieldsForJoinedLoadOptions<T extends object> {
|
|
84
84
|
explicitFields?: readonly Field<T>[];
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -25,9 +25,10 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
25
25
|
const connectionType = this.resolveConnectionType({ ctx: options.ctx, connectionType: options.connectionType });
|
|
26
26
|
const populate = this.autoJoinOneToOneOwner(meta, options.populate, options.fields);
|
|
27
27
|
const joinedProps = this.joinedProps(meta, populate, options);
|
|
28
|
+
const schema = this.getSchemaName(meta, options);
|
|
28
29
|
const qb = this.createQueryBuilder(meta.class, options.ctx, connectionType, false, options.logging, undefined, options.em)
|
|
29
|
-
.withSchema(
|
|
30
|
-
const fields = this.buildFields(meta, populate, joinedProps, qb, qb.alias, options);
|
|
30
|
+
.withSchema(schema);
|
|
31
|
+
const fields = this.buildFields(meta, populate, joinedProps, qb, qb.alias, options, schema);
|
|
31
32
|
const orderBy = this.buildOrderBy(qb, meta, populate, options);
|
|
32
33
|
const populateWhere = this.buildPopulateWhere(meta, joinedProps, options);
|
|
33
34
|
Utils.asArray(options.flags).forEach(flag => qb.setFlag(flag));
|
|
@@ -361,10 +362,11 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
361
362
|
options = { populate: [], ...options };
|
|
362
363
|
const populate = options.populate;
|
|
363
364
|
const joinedProps = this.joinedProps(meta, populate, options);
|
|
365
|
+
const schema = this.getSchemaName(meta, options);
|
|
364
366
|
const qb = this.createQueryBuilder(entityName, options.ctx, options.connectionType, false, options.logging);
|
|
365
367
|
const populateWhere = this.buildPopulateWhere(meta, joinedProps, options);
|
|
366
368
|
if (meta && !Utils.isEmpty(populate)) {
|
|
367
|
-
this.buildFields(meta, populate, joinedProps, qb, qb.alias, options);
|
|
369
|
+
this.buildFields(meta, populate, joinedProps, qb, qb.alias, options, schema);
|
|
368
370
|
}
|
|
369
371
|
qb.__populateWhere = options._populateWhere;
|
|
370
372
|
qb.indexHint(options.indexHint)
|
|
@@ -373,7 +375,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
373
375
|
.groupBy(options.groupBy)
|
|
374
376
|
.having(options.having)
|
|
375
377
|
.populate(populate, joinedProps.length > 0 ? populateWhere : undefined, joinedProps.length > 0 ? options.populateFilter : undefined)
|
|
376
|
-
.withSchema(
|
|
378
|
+
.withSchema(schema)
|
|
377
379
|
.where(where);
|
|
378
380
|
if (options.em) {
|
|
379
381
|
await qb.applyJoinedFilters(options.em, options.filters);
|
|
@@ -1008,7 +1010,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1008
1010
|
// alias all fields in the primary table
|
|
1009
1011
|
meta.props
|
|
1010
1012
|
.filter(prop => this.shouldHaveColumn(meta, prop, populate, options.explicitFields, options.exclude))
|
|
1011
|
-
.forEach(prop => fields.push(...this.mapPropToFieldNames(qb, prop, options.parentTableAlias, options.explicitFields)));
|
|
1013
|
+
.forEach(prop => fields.push(...this.mapPropToFieldNames(qb, prop, options.parentTableAlias, meta, options.schema, options.explicitFields)));
|
|
1012
1014
|
}
|
|
1013
1015
|
for (const hint of joinedProps) {
|
|
1014
1016
|
const [propName, ref] = hint.field.split(':', 2);
|
|
@@ -1074,14 +1076,14 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1074
1076
|
/**
|
|
1075
1077
|
* @internal
|
|
1076
1078
|
*/
|
|
1077
|
-
mapPropToFieldNames(qb, prop, tableAlias, explicitFields) {
|
|
1079
|
+
mapPropToFieldNames(qb, prop, tableAlias, meta, schema, explicitFields) {
|
|
1078
1080
|
if (prop.kind === ReferenceKind.EMBEDDED && !prop.object) {
|
|
1079
1081
|
return Object.entries(prop.embeddedProps).flatMap(([name, childProp]) => {
|
|
1080
1082
|
const childFields = explicitFields ? Utils.extractChildElements(explicitFields, prop.name) : [];
|
|
1081
1083
|
if (!this.shouldHaveColumn(prop.targetMeta, { ...childProp, name }, [], childFields.length > 0 ? childFields : undefined)) {
|
|
1082
1084
|
return [];
|
|
1083
1085
|
}
|
|
1084
|
-
return this.mapPropToFieldNames(qb, childProp, tableAlias, childFields);
|
|
1086
|
+
return this.mapPropToFieldNames(qb, childProp, tableAlias, meta, schema, childFields);
|
|
1085
1087
|
});
|
|
1086
1088
|
}
|
|
1087
1089
|
const aliased = this.platform.quoteIdentifier(`${tableAlias}__${prop.fieldNames[0]}`);
|
|
@@ -1101,7 +1103,17 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1101
1103
|
}
|
|
1102
1104
|
if (prop.formula) {
|
|
1103
1105
|
const alias = this.platform.quoteIdentifier(tableAlias);
|
|
1104
|
-
|
|
1106
|
+
const effectiveSchema = schema ?? (meta.schema !== '*' ? meta.schema : undefined);
|
|
1107
|
+
const qualifiedName = effectiveSchema ? `${effectiveSchema}.${meta.tableName}` : meta.tableName;
|
|
1108
|
+
const table = {
|
|
1109
|
+
alias: alias.toString(),
|
|
1110
|
+
name: meta.tableName,
|
|
1111
|
+
schema: effectiveSchema,
|
|
1112
|
+
qualifiedName,
|
|
1113
|
+
toString: () => alias.toString(),
|
|
1114
|
+
};
|
|
1115
|
+
const columns = meta.createColumnMappingObject();
|
|
1116
|
+
return [raw(`${(prop.formula(table, columns))} as ${aliased}`)];
|
|
1105
1117
|
}
|
|
1106
1118
|
return prop.fieldNames.map(fieldName => {
|
|
1107
1119
|
return `${tableAlias}.${fieldName} as ${tableAlias}__${fieldName}`;
|
|
@@ -1323,7 +1335,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1323
1335
|
}
|
|
1324
1336
|
ret.push(prop.name);
|
|
1325
1337
|
}
|
|
1326
|
-
buildFields(meta, populate, joinedProps, qb, alias, options) {
|
|
1338
|
+
buildFields(meta, populate, joinedProps, qb, alias, options, schema) {
|
|
1327
1339
|
const lazyProps = meta.props.filter(prop => prop.lazy && !populate.some(p => this.isPopulated(meta, prop, p)));
|
|
1328
1340
|
const hasLazyFormulas = meta.props.some(p => p.lazy && p.formula);
|
|
1329
1341
|
const requiresSQLConversion = meta.props.some(p => p.customType?.convertToJSValueSQL && p.persist !== false);
|
|
@@ -1368,6 +1380,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1368
1380
|
ret.push('*');
|
|
1369
1381
|
}
|
|
1370
1382
|
if (ret.length > 0 && !hasExplicitFields && addFormulas) {
|
|
1383
|
+
const columns = meta.createColumnMappingObject();
|
|
1384
|
+
const effectiveSchema = schema ?? (meta.schema !== '*' ? meta.schema : undefined);
|
|
1371
1385
|
for (const prop of meta.props) {
|
|
1372
1386
|
if (lazyProps.includes(prop)) {
|
|
1373
1387
|
continue;
|
|
@@ -1375,7 +1389,15 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1375
1389
|
if (prop.formula) {
|
|
1376
1390
|
const a = this.platform.quoteIdentifier(alias);
|
|
1377
1391
|
const aliased = this.platform.quoteIdentifier(prop.fieldNames[0]);
|
|
1378
|
-
|
|
1392
|
+
const qualifiedName = effectiveSchema ? `${effectiveSchema}.${meta.tableName}` : meta.tableName;
|
|
1393
|
+
const table = {
|
|
1394
|
+
alias: a.toString(),
|
|
1395
|
+
name: meta.tableName,
|
|
1396
|
+
schema: effectiveSchema,
|
|
1397
|
+
qualifiedName,
|
|
1398
|
+
toString: () => a.toString(),
|
|
1399
|
+
};
|
|
1400
|
+
ret.push(raw(`${(prop.formula(table, columns))} as ${aliased}`));
|
|
1379
1401
|
}
|
|
1380
1402
|
if (!prop.object && (prop.hasConvertToDatabaseValueSQL || prop.hasConvertToJSValueSQL)) {
|
|
1381
1403
|
ret.push(prop.name);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/sql",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.155",
|
|
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
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -56,6 +56,6 @@
|
|
|
56
56
|
"@mikro-orm/core": "^6.6.4"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
59
|
+
"@mikro-orm/core": "7.0.0-dev.155"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/query/QueryBuilder.js
CHANGED
|
@@ -209,6 +209,8 @@ export class QueryBuilder {
|
|
|
209
209
|
const fields = [];
|
|
210
210
|
const populate = [];
|
|
211
211
|
const joinKey = Object.keys(this._joins).find(join => join.endsWith(`#${alias}`));
|
|
212
|
+
const targetMeta = prop.targetMeta;
|
|
213
|
+
const schema = this._schema ?? (targetMeta.schema !== '*' ? targetMeta.schema : undefined);
|
|
212
214
|
if (joinKey) {
|
|
213
215
|
const path = this._joins[joinKey].path.split('.').slice(1);
|
|
214
216
|
let children = this._populate;
|
|
@@ -221,29 +223,29 @@ export class QueryBuilder {
|
|
|
221
223
|
}
|
|
222
224
|
populate.push(...children);
|
|
223
225
|
}
|
|
224
|
-
for (const p of
|
|
225
|
-
fields.push(...this.driver.mapPropToFieldNames(this, p, alias));
|
|
226
|
+
for (const p of targetMeta.getPrimaryProps()) {
|
|
227
|
+
fields.push(...this.driver.mapPropToFieldNames(this, p, alias, targetMeta, schema));
|
|
226
228
|
}
|
|
227
229
|
if (explicitFields) {
|
|
228
230
|
for (const field of explicitFields) {
|
|
229
231
|
const [a, f] = this.helper.splitField(field);
|
|
230
|
-
const p =
|
|
232
|
+
const p = targetMeta.properties[f];
|
|
231
233
|
if (p) {
|
|
232
|
-
fields.push(...this.driver.mapPropToFieldNames(this, p, alias));
|
|
234
|
+
fields.push(...this.driver.mapPropToFieldNames(this, p, alias, targetMeta, schema));
|
|
233
235
|
}
|
|
234
236
|
else {
|
|
235
237
|
fields.push(`${a}.${f} as ${a}__${f}`);
|
|
236
238
|
}
|
|
237
239
|
}
|
|
238
240
|
}
|
|
239
|
-
|
|
241
|
+
targetMeta.props
|
|
240
242
|
.filter(prop => {
|
|
241
243
|
if (!explicitFields) {
|
|
242
244
|
return this.platform.shouldHaveColumn(prop, populate);
|
|
243
245
|
}
|
|
244
246
|
return prop.primary && !explicitFields.includes(prop.name) && !explicitFields.includes(`${alias}.${prop.name}`);
|
|
245
247
|
})
|
|
246
|
-
.forEach(prop => fields.push(...this.driver.mapPropToFieldNames(this, prop, alias)));
|
|
248
|
+
.forEach(prop => fields.push(...this.driver.mapPropToFieldNames(this, prop, alias, targetMeta, schema)));
|
|
247
249
|
return fields;
|
|
248
250
|
}
|
|
249
251
|
/**
|
|
@@ -1177,12 +1179,15 @@ export class QueryBuilder {
|
|
|
1177
1179
|
this.processPopulateHint();
|
|
1178
1180
|
this.processNestedJoins();
|
|
1179
1181
|
if (meta && (this._fields?.includes('*') || this._fields?.includes(`${this.mainAlias.aliasName}.*`))) {
|
|
1182
|
+
const schema = this.getSchema(this.mainAlias);
|
|
1183
|
+
const columns = meta.createColumnMappingObject();
|
|
1180
1184
|
meta.props
|
|
1181
1185
|
.filter(prop => prop.formula && (!prop.lazy || this.flags.has(QueryFlag.INCLUDE_LAZY_FORMULAS)))
|
|
1182
1186
|
.map(prop => {
|
|
1183
1187
|
const alias = this.platform.quoteIdentifier(this.mainAlias.aliasName);
|
|
1184
1188
|
const aliased = this.platform.quoteIdentifier(prop.fieldNames[0]);
|
|
1185
|
-
|
|
1189
|
+
const table = this.helper.createFormulaTable(alias.toString(), meta, schema);
|
|
1190
|
+
return `${(prop.formula(table, columns))} as ${aliased}`;
|
|
1186
1191
|
})
|
|
1187
1192
|
.filter(field => !this._fields.some(f => {
|
|
1188
1193
|
if (isRaw(f)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityName, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery, type QBQueryOrderMap, Raw, type RawQueryFragmentSymbol } from '@mikro-orm/core';
|
|
1
|
+
import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityName, type EntityProperty, type FlatQueryOrderMap, type FormulaTable, LockMode, type QBFilterQuery, type QBQueryOrderMap, Raw, type RawQueryFragmentSymbol } from '@mikro-orm/core';
|
|
2
2
|
import { JoinType, QueryType } from './enums.js';
|
|
3
3
|
import type { Field, JoinOptions } from '../typings.js';
|
|
4
4
|
import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
|
|
@@ -16,7 +16,7 @@ export declare class QueryBuilderHelper {
|
|
|
16
16
|
private readonly metadata;
|
|
17
17
|
constructor(entityName: EntityName, alias: string, aliasMap: Dictionary<Alias<any>>, subQueries: Dictionary<string>, driver: AbstractSqlDriver);
|
|
18
18
|
mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType): string;
|
|
19
|
-
mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType, value?: any, alias?: string | null): string;
|
|
19
|
+
mapper(field: string | Raw | RawQueryFragmentSymbol, type?: QueryType, value?: any, alias?: string | null, schema?: string): string;
|
|
20
20
|
processData(data: Dictionary, convertCustomTypes: boolean, multi?: boolean): any;
|
|
21
21
|
joinOneToReference(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, cond?: Dictionary, schema?: string): JoinOptions;
|
|
22
22
|
joinManyToOneReference(prop: EntityProperty, ownerAlias: string, alias: string, type: JoinType, cond?: Dictionary, schema?: string): JoinOptions;
|
|
@@ -59,6 +59,7 @@ export declare class QueryBuilderHelper {
|
|
|
59
59
|
getProperty(field: string, alias?: string): EntityProperty | undefined;
|
|
60
60
|
isTableNameAliasRequired(type: QueryType): boolean;
|
|
61
61
|
processOnConflictCondition(cond: QBFilterQuery, schema?: string): QBFilterQuery;
|
|
62
|
+
createFormulaTable(alias: string, meta: EntityMetadata, schema?: string): FormulaTable;
|
|
62
63
|
}
|
|
63
64
|
export interface Alias<T> {
|
|
64
65
|
aliasName: string;
|
|
@@ -21,7 +21,7 @@ export class QueryBuilderHelper {
|
|
|
21
21
|
this.platform = this.driver.getPlatform();
|
|
22
22
|
this.metadata = this.driver.getMetadata();
|
|
23
23
|
}
|
|
24
|
-
mapper(field, type = QueryType.SELECT, value, alias) {
|
|
24
|
+
mapper(field, type = QueryType.SELECT, value, alias, schema) {
|
|
25
25
|
if (isRaw(field)) {
|
|
26
26
|
return raw(field.sql, field.params);
|
|
27
27
|
}
|
|
@@ -83,7 +83,10 @@ export class QueryBuilderHelper {
|
|
|
83
83
|
const alias2 = this.platform.quoteIdentifier(a).toString();
|
|
84
84
|
const aliased = this.platform.quoteIdentifier(prop.fieldNames[0]).toString();
|
|
85
85
|
const as = alias === null ? '' : ` as ${aliased}`;
|
|
86
|
-
|
|
86
|
+
const meta = this.aliasMap[a]?.meta ?? this.metadata.get(this.entityName);
|
|
87
|
+
const table = this.createFormulaTable(alias2, meta, schema);
|
|
88
|
+
const columns = meta.createColumnMappingObject();
|
|
89
|
+
let value = prop.formula(table, columns);
|
|
87
90
|
if (!this.isTableNameAliasRequired(type)) {
|
|
88
91
|
value = value.replaceAll(alias2 + '.', '');
|
|
89
92
|
}
|
|
@@ -201,7 +204,10 @@ export class QueryBuilderHelper {
|
|
|
201
204
|
const right = `${join.alias}.${join.joinColumns[idx]}`;
|
|
202
205
|
if (join.prop.formula) {
|
|
203
206
|
const alias = this.platform.quoteIdentifier(join.ownerAlias);
|
|
204
|
-
const
|
|
207
|
+
const ownerMeta = this.aliasMap[join.ownerAlias]?.meta ?? this.metadata.get(this.entityName);
|
|
208
|
+
const table = this.createFormulaTable(alias.toString(), ownerMeta, schema);
|
|
209
|
+
const columns = ownerMeta.createColumnMappingObject();
|
|
210
|
+
const left = join.prop.formula(table, columns);
|
|
205
211
|
conditions.push(`${left} = ${this.platform.quoteIdentifier(right)}`);
|
|
206
212
|
return;
|
|
207
213
|
}
|
|
@@ -773,4 +779,15 @@ export class QueryBuilderHelper {
|
|
|
773
779
|
}
|
|
774
780
|
return cond;
|
|
775
781
|
}
|
|
782
|
+
createFormulaTable(alias, meta, schema) {
|
|
783
|
+
const effectiveSchema = schema ?? (meta.schema !== '*' ? meta.schema : undefined);
|
|
784
|
+
const qualifiedName = effectiveSchema ? `${effectiveSchema}.${meta.tableName}` : meta.tableName;
|
|
785
|
+
return {
|
|
786
|
+
alias,
|
|
787
|
+
name: meta.tableName,
|
|
788
|
+
schema: effectiveSchema,
|
|
789
|
+
qualifiedName,
|
|
790
|
+
toString: () => alias,
|
|
791
|
+
};
|
|
792
|
+
}
|
|
776
793
|
}
|