(
entityName: EntityName<T>,
where: ObjectQuery<T>,
options: FindOptions<T, any> | CountOptions<T, any>,
type: QueryType,
)
| 333 | } |
| 334 | |
| 335 | protected async findFromVirtual<T extends object>( |
| 336 | entityName: EntityName<T>, |
| 337 | where: ObjectQuery<T>, |
| 338 | options: FindOptions<T, any> | CountOptions<T, any>, |
| 339 | type: QueryType, |
| 340 | ): Promise<EntityData<T>[] | number> { |
| 341 | const meta = this.metadata.get<T>(entityName); |
| 342 | |
| 343 | /* v8 ignore next */ |
| 344 | if (!meta.expression) { |
| 345 | return type === QueryType.SELECT ? [] : 0; |
| 346 | } |
| 347 | |
| 348 | if (typeof meta.expression === 'string') { |
| 349 | return this.wrapVirtualExpressionInSubquery(meta, meta.expression, where, options as FindOptions<T, any>, type); |
| 350 | } |
| 351 | |
| 352 | const em = this.createEntityManager(); |
| 353 | em.setTransactionContext(options.ctx); |
| 354 | |
| 355 | const res = meta.expression(em, where, options as FindOptions<T, any, any, any>); |
| 356 | |
| 357 | if (typeof res === 'string') { |
| 358 | return this.wrapVirtualExpressionInSubquery(meta, res, where, options as FindOptions<T, any>, type); |
| 359 | } |
| 360 | |
| 361 | if (res instanceof QueryBuilder) { |
| 362 | return this.wrapVirtualExpressionInSubquery( |
| 363 | meta, |
| 364 | res.getFormattedQuery(), |
| 365 | where, |
| 366 | options as FindOptions<T, any>, |
| 367 | type, |
| 368 | ); |
| 369 | } |
| 370 | |
| 371 | if (isRaw(res)) { |
| 372 | const expr = this.platform.formatQuery(res.sql, res.params); |
| 373 | return this.wrapVirtualExpressionInSubquery(meta, expr, where, options as FindOptions<T, any>, type); |
| 374 | } |
| 375 | |
| 376 | /* v8 ignore next */ |
| 377 | return res as EntityData<T>[]; |
| 378 | } |
| 379 | |
| 380 | protected async *streamFromVirtual<T extends object>( |
| 381 | entityName: EntityName<T>, |
nothing calls this directly
no test coverage detected