rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
108 lines • 5.06 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqlPaginationInjector = void 0;
const SelectQuery_1 = require("../models/SelectQuery");
const Clause_1 = require("../models/Clause");
const ValueComponent_1 = require("../models/ValueComponent");
const SelectQueryParser_1 = require("../parsers/SelectQueryParser");
/**
* SqlPaginationInjector injects pagination (LIMIT/OFFSET) into a SelectQuery model,
* creating LIMIT and OFFSET clauses based on provided pagination options.
*/
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_1.SelectQueryParser.parse(query);
}
// Check if query is SimpleSelectQuery
if (!(query instanceof SelectQuery_1.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 Clause_1.LimitClause(new ValueComponent_1.ParameterExpression('paging_limit', pagination.pageSize));
// Create OFFSET clause (always include for consistent query caching)
const offsetClause = new Clause_1.OffsetClause(new ValueComponent_1.ParameterExpression('paging_offset', offset));
// Create a new query with pagination clauses
return new SelectQuery_1.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_1.SelectQueryParser.parse(query);
}
// Check if query is SimpleSelectQuery
if (!(query instanceof SelectQuery_1.SimpleSelectQuery)) {
throw new Error('Complex queries are not supported for pagination removal');
}
// Create a new query without LIMIT and OFFSET clauses
return new SelectQuery_1.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');
}
}
}
exports.SqlPaginationInjector = SqlPaginationInjector;
//# sourceMappingURL=SqlPaginationInjector.js.map