@mikro-orm/core 6.4.16-dev.17 → 6.4.16-dev.18
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/EntityManager.d.ts +1 -0
- package/EntityManager.js +1 -0
- package/entity/Collection.js +3 -2
- package/package.json +2 -2
- package/utils/DataloaderUtils.d.ts +6 -1
- package/utils/DataloaderUtils.js +37 -19
package/EntityManager.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
27
27
|
readonly name: string;
|
|
28
28
|
protected readonly refLoader: DataLoader<[Reference<any>, (Omit<import("./entity").LoadReferenceOptions<any, any, "*", never>, "dataloader"> | undefined)?], any, [Reference<any>, (Omit<import("./entity").LoadReferenceOptions<any, any, "*", never>, "dataloader"> | undefined)?]>;
|
|
29
29
|
protected readonly colLoader: DataLoader<[import("./entity").Collection<any, object>, (Omit<import("./entity").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?], any, [import("./entity").Collection<any, object>, (Omit<import("./entity").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?]>;
|
|
30
|
+
protected readonly colLoaderMtoN: DataLoader<[import("./entity").Collection<any, object>, (Omit<import("./entity").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?], any, [import("./entity").Collection<any, object>, (Omit<import("./entity").InitCollectionOptions<any, any, "*", never>, "dataloader"> | undefined)?]>;
|
|
30
31
|
private readonly validator;
|
|
31
32
|
private readonly repositoryMap;
|
|
32
33
|
private readonly entityLoader;
|
package/EntityManager.js
CHANGED
|
@@ -29,6 +29,7 @@ class EntityManager {
|
|
|
29
29
|
name;
|
|
30
30
|
refLoader = new dataloader_1.default(utils_1.DataloaderUtils.getRefBatchLoadFn(this));
|
|
31
31
|
colLoader = new dataloader_1.default(utils_1.DataloaderUtils.getColBatchLoadFn(this));
|
|
32
|
+
colLoaderMtoN = new dataloader_1.default(utils_1.DataloaderUtils.getManyToManyColBatchLoadFn(this));
|
|
32
33
|
validator;
|
|
33
34
|
repositoryMap = {};
|
|
34
35
|
entityLoader;
|
package/entity/Collection.js
CHANGED
|
@@ -224,8 +224,9 @@ class Collection extends ArrayCollection_1.ArrayCollection {
|
|
|
224
224
|
const order = [...this.items]; // copy order of references
|
|
225
225
|
const orderBy = this.createOrderBy(options.orderBy);
|
|
226
226
|
const customOrder = orderBy.length > 0;
|
|
227
|
-
|
|
228
|
-
const
|
|
227
|
+
const pivotTable = this.property.kind === enums_1.ReferenceKind.MANY_TO_MANY && em.getPlatform().usesPivotTable();
|
|
228
|
+
const loader = pivotTable ? 'colLoaderMtoN' : 'colLoader';
|
|
229
|
+
const items = await em[loader].load([
|
|
229
230
|
this,
|
|
230
231
|
{ ...options, orderBy },
|
|
231
232
|
]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "6.4.16-dev.
|
|
3
|
+
"version": "6.4.16-dev.18",
|
|
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",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"esprima": "4.0.1",
|
|
65
65
|
"fs-extra": "11.3.0",
|
|
66
66
|
"globby": "11.1.0",
|
|
67
|
-
"mikro-orm": "6.4.16-dev.
|
|
67
|
+
"mikro-orm": "6.4.16-dev.18",
|
|
68
68
|
"reflect-metadata": "0.2.2"
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -35,9 +35,14 @@ export declare class DataloaderUtils {
|
|
|
35
35
|
*/
|
|
36
36
|
static getColFilter<T, S extends T>(collection: Collection<any>): (result: T) => result is S;
|
|
37
37
|
/**
|
|
38
|
-
* Returns the collection dataloader batchLoadFn, which aggregates collections by entity,
|
|
38
|
+
* Returns the 1:M collection dataloader batchLoadFn, which aggregates collections by entity,
|
|
39
39
|
* makes one query per entity and maps each input collection to the corresponding result.
|
|
40
40
|
*/
|
|
41
41
|
static getColBatchLoadFn(em: EntityManager): DataLoader.BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
|
|
42
|
+
/**
|
|
43
|
+
* Returns the M:N collection dataloader batchLoadFn, which aggregates collections by entity,
|
|
44
|
+
* makes one query per entity and maps each input collection to the corresponding result.
|
|
45
|
+
*/
|
|
46
|
+
static getManyToManyColBatchLoadFn(em: EntityManager): DataLoader.BatchLoadFn<[Collection<any>, Omit<InitCollectionOptions<any, any>, 'dataloader'>?], any>;
|
|
42
47
|
static getDataloaderType(dataloaderCfg: DataloaderType | boolean): DataloaderType;
|
|
43
48
|
}
|
package/utils/DataloaderUtils.js
CHANGED
|
@@ -156,29 +156,11 @@ class DataloaderUtils {
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
/**
|
|
159
|
-
* Returns the collection dataloader batchLoadFn, which aggregates collections by entity,
|
|
159
|
+
* Returns the 1:M collection dataloader batchLoadFn, which aggregates collections by entity,
|
|
160
160
|
* makes one query per entity and maps each input collection to the corresponding result.
|
|
161
161
|
*/
|
|
162
162
|
static getColBatchLoadFn(em) {
|
|
163
163
|
return async (collsWithOpts) => {
|
|
164
|
-
const prop = collsWithOpts[0][0].property;
|
|
165
|
-
if (prop.kind === enums_1.ReferenceKind.MANY_TO_MANY && em.getPlatform().usesPivotTable()) {
|
|
166
|
-
const options = {};
|
|
167
|
-
const wrap = (cond) => ({ [prop.name]: cond });
|
|
168
|
-
const orderBy = Utils_1.Utils.asArray(collsWithOpts[0][1]?.orderBy).map(o => wrap(o));
|
|
169
|
-
const populate = wrap(collsWithOpts[0][1]?.populate);
|
|
170
|
-
const owners = collsWithOpts.map(c => c[0].owner);
|
|
171
|
-
const $or = [];
|
|
172
|
-
// a bit of a hack, but we need to prefix the key, since we have only a column name, not a property name
|
|
173
|
-
const alias = em.config.getNamingStrategy().aliasName(prop.pivotEntity, 0);
|
|
174
|
-
const fk = `${alias}.${Utils_1.Utils.getPrimaryKeyHash(prop.joinColumns)}`;
|
|
175
|
-
for (const c of collsWithOpts) {
|
|
176
|
-
$or.push({ $and: [c[1]?.where ?? {}, { [fk]: c[0].owner }] });
|
|
177
|
-
options.refresh ??= c[1]?.refresh;
|
|
178
|
-
}
|
|
179
|
-
options.where = wrap({ $or });
|
|
180
|
-
return em.getEntityLoader().findChildrenFromPivotTable(owners, prop, options, orderBy, populate, collsWithOpts[0][1]?.ref);
|
|
181
|
-
}
|
|
182
164
|
const entitiesAndOptsMap = DataloaderUtils.groupInversedOrMappedKeysByEntityAndOpts(collsWithOpts);
|
|
183
165
|
const promises = DataloaderUtils.entitiesAndOptsMapToQueries(entitiesAndOptsMap, em);
|
|
184
166
|
const resultsMap = new Map(await Promise.all(promises));
|
|
@@ -196,6 +178,42 @@ class DataloaderUtils {
|
|
|
196
178
|
});
|
|
197
179
|
};
|
|
198
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Returns the M:N collection dataloader batchLoadFn, which aggregates collections by entity,
|
|
183
|
+
* makes one query per entity and maps each input collection to the corresponding result.
|
|
184
|
+
*/
|
|
185
|
+
static getManyToManyColBatchLoadFn(em) {
|
|
186
|
+
return async (collsWithOpts) => {
|
|
187
|
+
const groups = new Map();
|
|
188
|
+
for (const [col, opts] of collsWithOpts) {
|
|
189
|
+
const key = `${col.property.targetMeta.className}.${col.property.name}|${JSON.stringify(opts ?? {})}`;
|
|
190
|
+
const value = groups.get(key) ?? [];
|
|
191
|
+
value.push([col, opts ?? {}]);
|
|
192
|
+
groups.set(key, value);
|
|
193
|
+
}
|
|
194
|
+
const ret = [];
|
|
195
|
+
for (const group of groups.values()) {
|
|
196
|
+
const prop = group[0][0].property;
|
|
197
|
+
const options = {};
|
|
198
|
+
const wrap = (cond) => ({ [prop.name]: cond });
|
|
199
|
+
const orderBy = Utils_1.Utils.asArray(group[0][1]?.orderBy).map(o => wrap(o));
|
|
200
|
+
const populate = wrap(group[0][1]?.populate);
|
|
201
|
+
const owners = group.map(c => c[0].owner);
|
|
202
|
+
const $or = [];
|
|
203
|
+
// a bit of a hack, but we need to prefix the key, since we have only a column name, not a property name
|
|
204
|
+
const alias = em.config.getNamingStrategy().aliasName(prop.pivotEntity, 0);
|
|
205
|
+
const fk = `${alias}.${Utils_1.Utils.getPrimaryKeyHash(prop.joinColumns)}`;
|
|
206
|
+
for (const c of group) {
|
|
207
|
+
$or.push({ $and: [c[1]?.where ?? {}, { [fk]: c[0].owner }] });
|
|
208
|
+
options.refresh ??= c[1]?.refresh;
|
|
209
|
+
}
|
|
210
|
+
options.where = wrap({ $or });
|
|
211
|
+
const r = await em.getEntityLoader().findChildrenFromPivotTable(owners, prop, options, orderBy, populate, group[0][1]?.ref);
|
|
212
|
+
ret.push(...r);
|
|
213
|
+
}
|
|
214
|
+
return ret;
|
|
215
|
+
};
|
|
216
|
+
}
|
|
199
217
|
static getDataloaderType(dataloaderCfg) {
|
|
200
218
|
switch (dataloaderCfg) {
|
|
201
219
|
case true:
|