UNPKG

@dudousxd/nestjs-filter-clickhouse

Version:

ClickHouse adapter for @dudousxd/nestjs-filter: compiles structured filter input to parameterized ClickHouse SQL.

83 lines • 4.55 kB
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