@mikro-orm/core 7.0.0-dev.290 → 7.0.0-dev.292
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 +15 -2
- package/drivers/IDatabaseDriver.d.ts +43 -0
- package/package.json +1 -1
- package/platforms/Platform.d.ts +1 -0
- package/platforms/Platform.js +3 -0
- package/utils/Utils.js +1 -1
package/EntityManager.d.ts
CHANGED
|
@@ -121,6 +121,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
|
|
|
121
121
|
}): T;
|
|
122
122
|
setFlushMode(flushMode?: FlushMode | `${FlushMode}`): void;
|
|
123
123
|
protected processWhere<Entity extends object, Hint extends string = never, Fields extends string = '*', Excludes extends string = never>(entityName: EntityName<Entity>, where: FilterQuery<Entity>, options: FindOptions<Entity, Hint, Fields, Excludes> | FindOneOptions<Entity, Hint, Fields, Excludes>, type: 'read' | 'update' | 'delete'): Promise<FilterQuery<Entity>>;
|
|
124
|
+
protected processUnionWhere<Entity extends object, Hint extends string = never>(entityName: EntityName<Entity>, options: FindOptions<Entity, Hint, any, any> | CountOptions<Entity, Hint> | UpdateOptions<Entity> | DeleteOptions<Entity>, type: 'read' | 'update' | 'delete'): Promise<void>;
|
|
124
125
|
protected applyDiscriminatorCondition<Entity extends object>(entityName: EntityName<Entity>, where: FilterQuery<Entity>): FilterQuery<Entity>;
|
|
125
126
|
protected createPopulateWhere<Entity extends object>(cond: ObjectQuery<Entity>, options: FindOptions<Entity, any, any, any> | FindOneOptions<Entity, any, any, any> | CountOptions<Entity, any>): ObjectQuery<Entity>;
|
|
126
127
|
protected getJoinedFilters<Entity extends object>(meta: EntityMetadata<Entity>, options: FindOptions<Entity, any, any, any> | FindOneOptions<Entity, any, any, any>): Promise<ObjectQuery<Entity> | undefined>;
|
package/EntityManager.js
CHANGED
|
@@ -141,6 +141,7 @@ export class EntityManager {
|
|
|
141
141
|
options._populateWhere = options.populateWhere ?? this.config.get('populateWhere');
|
|
142
142
|
options.populateWhere = this.createPopulateWhere({ ...where }, options);
|
|
143
143
|
options.populateFilter = await this.getJoinedFilters(meta, options);
|
|
144
|
+
await em.processUnionWhere(entityName, options, 'read');
|
|
144
145
|
const results = await em.driver.find(entityName, where, { ctx: em.transactionContext, em, ...options });
|
|
145
146
|
if (results.length === 0) {
|
|
146
147
|
await em.storeCache(options.cache, cached, []);
|
|
@@ -298,6 +299,14 @@ export class EntityManager {
|
|
|
298
299
|
where = this.applyDiscriminatorCondition(entityName, where);
|
|
299
300
|
return where;
|
|
300
301
|
}
|
|
302
|
+
async processUnionWhere(entityName, options, type) {
|
|
303
|
+
if (options.unionWhere?.length) {
|
|
304
|
+
if (!this.driver.getPlatform().supportsUnionWhere()) {
|
|
305
|
+
throw new Error(`unionWhere is only supported on SQL drivers`);
|
|
306
|
+
}
|
|
307
|
+
options.unionWhere = await Promise.all(options.unionWhere.map(branch => this.processWhere(entityName, branch, options, type)));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
301
310
|
// this method only handles the problem for mongo driver, SQL drivers have their implementation inside QueryBuilder
|
|
302
311
|
applyDiscriminatorCondition(entityName, where) {
|
|
303
312
|
const meta = this.metadata.find(entityName);
|
|
@@ -642,6 +651,7 @@ export class EntityManager {
|
|
|
642
651
|
options._populateWhere = options.populateWhere ?? this.config.get('populateWhere');
|
|
643
652
|
options.populateWhere = this.createPopulateWhere({ ...where }, options);
|
|
644
653
|
options.populateFilter = await this.getJoinedFilters(meta, options);
|
|
654
|
+
await em.processUnionWhere(entityName, options, 'read');
|
|
645
655
|
const data = await em.driver.findOne(entityName, where, {
|
|
646
656
|
ctx: em.transactionContext,
|
|
647
657
|
em,
|
|
@@ -1188,11 +1198,12 @@ export class EntityManager {
|
|
|
1188
1198
|
async nativeUpdate(entityName, where, data, options = {}) {
|
|
1189
1199
|
const em = this.getContext(false);
|
|
1190
1200
|
em.prepareOptions(options);
|
|
1201
|
+
await em.processUnionWhere(entityName, options, 'update');
|
|
1191
1202
|
data = QueryHelper.processObjectParams(data);
|
|
1192
1203
|
where = await em.processWhere(entityName, where, { ...options, convertCustomTypes: false }, 'update');
|
|
1193
1204
|
validateParams(data, 'update data');
|
|
1194
1205
|
validateParams(where, 'update condition');
|
|
1195
|
-
const res = await em.driver.nativeUpdate(entityName, where, data, { ctx: em.transactionContext, ...options });
|
|
1206
|
+
const res = await em.driver.nativeUpdate(entityName, where, data, { ctx: em.transactionContext, em, ...options });
|
|
1196
1207
|
return res.affectedRows;
|
|
1197
1208
|
}
|
|
1198
1209
|
/**
|
|
@@ -1201,9 +1212,10 @@ export class EntityManager {
|
|
|
1201
1212
|
async nativeDelete(entityName, where, options = {}) {
|
|
1202
1213
|
const em = this.getContext(false);
|
|
1203
1214
|
em.prepareOptions(options);
|
|
1215
|
+
await em.processUnionWhere(entityName, options, 'delete');
|
|
1204
1216
|
where = await em.processWhere(entityName, where, options, 'delete');
|
|
1205
1217
|
validateParams(where, 'delete condition');
|
|
1206
|
-
const res = await em.driver.nativeDelete(entityName, where, { ctx: em.transactionContext, ...options });
|
|
1218
|
+
const res = await em.driver.nativeDelete(entityName, where, { ctx: em.transactionContext, em, ...options });
|
|
1207
1219
|
return res.affectedRows;
|
|
1208
1220
|
}
|
|
1209
1221
|
/**
|
|
@@ -1322,6 +1334,7 @@ export class EntityManager {
|
|
|
1322
1334
|
options.populateFilter = await this.getJoinedFilters(meta, options);
|
|
1323
1335
|
validateParams(where);
|
|
1324
1336
|
delete options.orderBy;
|
|
1337
|
+
await em.processUnionWhere(entityName, options, 'read');
|
|
1325
1338
|
const cacheKey = em.cacheKey(entityName, options, 'em.count', where);
|
|
1326
1339
|
const cached = await em.tryCache(entityName, options.cache, cacheKey);
|
|
1327
1340
|
if (cached?.data !== undefined) {
|
|
@@ -110,6 +110,22 @@ export interface FindOptions<Entity, Hint extends string = never, Fields extends
|
|
|
110
110
|
* when nesting the condition. This is used for implementation of joined filters.
|
|
111
111
|
*/
|
|
112
112
|
populateFilter?: ObjectQuery<Entity>;
|
|
113
|
+
/**
|
|
114
|
+
* Index-friendly alternative to `$or` for conditions that span joined relations.
|
|
115
|
+
* Each array element becomes an independent branch combined via `UNION ALL` subquery:
|
|
116
|
+
* `WHERE pk IN (branch_1 UNION ALL branch_2 ... branch_N)`.
|
|
117
|
+
* The database plans each branch independently, enabling per-table index usage
|
|
118
|
+
* (e.g. GIN trigram indexes for fuzzy search across related entities).
|
|
119
|
+
* sql only
|
|
120
|
+
*/
|
|
121
|
+
unionWhere?: ObjectQuery<Entity>[];
|
|
122
|
+
/**
|
|
123
|
+
* Strategy for combining `unionWhere` branches.
|
|
124
|
+
* - `'union-all'` (default) — skips deduplication, faster for most use cases.
|
|
125
|
+
* - `'union'` — deduplicates rows between branches; useful when branch overlap is very high.
|
|
126
|
+
* sql only
|
|
127
|
+
*/
|
|
128
|
+
unionWhereStrategy?: 'union-all' | 'union';
|
|
113
129
|
/** Used for ordering of the populate queries. If not specified, the value of `options.orderBy` is used. */
|
|
114
130
|
populateOrderBy?: OrderDefinition<Entity>;
|
|
115
131
|
/** Per-relation overrides for populate loading behavior. Keys are populate paths (same as used in `populate`). */
|
|
@@ -199,6 +215,13 @@ export interface NativeInsertUpdateOptions<T> {
|
|
|
199
215
|
/** `nativeUpdate()` only option */
|
|
200
216
|
upsert?: boolean;
|
|
201
217
|
loggerContext?: LogContext;
|
|
218
|
+
/** sql only */
|
|
219
|
+
unionWhere?: ObjectQuery<T>[];
|
|
220
|
+
/** sql only */
|
|
221
|
+
unionWhereStrategy?: 'union-all' | 'union';
|
|
222
|
+
filters?: FilterOptions;
|
|
223
|
+
/** @internal */
|
|
224
|
+
em?: EntityManager;
|
|
202
225
|
}
|
|
203
226
|
export interface NativeInsertUpdateManyOptions<T> extends NativeInsertUpdateOptions<T> {
|
|
204
227
|
processCollections?: boolean;
|
|
@@ -223,6 +246,10 @@ export interface CountOptions<T extends object, P extends string = never> {
|
|
|
223
246
|
populate?: Populate<T, P>;
|
|
224
247
|
populateWhere?: ObjectQuery<T> | PopulateHint | `${PopulateHint}`;
|
|
225
248
|
populateFilter?: ObjectQuery<T>;
|
|
249
|
+
/** @see FindOptions.unionWhere */
|
|
250
|
+
unionWhere?: ObjectQuery<T>[];
|
|
251
|
+
/** @see FindOptions.unionWhereStrategy */
|
|
252
|
+
unionWhereStrategy?: 'union-all' | 'union';
|
|
226
253
|
ctx?: Transaction;
|
|
227
254
|
connectionType?: ConnectionType;
|
|
228
255
|
flushMode?: FlushMode | `${FlushMode}`;
|
|
@@ -245,12 +272,28 @@ export interface UpdateOptions<T> {
|
|
|
245
272
|
filters?: FilterOptions;
|
|
246
273
|
schema?: string;
|
|
247
274
|
ctx?: Transaction;
|
|
275
|
+
/** sql only */
|
|
276
|
+
unionWhere?: ObjectQuery<T>[];
|
|
277
|
+
/** sql only */
|
|
278
|
+
unionWhereStrategy?: 'union-all' | 'union';
|
|
248
279
|
}
|
|
249
280
|
export interface DeleteOptions<T> extends DriverMethodOptions {
|
|
250
281
|
filters?: FilterOptions;
|
|
282
|
+
/** sql only */
|
|
283
|
+
unionWhere?: ObjectQuery<T>[];
|
|
284
|
+
/** sql only */
|
|
285
|
+
unionWhereStrategy?: 'union-all' | 'union';
|
|
286
|
+
/** @internal */
|
|
287
|
+
em?: EntityManager;
|
|
251
288
|
}
|
|
252
289
|
export interface NativeDeleteOptions<T> extends DriverMethodOptions {
|
|
253
290
|
filters?: FilterOptions;
|
|
291
|
+
/** sql only */
|
|
292
|
+
unionWhere?: ObjectQuery<T>[];
|
|
293
|
+
/** sql only */
|
|
294
|
+
unionWhereStrategy?: 'union-all' | 'union';
|
|
295
|
+
/** @internal */
|
|
296
|
+
em?: EntityManager;
|
|
254
297
|
}
|
|
255
298
|
export interface LockOptions extends DriverMethodOptions {
|
|
256
299
|
lockMode?: LockMode;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.0-dev.
|
|
4
|
+
"version": "7.0.0-dev.292",
|
|
5
5
|
"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.",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./package.json": "./package.json",
|
package/platforms/Platform.d.ts
CHANGED
|
@@ -140,6 +140,7 @@ export declare abstract class Platform {
|
|
|
140
140
|
getDefaultMappedType(type: string): Type<unknown>;
|
|
141
141
|
supportsMultipleCascadePaths(): boolean;
|
|
142
142
|
supportsMultipleStatements(): boolean;
|
|
143
|
+
supportsUnionWhere(): boolean;
|
|
143
144
|
getArrayDeclarationSQL(): string;
|
|
144
145
|
marshallArray(values: string[]): string;
|
|
145
146
|
unmarshallArray(value: string): string[];
|
package/platforms/Platform.js
CHANGED
package/utils/Utils.js
CHANGED
|
@@ -123,7 +123,7 @@ export function parseJsonSafe(value) {
|
|
|
123
123
|
}
|
|
124
124
|
export class Utils {
|
|
125
125
|
static PK_SEPARATOR = '~~~';
|
|
126
|
-
static #ORM_VERSION = '7.0.0-dev.
|
|
126
|
+
static #ORM_VERSION = '7.0.0-dev.292';
|
|
127
127
|
/**
|
|
128
128
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
129
129
|
*/
|