Skip to content

Commit

Permalink
Query for all chains if no chain parameter present
Browse files Browse the repository at this point in the history
Previously when not passing any `chain` parameter with the query, the
result would be the first row in the DB matching the expression. This
change now runs the query as a `UNION` between all the available chains
in the DB when no `chain` parameter is passed.
  • Loading branch information
0237h committed Nov 3, 2023
1 parent 3636578 commit 34b5c8b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/fetch/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const TAGS = {
DOCS: "Documentation",
} as const;

const chains = await supportedChainsQuery();
export const chains = await supportedChainsQuery();
const block_example = (await makeQuery(await getBlock( new URLSearchParams({limit: "2"})))).data;

const timestampSchema: SchemaObject = { anyOf: [
Expand Down
7 changes: 7 additions & 0 deletions src/queries.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { expect, test } from "bun:test";
import { getBlock, getChain } from "./queries.js";
import { chains } from './fetch/openapi.js';

test("getBlock", () => {
expect(getBlock(new URLSearchParams({ chain: "eth", block_number: "123" })))
.toBe(`SELECT * FROM blocks WHERE (chain == 'eth' AND block_number == '123') ORDER BY block_number DESC LIMIT 1`);

expect(getBlock(new URLSearchParams({ chain: "eth", greater_or_equals_by_timestamp: '1438270048', less_or_equals_by_timestamp: '1438270083', limit: '3' })))
.toBe(`SELECT * FROM blocks WHERE (toUnixTimestamp(timestamp) >= 1438270048 AND toUnixTimestamp(timestamp) <= 1438270083 AND chain == 'eth') ORDER BY block_number DESC LIMIT 3`);

// Check that if not chain parameter is passed, all chains are included in the selection
chains.forEach((chain) => {
expect(getBlock(new URLSearchParams({ block_number: "123" })))
.toContain(`SELECT * FROM blocks WHERE (chain == '${chain}' AND block_number == '123') ORDER BY block_number DESC LIMIT 1`);
});
});

test("getChain", () => {
Expand Down
90 changes: 54 additions & 36 deletions src/queries.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { DEFAULT_SORT_BY, config } from './config.js';
import { parseBlockId, parseLimit, parseTimestamp } from './utils.js';
import { chains } from './fetch/openapi.js';
import { create } from 'domain';

export interface Block {
block_number: number;
Expand All @@ -11,44 +13,60 @@ export interface Block {
export function getBlock(searchParams: URLSearchParams) {
// TO-DO: Modulo block number (ex: search by every 1M blocks)

// SQL Query
let query = `SELECT * FROM ${config.table}`;
const where = [];

// Clickhouse Operators
// https://clickhouse.com/docs/en/sql-reference/operators
const operators = [
["greater_or_equals", ">="],
["greater", ">"],
["less_or_equals", "<="],
["less", "<"],
]
for ( const [key, operator] of operators ) {
const block_number = searchParams.get(`${key}_by_block_number`);
const timestamp = parseTimestamp(searchParams.get(`${key}_by_timestamp`));
if (block_number) where.push(`block_number ${operator} ${block_number}`);
if (timestamp) where.push(`toUnixTimestamp(timestamp) ${operator} ${timestamp}`);
}
let createBlockQuery = (searchParams: URLSearchParams) => {
// SQL Query
let query = `SELECT * FROM ${config.table}`;
const where = [];

// Clickhouse Operators
// https://clickhouse.com/docs/en/sql-reference/operators
const operators = [
["greater_or_equals", ">="],
["greater", ">"],
["less_or_equals", "<="],
["less", "<"],
]
for ( const [key, operator] of operators ) {
const block_number = searchParams.get(`${key}_by_block_number`);
const timestamp = parseTimestamp(searchParams.get(`${key}_by_timestamp`));
if (block_number) where.push(`block_number ${operator} ${block_number}`);
if (timestamp) where.push(`toUnixTimestamp(timestamp) ${operator} ${timestamp}`);
}

// equals
const chain = searchParams.get("chain");
const block_id = parseBlockId(searchParams.get("block_id"));
const block_number = searchParams.get('block_number');
const timestamp = parseTimestamp(searchParams.get('timestamp'));
if (chain) where.push(`chain == '${chain}'`);
if (block_id) where.push(`block_id == '${block_id}'`);
if (block_number) where.push(`block_number == '${block_number}'`);
if (timestamp) where.push(`toUnixTimestamp(timestamp) == ${timestamp}`);

// Join WHERE statements with AND
if ( where.length ) query += ` WHERE (${where.join(' AND ')})`;

// Sort and Limit
const limit = parseLimit(searchParams.get("limit"));
const sort_by = searchParams.get("sort_by");
query += ` ORDER BY block_number ${sort_by ?? DEFAULT_SORT_BY}`
query += ` LIMIT ${limit}`

return query;
};

// equals
const chain = searchParams.get("chain");
const block_id = parseBlockId(searchParams.get("block_id"));
const block_number = searchParams.get('block_number');
const timestamp = parseTimestamp(searchParams.get('timestamp'));
if (chain) where.push(`chain == '${chain}'`);
if (block_id) where.push(`block_id == '${block_id}'`);
if (block_number) where.push(`block_number == '${block_number}'`);
if (timestamp) where.push(`toUnixTimestamp(timestamp) == ${timestamp}`);

// Join WHERE statements with AND
if ( where.length ) query += ` WHERE (${where.join(' AND ')})`;

// Sort and Limit
const limit = parseLimit(searchParams.get("limit"));
const sort_by = searchParams.get("sort_by");
query += ` ORDER BY block_number ${sort_by ?? DEFAULT_SORT_BY}`
query += ` LIMIT ${limit}`
return query;

if (!chain) {
let queries = chains.map((chain) => {
searchParams.set('chain', chain);
return createBlockQuery(searchParams);
});

return queries.join(' UNION ALL ');
} else {
return createBlockQuery(searchParams);
}
}

export function getChain() {
Expand Down

0 comments on commit 34b5c8b

Please sign in to comment.