From 202873be71628fd6770ea9454ee2a24b865958e6 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Mon, 31 May 2021 22:00:54 +0200 Subject: [PATCH] code cleanup --- packages/querysplitter/src/defines.ts | 22 -- packages/querysplitter/src/index.ts | 1 + packages/querysplitter/src/splitQuery-old.ts | 226 ------------------- 3 files changed, 1 insertion(+), 248 deletions(-) delete mode 100644 packages/querysplitter/src/defines.ts delete mode 100644 packages/querysplitter/src/splitQuery-old.ts diff --git a/packages/querysplitter/src/defines.ts b/packages/querysplitter/src/defines.ts deleted file mode 100644 index 1b124a9e1..000000000 --- a/packages/querysplitter/src/defines.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { SplitterOptions } from './options'; - -export interface State { - options: SplitterOptions; - start: number; - end: number; - position: number; - input: string; - - // unread: string; - // currentDelimiter: string; - // currentStatement: string; - // output: string[]; - semicolonKeyTokenRegex: RegExp; -} - -export interface Token { - type: string; - value: string; - start: number; - end: number; -} diff --git a/packages/querysplitter/src/index.ts b/packages/querysplitter/src/index.ts index 3d42416b3..7ded2fc5b 100644 --- a/packages/querysplitter/src/index.ts +++ b/packages/querysplitter/src/index.ts @@ -1 +1,2 @@ export * from './splitQuery'; +export * from './options'; diff --git a/packages/querysplitter/src/splitQuery-old.ts b/packages/querysplitter/src/splitQuery-old.ts deleted file mode 100644 index 5256d1260..000000000 --- a/packages/querysplitter/src/splitQuery-old.ts +++ /dev/null @@ -1,226 +0,0 @@ -import { SplitterOptions, defaultSplitterOptions } from './options'; - -const SINGLE_QUOTE = "'"; -const DOUBLE_QUOTE = '"'; -const BACKTICK = '`'; -const DOUBLE_DASH_COMMENT_START = '--'; -const HASH_COMMENT_START = '#'; -const C_STYLE_COMMENT_START = '/*'; -const SEMICOLON = ';'; -const LINE_FEED = '\n'; -const DELIMITER_KEYWORD = 'DELIMITER'; - -interface SplitExecutionContext { - options: SplitterOptions; - unread: string; - currentDelimiter: string; - currentStatement: string; - output: string[]; - semicolonKeyTokenRegex: RegExp; -} - -interface FindExpResult { - expIndex: number; - exp: string | null; - nextIndex: number; -} - -const regexEscapeSetRegex = /[-/\\^$*+?.()|[\]{}]/g; -const singleQuoteStringEndRegex = /(? = { - [SINGLE_QUOTE]: singleQuoteStringEndRegex, - [DOUBLE_QUOTE]: doubleQuoteStringEndRegex, - [BACKTICK]: backtickQuoteEndRegex, -}; - -function escapeRegex(value: string): string { - return value.replace(regexEscapeSetRegex, '\\$&'); -} - -function buildKeyTokenRegex(delimiter: string, context: SplitExecutionContext): RegExp { - const { options } = context; - return new RegExp( - '(?:' + - [ - escapeRegex(delimiter), - SINGLE_QUOTE, - DOUBLE_QUOTE, - options.allowBacktickString ? BACKTICK : undefined, - doubleDashCommentStartRegex.source, - HASH_COMMENT_START, - cStyleCommentStartRegex.source, - options.allowCustomDelimiter ? delimiterStartRegex.source : undefined, - ] - .filter(x => x !== undefined) - .join('|') + - ')', - 'i' - ); -} - -function findExp(content: string, regex: RegExp): FindExpResult { - const match = content.match(regex); - let result: FindExpResult; - if (match?.index !== undefined) { - result = { - expIndex: match.index, - exp: match[0], - nextIndex: match.index + match[0].length, - }; - } else { - result = { - expIndex: -1, - exp: null, - nextIndex: content.length, - }; - } - return result; -} - -function findKeyToken(content: string, currentDelimiter: string, context: SplitExecutionContext): FindExpResult { - let regex; - if (currentDelimiter === SEMICOLON) { - regex = context.semicolonKeyTokenRegex; - } else { - regex = buildKeyTokenRegex(currentDelimiter, context); - } - return findExp(content, regex); -} - -function findEndQuote(content: string, quote: string): FindExpResult { - if (!(quote in quoteEndRegexDict)) { - throw new TypeError(`Incorrect quote ${quote} supplied`); - } - return findExp(content, quoteEndRegexDict[quote]); -} - -function read(context: SplitExecutionContext, readToIndex: number, nextUnreadIndex?: number): void { - const readContent = context.unread.slice(0, readToIndex); - context.currentStatement += readContent; - if (nextUnreadIndex !== undefined && nextUnreadIndex > 0) { - context.unread = context.unread.slice(nextUnreadIndex); - } else { - context.unread = context.unread.slice(readToIndex); - } -} - -function readTillNewLine(context: SplitExecutionContext): void { - const findResult = findExp(context.unread, newLineRegex); - read(context, findResult.expIndex, findResult.expIndex); -} - -function discard(context: SplitExecutionContext, nextUnreadIndex: number): void { - if (nextUnreadIndex > 0) { - context.unread = context.unread.slice(nextUnreadIndex); - } -} - -function discardTillNewLine(context: SplitExecutionContext): void { - const findResult = findExp(context.unread, newLineRegex); - discard(context, findResult.expIndex); -} - -function publishStatement(context: SplitExecutionContext): void { - const trimmed = context.currentStatement.trim(); - if (trimmed) { - context.output.push(trimmed); - } - context.currentStatement = ''; -} - -function handleKeyTokenFindResult(context: SplitExecutionContext, findResult: FindExpResult): void { - switch (findResult.exp?.trim()) { - case context.currentDelimiter: - read(context, findResult.expIndex, findResult.nextIndex); - publishStatement(context); - break; - case SINGLE_QUOTE: - case DOUBLE_QUOTE: - case BACKTICK: { - read(context, findResult.nextIndex); - const findQuoteResult = findEndQuote(context.unread, findResult.exp); - read(context, findQuoteResult.nextIndex, undefined); - break; - } - case DOUBLE_DASH_COMMENT_START: { - read(context, findResult.nextIndex); - readTillNewLine(context); - break; - } - case HASH_COMMENT_START: { - read(context, findResult.nextIndex); - readTillNewLine(context); - break; - } - case C_STYLE_COMMENT_START: { - read(context, findResult.nextIndex); - const findCommentResult = findExp(context.unread, cStyleCommentEndRegex); - read(context, findCommentResult.nextIndex); - break; - } - case DELIMITER_KEYWORD: { - read(context, findResult.expIndex, findResult.nextIndex); - // MySQL client will return `DELIMITER cannot contain a backslash character` if backslash is used - // Shall we reject backslash as well? - const matched = context.unread.match(delimiterTokenRegex); - if (matched?.index !== undefined) { - context.currentDelimiter = matched[0].trim(); - discard(context, matched[0].length); - } - discardTillNewLine(context); - break; - } - case undefined: - case null: - read(context, findResult.nextIndex); - publishStatement(context); - break; - default: - // This should never happen - throw new Error(`Unknown token '${findResult.exp ?? '(null)'}'`); - } -} - -export function splitQuery(sql: string, options: SplitterOptions = null): string[] { - const context: SplitExecutionContext = { - unread: sql, - currentDelimiter: SEMICOLON, - currentStatement: '', - output: [], - semicolonKeyTokenRegex: null, - options: { - ...defaultSplitterOptions, - ...options, - }, - }; - context.semicolonKeyTokenRegex = buildKeyTokenRegex(SEMICOLON, context); - let findResult: FindExpResult = { - expIndex: -1, - exp: null, - nextIndex: 0, - }; - let lastUnreadLength; - do { - // console.log('context.unread', context.unread); - lastUnreadLength = context.unread.length; - findResult = findKeyToken(context.unread, context.currentDelimiter, context); - handleKeyTokenFindResult(context, findResult); - // Prevent infinite loop by returning incorrect result - if (lastUnreadLength === context.unread.length) { - read(context, context.unread.length); - } - } while (context.unread !== ''); - publishStatement(context); - // console.log('RESULT', context.output); - return context.output; -}