UNPKG

rawsql-ts

Version:

High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.

177 lines (175 loc) 7.13 kB
import { SelectQuery } from "../models/SelectQuery"; import { SortConditions } from "./SqlSortInjector"; import { PaginationOptions } from "./SqlPaginationInjector"; import { JsonMapping } from "./PostgresJsonQueryBuilder"; import { SqlParameterValue } from "../models/ValueComponent"; /** * Value union accepted for a single filter entry in DynamicQueryBuilder. * * @example * ```typescript * const options = { filter: { price: { min: 10, max: 100 }, status: ['active', 'pending'] } }; * builder.buildQuery('SELECT * FROM orders', options); * ``` * Related tests: packages/core/tests/transformers/DynamicQueryBuilder.test.ts */ export type FilterConditionValue = SqlParameterValue | SqlParameterValue[] | { min?: SqlParameterValue; max?: SqlParameterValue; like?: string; ilike?: string; in?: SqlParameterValue[]; any?: SqlParameterValue[]; '='?: SqlParameterValue; '>'?: SqlParameterValue; '<'?: SqlParameterValue; '>='?: SqlParameterValue; '<='?: SqlParameterValue; '!='?: SqlParameterValue; '<>'?: SqlParameterValue; or?: { column: string; [operator: string]: SqlParameterValue | string; }[]; and?: { column: string; [operator: string]: SqlParameterValue | string; }[]; column?: string; }; /** * Filter conditions for dynamic query building. * * Supports both unqualified and qualified column names: * - Unqualified: `{ name: 'Alice' }` - applies to all columns named 'name' * - Qualified: `{ 'users.name': 'Bob' }` - applies only to the 'name' column in the 'users' table/alias * - Hybrid: `{ name: 'Default', 'users.name': 'Override' }` - qualified names take priority over unqualified * * @example * ```typescript * // Basic usage (backward compatible) * const filter: FilterConditions = { * name: 'Alice', * status: 'active' * }; * * // Qualified names for disambiguation in JOINs * const filter: FilterConditions = { * 'users.name': 'Alice', // Only applies to users.name * 'profiles.name': 'Bob' // Only applies to profiles.name * }; * * // Hybrid approach * const filter: FilterConditions = { * status: 'active', // Applies to all 'status' columns * 'users.name': 'Alice', // Overrides for users.name specifically * 'profiles.name': 'Bob' // Overrides for profiles.name specifically * }; * ``` * Related tests: packages/core/tests/transformers/DynamicQueryBuilder.test.ts */ export type FilterConditions = Record<string, FilterConditionValue>; /** * Options for dynamic query building */ export interface QueryBuildOptions { /** Filter conditions to inject into WHERE clause */ filter?: FilterConditions; /** Sort conditions to inject into ORDER BY clause */ sort?: SortConditions; /** Pagination options to inject LIMIT/OFFSET clauses */ paging?: PaginationOptions; /** JSON serialization mapping to transform results into hierarchical JSON * - JsonMapping object: explicit mapping configuration * - true: auto-load mapping from corresponding .json file * - false/undefined: no serialization */ serialize?: JsonMapping | boolean; /** * JSONB usage setting. Must be true (default) for PostgreSQL GROUP BY compatibility. * Setting to false will throw an error as JSON type cannot be used in GROUP BY clauses. * @default true */ jsonb?: boolean; } /** * DynamicQueryBuilder combines SQL parsing with dynamic condition injection (filters, sorts, paging, JSON serialization). * * Key behaviours verified in packages/core/tests/transformers/DynamicQueryBuilder.test.ts: * - Preserves the input SQL when no options are supplied. * - Applies filter, sort, and pagination in a deterministic order. * - Supports JSON serialization for hierarchical projections. */ export declare class DynamicQueryBuilder { private tableColumnResolver?; /** * Creates a new DynamicQueryBuilder instance * @param tableColumnResolver Optional function to resolve table columns for wildcard queries */ constructor(tableColumnResolver?: (tableName: string) => string[]); /** * Builds a SelectQuery from SQL content with dynamic conditions. * This is a pure function that does not perform any I/O operations. * @param sqlContent Raw SQL string to parse and modify * @param options Dynamic conditions to apply (filter, sort, paging, serialize) * @returns Modified SelectQuery with all dynamic conditions applied * @example * ```typescript * const builder = new DynamicQueryBuilder(); * const query = builder.buildQuery( * 'SELECT id, name FROM users WHERE active = true', * { * filter: { status: 'premium' }, * sort: { created_at: { desc: true } }, * paging: { page: 2, pageSize: 10 }, * serialize: { rootName: 'user', rootEntity: { id: 'user', name: 'User', columns: { id: 'id', name: 'name' } }, nestedEntities: [] } * } * ); * ``` */ buildQuery(sqlContent: string, options?: QueryBuildOptions): SelectQuery; /** * Builds a SelectQuery with only filtering applied. * Convenience method for when you only need dynamic WHERE conditions. * * @param sqlContent Raw SQL string to parse and modify * @param filter Filter conditions to apply * @returns Modified SelectQuery with filter conditions applied */ buildFilteredQuery(sqlContent: string, filter: FilterConditions): SelectQuery; /** * Builds a SelectQuery with only sorting applied. * Convenience method for when you only need dynamic ORDER BY clauses. * * @param sqlContent Raw SQL string to parse and modify * @param sort Sort conditions to apply * @returns Modified SelectQuery with sort conditions applied */ buildSortedQuery(sqlContent: string, sort: SortConditions): SelectQuery; /** * Builds a SelectQuery with only pagination applied. * Convenience method for when you only need LIMIT/OFFSET clauses. * * @param sqlContent Raw SQL string to parse and modify * @param paging Pagination options to apply * @returns Modified SelectQuery with pagination applied */ buildPaginatedQuery(sqlContent: string, paging: PaginationOptions): SelectQuery; /** * Builds a SelectQuery with only JSON serialization applied. * Convenience method for when you only need hierarchical JSON transformation. * * @param sqlContent Raw SQL string to parse and modify * @param serialize JSON mapping configuration to apply * @returns Modified SelectQuery with JSON serialization applied */ buildSerializedQuery(sqlContent: string, serialize: JsonMapping): SelectQuery; /** * Validates SQL content by attempting to parse it. * Useful for testing SQL validity without applying any modifications. * * @param sqlContent Raw SQL string to validate * @returns true if SQL is valid, throws error if invalid * @throws Error if SQL cannot be parsed */ validateSql(sqlContent: string): boolean; }