From 859edeb33138040bf2382688820adccd7aad363e Mon Sep 17 00:00:00 2001 From: Etienne Donneger Date: Wed, 24 Apr 2024 12:32:29 -0400 Subject: [PATCH] Include statistics from ClickHouse in `meta` response field (#14) See #8 --- src/fetch/balance.ts | 3 +-- src/fetch/supply.ts | 3 +-- src/fetch/transfers.ts | 3 +-- src/fetch/utils.spec.ts | 17 ++++++++++++----- src/fetch/utils.ts | 15 +++++++++------ 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/fetch/balance.ts b/src/fetch/balance.ts index d470c97..56172d9 100644 --- a/src/fetch/balance.ts +++ b/src/fetch/balance.ts @@ -23,8 +23,7 @@ export default async function (req: Request) { return toJSON( addMetadata( - response.data, - response.rows_before_limit_at_least, + response, parseLimit(searchParams.get("limit")), parsePage(searchParams.get("page")) ) diff --git a/src/fetch/supply.ts b/src/fetch/supply.ts index 280ac50..2838e78 100644 --- a/src/fetch/supply.ts +++ b/src/fetch/supply.ts @@ -23,8 +23,7 @@ export default async function (req: Request) { return toJSON( addMetadata( - response.data, - response.rows_before_limit_at_least, + response, parseLimit(searchParams.get("limit")), parsePage(searchParams.get("page")) ) diff --git a/src/fetch/transfers.ts b/src/fetch/transfers.ts index 5ec0b8d..26aaeb5 100644 --- a/src/fetch/transfers.ts +++ b/src/fetch/transfers.ts @@ -15,8 +15,7 @@ export default async function (req: Request) { return toJSON( addMetadata( - response.data, - response.rows_before_limit_at_least, + response, parseLimit(searchParams.get("limit")), parsePage(searchParams.get("page")) ) diff --git a/src/fetch/utils.spec.ts b/src/fetch/utils.spec.ts index 06144e9..d4eed9f 100644 --- a/src/fetch/utils.spec.ts +++ b/src/fetch/utils.spec.ts @@ -1,33 +1,40 @@ import { expect, test } from "bun:test"; import { addMetadata } from "./utils.js"; +import { Query } from "../clickhouse/makeQuery.js"; test("addMetadata pagination", () => { const limit = 5; - const mock_query_reponse = { + const mock_query_reponse: Query = { + meta: [], data: Array(limit), rows: limit, rows_before_limit_at_least: 5*limit, // Simulate query with more total results than the query limit making pagination relevant + statistics: { + elapsed: 0, + rows_read: 0, + bytes_read: 0, + } }; - const first_page = addMetadata(mock_query_reponse.data, mock_query_reponse.rows_before_limit_at_least, limit, 1); + const first_page = addMetadata(mock_query_reponse, limit, 1); expect(first_page.meta.next_page).toBe(2); expect(first_page.meta.previous_page).toBe(1); // Previous page should be set to 1 on first page expect(first_page.meta.total_pages).toBe(5); expect(first_page.meta.total_results).toBe(5*limit); - const odd_page = addMetadata(mock_query_reponse.data, mock_query_reponse.rows_before_limit_at_least, limit, 3); + const odd_page = addMetadata(mock_query_reponse, limit, 3); expect(odd_page.meta.next_page).toBe(4); expect(odd_page.meta.previous_page).toBe(2); expect(odd_page.meta.total_pages).toBe(5); expect(odd_page.meta.total_results).toBe(5*limit); - const even_page = addMetadata(mock_query_reponse.data, mock_query_reponse.rows_before_limit_at_least, limit, 4); + const even_page = addMetadata(mock_query_reponse, limit, 4); expect(even_page.meta.next_page).toBe(5); expect(even_page.meta.previous_page).toBe(3); expect(even_page.meta.total_pages).toBe(5); expect(even_page.meta.total_results).toBe(5*limit); - const last_page = addMetadata(mock_query_reponse.data, mock_query_reponse.rows_before_limit_at_least, limit, 5); + const last_page = addMetadata(mock_query_reponse, limit, 5); expect(last_page.meta.next_page).toBe(last_page.meta.total_pages); // Next page should be capped to total_pages on last page expect(last_page.meta.previous_page).toBe(4); expect(last_page.meta.total_pages).toBe(5); diff --git a/src/fetch/utils.ts b/src/fetch/utils.ts index 2601853..be97426 100644 --- a/src/fetch/utils.ts +++ b/src/fetch/utils.ts @@ -1,16 +1,19 @@ +import { Query } from "../clickhouse/makeQuery.js"; + export function toJSON(data: any, status: number = 200) { return new Response(JSON.stringify(data), { status, headers: { "Content-Type": "application/json" } }); } -export function addMetadata(data: any[], total_before_limit: number, limit: number, page: number) { +export function addMetadata(response: Query, req_limit: number, req_page: number) { // TODO: Catch page number greater than total_pages and return error return { - data, + data: response.data, meta: { - "next_page": (page * limit >= total_before_limit) ? page : page + 1, - "previous_page": (page <= 1) ? page : page - 1, - "total_pages": Math.ceil(total_before_limit / limit), - "total_results": total_before_limit + statistics: response.statistics, + "next_page": (req_page * req_limit >= response.rows_before_limit_at_least) ? req_page : req_page + 1, + "previous_page": (req_page <= 1) ? req_page : req_page - 1, + "total_pages": Math.ceil( response.rows_before_limit_at_least / req_limit), + "total_results": response.rows_before_limit_at_least } } } \ No newline at end of file