@mikro-orm/knex 5.8.9-dev.0 → 5.8.9-dev.2
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 +4 -1
- package/AbstractSqlDriver.js +24 -36
- package/package.json +4 -4
- package/query/QueryBuilder.js +18 -10
- package/schema/SchemaComparator.js +3 -1
package/AbstractSqlDriver.d.ts
CHANGED
|
@@ -35,7 +35,10 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
35
35
|
* 1:1 owner side needs to be marked for population so QB auto-joins the owner id
|
|
36
36
|
*/
|
|
37
37
|
protected autoJoinOneToOneOwner<T extends object, P extends string = never>(meta: EntityMetadata, populate: PopulateOptions<T>[], fields?: readonly EntityField<T, P>[]): PopulateOptions<T>[];
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
joinedProps<T>(meta: EntityMetadata, populate: PopulateOptions<T>[]): PopulateOptions<T>[];
|
|
39
42
|
/**
|
|
40
43
|
* @internal
|
|
41
44
|
*/
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -49,11 +49,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
49
49
|
qb.setLockMode(options.lockMode, options.lockTableAliases);
|
|
50
50
|
}
|
|
51
51
|
core_1.Utils.asArray(options.flags).forEach(flag => qb.setFlag(flag));
|
|
52
|
-
|
|
53
|
-
if (joinedProps.length > 0) {
|
|
54
|
-
return this.mergeJoinedResult(result, meta, joinedProps);
|
|
55
|
-
}
|
|
56
|
-
return result;
|
|
52
|
+
return this.rethrow(qb.execute('all'));
|
|
57
53
|
}
|
|
58
54
|
async findOne(entityName, where, options) {
|
|
59
55
|
const opts = { populate: [], ...(options || {}) };
|
|
@@ -135,8 +131,6 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
135
131
|
if (qb) {
|
|
136
132
|
// here we map the aliased results (cartesian product) to an object graph
|
|
137
133
|
this.mapJoinedProps(ret, meta, populate, qb, ret, map);
|
|
138
|
-
// we need to remove the cycles from the mapped values
|
|
139
|
-
core_1.Utils.removeCycles(ret, meta);
|
|
140
134
|
}
|
|
141
135
|
return ret;
|
|
142
136
|
}
|
|
@@ -151,7 +145,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
151
145
|
const meta2 = this.metadata.find(relation.type);
|
|
152
146
|
const path = parentJoinPath ? `${parentJoinPath}.${relation.name}` : `${meta.name}.${relation.name}`;
|
|
153
147
|
const relationAlias = qb.getAliasForJoinPath(path);
|
|
154
|
-
|
|
148
|
+
const relationPojo = {};
|
|
155
149
|
// If the primary key value for the relation is null, we know we haven't joined to anything
|
|
156
150
|
// and therefore we don't return any record (since all values would be null)
|
|
157
151
|
const hasPK = meta2.primaryKeys.every(pk => meta2.properties[pk].fieldNames.every(name => {
|
|
@@ -190,22 +184,6 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
190
184
|
delete root[alias];
|
|
191
185
|
}
|
|
192
186
|
});
|
|
193
|
-
const key = `${meta.name}-${core_1.Utils.getCompositeKeyHash(result, meta)}`;
|
|
194
|
-
const key2 = `${meta2.name}-${core_1.Utils.getCompositeKeyHash(relationPojo, meta2)}`;
|
|
195
|
-
if (map[key2]) {
|
|
196
|
-
const old = map[key2];
|
|
197
|
-
Object.assign(old, relationPojo);
|
|
198
|
-
relationPojo = old;
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
map[key2] = relationPojo;
|
|
202
|
-
}
|
|
203
|
-
if (map[key]) {
|
|
204
|
-
result[relation.name] = map[key][relation.name];
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
map[key] = result;
|
|
208
|
-
}
|
|
209
187
|
if ([core_1.ReferenceType.MANY_TO_MANY, core_1.ReferenceType.ONE_TO_MANY].includes(relation.reference)) {
|
|
210
188
|
result[relation.name] = result[relation.name] || [];
|
|
211
189
|
this.appendToCollection(meta2, result[relation.name], relationPojo);
|
|
@@ -603,6 +581,9 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
603
581
|
.map(prop => ({ field: prop.name, strategy: prop.strategy }));
|
|
604
582
|
return [...populate, ...toPopulate];
|
|
605
583
|
}
|
|
584
|
+
/**
|
|
585
|
+
* @internal
|
|
586
|
+
*/
|
|
606
587
|
joinedProps(meta, populate) {
|
|
607
588
|
return populate.filter(p => {
|
|
608
589
|
const prop = meta.properties[p.field] || {};
|
|
@@ -613,26 +594,33 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
613
594
|
* @internal
|
|
614
595
|
*/
|
|
615
596
|
mergeJoinedResult(rawResults, meta, joinedProps) {
|
|
616
|
-
// group by the root entity primary key first
|
|
617
|
-
const map = {};
|
|
618
597
|
const res = [];
|
|
619
|
-
|
|
598
|
+
const map = {};
|
|
599
|
+
for (const item of rawResults) {
|
|
620
600
|
const pk = core_1.Utils.getCompositeKeyHash(item, meta);
|
|
621
601
|
if (map[pk]) {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
if (Array.isArray(map[pk][hint.field]) && Array.isArray(item[hint.field]) && map[pk][hint.field].length === 0) {
|
|
627
|
-
item[hint.field].forEach((el) => map[pk][hint.field].push(el));
|
|
602
|
+
for (const hint of joinedProps) {
|
|
603
|
+
const prop = meta.properties[hint.field];
|
|
604
|
+
if (!item[hint.field]) {
|
|
605
|
+
continue;
|
|
628
606
|
}
|
|
629
|
-
|
|
607
|
+
switch (prop.reference) {
|
|
608
|
+
case core_1.ReferenceType.ONE_TO_MANY:
|
|
609
|
+
case core_1.ReferenceType.MANY_TO_MANY:
|
|
610
|
+
map[pk][hint.field] = this.mergeJoinedResult([...map[pk][hint.field], ...item[hint.field]], prop.targetMeta, hint.children ?? []);
|
|
611
|
+
break;
|
|
612
|
+
case core_1.ReferenceType.MANY_TO_ONE:
|
|
613
|
+
case core_1.ReferenceType.ONE_TO_ONE:
|
|
614
|
+
map[pk][hint.field] = this.mergeJoinedResult([map[pk][hint.field], item[hint.field]], prop.targetMeta, hint.children ?? [])[0];
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
630
618
|
}
|
|
631
619
|
else {
|
|
632
620
|
map[pk] = item;
|
|
633
621
|
res.push(item);
|
|
634
622
|
}
|
|
635
|
-
}
|
|
623
|
+
}
|
|
636
624
|
return res;
|
|
637
625
|
}
|
|
638
626
|
getFieldsForJoinedLoad(qb, meta, explicitFields, populate = [], parentTableAlias, parentJoinPath) {
|
|
@@ -837,7 +825,7 @@ class AbstractSqlDriver extends core_1.DatabaseDriver {
|
|
|
837
825
|
buildFields(meta, populate, joinedProps, qb, fields) {
|
|
838
826
|
const lazyProps = meta.props.filter(prop => prop.lazy && !populate.some(p => p.field === prop.name || p.all));
|
|
839
827
|
const hasLazyFormulas = meta.props.some(p => p.lazy && p.formula);
|
|
840
|
-
const requiresSQLConversion = meta.props.some(p => p.customType?.convertToJSValueSQL);
|
|
828
|
+
const requiresSQLConversion = meta.props.some(p => p.customType?.convertToJSValueSQL && p.persist !== false);
|
|
841
829
|
const hasExplicitFields = !!fields;
|
|
842
830
|
const ret = [];
|
|
843
831
|
if (joinedProps.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/knex",
|
|
3
|
-
"version": "5.8.9-dev.
|
|
3
|
+
"version": "5.8.9-dev.2",
|
|
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,9 +66,9 @@
|
|
|
66
66
|
"@mikro-orm/core": "^5.8.8"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@mikro-orm/core": "5.8.9-dev.
|
|
70
|
-
"@mikro-orm/entity-generator": "5.8.9-dev.
|
|
71
|
-
"@mikro-orm/migrations": "5.8.9-dev.
|
|
69
|
+
"@mikro-orm/core": "5.8.9-dev.2",
|
|
70
|
+
"@mikro-orm/entity-generator": "5.8.9-dev.2",
|
|
71
|
+
"@mikro-orm/migrations": "5.8.9-dev.2",
|
|
72
72
|
"better-sqlite3": "*",
|
|
73
73
|
"mssql": "*",
|
|
74
74
|
"mysql": "*",
|
package/query/QueryBuilder.js
CHANGED
|
@@ -477,14 +477,25 @@ class QueryBuilder {
|
|
|
477
477
|
await this.em?.storeCache(this._cache, cached, res);
|
|
478
478
|
return res;
|
|
479
479
|
}
|
|
480
|
-
if (method === '
|
|
480
|
+
if (method === 'run') {
|
|
481
|
+
return res;
|
|
482
|
+
}
|
|
483
|
+
const joinedProps = this.driver.joinedProps(meta, this._populate);
|
|
484
|
+
let mapped;
|
|
485
|
+
if (Array.isArray(res)) {
|
|
481
486
|
const map = {};
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
487
|
+
mapped = res.map(r => this.driver.mapResult(r, meta, this._populate, this, map));
|
|
488
|
+
if (joinedProps.length > 0) {
|
|
489
|
+
mapped = this.driver.mergeJoinedResult(mapped, this.mainAlias.metadata, joinedProps);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
mapped = [this.driver.mapResult(res, meta, joinedProps, this)];
|
|
485
494
|
}
|
|
486
|
-
const mapped = this.driver.mapResult(res, meta, this._populate, this);
|
|
487
495
|
await this.em?.storeCache(this._cache, cached, mapped);
|
|
496
|
+
if (method === 'get') {
|
|
497
|
+
return mapped[0];
|
|
498
|
+
}
|
|
488
499
|
return mapped;
|
|
489
500
|
}
|
|
490
501
|
/**
|
|
@@ -498,10 +509,7 @@ class QueryBuilder {
|
|
|
498
509
|
*/
|
|
499
510
|
async getResultList() {
|
|
500
511
|
await this.em.tryFlush(this.mainAlias.entityName, { flushMode: this.flushMode });
|
|
501
|
-
|
|
502
|
-
if (this._joinedProps.size > 0) {
|
|
503
|
-
res = this.driver.mergeJoinedResult(res, this.mainAlias.metadata, [...this._joinedProps.values()]);
|
|
504
|
-
}
|
|
512
|
+
const res = await this.execute('all', true);
|
|
505
513
|
const entities = [];
|
|
506
514
|
function propagatePopulateHint(entity, hint) {
|
|
507
515
|
var _a;
|
|
@@ -725,7 +733,7 @@ class QueryBuilder {
|
|
|
725
733
|
});
|
|
726
734
|
const meta = this.mainAlias.metadata;
|
|
727
735
|
/* istanbul ignore next */
|
|
728
|
-
const requiresSQLConversion = meta?.props.filter(p => p.hasConvertToJSValueSQL) ?? [];
|
|
736
|
+
const requiresSQLConversion = meta?.props.filter(p => p.hasConvertToJSValueSQL && p.persist !== false) ?? [];
|
|
729
737
|
if (this.flags.has(core_1.QueryFlag.CONVERT_CUSTOM_TYPES) && (fields.includes('*') || fields.includes(`${this.mainAlias.aliasName}.*`)) && requiresSQLConversion.length > 0) {
|
|
730
738
|
requiresSQLConversion.forEach(p => ret.push(this.helper.mapper(p.name, this.type)));
|
|
731
739
|
}
|
|
@@ -363,7 +363,9 @@ class SchemaComparator {
|
|
|
363
363
|
log(`'comment' changed for column ${tableName}.${column1.name}`, { column1, column2 });
|
|
364
364
|
changedProperties.add('comment');
|
|
365
365
|
}
|
|
366
|
-
if (
|
|
366
|
+
if (!(column1.mappedType instanceof core_1.ArrayType) &&
|
|
367
|
+
!(column2.mappedType instanceof core_1.ArrayType) &&
|
|
368
|
+
this.diffEnumItems(column1.enumItems, column2.enumItems)) {
|
|
367
369
|
log(`'enumItems' changed for column ${tableName}.${column1.name}`, { column1, column2 });
|
|
368
370
|
changedProperties.add('enumItems');
|
|
369
371
|
}
|