rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
154 lines • 7.52 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqlPrinter = void 0;
const SqlPrintToken_1 = require("../models/SqlPrintToken");
const LinePrinter_1 = require("./LinePrinter");
/**
* SqlPrinter formats a SqlPrintToken tree into a SQL string with flexible style options.
*/
class SqlPrinter {
/**
* @param options Optional style settings for pretty printing
*/
constructor(options) {
var _a, _b, _c, _d, _e, _f, _g;
this.indentChar = (_a = options === null || options === void 0 ? void 0 : options.indentChar) !== null && _a !== void 0 ? _a : '';
this.indentSize = (_b = options === null || options === void 0 ? void 0 : options.indentSize) !== null && _b !== void 0 ? _b : 0;
// The default newline character is set to a blank space (' ') to enable one-liner formatting.
// This is intentional and differs from the LinePrinter default of '\r\n'.
this.newline = (_c = options === null || options === void 0 ? void 0 : options.newline) !== null && _c !== void 0 ? _c : ' ';
this.commaBreak = (_d = options === null || options === void 0 ? void 0 : options.commaBreak) !== null && _d !== void 0 ? _d : 'none';
this.andBreak = (_e = options === null || options === void 0 ? void 0 : options.andBreak) !== null && _e !== void 0 ? _e : 'none';
this.keywordCase = (_f = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _f !== void 0 ? _f : 'none';
this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline);
// Initialize
this.indentIncrementContainers = new Set((_g = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _g !== void 0 ? _g : [
SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause,
SqlPrintToken_1.SqlPrintTokenContainerType.FromClause,
SqlPrintToken_1.SqlPrintTokenContainerType.WhereClause,
SqlPrintToken_1.SqlPrintTokenContainerType.GroupByClause,
SqlPrintToken_1.SqlPrintTokenContainerType.HavingClause,
SqlPrintToken_1.SqlPrintTokenContainerType.WindowFrameExpression,
SqlPrintToken_1.SqlPrintTokenContainerType.PartitionByClause,
SqlPrintToken_1.SqlPrintTokenContainerType.OrderByClause,
SqlPrintToken_1.SqlPrintTokenContainerType.WindowClause,
SqlPrintToken_1.SqlPrintTokenContainerType.LimitClause,
SqlPrintToken_1.SqlPrintTokenContainerType.OffsetClause,
SqlPrintToken_1.SqlPrintTokenContainerType.SubQuerySource,
SqlPrintToken_1.SqlPrintTokenContainerType.BinarySelectQueryOperator, SqlPrintToken_1.SqlPrintTokenContainerType.Values,
SqlPrintToken_1.SqlPrintTokenContainerType.WithClause,
SqlPrintToken_1.SqlPrintTokenContainerType.SwitchCaseArgument,
SqlPrintToken_1.SqlPrintTokenContainerType.CaseKeyValuePair,
SqlPrintToken_1.SqlPrintTokenContainerType.CaseThenValue,
SqlPrintToken_1.SqlPrintTokenContainerType.ElseClause,
SqlPrintToken_1.SqlPrintTokenContainerType.CaseElseValue
// CaseExpression, SwitchCaseArgument, CaseKeyValuePair, and ElseClause
// are not included by default to maintain backward compatibility with tests
//SqlPrintTokenContainerType.CommonTable
]);
}
/**
* Converts a SqlPrintToken tree to a formatted SQL string.
* @param token The root SqlPrintToken
* @param level Indentation level (default: 0)
*/
print(token, level = 0) {
// initialize
this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline);
if (this.linePrinter.lines.length > 0 && level !== this.linePrinter.lines[0].level) {
this.linePrinter.lines[0].level = level;
}
this.appendToken(token, level);
return this.linePrinter.print();
}
appendToken(token, level) {
if (!token.innerTokens || token.innerTokens.length === 0) {
if (token.text === '') {
return;
}
}
const current = this.linePrinter.getCurrentLine();
if (token.type === SqlPrintToken_1.SqlPrintTokenType.keyword) {
let text = token.text;
if (this.keywordCase === 'upper') {
text = text.toUpperCase();
}
else if (this.keywordCase === 'lower') {
text = text.toLowerCase();
}
this.linePrinter.appendText(text);
}
else if (token.type === SqlPrintToken_1.SqlPrintTokenType.comma) {
let text = token.text;
if (this.commaBreak === 'before') {
this.linePrinter.appendNewline(level);
this.linePrinter.appendText(text);
}
else if (this.commaBreak === 'after') {
this.linePrinter.appendText(text);
this.linePrinter.appendNewline(level);
}
else {
this.linePrinter.appendText(text);
}
}
else if (token.type === SqlPrintToken_1.SqlPrintTokenType.operator && token.text.toLowerCase() === 'and') {
let text = token.text;
if (this.keywordCase === 'upper') {
text = text.toUpperCase();
}
else if (this.keywordCase === 'lower') {
text = text.toLowerCase();
}
if (this.andBreak === 'before') {
this.linePrinter.appendNewline(level);
this.linePrinter.appendText(text);
}
else if (this.andBreak === 'after') {
this.linePrinter.appendText(text);
this.linePrinter.appendNewline(level);
}
else {
this.linePrinter.appendText(text);
}
}
else if (token.containerType === "JoinClause") {
let text = token.text;
if (this.keywordCase === 'upper') {
text = text.toUpperCase();
}
else if (this.keywordCase === 'lower') {
text = text.toLowerCase();
}
// before join clause, add newline
this.linePrinter.appendNewline(level);
this.linePrinter.appendText(text);
}
else {
this.linePrinter.appendText(token.text);
}
// append keyword tokens(not indented)
if (token.keywordTokens && token.keywordTokens.length > 0) {
for (let i = 0; i < token.keywordTokens.length; i++) {
const keywordToken = token.keywordTokens[i];
this.appendToken(keywordToken, level);
}
}
let innerLevel = level;
// indent level up
if (this.newline !== ' ' && current.text !== '' && this.indentIncrementContainers.has(token.containerType)) { // Changed condition
innerLevel++;
this.linePrinter.appendNewline(innerLevel);
}
for (let i = 0; i < token.innerTokens.length; i++) {
const child = token.innerTokens[i];
this.appendToken(child, innerLevel);
}
// indent level down
if (innerLevel !== level) {
this.linePrinter.appendNewline(level);
}
}
}
exports.SqlPrinter = SqlPrinter;
//# sourceMappingURL=SqlPrinter.js.map