rawsql-ts 0.11.32-beta → 0.11.33-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +37 -29
- package/dist/esm/index.min.js.map +4 -4
- package/dist/esm/src/formatters/OriginalFormatRestorer.d.ts +40 -0
- package/dist/esm/src/formatters/OriginalFormatRestorer.js +135 -0
- package/dist/esm/src/formatters/OriginalFormatRestorer.js.map +1 -0
- package/dist/esm/src/index.d.ts +11 -0
- package/dist/esm/src/index.js +9 -0
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/models/FormattingLexeme.d.ts +66 -0
- package/dist/esm/src/models/FormattingLexeme.js +2 -0
- package/dist/esm/src/models/FormattingLexeme.js.map +1 -0
- package/dist/esm/src/models/ValueComponent.d.ts +3 -1
- package/dist/esm/src/models/ValueComponent.js +3 -1
- package/dist/esm/src/models/ValueComponent.js.map +1 -1
- package/dist/esm/src/parsers/FunctionExpressionParser.d.ts +12 -0
- package/dist/esm/src/parsers/FunctionExpressionParser.js +111 -7
- package/dist/esm/src/parsers/FunctionExpressionParser.js.map +1 -1
- package/dist/esm/src/parsers/KeywordParser.d.ts +1 -0
- package/dist/esm/src/parsers/KeywordParser.js +10 -4
- package/dist/esm/src/parsers/KeywordParser.js.map +1 -1
- package/dist/esm/src/parsers/SqlPrintTokenParser.js +8 -0
- package/dist/esm/src/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/esm/src/parsers/SqlTokenizer.d.ts +42 -2
- package/dist/esm/src/parsers/SqlTokenizer.js +213 -12
- package/dist/esm/src/parsers/SqlTokenizer.js.map +1 -1
- package/dist/esm/src/tokenReaders/CommandTokenReader.d.ts +3 -0
- package/dist/esm/src/tokenReaders/CommandTokenReader.js +4 -1
- package/dist/esm/src/tokenReaders/CommandTokenReader.js.map +1 -1
- package/dist/esm/src/transformers/AliasRenamer.d.ts +199 -0
- package/dist/esm/src/transformers/AliasRenamer.js +595 -0
- package/dist/esm/src/transformers/AliasRenamer.js.map +1 -0
- package/dist/esm/src/transformers/CTERenamer.d.ts +53 -0
- package/dist/esm/src/transformers/CTERenamer.js +138 -0
- package/dist/esm/src/transformers/CTERenamer.js.map +1 -1
- package/dist/esm/src/transformers/DynamicQueryBuilder.d.ts +72 -0
- package/dist/esm/src/transformers/DynamicQueryBuilder.js +42 -0
- package/dist/esm/src/transformers/DynamicQueryBuilder.js.map +1 -1
- package/dist/esm/src/transformers/FilterableItemCollector.d.ts +80 -0
- package/dist/esm/src/transformers/FilterableItemCollector.js +254 -0
- package/dist/esm/src/transformers/FilterableItemCollector.js.map +1 -0
- package/dist/esm/src/transformers/SelectableColumnCollector.d.ts +3 -0
- package/dist/esm/src/transformers/SelectableColumnCollector.js +68 -7
- package/dist/esm/src/transformers/SelectableColumnCollector.js.map +1 -1
- package/dist/esm/src/transformers/SmartRenamer.d.ts +134 -0
- package/dist/esm/src/transformers/SmartRenamer.js +430 -0
- package/dist/esm/src/transformers/SmartRenamer.js.map +1 -0
- package/dist/esm/src/transformers/SqlIdentifierRenamer.d.ts +150 -0
- package/dist/esm/src/transformers/SqlIdentifierRenamer.js +493 -0
- package/dist/esm/src/transformers/SqlIdentifierRenamer.js.map +1 -0
- package/dist/esm/src/transformers/SqlParamInjector.d.ts +27 -0
- package/dist/esm/src/transformers/SqlParamInjector.js +304 -16
- package/dist/esm/src/transformers/SqlParamInjector.js.map +1 -1
- package/dist/esm/src/transformers/SqlSortInjector.js +6 -3
- package/dist/esm/src/transformers/SqlSortInjector.js.map +1 -1
- package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js +5 -2
- package/dist/esm/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
- package/dist/esm/src/utils/LexemeCursor.d.ts +41 -0
- package/dist/esm/src/utils/LexemeCursor.js +93 -0
- package/dist/esm/src/utils/LexemeCursor.js.map +1 -1
- package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
- package/dist/index.min.js +37 -29
- package/dist/index.min.js.map +4 -4
- package/dist/src/formatters/OriginalFormatRestorer.d.ts +40 -0
- package/dist/src/formatters/OriginalFormatRestorer.js +139 -0
- package/dist/src/formatters/OriginalFormatRestorer.js.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.js +11 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/models/FormattingLexeme.d.ts +66 -0
- package/dist/src/models/FormattingLexeme.js +3 -0
- package/dist/src/models/FormattingLexeme.js.map +1 -0
- package/dist/src/models/ValueComponent.d.ts +3 -1
- package/dist/src/models/ValueComponent.js +3 -1
- package/dist/src/models/ValueComponent.js.map +1 -1
- package/dist/src/parsers/FunctionExpressionParser.d.ts +12 -0
- package/dist/src/parsers/FunctionExpressionParser.js +110 -6
- package/dist/src/parsers/FunctionExpressionParser.js.map +1 -1
- package/dist/src/parsers/KeywordParser.d.ts +1 -0
- package/dist/src/parsers/KeywordParser.js +10 -4
- package/dist/src/parsers/KeywordParser.js.map +1 -1
- package/dist/src/parsers/SqlPrintTokenParser.js +8 -0
- package/dist/src/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/src/parsers/SqlTokenizer.d.ts +42 -2
- package/dist/src/parsers/SqlTokenizer.js +222 -12
- package/dist/src/parsers/SqlTokenizer.js.map +1 -1
- package/dist/src/tokenReaders/CommandTokenReader.d.ts +3 -0
- package/dist/src/tokenReaders/CommandTokenReader.js +5 -2
- package/dist/src/tokenReaders/CommandTokenReader.js.map +1 -1
- package/dist/src/transformers/AliasRenamer.d.ts +199 -0
- package/dist/src/transformers/AliasRenamer.js +599 -0
- package/dist/src/transformers/AliasRenamer.js.map +1 -0
- package/dist/src/transformers/CTERenamer.d.ts +53 -0
- package/dist/src/transformers/CTERenamer.js +138 -0
- package/dist/src/transformers/CTERenamer.js.map +1 -1
- package/dist/src/transformers/DynamicQueryBuilder.d.ts +72 -0
- package/dist/src/transformers/DynamicQueryBuilder.js +42 -0
- package/dist/src/transformers/DynamicQueryBuilder.js.map +1 -1
- package/dist/src/transformers/FilterableItemCollector.d.ts +80 -0
- package/dist/src/transformers/FilterableItemCollector.js +259 -0
- package/dist/src/transformers/FilterableItemCollector.js.map +1 -0
- package/dist/src/transformers/SelectableColumnCollector.d.ts +3 -0
- package/dist/src/transformers/SelectableColumnCollector.js +67 -6
- package/dist/src/transformers/SelectableColumnCollector.js.map +1 -1
- package/dist/src/transformers/SmartRenamer.d.ts +134 -0
- package/dist/src/transformers/SmartRenamer.js +442 -0
- package/dist/src/transformers/SmartRenamer.js.map +1 -0
- package/dist/src/transformers/SqlIdentifierRenamer.d.ts +150 -0
- package/dist/src/transformers/SqlIdentifierRenamer.js +497 -0
- package/dist/src/transformers/SqlIdentifierRenamer.js.map +1 -0
- package/dist/src/transformers/SqlParamInjector.d.ts +27 -0
- package/dist/src/transformers/SqlParamInjector.js +303 -15
- package/dist/src/transformers/SqlParamInjector.js.map +1 -1
- package/dist/src/transformers/SqlSortInjector.js +5 -2
- package/dist/src/transformers/SqlSortInjector.js.map +1 -1
- package/dist/src/transformers/UpstreamSelectQueryFinder.js +4 -1
- package/dist/src/transformers/UpstreamSelectQueryFinder.js.map +1 -1
- package/dist/src/utils/LexemeCursor.d.ts +41 -0
- package/dist/src/utils/LexemeCursor.js +93 -0
- package/dist/src/utils/LexemeCursor.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -0,0 +1,430 @@
|
|
1
|
+
import { LexemeCursor } from "../utils/LexemeCursor";
|
2
|
+
import { SelectQueryParser } from "../parsers/SelectQueryParser";
|
3
|
+
import { SimpleSelectQuery } from "../models/SimpleSelectQuery";
|
4
|
+
import { BinarySelectQuery } from "../models/BinarySelectQuery";
|
5
|
+
import { TokenType } from "../models/Lexeme";
|
6
|
+
import { CTERenamer } from "./CTERenamer";
|
7
|
+
import { AliasRenamer } from "./AliasRenamer";
|
8
|
+
import { SqlIdentifierRenamer } from "./SqlIdentifierRenamer";
|
9
|
+
/**
|
10
|
+
* Smart renamer that automatically detects whether to use CTERenamer or AliasRenamer
|
11
|
+
* based on the cursor position in SQL text.
|
12
|
+
*
|
13
|
+
* This class provides unified GUI integration for SQL renaming operations:
|
14
|
+
* - If cursor is on a CTE name → uses CTERenamer
|
15
|
+
* - If cursor is on a table alias → uses AliasRenamer
|
16
|
+
* - Auto-detects the type and calls appropriate renamer
|
17
|
+
* - Supports optional formatting preservation via SqlIdentifierRenamer
|
18
|
+
*
|
19
|
+
* @example
|
20
|
+
* ```typescript
|
21
|
+
* const renamer = new SmartRenamer();
|
22
|
+
* const sql = `
|
23
|
+
* -- User analysis
|
24
|
+
* WITH user_data AS ( /* User CTE *\/
|
25
|
+
* SELECT * FROM users u
|
26
|
+
* WHERE u.active = true
|
27
|
+
* )
|
28
|
+
* SELECT * FROM user_data
|
29
|
+
* `;
|
30
|
+
*
|
31
|
+
* // Standard rename (no formatting preservation)
|
32
|
+
* const result1 = renamer.rename(sql, { line: 3, column: 8 }, 'customer_data');
|
33
|
+
*
|
34
|
+
* // Rename with formatting preservation
|
35
|
+
* const result2 = renamer.rename(sql, { line: 3, column: 8 }, 'customer_data',
|
36
|
+
* { preserveFormatting: true });
|
37
|
+
* // Preserves comments, indentation, line breaks
|
38
|
+
*
|
39
|
+
* // Batch rename with formatting preservation
|
40
|
+
* const result3 = renamer.batchRename(sql, {
|
41
|
+
* 'user_data': 'customers',
|
42
|
+
* 'u': 'users_tbl'
|
43
|
+
* }, { preserveFormatting: true });
|
44
|
+
*
|
45
|
+
* // Check if position is renameable (for GUI context menus)
|
46
|
+
* const isRenameable = renamer.isRenameable(sql, { line: 3, column: 8 });
|
47
|
+
* ```
|
48
|
+
*/
|
49
|
+
export class SmartRenamer {
|
50
|
+
constructor() {
|
51
|
+
this.cteRenamer = new CTERenamer();
|
52
|
+
this.aliasRenamer = new AliasRenamer();
|
53
|
+
this.identifierRenamer = new SqlIdentifierRenamer();
|
54
|
+
}
|
55
|
+
/**
|
56
|
+
* Check if the token at the given position is renameable (CTE name or table alias).
|
57
|
+
* This is a lightweight check for GUI applications to determine if a rename context menu
|
58
|
+
* should be shown when right-clicking.
|
59
|
+
*
|
60
|
+
* @param sql - The complete SQL string
|
61
|
+
* @param position - Line and column position where user clicked (1-based)
|
62
|
+
* @returns Object indicating if renameable and what type of renamer would be used
|
63
|
+
*/
|
64
|
+
isRenameable(sql, position) {
|
65
|
+
try {
|
66
|
+
// Basic validation
|
67
|
+
if (!(sql === null || sql === void 0 ? void 0 : sql.trim())) {
|
68
|
+
return { renameable: false, renamerType: 'none', reason: 'Empty SQL' };
|
69
|
+
}
|
70
|
+
if (!position || position.line < 1 || position.column < 1) {
|
71
|
+
return { renameable: false, renamerType: 'none', reason: 'Invalid position' };
|
72
|
+
}
|
73
|
+
// Find lexeme at position
|
74
|
+
const lexeme = LexemeCursor.findLexemeAtLineColumn(sql, position);
|
75
|
+
if (!lexeme) {
|
76
|
+
return { renameable: false, renamerType: 'none', reason: 'No token found' };
|
77
|
+
}
|
78
|
+
// Must be an identifier or function
|
79
|
+
if (!(lexeme.type & (TokenType.Identifier | TokenType.Function))) {
|
80
|
+
return {
|
81
|
+
renameable: false,
|
82
|
+
renamerType: 'none',
|
83
|
+
tokenName: lexeme.value,
|
84
|
+
reason: `Token '${lexeme.value}' is not an identifier`
|
85
|
+
};
|
86
|
+
}
|
87
|
+
const tokenName = lexeme.value;
|
88
|
+
// Detect what type of identifier this is
|
89
|
+
const renamerType = this.detectRenamerType(sql, tokenName);
|
90
|
+
if (renamerType === 'unknown') {
|
91
|
+
return {
|
92
|
+
renameable: false,
|
93
|
+
renamerType: 'none',
|
94
|
+
tokenName,
|
95
|
+
reason: `Cannot determine if '${tokenName}' is renameable`
|
96
|
+
};
|
97
|
+
}
|
98
|
+
// Additional check: some identifiers might be column names or other non-renameable items
|
99
|
+
// For now, if we can detect it as CTE or potential alias, consider it renameable
|
100
|
+
return {
|
101
|
+
renameable: true,
|
102
|
+
renamerType,
|
103
|
+
tokenName
|
104
|
+
};
|
105
|
+
}
|
106
|
+
catch (error) {
|
107
|
+
return {
|
108
|
+
renameable: false,
|
109
|
+
renamerType: 'none',
|
110
|
+
reason: `Error: ${error instanceof Error ? error.message : String(error)}`
|
111
|
+
};
|
112
|
+
}
|
113
|
+
}
|
114
|
+
/**
|
115
|
+
* Automatically detect and rename CTE names or table aliases based on cursor position.
|
116
|
+
*
|
117
|
+
* @param sql - The complete SQL string
|
118
|
+
* @param position - Line and column position where user clicked (1-based)
|
119
|
+
* @param newName - The new name to assign
|
120
|
+
* @param options - Optional configuration { preserveFormatting?: boolean }
|
121
|
+
* @returns Result object with success status and details
|
122
|
+
*/
|
123
|
+
rename(sql, position, newName, options) {
|
124
|
+
var _a, _b;
|
125
|
+
try {
|
126
|
+
// Input validation
|
127
|
+
if (!(sql === null || sql === void 0 ? void 0 : sql.trim())) {
|
128
|
+
return this.createErrorResult(sql, newName, 'unknown', '', 'SQL cannot be empty');
|
129
|
+
}
|
130
|
+
if (!position || position.line < 1 || position.column < 1) {
|
131
|
+
return this.createErrorResult(sql, newName, 'unknown', '', 'Position must be valid line/column (1-based)');
|
132
|
+
}
|
133
|
+
if (!(newName === null || newName === void 0 ? void 0 : newName.trim())) {
|
134
|
+
return this.createErrorResult(sql, newName, 'unknown', '', 'New name cannot be empty');
|
135
|
+
}
|
136
|
+
// Find lexeme at position
|
137
|
+
const lexeme = LexemeCursor.findLexemeAtLineColumn(sql, position);
|
138
|
+
if (!lexeme) {
|
139
|
+
return this.createErrorResult(sql, newName, 'unknown', '', `No identifier found at line ${position.line}, column ${position.column}`);
|
140
|
+
}
|
141
|
+
// Must be an identifier
|
142
|
+
if (!(lexeme.type & TokenType.Identifier)) {
|
143
|
+
return this.createErrorResult(sql, newName, 'unknown', lexeme.value, `Token '${lexeme.value}' is not renameable`);
|
144
|
+
}
|
145
|
+
const originalName = lexeme.value;
|
146
|
+
const preserveFormatting = (_a = options === null || options === void 0 ? void 0 : options.preserveFormatting) !== null && _a !== void 0 ? _a : false;
|
147
|
+
// Detect the renamer type
|
148
|
+
const renamerType = this.detectRenamerType(sql, originalName);
|
149
|
+
// If formatting preservation is requested, try that approach first
|
150
|
+
if (preserveFormatting) {
|
151
|
+
try {
|
152
|
+
const formatPreservedResult = this.attemptFormattingPreservationRename(sql, position, newName, originalName, renamerType);
|
153
|
+
if (formatPreservedResult.success) {
|
154
|
+
return formatPreservedResult;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
catch (error) {
|
158
|
+
// Log error but continue with fallback approach
|
159
|
+
console.warn('Formatting preservation failed, falling back to standard rename:', error);
|
160
|
+
}
|
161
|
+
}
|
162
|
+
// Standard rename approach (no formatting preservation)
|
163
|
+
try {
|
164
|
+
let newSql;
|
165
|
+
if (renamerType === 'cte') {
|
166
|
+
newSql = this.cteRenamer.renameCTEAtPosition(sql, position, newName);
|
167
|
+
}
|
168
|
+
else if (renamerType === 'alias') {
|
169
|
+
const result = this.aliasRenamer.renameAlias(sql, position, newName);
|
170
|
+
if (!result.success) {
|
171
|
+
return {
|
172
|
+
success: false,
|
173
|
+
originalSql: sql,
|
174
|
+
renamerType: 'alias',
|
175
|
+
originalName,
|
176
|
+
newName,
|
177
|
+
error: ((_b = result.conflicts) === null || _b === void 0 ? void 0 : _b.join(', ')) || 'Alias rename failed',
|
178
|
+
formattingPreserved: false,
|
179
|
+
formattingMethod: 'smart-renamer-only'
|
180
|
+
};
|
181
|
+
}
|
182
|
+
newSql = result.newSql;
|
183
|
+
}
|
184
|
+
else {
|
185
|
+
return this.createErrorResult(sql, newName, 'unknown', originalName, `Cannot determine if '${originalName}' is a CTE name or table alias`);
|
186
|
+
}
|
187
|
+
return {
|
188
|
+
success: true,
|
189
|
+
originalSql: sql,
|
190
|
+
newSql,
|
191
|
+
renamerType,
|
192
|
+
originalName,
|
193
|
+
newName,
|
194
|
+
formattingPreserved: false,
|
195
|
+
formattingMethod: 'smart-renamer-only'
|
196
|
+
};
|
197
|
+
}
|
198
|
+
catch (error) {
|
199
|
+
return this.createErrorResult(sql, newName, renamerType, originalName, `${renamerType.toUpperCase()} rename failed: ${error instanceof Error ? error.message : String(error)}`);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
catch (error) {
|
203
|
+
return this.createErrorResult(sql, newName, 'unknown', '', `Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
204
|
+
}
|
205
|
+
}
|
206
|
+
/**
|
207
|
+
* Detect whether an identifier is a CTE name or table alias.
|
208
|
+
* @private
|
209
|
+
*/
|
210
|
+
detectRenamerType(sql, identifierName) {
|
211
|
+
try {
|
212
|
+
const query = SelectQueryParser.parse(sql);
|
213
|
+
// Check if it's a CTE name
|
214
|
+
if (this.isCTEName(query, identifierName)) {
|
215
|
+
return 'cte';
|
216
|
+
}
|
217
|
+
// If not a CTE, assume it's a table alias
|
218
|
+
// Note: More sophisticated detection could be added here
|
219
|
+
return 'alias';
|
220
|
+
}
|
221
|
+
catch (error) {
|
222
|
+
return 'unknown';
|
223
|
+
}
|
224
|
+
}
|
225
|
+
/**
|
226
|
+
* Check if identifier is a CTE name in the query.
|
227
|
+
* @private
|
228
|
+
*/
|
229
|
+
isCTEName(query, name) {
|
230
|
+
if (query instanceof SimpleSelectQuery && query.withClause) {
|
231
|
+
return query.withClause.tables.some((cte) => cte.aliasExpression && cte.aliasExpression.table && cte.aliasExpression.table.name === name);
|
232
|
+
}
|
233
|
+
if (query instanceof BinarySelectQuery) {
|
234
|
+
return this.isCTEName(query.left, name) || this.isCTEName(query.right, name);
|
235
|
+
}
|
236
|
+
return false;
|
237
|
+
}
|
238
|
+
/**
|
239
|
+
* Attempts to perform rename using SqlIdentifierRenamer to preserve formatting.
|
240
|
+
* @private
|
241
|
+
*/
|
242
|
+
attemptFormattingPreservationRename(sql, position, newName, originalName, renamerType) {
|
243
|
+
// First, use standard renaming to validate the operation
|
244
|
+
const standardResult = this.performStandardRename(sql, position, newName, originalName, renamerType);
|
245
|
+
if (!standardResult.success) {
|
246
|
+
return Object.assign(Object.assign({}, standardResult), { formattingPreserved: false, formattingMethod: 'smart-renamer-only' });
|
247
|
+
}
|
248
|
+
// Create rename mapping for format restorer
|
249
|
+
const renameMap = new Map([[originalName, newName]]);
|
250
|
+
try {
|
251
|
+
// Use SqlIdentifierRenamer to apply the rename while preserving formatting
|
252
|
+
const formattedSql = this.identifierRenamer.renameIdentifiers(sql, renameMap);
|
253
|
+
// Validate that the rename was successful
|
254
|
+
if (this.validateRenameResult(sql, formattedSql, originalName, newName)) {
|
255
|
+
return {
|
256
|
+
success: true,
|
257
|
+
originalSql: sql,
|
258
|
+
newSql: formattedSql,
|
259
|
+
renamerType,
|
260
|
+
originalName,
|
261
|
+
newName,
|
262
|
+
formattingPreserved: true,
|
263
|
+
formattingMethod: 'sql-identifier-renamer'
|
264
|
+
};
|
265
|
+
}
|
266
|
+
else {
|
267
|
+
throw new Error('Validation failed: rename may not have been applied correctly');
|
268
|
+
}
|
269
|
+
}
|
270
|
+
catch (error) {
|
271
|
+
// Return standard result on formatting preservation failure
|
272
|
+
return Object.assign(Object.assign({}, standardResult), { formattingPreserved: false, formattingMethod: 'smart-renamer-only' });
|
273
|
+
}
|
274
|
+
}
|
275
|
+
/**
|
276
|
+
* Perform standard rename without formatting preservation
|
277
|
+
* @private
|
278
|
+
*/
|
279
|
+
performStandardRename(sql, position, newName, originalName, renamerType) {
|
280
|
+
var _a;
|
281
|
+
try {
|
282
|
+
let newSql;
|
283
|
+
if (renamerType === 'cte') {
|
284
|
+
newSql = this.cteRenamer.renameCTEAtPosition(sql, position, newName);
|
285
|
+
}
|
286
|
+
else if (renamerType === 'alias') {
|
287
|
+
const result = this.aliasRenamer.renameAlias(sql, position, newName);
|
288
|
+
if (!result.success) {
|
289
|
+
return {
|
290
|
+
success: false,
|
291
|
+
originalSql: sql,
|
292
|
+
renamerType: 'alias',
|
293
|
+
originalName,
|
294
|
+
newName,
|
295
|
+
error: ((_a = result.conflicts) === null || _a === void 0 ? void 0 : _a.join(', ')) || 'Alias rename failed'
|
296
|
+
};
|
297
|
+
}
|
298
|
+
newSql = result.newSql;
|
299
|
+
}
|
300
|
+
else {
|
301
|
+
return {
|
302
|
+
success: false,
|
303
|
+
originalSql: sql,
|
304
|
+
renamerType: 'unknown',
|
305
|
+
originalName,
|
306
|
+
newName,
|
307
|
+
error: `Cannot determine if '${originalName}' is a CTE name or table alias`
|
308
|
+
};
|
309
|
+
}
|
310
|
+
return {
|
311
|
+
success: true,
|
312
|
+
originalSql: sql,
|
313
|
+
newSql,
|
314
|
+
renamerType,
|
315
|
+
originalName,
|
316
|
+
newName
|
317
|
+
};
|
318
|
+
}
|
319
|
+
catch (error) {
|
320
|
+
return {
|
321
|
+
success: false,
|
322
|
+
originalSql: sql,
|
323
|
+
renamerType,
|
324
|
+
originalName,
|
325
|
+
newName,
|
326
|
+
error: `${renamerType.toUpperCase()} rename failed: ${error instanceof Error ? error.message : String(error)}`
|
327
|
+
};
|
328
|
+
}
|
329
|
+
}
|
330
|
+
/**
|
331
|
+
* Validates that the rename operation was successful
|
332
|
+
* @private
|
333
|
+
*/
|
334
|
+
validateRenameResult(originalSql, newSql, oldName, newName) {
|
335
|
+
// Basic validation: new SQL should be different from original
|
336
|
+
if (originalSql === newSql) {
|
337
|
+
return false;
|
338
|
+
}
|
339
|
+
// The new name should appear in the result
|
340
|
+
if (!newSql.includes(newName)) {
|
341
|
+
return false;
|
342
|
+
}
|
343
|
+
// The new SQL should have fewer occurrences of the old name than the original
|
344
|
+
const originalOccurrences = this.countWordOccurrences(originalSql, oldName);
|
345
|
+
const newOccurrences = this.countWordOccurrences(newSql, oldName);
|
346
|
+
return newOccurrences < originalOccurrences;
|
347
|
+
}
|
348
|
+
/**
|
349
|
+
* Counts word boundary occurrences of a name in SQL
|
350
|
+
* @private
|
351
|
+
*/
|
352
|
+
countWordOccurrences(sql, name) {
|
353
|
+
const regex = new RegExp(`\\b${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'gi');
|
354
|
+
const matches = sql.match(regex);
|
355
|
+
return matches ? matches.length : 0;
|
356
|
+
}
|
357
|
+
/**
|
358
|
+
* Create error result object.
|
359
|
+
* @private
|
360
|
+
*/
|
361
|
+
createErrorResult(sql, newName, renamerType, originalName, error) {
|
362
|
+
return {
|
363
|
+
success: false,
|
364
|
+
originalSql: sql,
|
365
|
+
renamerType,
|
366
|
+
originalName,
|
367
|
+
newName,
|
368
|
+
error,
|
369
|
+
formattingPreserved: false,
|
370
|
+
formattingMethod: 'smart-renamer-only'
|
371
|
+
};
|
372
|
+
}
|
373
|
+
/**
|
374
|
+
* Batch rename multiple identifiers with optional formatting preservation.
|
375
|
+
*
|
376
|
+
* @param sql - The complete SQL string
|
377
|
+
* @param renames - Map of old names to new names
|
378
|
+
* @param options - Optional configuration { preserveFormatting?: boolean }
|
379
|
+
* @returns Result with success status and details
|
380
|
+
*/
|
381
|
+
batchRename(sql, renames, options) {
|
382
|
+
var _a;
|
383
|
+
const preserveFormatting = (_a = options === null || options === void 0 ? void 0 : options.preserveFormatting) !== null && _a !== void 0 ? _a : false;
|
384
|
+
if (preserveFormatting) {
|
385
|
+
try {
|
386
|
+
const renameMap = new Map(Object.entries(renames));
|
387
|
+
const formattedSql = this.identifierRenamer.renameIdentifiers(sql, renameMap);
|
388
|
+
const originalNames = Object.keys(renames);
|
389
|
+
const newNames = Object.values(renames);
|
390
|
+
return {
|
391
|
+
success: true,
|
392
|
+
originalSql: sql,
|
393
|
+
newSql: formattedSql,
|
394
|
+
renamerType: 'alias', // Assume alias for batch operations
|
395
|
+
originalName: originalNames.join(', '),
|
396
|
+
newName: newNames.join(', '),
|
397
|
+
formattingPreserved: true,
|
398
|
+
formattingMethod: 'sql-identifier-renamer'
|
399
|
+
};
|
400
|
+
}
|
401
|
+
catch (error) {
|
402
|
+
return {
|
403
|
+
success: false,
|
404
|
+
originalSql: sql,
|
405
|
+
renamerType: 'unknown',
|
406
|
+
originalName: Object.keys(renames).join(', '),
|
407
|
+
newName: Object.values(renames).join(', '),
|
408
|
+
error: `Batch rename failed: ${error instanceof Error ? error.message : String(error)}`,
|
409
|
+
formattingPreserved: false,
|
410
|
+
formattingMethod: 'smart-renamer-only'
|
411
|
+
};
|
412
|
+
}
|
413
|
+
}
|
414
|
+
else {
|
415
|
+
// Standard batch rename without formatting preservation would need implementation
|
416
|
+
// For now, return error suggesting individual renames
|
417
|
+
return {
|
418
|
+
success: false,
|
419
|
+
originalSql: sql,
|
420
|
+
renamerType: 'unknown',
|
421
|
+
originalName: Object.keys(renames).join(', '),
|
422
|
+
newName: Object.values(renames).join(', '),
|
423
|
+
error: 'Batch rename without formatting preservation not implemented. Use individual renames or enable formatting preservation.',
|
424
|
+
formattingPreserved: false,
|
425
|
+
formattingMethod: 'smart-renamer-only'
|
426
|
+
};
|
427
|
+
}
|
428
|
+
}
|
429
|
+
}
|
430
|
+
//# sourceMappingURL=SmartRenamer.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"SmartRenamer.js","sourceRoot":"","sources":["../../../../src/transformers/SmartRenamer.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,150 @@
|
|
1
|
+
/**
|
2
|
+
* Represents a position in the SQL text
|
3
|
+
*/
|
4
|
+
export interface Position {
|
5
|
+
line: number;
|
6
|
+
column: number;
|
7
|
+
}
|
8
|
+
/**
|
9
|
+
* Represents a scope range for identifier renaming
|
10
|
+
*/
|
11
|
+
export interface ScopeRange {
|
12
|
+
start: number;
|
13
|
+
end: number;
|
14
|
+
}
|
15
|
+
/**
|
16
|
+
* Result of renameability check
|
17
|
+
*/
|
18
|
+
export interface Renameability {
|
19
|
+
canRename: boolean;
|
20
|
+
currentName?: string;
|
21
|
+
type?: 'cte' | 'table_alias' | 'column_alias';
|
22
|
+
scopeRange?: ScopeRange;
|
23
|
+
reason?: string;
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* Handles safe renaming of SQL identifiers within SQL strings
|
27
|
+
* Uses character-by-character parsing instead of regex for better performance and maintainability
|
28
|
+
*/
|
29
|
+
export declare class SqlIdentifierRenamer {
|
30
|
+
/**
|
31
|
+
* Safely renames identifiers in SQL string while preserving context
|
32
|
+
* @param sql SQL string to modify
|
33
|
+
* @param renames Map of original identifiers to new identifiers
|
34
|
+
* @returns Modified SQL string with renamed identifiers
|
35
|
+
*/
|
36
|
+
renameIdentifiers(sql: string, renames: Map<string, string>): string;
|
37
|
+
/**
|
38
|
+
* Renames a single identifier in SQL string
|
39
|
+
* @param sql SQL string to modify
|
40
|
+
* @param oldIdentifier Original identifier to replace
|
41
|
+
* @param newIdentifier New identifier to replace with
|
42
|
+
* @returns Modified SQL string
|
43
|
+
*/
|
44
|
+
renameIdentifier(sql: string, oldIdentifier: string, newIdentifier: string): string;
|
45
|
+
/**
|
46
|
+
* Renames a single identifier within a specified scope range
|
47
|
+
* @param sql SQL string to modify
|
48
|
+
* @param oldIdentifier Original identifier to replace
|
49
|
+
* @param newIdentifier New identifier to replace with
|
50
|
+
* @param scopeRange Optional scope range to limit replacement
|
51
|
+
* @returns Modified SQL string
|
52
|
+
*/
|
53
|
+
renameIdentifierInScope(sql: string, oldIdentifier: string, newIdentifier: string, scopeRange?: ScopeRange): string;
|
54
|
+
/**
|
55
|
+
* Checks if an identifier at the given position can be renamed
|
56
|
+
* @param sql SQL string
|
57
|
+
* @param position Position in the SQL text
|
58
|
+
* @returns Renameability result
|
59
|
+
*/
|
60
|
+
checkRenameability(sql: string, position: Position): Renameability;
|
61
|
+
/**
|
62
|
+
* Renames identifier at the specified position
|
63
|
+
* @param sql SQL string
|
64
|
+
* @param position Position in the SQL text
|
65
|
+
* @param newName New identifier name
|
66
|
+
* @returns Modified SQL string
|
67
|
+
*/
|
68
|
+
renameAtPosition(sql: string, position: Position, newName: string): string;
|
69
|
+
/**
|
70
|
+
* Convert line/column position to character index
|
71
|
+
*/
|
72
|
+
private positionToCharIndex;
|
73
|
+
/**
|
74
|
+
* Check if position is inside a string literal
|
75
|
+
*/
|
76
|
+
private isInsideStringLiteral;
|
77
|
+
/**
|
78
|
+
* Get identifier at the specified character position
|
79
|
+
*/
|
80
|
+
private getIdentifierAtPosition;
|
81
|
+
/**
|
82
|
+
* Determine the type of identifier (improved logic)
|
83
|
+
*/
|
84
|
+
private determineIdentifierType;
|
85
|
+
/**
|
86
|
+
* Calculate scope range for the identifier
|
87
|
+
*/
|
88
|
+
private calculateScopeRange;
|
89
|
+
/**
|
90
|
+
* Safely replaces SQL identifiers while preserving word boundaries and context
|
91
|
+
* Uses character-by-character parsing instead of regex for better maintainability
|
92
|
+
* @param sql SQL string to modify
|
93
|
+
* @param oldIdentifier Original identifier to replace
|
94
|
+
* @param newIdentifier New identifier to replace with
|
95
|
+
* @returns Modified SQL string
|
96
|
+
*/
|
97
|
+
private replaceIdentifierSafely;
|
98
|
+
/**
|
99
|
+
* Validates that the rename operation was successful
|
100
|
+
* @param originalSql Original SQL string
|
101
|
+
* @param modifiedSql Modified SQL string after rename
|
102
|
+
* @param oldIdentifier Old identifier that was replaced
|
103
|
+
* @param newIdentifier New identifier that was added
|
104
|
+
* @returns True if rename appears successful
|
105
|
+
*/
|
106
|
+
validateRename(originalSql: string, modifiedSql: string, oldIdentifier: string, newIdentifier: string): boolean;
|
107
|
+
/**
|
108
|
+
* Extract and potentially replace quoted identifiers
|
109
|
+
*/
|
110
|
+
private extractAndReplaceQuotedIdentifier;
|
111
|
+
/**
|
112
|
+
* Extract and potentially replace bracketed identifiers [identifier]
|
113
|
+
*/
|
114
|
+
private extractAndReplaceBracketedIdentifier;
|
115
|
+
/**
|
116
|
+
* Extract quoted string (handles quotes)
|
117
|
+
*/
|
118
|
+
private extractQuotedString;
|
119
|
+
/**
|
120
|
+
* Extract line comment
|
121
|
+
*/
|
122
|
+
private extractLineComment;
|
123
|
+
/**
|
124
|
+
* Extract block comment
|
125
|
+
*/
|
126
|
+
private extractBlockComment;
|
127
|
+
/**
|
128
|
+
* Check if character code can start an identifier
|
129
|
+
*/
|
130
|
+
private isIdentifierStartChar;
|
131
|
+
/**
|
132
|
+
* Check if character code can be part of an identifier
|
133
|
+
*/
|
134
|
+
private isIdentifierChar;
|
135
|
+
/**
|
136
|
+
* Check if the identifier matches at the given position (case-insensitive)
|
137
|
+
*/
|
138
|
+
private matchesIdentifierAt;
|
139
|
+
/**
|
140
|
+
* Validate word boundaries
|
141
|
+
*/
|
142
|
+
private hasValidWordBoundaries;
|
143
|
+
/**
|
144
|
+
* Counts word boundary occurrences of an identifier in SQL
|
145
|
+
* @param sql SQL string to search
|
146
|
+
* @param identifier Identifier to count
|
147
|
+
* @returns Number of occurrences
|
148
|
+
*/
|
149
|
+
private countWordOccurrences;
|
150
|
+
}
|