@dudousxd/nestjs-filter-clickhouse
Version:
ClickHouse adapter for @dudousxd/nestjs-filter: compiles structured filter input to parameterized ClickHouse SQL.
83 lines • 4.55 kB
TypeScript
import { type ColumnFilter, type ComputedSource, type EntityFieldInfo, type FieldExtent, type FieldExtentField, type FilterAdapter, type FilterEntity, type GroupByCountField, type SortItem } from '@dudousxd/nestjs-filter';
import { type ClickHouseClientLike, ClickHouseQuery } from './clickhouse-query.js';
import { type ClickHouseTable } from './table.js';
export interface ClickHouseAdapterOptions {
/**
* Settings sent with every query the adapter runs itself (the terminal aggregations). Queries run
* through {@link ClickHouseQuery.execute} use the client's defaults.
*/
clickhouseSettings?: Record<string, unknown>;
}
/**
* {@link FilterAdapter} for ClickHouse.
*
* The "entity" is a {@link ClickHouseTable} (`defineClickHouseTable({ table, fields })`) — a
* whitelist of fields, each a trusted SQL expression with its ClickHouse type — and the query
* builder is a {@link ClickHouseQuery} that compiles to ONE parameterized statement: every client
* value is bound as a typed `{pN:Type}` parameter and sent in `query_params`; client-supplied field
* names only ever select among declared expressions.
*
* Tables with **measures** (aggregate expressions) are aggregated: rows are groups by the selected
* dimensions, a filter touching a measure goes to HAVING, and totals count groups.
*/
export declare class ClickHouseAdapter implements FilterAdapter {
readonly client?: ClickHouseClientLike | undefined;
private readonly options;
constructor(client?: ClickHouseClientLike | undefined, options?: ClickHouseAdapterOptions);
/** A fresh query over `table`, executing through this adapter's client. */
query<T>(table: ClickHouseTable<T>): ClickHouseQuery<T>;
createQueryBuilder<E>(entity: FilterEntity<E>): unknown;
getEntityFields(entity: FilterEntity): EntityFieldInfo[] | null;
getEntityRelations(entity: FilterEntity): [] | null;
resolveFieldPath(entity: FilterEntity, path: string): 'field' | null;
getPrimaryKey(entity: FilterEntity): string | null;
private field;
/** Routes a compiled condition to WHERE, or to HAVING when it touches a measure. */
private addCondition;
applyColumnFilters(qb: unknown, filters: ColumnFilter[]): void;
applyAutoField(qb: unknown, name: string, value: unknown): void;
applySearch(qb: unknown, term: string, columns: string[]): void;
applyDistinct(qb: unknown, fields: string[]): void;
applySelect(qb: unknown, fields: string[], entity: FilterEntity): void;
applySort(qb: unknown, sorts: SortItem[]): void;
applyOffsetPagination(qb: unknown, page: number, size: number): void;
applyKeysetPagination(qb: unknown, keyset: SortItem[], values: unknown[]): void;
applyKeysetOrderAndLimit(qb: unknown, keyset: SortItem[], limit: number): void;
getResultAndCount<T = unknown>(qb: unknown): Promise<{
rows: T[];
total: number;
}>;
getDistinctResultAndCount(qb: unknown): Promise<{
rows: Record<string, unknown>[];
total: number;
}>;
getResult(qb: unknown): Promise<unknown[]>;
/**
* A computed source as a SQL expression — developer-written, never client input. A string is
* used verbatim (`{alias}` is replaced by the table expression); a function receives
* `{ alias: <table>, em: <client> }` and returns the SQL string.
*/
private computedExpression;
applyComputedField(qb: unknown, source: ComputedSource, value: unknown): void;
applyComputedSort(qb: unknown, source: ComputedSource, direction: 'asc' | 'desc'): void;
applyComputedSelect(qb: unknown, alias: string, source: ComputedSource): void;
applyComputedDistinct(qb: unknown, alias: string, source: ComputedSource): void;
private measurable;
private runRows;
/**
* `SELECT <expr> AS value, count() AS count … GROUP BY value` over the filtered rows (WHERE only —
* a terminal aggregation replaces the row output). The bucket width is a bound parameter.
*/
groupByCount(qb: unknown, field: GroupByCountField, _entity: FilterEntity, opts?: {
bucket?: number;
limit?: number;
offset?: number;
search?: string;
}): Promise<Array<{
value: unknown;
count: number;
}>>;
/** `minOrNull`/`maxOrNull` of every requested field in one query (ClickHouse's plain `min` over no rows is 0, not NULL). */
fieldExtent(qb: unknown, fields: FieldExtentField[]): Promise<Record<string, FieldExtent>>;
}
//# sourceMappingURL=clickhouse.adapter.d.ts.map