From aef1dbda85b7037af09beb0d3e0054654718e5c0 Mon Sep 17 00:00:00 2001 From: XingY Date: Tue, 8 Sep 2026 18:59:53 -0700 Subject: [PATCH] GitHub Issue 1534: Cap row counts for React grid pagination --- package-lock.json | 4 ++-- package.json | 2 +- src/labkey/query/ExecuteSql.ts | 8 ++++++++ src/labkey/query/Response.ts | 2 ++ src/labkey/query/SelectRows.ts | 8 ++++++++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9d52523b..4c37660a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/api", - "version": "1.52.4", + "version": "1.52.5-fb-limitMaxCount.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/api", - "version": "1.52.4", + "version": "1.52.5-fb-limitMaxCount.1", "license": "Apache-2.0", "devDependencies": { "@babel/core": "8.0.1", diff --git a/package.json b/package.json index 991e82b2..df9a1ea1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/api", - "version": "1.52.4", + "version": "1.52.5-fb-limitMaxCount.1", "description": "JavaScript client API for LabKey Server", "scripts": { "build": "npm run build:dist && npm run build:docs", diff --git a/src/labkey/query/ExecuteSql.ts b/src/labkey/query/ExecuteSql.ts index 85c8129b..2ffdcb15 100644 --- a/src/labkey/query/ExecuteSql.ts +++ b/src/labkey/query/ExecuteSql.ts @@ -39,6 +39,11 @@ export interface ExecuteSqlOptions extends RequestCallbackOptions { * If false totalCount will equal number of rows returned (equal to maxRows unless maxRows == 0). */ includeTotalCount?: boolean; + /** + * Cap the total-count query at this many rows so COUNT(*) is performant. When exceeded the response reports + * rowCount clamped to this value and rowCountCapped: true. Omitted or 0 counts exactly (the default). + */ + maxCount?: number; /** The maximum number of rows to return from the server (defaults to returning 100,000 rows). */ maxRows?: number; /** @@ -117,6 +122,9 @@ function buildParams(options: ExecuteSqlOptions): any { if (options.includeTotalCount !== undefined) { jsonData.includeTotalCount = options.includeTotalCount; } + if (options.maxCount !== undefined) { + jsonData.maxCount = options.maxCount; + } if (options.containerFilter) { jsonData.containerFilter = options.containerFilter; diff --git a/src/labkey/query/Response.ts b/src/labkey/query/Response.ts index e250a588..33d43339 100644 --- a/src/labkey/query/Response.ts +++ b/src/labkey/query/Response.ts @@ -178,6 +178,8 @@ export class Response { metaData: ResponseMetadata; queryName: string; rowCount: number; + /** True when rowCount was capped at the request's maxCount rather than counted exactly. Absent unless maxCount was hit. */ + rowCountCapped?: boolean; rows: Row[]; schemaKey: SchemaKey; schemaName: string; diff --git a/src/labkey/query/SelectRows.ts b/src/labkey/query/SelectRows.ts index 61533699..82e1ff77 100644 --- a/src/labkey/query/SelectRows.ts +++ b/src/labkey/query/SelectRows.ts @@ -63,6 +63,12 @@ export interface SelectRowsOptions extends RequestCallbackOptions { * number of rows returned (equal to maxRows unless maxRows == 0). */ includeTotalCount?: boolean; + /** + * Cap the total-count query at this many rows, so a large grid's COUNT(*) won't do a full scan. + * When exceeded the response reports rowCount clamped to this value and rowCountCapped: true. Omitted or 0 + * counts exactly (the default). Only affects the count; row data is unaffected. + */ + maxCount?: number; /** * Include the Update (or edit) link column in the set of columns (defaults to false). If included, the column * will have the name "~~Update~~". The underlying table/query must support update links or the column @@ -172,6 +178,8 @@ function buildSelectRowsParams(options: SelectRowsOptions): any { if (options.includeTotalCount !== undefined) params.includeTotalCount = options.includeTotalCount; + if (options.maxCount !== undefined) params.maxCount = options.maxCount; + if (options.includeDetailsColumn) params.includeDetailsColumn = options.includeDetailsColumn; if (options.includeUpdateColumn) params.includeUpdateColumn = options.includeUpdateColumn;