@mikro-orm/knex 6.4.2-dev.0 → 6.4.2-dev.10
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.js +9 -4
- package/package.json +2 -2
- package/query/QueryBuilder.d.ts +3 -0
- package/query/QueryBuilder.js +41 -28
- package/schema/SchemaHelper.d.ts +2 -0
- package/schema/SchemaHelper.js +7 -1
package/AbstractSqlDriver.js
CHANGED
|
@@ -248,7 +248,8 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
248
248
|
relationPojo[prop.name] = root[alias];
|
|
249
249
|
}
|
|
250
250
|
});
|
|
251
|
-
const
|
|
251
|
+
const mapToPk = !!(ref || prop.mapToPk);
|
|
252
|
+
const targetProps = mapToPk
|
|
252
253
|
? meta2.getPrimaryProps()
|
|
253
254
|
: meta2.props.filter(prop => this.platform.shouldHaveColumn(prop, hint.children || []));
|
|
254
255
|
const tz = this.platform.getTimezone();
|
|
@@ -290,7 +291,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
290
291
|
for (const prop of targetProps) {
|
|
291
292
|
prop.fieldNames.map(name => delete root[`${relationAlias}__${name}`]);
|
|
292
293
|
}
|
|
293
|
-
if (
|
|
294
|
+
if (mapToPk) {
|
|
294
295
|
const tmp = Object.values(relationPojo);
|
|
295
296
|
/* istanbul ignore next */
|
|
296
297
|
relationPojo = (meta2.compositePK ? tmp : tmp[0]);
|
|
@@ -870,6 +871,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
870
871
|
if (hint.filter && hint.strategy === core_1.LoadStrategy.JOINED) {
|
|
871
872
|
return true;
|
|
872
873
|
}
|
|
874
|
+
// skip redundant joins for 1:1 owner population hints when using `mapToPk`
|
|
875
|
+
if (prop.kind === core_1.ReferenceKind.ONE_TO_ONE && prop.mapToPk && prop.owner) {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
873
878
|
if ((options?.strategy || hint.strategy || prop.strategy || this.config.get('loadStrategy')) !== core_1.LoadStrategy.JOINED) {
|
|
874
879
|
// force joined strategy for explicit 1:1 owner populate hint as it would require a join anyway
|
|
875
880
|
return prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner;
|
|
@@ -972,10 +977,10 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
972
977
|
}
|
|
973
978
|
});
|
|
974
979
|
const childExclude = exclude ? core_1.Utils.extractChildElements(exclude, prop.name) : exclude;
|
|
975
|
-
if (!ref) {
|
|
980
|
+
if (!ref && !prop.mapToPk) {
|
|
976
981
|
fields.push(...this.getFieldsForJoinedLoad(qb, meta2, childExplicitFields.length === 0 ? undefined : childExplicitFields, childExclude, hint.children, options, tableAlias, path, count));
|
|
977
982
|
}
|
|
978
|
-
else if (hint.filter) {
|
|
983
|
+
else if (hint.filter || prop.mapToPk) {
|
|
979
984
|
fields.push(...prop.referencedColumnNames.map(col => qb.helper.mapper(`${tableAlias}.${col}`, qb.type, undefined, `${tableAlias}__${col}`)));
|
|
980
985
|
}
|
|
981
986
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "6.4.2-dev.
|
|
3
|
+
"version": "6.4.2-dev.10",
|
|
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.4.1"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "6.4.2-dev.
|
|
69
|
+
"@mikro-orm/core": "6.4.2-dev.10",
|
|
70
70
|
"better-sqlite3": "*",
|
|
71
71
|
"libsql": "*",
|
|
72
72
|
"mariadb": "*"
|
package/query/QueryBuilder.d.ts
CHANGED
|
@@ -80,6 +80,7 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
|
|
|
80
80
|
protected aliasCounter: number;
|
|
81
81
|
protected flags: Set<QueryFlag>;
|
|
82
82
|
protected finalized: boolean;
|
|
83
|
+
protected populateHintFinalized: boolean;
|
|
83
84
|
protected _joins: Dictionary<JoinOptions>;
|
|
84
85
|
protected _explicitAlias: boolean;
|
|
85
86
|
protected _schema?: string;
|
|
@@ -285,6 +286,8 @@ export declare class QueryBuilder<Entity extends object = AnyEntity, RootAlias e
|
|
|
285
286
|
private getQueryBase;
|
|
286
287
|
private applyDiscriminatorCondition;
|
|
287
288
|
private finalize;
|
|
289
|
+
/** @internal */
|
|
290
|
+
processPopulateHint(): void;
|
|
288
291
|
private processPopulateWhere;
|
|
289
292
|
private mergeOnConditions;
|
|
290
293
|
private hasToManyJoins;
|
package/query/QueryBuilder.js
CHANGED
|
@@ -62,6 +62,7 @@ class QueryBuilder {
|
|
|
62
62
|
aliasCounter = 0;
|
|
63
63
|
flags = new Set([core_1.QueryFlag.CONVERT_CUSTOM_TYPES]);
|
|
64
64
|
finalized = false;
|
|
65
|
+
populateHintFinalized = false;
|
|
65
66
|
_joins = {};
|
|
66
67
|
_explicitAlias = false;
|
|
67
68
|
_schema;
|
|
@@ -150,7 +151,7 @@ class QueryBuilder {
|
|
|
150
151
|
if (field) {
|
|
151
152
|
this._fields = core_1.Utils.asArray(field);
|
|
152
153
|
}
|
|
153
|
-
else if (this.hasToManyJoins()) {
|
|
154
|
+
else if (distinct || this.hasToManyJoins()) {
|
|
154
155
|
this._fields = this.mainAlias.metadata.primaryKeys;
|
|
155
156
|
}
|
|
156
157
|
else {
|
|
@@ -699,7 +700,7 @@ class QueryBuilder {
|
|
|
699
700
|
const res = await this.execute('all', true);
|
|
700
701
|
const entities = [];
|
|
701
702
|
function propagatePopulateHint(entity, hint) {
|
|
702
|
-
(0, core_1.helper)(entity).__serializationContext.populate
|
|
703
|
+
(0, core_1.helper)(entity).__serializationContext.populate = hint.concat((0, core_1.helper)(entity).__serializationContext.populate ?? []);
|
|
703
704
|
hint.forEach(hint => {
|
|
704
705
|
const [propName] = hint.field.split(':', 2);
|
|
705
706
|
const value = core_1.Reference.unwrapReference(entity[propName]);
|
|
@@ -742,6 +743,7 @@ class QueryBuilder {
|
|
|
742
743
|
}
|
|
743
744
|
else {
|
|
744
745
|
const qb = this.type === undefined ? this : this.clone();
|
|
746
|
+
qb.processPopulateHint(); // needs to happen sooner so `qb.hasToManyJoins()` reports correctly
|
|
745
747
|
qb.count(field, distinct ?? qb.hasToManyJoins()).limit(undefined).offset(undefined).orderBy([]);
|
|
746
748
|
res = await qb.execute('get', false);
|
|
747
749
|
}
|
|
@@ -1121,30 +1123,7 @@ class QueryBuilder {
|
|
|
1121
1123
|
}
|
|
1122
1124
|
const meta = this.mainAlias.metadata;
|
|
1123
1125
|
this.applyDiscriminatorCondition();
|
|
1124
|
-
|
|
1125
|
-
const relationsToPopulate = this._populate.map(({ field }) => field);
|
|
1126
|
-
meta.relations
|
|
1127
|
-
.filter(prop => prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner && !relationsToPopulate.includes(prop.name) && !relationsToPopulate.includes(`${prop.name}:ref`))
|
|
1128
|
-
.map(prop => ({ field: `${prop.name}:ref` }))
|
|
1129
|
-
.forEach(item => this._populate.push(item));
|
|
1130
|
-
}
|
|
1131
|
-
this._populate.forEach(({ field }) => {
|
|
1132
|
-
const [fromAlias, fromField] = this.helper.splitField(field);
|
|
1133
|
-
const aliasedField = `${fromAlias}.${fromField}`;
|
|
1134
|
-
const join = Object.keys(this._joins).find(k => `${aliasedField}#${this._joins[k].alias}` === k);
|
|
1135
|
-
if (join && this._joins[join] && this.helper.isOneToOneInverse(fromField)) {
|
|
1136
|
-
this._populateMap[join] = this._joins[join].alias;
|
|
1137
|
-
return;
|
|
1138
|
-
}
|
|
1139
|
-
if (meta && this.helper.isOneToOneInverse(fromField)) {
|
|
1140
|
-
const prop = meta.properties[fromField];
|
|
1141
|
-
const alias = this.getNextAlias(prop.pivotEntity ?? prop.type);
|
|
1142
|
-
const aliasedName = `${fromAlias}.${prop.name}#${alias}`;
|
|
1143
|
-
this._joins[aliasedName] = this.helper.joinOneToReference(prop, this.mainAlias.aliasName, alias, enums_1.JoinType.leftJoin);
|
|
1144
|
-
this._joins[aliasedName].path = `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? meta.className)}.${prop.name}`;
|
|
1145
|
-
this._populateMap[aliasedName] = this._joins[aliasedName].alias;
|
|
1146
|
-
}
|
|
1147
|
-
});
|
|
1126
|
+
this.processPopulateHint();
|
|
1148
1127
|
if (meta && (this._fields?.includes('*') || this._fields?.includes(`${this.mainAlias.aliasName}.*`))) {
|
|
1149
1128
|
meta.props
|
|
1150
1129
|
.filter(prop => prop.formula && (!prop.lazy || this.flags.has(core_1.QueryFlag.INCLUDE_LAZY_FORMULAS)))
|
|
@@ -1161,8 +1140,6 @@ class QueryBuilder {
|
|
|
1161
1140
|
}))
|
|
1162
1141
|
.forEach(field => this._fields.push((0, core_1.raw)(field)));
|
|
1163
1142
|
}
|
|
1164
|
-
this.processPopulateWhere(false);
|
|
1165
|
-
this.processPopulateWhere(true);
|
|
1166
1143
|
core_1.QueryHelper.processObjectParams(this._data);
|
|
1167
1144
|
core_1.QueryHelper.processObjectParams(this._cond);
|
|
1168
1145
|
core_1.QueryHelper.processObjectParams(this._having);
|
|
@@ -1178,6 +1155,40 @@ class QueryBuilder {
|
|
|
1178
1155
|
}
|
|
1179
1156
|
this.finalized = true;
|
|
1180
1157
|
}
|
|
1158
|
+
/** @internal */
|
|
1159
|
+
processPopulateHint() {
|
|
1160
|
+
if (this.populateHintFinalized) {
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
const meta = this.mainAlias.metadata;
|
|
1164
|
+
if (meta && this.flags.has(core_1.QueryFlag.AUTO_JOIN_ONE_TO_ONE_OWNER)) {
|
|
1165
|
+
const relationsToPopulate = this._populate.map(({ field }) => field);
|
|
1166
|
+
meta.relations
|
|
1167
|
+
.filter(prop => prop.kind === core_1.ReferenceKind.ONE_TO_ONE && !prop.owner && !relationsToPopulate.includes(prop.name) && !relationsToPopulate.includes(`${prop.name}:ref`))
|
|
1168
|
+
.map(prop => ({ field: `${prop.name}:ref` }))
|
|
1169
|
+
.forEach(item => this._populate.push(item));
|
|
1170
|
+
}
|
|
1171
|
+
this._populate.forEach(({ field }) => {
|
|
1172
|
+
const [fromAlias, fromField] = this.helper.splitField(field);
|
|
1173
|
+
const aliasedField = `${fromAlias}.${fromField}`;
|
|
1174
|
+
const join = Object.keys(this._joins).find(k => `${aliasedField}#${this._joins[k].alias}` === k);
|
|
1175
|
+
if (join && this._joins[join] && this.helper.isOneToOneInverse(fromField)) {
|
|
1176
|
+
this._populateMap[join] = this._joins[join].alias;
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1179
|
+
if (meta && this.helper.isOneToOneInverse(fromField)) {
|
|
1180
|
+
const prop = meta.properties[fromField];
|
|
1181
|
+
const alias = this.getNextAlias(prop.pivotEntity ?? prop.type);
|
|
1182
|
+
const aliasedName = `${fromAlias}.${prop.name}#${alias}`;
|
|
1183
|
+
this._joins[aliasedName] = this.helper.joinOneToReference(prop, this.mainAlias.aliasName, alias, enums_1.JoinType.leftJoin);
|
|
1184
|
+
this._joins[aliasedName].path = `${(Object.values(this._joins).find(j => j.alias === fromAlias)?.path ?? meta.className)}.${prop.name}`;
|
|
1185
|
+
this._populateMap[aliasedName] = this._joins[aliasedName].alias;
|
|
1186
|
+
}
|
|
1187
|
+
});
|
|
1188
|
+
this.processPopulateWhere(false);
|
|
1189
|
+
this.processPopulateWhere(true);
|
|
1190
|
+
this.populateHintFinalized = true;
|
|
1191
|
+
}
|
|
1181
1192
|
processPopulateWhere(filter) {
|
|
1182
1193
|
const key = filter ? '_populateFilter' : '_populateWhere';
|
|
1183
1194
|
if (this[key] == null || this[key] === core_1.PopulateHint.ALL) {
|
|
@@ -1233,7 +1244,9 @@ class QueryBuilder {
|
|
|
1233
1244
|
}
|
|
1234
1245
|
}
|
|
1235
1246
|
hasToManyJoins() {
|
|
1247
|
+
// console.log(this._joins);
|
|
1236
1248
|
return Object.values(this._joins).some(join => {
|
|
1249
|
+
// console.log(join.prop.name, join.prop.kind, [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(join.prop.kind));
|
|
1237
1250
|
return [core_1.ReferenceKind.ONE_TO_MANY, core_1.ReferenceKind.MANY_TO_MANY].includes(join.prop.kind);
|
|
1238
1251
|
});
|
|
1239
1252
|
}
|
package/schema/SchemaHelper.d.ts
CHANGED
package/schema/SchemaHelper.js
CHANGED
|
@@ -147,7 +147,7 @@ class SchemaHelper {
|
|
|
147
147
|
core_1.Utils.runIfNotEmpty(() => col.nullable(), column.nullable && guard('nullable'));
|
|
148
148
|
core_1.Utils.runIfNotEmpty(() => col.notNullable(), !column.nullable && !column.generated);
|
|
149
149
|
core_1.Utils.runIfNotEmpty(() => col.unsigned(), column.unsigned);
|
|
150
|
-
core_1.Utils.runIfNotEmpty(() => col.comment(column.comment), column.comment);
|
|
150
|
+
core_1.Utils.runIfNotEmpty(() => col.comment(this.processComment(column.comment)), column.comment);
|
|
151
151
|
this.configureColumnDefault(column, col, knex, changedProperties);
|
|
152
152
|
return col;
|
|
153
153
|
}
|
|
@@ -425,5 +425,11 @@ class SchemaHelper {
|
|
|
425
425
|
get options() {
|
|
426
426
|
return this.platform.getConfig().get('schemaGenerator');
|
|
427
427
|
}
|
|
428
|
+
processComment(comment) {
|
|
429
|
+
return this.platform.getSchemaHelper().handleMultilineComment(comment);
|
|
430
|
+
}
|
|
431
|
+
handleMultilineComment(comment) {
|
|
432
|
+
return comment.replaceAll('\n', '\\n');
|
|
433
|
+
}
|
|
428
434
|
}
|
|
429
435
|
exports.SchemaHelper = SchemaHelper;
|