rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
132 lines (131 loc) • 4.1 kB
TypeScript
import { LineColumn } from './LexemeCursor';
/**
* Information about a single query within multi-query text
*/
export interface QueryInfo {
/** SQL text of this query */
sql: string;
/** Start position in the original text (0-based character offset) */
start: number;
/** End position in the original text (0-based character offset) */
end: number;
/** Line number where query starts (1-based) */
startLine: number;
/** Line number where query ends (1-based) */
endLine: number;
/** Query index in the original text (0-based) */
index: number;
/** Whether this query is empty or contains only whitespace/comments */
isEmpty: boolean;
}
/**
* Collection of queries from multi-query text
*/
export interface QueryCollection {
/** All queries found in the text */
queries: QueryInfo[];
/** Original text that was split */
originalText: string;
/**
* Get the query that contains the specified cursor position
* @param cursorPosition - Cursor position (character offset or line/column)
*/
getActive(cursorPosition: number | LineColumn): QueryInfo | undefined;
/**
* Get the query at the specified index
* @param index - Query index (0-based)
*/
getQuery(index: number): QueryInfo | undefined;
/**
* Get all non-empty queries
*/
getNonEmpty(): QueryInfo[];
}
/**
* Splits SQL text containing multiple queries separated by semicolons
*
* Provides sophisticated query boundary detection that properly handles:
* - String literals containing semicolons
* - Comments containing semicolons
* - Nested structures and complex SQL
* - Empty queries and whitespace handling
*
* @example
* ```typescript
* const multiSQL = `
* -- First query
* SELECT 'hello;world' FROM users;
*
* // Second query with comment
* SELECT id FROM orders WHERE status = 'active';
*
* -- Empty query
* ;
* `;
*
* const queries = MultiQuerySplitter.split(multiSQL);
* console.log(queries.queries.length); // 3 queries
*
* // Find query at cursor position
* const active = queries.getActive(150);
* console.log(active?.sql); // Query containing position 150
* ```
*/
export declare class MultiQuerySplitter {
/**
* Split multi-query SQL text into individual queries
*
* @param text - SQL text that may contain multiple queries separated by semicolons
* @returns Collection of individual queries with position information
*/
static split(text: string): QueryCollection;
/**
* Get query boundaries from SQL text with proper semicolon handling
*
* @param text - SQL text to analyze
* @returns Array of boundary positions
*/
/**
* Split text by semicolons while respecting quotes and comments
*/
private static splitRespectingQuotesAndComments;
/**
* Check if character at position is a valid semicolon (not in quotes/comments)
*/
private static isValidSemicolon;
/**
* Merge comment-only segments with previous executable segments
*/
private static mergeTrailingCommentSegments;
/**
* Clean SQL comments and extract SQL statements
*
* @param sql - SQL query text
* @returns Cleaned SQL text or null if no SQL remains
*/
private static cleanSqlComments;
private static isEmptyQuery;
}
/**
* Utility functions for working with query collections
*/
export declare class MultiQueryUtils {
/**
* Get context information for IntelliSense at a cursor position
*
* @param text - Multi-query SQL text
* @param cursorPosition - Cursor position
* @returns Active query and position within that query
*/
static getContextAt(text: string, cursorPosition: number | LineColumn): {
query: QueryInfo;
relativePosition: number;
} | undefined;
/**
* Extract all non-empty queries from multi-query text
*
* @param text - Multi-query SQL text
* @returns Array of query SQL strings
*/
static extractQueries(text: string): string[];
}