diff --git a/src/domain-services/flows/flow-search-service.ts b/src/domain-services/flows/flow-search-service.ts index 94fc9e3d..245f33dc 100644 --- a/src/domain-services/flows/flow-search-service.ts +++ b/src/domain-services/flows/flow-search-service.ts @@ -27,6 +27,7 @@ import { type FlowPaged, type FlowParkedParentSource, type FlowSearchResult, + type FlowSearchResultNonPaginated, type FlowSearchTotalAmountResult, type FlowSortField, } from './graphql/types'; @@ -532,4 +533,39 @@ export class FlowSearchService { flowsCount: count, }; } + + async searchBatches( + models: Database, + args: SearchFlowsArgs + ): Promise { + const flowSearchResponse = await this.search(models, args); + + const batchesMissing = + Math.round(flowSearchResponse.total / args.limit) - 1; + const flows: FlowPaged[] = flowSearchResponse.flows; + + let hasNextPage = flowSearchResponse.hasNextPage; + let batchCount = 1; + + let cursor = flowSearchResponse.endCursor; + let nextArgs: SearchFlowsArgs = { ...args, afterCursor: cursor }; + + let nextFlowSearchResponse: FlowSearchResult; + while (hasNextPage) { + batchCount++; + + nextFlowSearchResponse = await this.search(models, nextArgs); + + flows.push(...nextFlowSearchResponse.flows); + + hasNextPage = + nextFlowSearchResponse.hasNextPage && batchCount <= batchesMissing; + + cursor = nextFlowSearchResponse.endCursor; + // Update the cursor for the next iteration + nextArgs = { ...args, afterCursor: cursor }; + } + + return { flows, flowsCount: flows.length }; + } } diff --git a/src/domain-services/flows/graphql/resolver.ts b/src/domain-services/flows/graphql/resolver.ts index ad49913d..00091d92 100644 --- a/src/domain-services/flows/graphql/resolver.ts +++ b/src/domain-services/flows/graphql/resolver.ts @@ -6,6 +6,7 @@ import { SearchFlowsArgs, SearchFlowsArgsNonPaginated } from './args'; import { FlowPaged, FlowSearchResult, + FlowSearchResultNonPaginated, FlowSearchTotalAmountResult, } from './types'; @@ -31,4 +32,16 @@ export default class FlowResolver { ): Promise { return await this.flowSearchService.searchTotalAmount(context.models, args); } + + @Query(() => FlowSearchResultNonPaginated) + async searchFlowsBatches( + @Ctx() context: Context, + @Args(() => SearchFlowsArgs, { validate: false }) + args: SearchFlowsArgs + ): Promise { + // Set default batch size to 1000 + args.limit = args.limit > 0 ? args.limit : 1000; + + return await this.flowSearchService.searchBatches(context.models, args); + } }