fix(public-api): Fix executions pagination in Postgres and Mysql

🐛 Fix executions pagination
This commit is contained in:
Iván Ovejero 2022-08-11 18:34:32 +02:00 committed by GitHub
parent 936264b3c6
commit 52015a6f03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 21 deletions

View file

@ -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: {

View file

@ -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();
}
});