UNPKG

rawsql-ts

Version:

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

104 lines 4.77 kB
import { SimpleSelectQuery } from "../models/SelectQuery"; import { LimitClause, OffsetClause } from "../models/Clause"; import { ParameterExpression } from "../models/ValueComponent"; import { SelectQueryParser } from "../parsers/SelectQueryParser"; /** * SqlPaginationInjector injects pagination (LIMIT/OFFSET) into a SelectQuery model, * creating LIMIT and OFFSET clauses based on provided pagination options. */ export class SqlPaginationInjector { /** * Injects pagination as LIMIT/OFFSET clauses into the given query model. * @param query The SelectQuery to modify * @param pagination Pagination options containing page number and page size * @returns The modified SimpleSelectQuery with pagination applied */ inject(query, pagination) { // Validate pagination options this.validatePaginationOptions(pagination); // Convert string query to SimpleSelectQuery using SelectQueryParser if needed if (typeof query === 'string') { query = SelectQueryParser.parse(query); } // Check if query is SimpleSelectQuery if (!(query instanceof SimpleSelectQuery)) { throw new Error('Complex queries are not supported for pagination'); } // Check if query already has LIMIT or OFFSET clauses if (query.limitClause || query.offsetClause) { throw new Error('Query already contains LIMIT or OFFSET clause. Use removePagination() first if you want to override existing pagination.'); } // Calculate offset const offset = (pagination.page - 1) * pagination.pageSize; // Create LIMIT clause const limitClause = new LimitClause(new ParameterExpression('paging_limit', pagination.pageSize)); // Create OFFSET clause (always include for consistent query caching) const offsetClause = new OffsetClause(new ParameterExpression('paging_offset', offset)); // Create a new query with pagination clauses return new SimpleSelectQuery({ withClause: query.withClause, selectClause: query.selectClause, fromClause: query.fromClause, whereClause: query.whereClause, groupByClause: query.groupByClause, havingClause: query.havingClause, orderByClause: query.orderByClause, windowClause: query.windowClause, limitClause: limitClause, offsetClause: offsetClause, fetchClause: query.fetchClause, forClause: query.forClause, }); } /** * Removes LIMIT and OFFSET clauses from the given query. * @param query The SelectQuery to modify * @returns The modified SimpleSelectQuery with pagination removed */ static removePagination(query) { // Convert string query to SimpleSelectQuery using SelectQueryParser if needed if (typeof query === 'string') { query = SelectQueryParser.parse(query); } // Check if query is SimpleSelectQuery if (!(query instanceof SimpleSelectQuery)) { throw new Error('Complex queries are not supported for pagination removal'); } // Create a new query without LIMIT and OFFSET clauses return new SimpleSelectQuery({ withClause: query.withClause, selectClause: query.selectClause, fromClause: query.fromClause, whereClause: query.whereClause, groupByClause: query.groupByClause, havingClause: query.havingClause, orderByClause: query.orderByClause, windowClause: query.windowClause, limitClause: null, // Remove LIMIT offsetClause: null, // Remove OFFSET fetchClause: query.fetchClause, forClause: query.forClause, }); } /** * Validates pagination options * @param pagination Pagination options to validate * @throws Error if validation fails */ validatePaginationOptions(pagination) { if (!pagination) { throw new Error('Pagination options are required'); } if (typeof pagination.page !== 'number' || pagination.page < 1) { throw new Error('Page number must be a positive integer (1 or greater)'); } if (typeof pagination.pageSize !== 'number' || pagination.pageSize < 1) { throw new Error('Page size must be a positive integer (1 or greater)'); } // Optional: Set reasonable upper limit for page size to prevent performance issues if (pagination.pageSize > 1000) { throw new Error('Page size cannot exceed 1000 items'); } } } //# sourceMappingURL=SqlPaginationInjector.js.map