mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-09 22:24:05 -08:00
fix(public-api): Fix executions pagination in Postgres and Mysql
🐛 Fix executions pagination
This commit is contained in:
parent
936264b3c6
commit
52015a6f03
|
@ -1,7 +1,8 @@
|
|||
import { parse } from 'flatted';
|
||||
import { In, Not, Raw, ObjectLiteral, LessThan, IsNull } from 'typeorm';
|
||||
import { In, Not, Raw, LessThan, IsNull, FindOperator } from 'typeorm';
|
||||
|
||||
import { Db, IExecutionFlattedDb, IExecutionResponseApi } from '../../../..';
|
||||
import { ExecutionEntity } from '../../../../databases/entities/ExecutionEntity';
|
||||
import { ExecutionStatus } from '../../../types';
|
||||
|
||||
function prepareExecutionData(
|
||||
|
@ -18,8 +19,12 @@ function prepareExecutionData(
|
|||
};
|
||||
}
|
||||
|
||||
function getStatusCondition(status: ExecutionStatus): ObjectLiteral {
|
||||
const condition: ObjectLiteral = {};
|
||||
function getStatusCondition(status: ExecutionStatus) {
|
||||
const condition: {
|
||||
finished?: boolean;
|
||||
waitTill?: FindOperator<ExecutionEntity>;
|
||||
stoppedAt?: FindOperator<ExecutionEntity>;
|
||||
} = {};
|
||||
|
||||
if (status === 'success') {
|
||||
condition.finished = true;
|
||||
|
@ -51,7 +56,7 @@ function getExecutionSelectableProperties(includeData?: boolean): Array<keyof IE
|
|||
return selectFields;
|
||||
}
|
||||
|
||||
export async function getExecutions(data: {
|
||||
export async function getExecutions(params: {
|
||||
limit: number;
|
||||
includeData?: boolean;
|
||||
lastId?: number;
|
||||
|
@ -59,28 +64,40 @@ export async function getExecutions(data: {
|
|||
status?: ExecutionStatus;
|
||||
excludedExecutionsIds?: number[];
|
||||
}): Promise<IExecutionResponseApi[]> {
|
||||
const where = {
|
||||
...(data.lastId && { id: LessThan(data.lastId) }),
|
||||
...(data.status && { ...getStatusCondition(data.status) }),
|
||||
...(data.workflowIds && { workflowId: In(data.workflowIds.map(String)) }),
|
||||
...(data.excludedExecutionsIds && { id: Not(In(data.excludedExecutionsIds)) }),
|
||||
};
|
||||
type WhereClause = Record<
|
||||
string,
|
||||
string | boolean | FindOperator<number | Partial<ExecutionEntity>>
|
||||
>;
|
||||
|
||||
if (data.lastId && data.excludedExecutionsIds) {
|
||||
let where: WhereClause = {};
|
||||
|
||||
if (params.lastId && params.excludedExecutionsIds?.length) {
|
||||
where.id = Raw((id) => `${id} < :lastId AND ${id} NOT IN (:...excludedExecutionsIds)`, {
|
||||
lastId: data.lastId,
|
||||
excludedExecutionsIds: data.excludedExecutionsIds,
|
||||
lastId: params.lastId,
|
||||
excludedExecutionsIds: params.excludedExecutionsIds,
|
||||
});
|
||||
} else if (params.lastId) {
|
||||
where.id = LessThan(params.lastId);
|
||||
} else if (params.excludedExecutionsIds?.length) {
|
||||
where.id = Not(In(params.excludedExecutionsIds));
|
||||
}
|
||||
|
||||
if (params.status) {
|
||||
where = { ...where, ...getStatusCondition(params.status) };
|
||||
}
|
||||
|
||||
if (params.workflowIds) {
|
||||
where = { ...where, workflowId: In(params.workflowIds) };
|
||||
}
|
||||
|
||||
const executions = await Db.collections.Execution.find({
|
||||
select: getExecutionSelectableProperties(data.includeData),
|
||||
select: getExecutionSelectableProperties(params.includeData),
|
||||
where,
|
||||
order: { id: 'DESC' },
|
||||
take: data.limit,
|
||||
take: params.limit,
|
||||
});
|
||||
|
||||
return executions.map((execution) => prepareExecutionData(execution)) as IExecutionResponseApi[];
|
||||
return executions.map(prepareExecutionData) as IExecutionResponseApi[];
|
||||
}
|
||||
|
||||
export async function getExecutionsCount(data: {
|
||||
|
|
|
@ -292,9 +292,9 @@ test.skip('GET /executions should paginate two executions', async () => {
|
|||
|
||||
const workflow = await testDb.createWorkflow({}, owner);
|
||||
|
||||
const fistSuccessfullExecution = await testDb.createSuccessfulExecution(workflow);
|
||||
const firstSuccessfulExecution = await testDb.createSuccessfulExecution(workflow);
|
||||
|
||||
const secondSuccessfullExecution = await testDb.createSuccessfulExecution(workflow);
|
||||
const secondSuccessfulExecution = await testDb.createSuccessfulExecution(workflow);
|
||||
|
||||
await testDb.createErrorExecution(workflow);
|
||||
|
||||
|
@ -317,7 +317,7 @@ test.skip('GET /executions should paginate two executions', async () => {
|
|||
expect(secondExecutionResponse.body.data.length).toBe(1);
|
||||
expect(secondExecutionResponse.body.nextCursor).toBeNull();
|
||||
|
||||
const successfullExecutions = [fistSuccessfullExecution, secondSuccessfullExecution];
|
||||
const successfulExecutions = [firstSuccessfulExecution, secondSuccessfulExecution];
|
||||
const executions = [...firstExecutionResponse.body.data, ...secondExecutionResponse.body.data];
|
||||
|
||||
for (let i = 0; i < executions.length; i++) {
|
||||
|
@ -335,12 +335,12 @@ test.skip('GET /executions should paginate two executions', async () => {
|
|||
|
||||
expect(id).toBeDefined();
|
||||
expect(finished).toBe(true);
|
||||
expect(mode).toEqual(successfullExecutions[i].mode);
|
||||
expect(mode).toEqual(successfulExecutions[i].mode);
|
||||
expect(retrySuccessId).toBeNull();
|
||||
expect(retryOf).toBeNull();
|
||||
expect(startedAt).not.toBeNull();
|
||||
expect(stoppedAt).not.toBeNull();
|
||||
expect(workflowId).toBe(successfullExecutions[i].workflowId);
|
||||
expect(workflowId).toBe(successfulExecutions[i].workflowId);
|
||||
expect(waitTill).toBeNull();
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue