From 3754c5c734814ed310eb08a6b69a38c632246696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Tue, 3 Jan 2023 10:58:34 +0100 Subject: [PATCH] fix: Fix executions bulk deletion (#5074) since QueryBuilder api doesn't use entity field transforms, we should remove the usage of QueryBuilder wherever there is a filter on a transformed column. --- .../cli/src/executions/executions.service.ts | 82 +++++++------------ 1 file changed, 28 insertions(+), 54 deletions(-) diff --git a/packages/cli/src/executions/executions.service.ts b/packages/cli/src/executions/executions.service.ts index 3542097187..fe3a98060e 100644 --- a/packages/cli/src/executions/executions.service.ts +++ b/packages/cli/src/executions/executions.service.ts @@ -12,10 +12,11 @@ import { jsonParse, Workflow, } from 'n8n-workflow'; -import { FindOperator, In, IsNull, LessThanOrEqual, Not, Raw } from 'typeorm'; +import { FindConditions, FindOperator, In, IsNull, LessThanOrEqual, Not, Raw } from 'typeorm'; import * as ActiveExecutions from '@/ActiveExecutions'; import config from '@/config'; -import { User } from '@/databases/entities/User'; +import type { User } from '@/databases/entities/User'; +import type { ExecutionEntity } from '@db/entities/ExecutionEntity'; import { IExecutionFlattedResponse, IExecutionResponse, @@ -199,7 +200,7 @@ export class ExecutionsService { .map(({ id }) => id), ); - const findWhere = { workflowId: In(sharedWorkflowIds) }; + const findWhere: FindConditions = { workflowId: In(sharedWorkflowIds) }; const rangeQuery: string[] = []; const rangeQueryParams: { @@ -452,66 +453,39 @@ export class ExecutionsService { throw new Error('Either "deleteBefore" or "ids" must be present in the request body'); } - const binaryDataManager = BinaryDataManager.getInstance(); - - // delete executions by date, if user may access the underlying workflows + const where: FindConditions = { workflowId: In(sharedWorkflowIds) }; if (deleteBefore) { - const filters: IDataObject = { - startedAt: LessThanOrEqual(deleteBefore), - }; + // delete executions by date, if user may access the underlying workflows + where.startedAt = LessThanOrEqual(deleteBefore); + Object.assign(where, requestFilters); + } else if (ids) { + // delete executions by IDs, if user may access the underlying workflows + where.id = In(ids); + } else return; - let query = Db.collections.Execution.createQueryBuilder() - .select('id') - .where({ - ...filters, - workflowId: In(sharedWorkflowIds), - }); + const executions = await Db.collections.Execution.find({ + select: ['id'], + where, + }); - if (requestFilters) { - query = query.andWhere(requestFilters); - } - - const executions = await query.getMany(); - - if (!executions.length) return; - - const idsToDelete = executions.map(({ id }) => id); - - await Promise.all( - idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)), - ); - - await Db.collections.Execution.delete({ id: In(idsToDelete) }); - - return; - } - - // delete executions by IDs, if user may access the underlying workflows - - if (ids) { - const executions = await Db.collections.Execution.find({ - where: { - id: In(ids), - workflowId: In(sharedWorkflowIds), - }, - }); - - if (!executions.length) { + if (!executions.length) { + if (ids) { LoggerProxy.error('Failed to delete an execution due to insufficient permissions', { userId: req.user.id, executionIds: ids, }); - return; } - - const idsToDelete = executions.map(({ id }) => id); - - await Promise.all( - idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)), - ); - - await Db.collections.Execution.delete(idsToDelete); + return; } + + const idsToDelete = executions.map(({ id }) => id); + + const binaryDataManager = BinaryDataManager.getInstance(); + await Promise.all( + idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)), + ); + + await Db.collections.Execution.delete(idsToDelete); } }