UNPKG

rawsql-ts

Version:

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

206 lines 7.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeywordCache = void 0; const CommandTokenReader_1 = require("../tokenReaders/CommandTokenReader"); /** * Utility for caching keyword relationships for fast access * Dynamically builds keyword relationships from existing joinkeywordParser * * SOURCE DICTIONARIES (single source of truth): * - JOIN patterns: /src/tokenReaders/CommandTokenReader.ts (joinTrie, lines 10-29) * - Command patterns: /src/tokenReaders/CommandTokenReader.ts (keywordTrie, lines 30-118) * * MIGRATION NOTE: * If keywords are added/modified in CommandTokenReader.ts, update the * extractCommandPatternsFromTrie() method to reflect those changes. * JOIN patterns are automatically extracted via joinkeywordParser. */ class KeywordCache { /** * Initialize JOIN-related keyword suggestions * Dynamically generated based on information extracted from joinkeywordParser */ static initialize() { if (this.initialized) return; // SOURCE: /src/tokenReaders/CommandTokenReader.ts joinTrie (lines 10-33) // Dynamically build keyword relationships from joinTrie const joinPatterns = [ ["join"], ["inner", "join"], ["cross", "join"], ["left", "join"], ["left", "outer", "join"], ["right", "join"], ["right", "outer", "join"], ["full", "join"], ["full", "outer", "join"], ["natural", "join"], ["natural", "inner", "join"], ["natural", "left", "join"], ["natural", "left", "outer", "join"], ["natural", "right", "join"], ["natural", "right", "outer", "join"], ["natural", "full", "join"], ["natural", "full", "outer", "join"], // LATERAL JOIN patterns ["lateral", "join"], ["lateral", "inner", "join"], ["lateral", "left", "join"], ["lateral", "left", "outer", "join"], ]; // Build keyword suggestion relationships const suggestionMap = new Map(); // Build complete phrase suggestions for better UX const completePhrases = new Set(); joinPatterns.forEach(pattern => { if (pattern.length > 1) { completePhrases.add(pattern.slice(1).join(' ').toUpperCase()); } }); // For each prefix, find all possible complete continuations joinPatterns.forEach(pattern => { for (let i = 0; i < pattern.length - 1; i++) { const prefix = pattern[i]; if (!suggestionMap.has(prefix)) { suggestionMap.set(prefix, new Set()); } // Find all patterns that start with this prefix and add complete phrases joinPatterns.forEach(candidatePattern => { if (candidatePattern.length > i + 1 && candidatePattern[i] === prefix) { const completePhrase = candidatePattern.slice(i + 1).join(' ').toUpperCase(); suggestionMap.get(prefix).add(completePhrase); } }); } }); // Convert Set to array and save to cache suggestionMap.forEach((suggestions, keyword) => { this.joinSuggestionCache.set(keyword.toLowerCase(), Array.from(suggestions)); }); // Also process command keywords this.initializeCommandKeywords(); this.initialized = true; } /** * Get next suggestions for the specified keyword * Example: "left" → ["join", "outer", "outer join"] */ static getJoinSuggestions(keyword) { this.initialize(); return this.joinSuggestionCache.get(keyword.toLowerCase()) || []; } /** * Check if a keyword is a valid JOIN keyword * Uses existing joinkeywordParser as the primary resource */ static isValidJoinKeyword(keyword) { const result = CommandTokenReader_1.joinkeywordParser.parse(keyword, 0); return result !== null; } /** * Generate suggestions based on partial keyword input * Example: "le" → find keywords starting with "left" */ static getPartialSuggestions(partialKeyword) { this.initialize(); const partial = partialKeyword.toLowerCase(); const suggestions = []; this.joinSuggestionCache.forEach((values, key) => { if (key.startsWith(partial)) { suggestions.push(key); // Include next suggestions for that keyword as well values.forEach(value => { if (!suggestions.includes(value)) { suggestions.push(value); } }); } }); return suggestions; } /** * Get all JOIN keywords */ static getAllJoinKeywords() { this.initialize(); const allKeywords = new Set(); this.joinSuggestionCache.forEach((values, key) => { allKeywords.add(key); values.forEach(value => allKeywords.add(value)); }); return Array.from(allKeywords); } /** * Initialize command keyword patterns * Dynamically extracted from commandKeywordTrie */ static initializeCommandKeywords() { // Extract multi-word patterns from commandKeywordTrie const commandPatterns = this.extractCommandPatternsFromTrie(); const suggestionMap = new Map(); commandPatterns.forEach(pattern => { for (let i = 0; i < pattern.length - 1; i++) { const prefix = pattern[i]; const nextWord = pattern[i + 1]; if (!suggestionMap.has(prefix)) { suggestionMap.set(prefix, new Set()); } suggestionMap.get(prefix).add(nextWord); } }); // Convert Set to array and save to cache suggestionMap.forEach((suggestions, keyword) => { this.commandSuggestionCache.set(keyword.toLowerCase(), Array.from(suggestions)); }); } /** * Extract multi-word patterns from commandKeywordTrie * Uses known patterns since direct extraction from trie structure is difficult * * SOURCE: /src/tokenReaders/CommandTokenReader.ts keywordTrie (lines 30-118) * MIGRATION: When updating, copy multi-word patterns from the source trie */ static extractCommandPatternsFromTrie() { // These are patterns defined in CommandTokenReader's keywordTrie return [ ["group", "by"], ["order", "by"], ["distinct", "on"], ["not", "materialized"], ["row", "only"], ["rows", "only"], ["percent", "with", "ties"], ["key", "share"], ["no", "key", "update"], ["union", "all"], ["intersect", "all"], ["except", "all"], ["partition", "by"], ["within", "group"], ["with", "ordinality"] ]; } /** * Get next command suggestions for the specified keyword * Example: "group" → ["by"] */ static getCommandSuggestions(keyword) { this.initialize(); return this.commandSuggestionCache.get(keyword.toLowerCase()) || []; } /** * Force cache re-initialization * Used for testing or when keyword definitions have changed */ static reset() { this.joinSuggestionCache.clear(); this.commandSuggestionCache.clear(); this.initialized = false; } } exports.KeywordCache = KeywordCache; KeywordCache.joinSuggestionCache = new Map(); KeywordCache.commandSuggestionCache = new Map(); KeywordCache.initialized = false; //# sourceMappingURL=KeywordCache.js.map