Skip to content

Commit

Permalink
fix: Fix executions bulk deletion (#5074)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
netroy authored Jan 3, 2023
1 parent ee28213 commit 3754c5c
Showing 1 changed file with 27 additions and 53 deletions.
80 changes: 27 additions & 53 deletions packages/cli/src/executions/executions.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -199,7 +200,7 @@ export class ExecutionsService {
.map(({ id }) => id),
);

const findWhere = { workflowId: In(sharedWorkflowIds) };
const findWhere: FindConditions<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };

const rangeQuery: string[] = [];
const rangeQueryParams: {
Expand Down Expand Up @@ -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<ExecutionEntity> = { workflowId: In(sharedWorkflowIds) };

if (deleteBefore) {
const filters: IDataObject = {
startedAt: LessThanOrEqual(deleteBefore),
};

let query = Db.collections.Execution.createQueryBuilder()
.select('id')
.where({
...filters,
workflowId: In(sharedWorkflowIds),
});

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),
},
});
// 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;

const executions = await Db.collections.Execution.find({
select: ['id'],
where,
});

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;
}
return;
}

const idsToDelete = executions.map(({ id }) => id);
const idsToDelete = executions.map(({ id }) => id);

await Promise.all(
idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)),
);
const binaryDataManager = BinaryDataManager.getInstance();
await Promise.all(
idsToDelete.map(async (id) => binaryDataManager.deleteBinaryDataByExecutionId(id)),
);

await Db.collections.Execution.delete(idsToDelete);
}
await Db.collections.Execution.delete(idsToDelete);
}
}

0 comments on commit 3754c5c

Please sign in to comment.