From a6f57fac2c8d8b39b3dfdb68c1fc28e63add7b97 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Thu, 19 Sep 2024 20:27:31 +0200 Subject: [PATCH] Fix --- ...raphql-query-find-many-resolver.service.ts | 40 +++++++++++++------ .../utils/apply-range-filter.util.ts | 16 -------- .../utils/compute-cursor-arg-filter.ts | 35 ++++++++++++++++ 3 files changed, 63 insertions(+), 28 deletions(-) delete mode 100644 packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/apply-range-filter.util.ts create mode 100644 packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-cursor-arg-filter.ts diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts index 5608d5ed5..6c6defd29 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts @@ -19,12 +19,12 @@ import { import { GraphqlQueryParser } from 'src/engine/api/graphql/graphql-query-runner/graphql-query-parsers/graphql-query.parser'; import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper'; import { ObjectRecordsToGraphqlConnectionMapper } from 'src/engine/api/graphql/graphql-query-runner/orm-mappers/object-records-to-graphql-connection.mapper'; -import { applyRangeFilter } from 'src/engine/api/graphql/graphql-query-runner/utils/apply-range-filter.util'; +import { computeCursorArgFilter } from 'src/engine/api/graphql/graphql-query-runner/utils/compute-cursor-arg-filter'; import { decodeCursor } from 'src/engine/api/graphql/graphql-query-runner/utils/cursors.util'; import { getObjectMetadataOrThrow } from 'src/engine/api/graphql/graphql-query-runner/utils/get-object-metadata-or-throw.util'; import { - generateObjectMetadataMap, ObjectMetadataMapItem, + generateObjectMetadataMap, } from 'src/engine/metadata-modules/utils/generate-object-metadata-map.util'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; @@ -79,15 +79,39 @@ export class GraphqlQueryFindManyResolverService { args.orderBy ?? [], isForwardPagination, ); - const { parsedFilters: where, withDeleted } = + const { parsedFilters: whereForCount, withDeleted } = graphqlQueryParser.parseFilter(args.filter ?? ({} as Filter)); - const cursor = this.getCursor(args); const limit = args.first ?? args.last ?? QUERY_MAX_RECORDS; this.addOrderByColumnsToSelect(order, select); this.addForeingKeyColumnsToSelect(relations, select, objectMetadata); + const totalCount = isDefined(selectedFields.totalCount) + ? await repository.count({ where: whereForCount, withDeleted }) + : 0; + + const cursor = this.getCursor(args); + + let where = whereForCount; + + if (cursor) { + const cursorArgFilter = computeCursorArgFilter( + cursor, + isForwardPagination, + ); + + const combinedArgFilter = { + ...args.filter, + or: cursorArgFilter, + } as unknown as Filter; + + const { parsedFilters: whereForQuery } = + graphqlQueryParser.parseFilter(combinedArgFilter); + + where = whereForQuery; + } + const findOptions: FindManyOptions = { where, order, @@ -96,14 +120,6 @@ export class GraphqlQueryFindManyResolverService { withDeleted, }; - const totalCount = isDefined(selectedFields.totalCount) - ? await repository.count({ where, withDeleted }) - : 0; - - if (cursor) { - applyRangeFilter(where, cursor, isForwardPagination); - } - const objectRecords = (await repository.find( findOptions, )) as ObjectRecord[]; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/apply-range-filter.util.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/apply-range-filter.util.ts deleted file mode 100644 index 3a536c68c..000000000 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/apply-range-filter.util.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { FindOptionsWhere, LessThan, MoreThan, ObjectLiteral } from 'typeorm'; - -export const applyRangeFilter = ( - where: FindOptionsWhere, - cursor: Record, - isForwardPagination = true, -): FindOptionsWhere => { - Object.entries(cursor ?? {}).forEach(([key, value]) => { - if (key === 'id') { - return; - } - where[key] = isForwardPagination ? MoreThan(value) : LessThan(value); - }); - - return where; -}; diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-cursor-arg-filter.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-cursor-arg-filter.ts new file mode 100644 index 000000000..b4276c12f --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-cursor-arg-filter.ts @@ -0,0 +1,35 @@ +import { RecordFilter } from 'src/engine/api/graphql/workspace-query-builder/interfaces/record.interface'; + +export const computeCursorArgFilter = ( + cursor: Record, + isForwardPagination = true, +): RecordFilter[] => { + const cursorKeys = Object.keys(cursor ?? {}); + const cursorValues = Object.values(cursor ?? {}); + + if (cursorKeys.length === 0) { + return []; + } + + return Object.entries(cursor ?? {}).map(([key, value], index) => { + let whereCondition = {}; + + for ( + let subConditionIndex = 0; + subConditionIndex < index; + subConditionIndex++ + ) { + whereCondition = { + ...whereCondition, + [cursorKeys[subConditionIndex]]: { + eq: cursorValues[subConditionIndex], + }, + }; + } + + return { + ...whereCondition, + ...{ [key]: isForwardPagination ? { gt: value } : { lt: value } }, + } as RecordFilter; + }); +};