From ea84ec34398d4a2e80cd9e2326d8990375e25b68 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 28 Oct 2021 10:18:05 +0200 Subject: [PATCH] #187 streamable split query --- packages/query-splitter/src/splitQuery.ts | 95 +++++++++++------------ 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/packages/query-splitter/src/splitQuery.ts b/packages/query-splitter/src/splitQuery.ts index b4c08830..226013a3 100644 --- a/packages/query-splitter/src/splitQuery.ts +++ b/packages/query-splitter/src/splitQuery.ts @@ -2,12 +2,17 @@ import { SplitterOptions, defaultSplitterOptions } from './options'; const SEMICOLON = ';'; -interface SplitExecutionContext { +interface SplitStreamContext { options: SplitterOptions; + currentDelimiter: string; + pushOutput: (sql: string) => void; + commandPart: string; +} + +interface SplitLineContext extends SplitStreamContext { source: string; position: number; - currentDelimiter: string; - output: string[]; + // output: string[]; end: number; wasDataOnLine: boolean; currentCommandStart: number; @@ -47,7 +52,7 @@ const DATA_TOKEN: Token = { length: 1, }; -function scanDollarQuotedString(context: SplitExecutionContext): Token { +function scanDollarQuotedString(context: SplitLineContext): Token { if (!context.options.allowDollarDollarString) return null; let pos = context.position; @@ -71,7 +76,7 @@ function scanDollarQuotedString(context: SplitExecutionContext): Token { return null; } -function scanToken(context: SplitExecutionContext): Token { +function scanToken(context: SplitLineContext): Token { let pos = context.position; const s = context.source; const ch = s[pos]; @@ -155,33 +160,13 @@ function scanToken(context: SplitExecutionContext): Token { return DATA_TOKEN; } -function pushQuery(context) { - const sql = context.source.slice(context.currentCommandStart, context.position); +function pushQuery(context: SplitLineContext) { + const sql = (context.commandPart || '') + context.source.slice(context.currentCommandStart, context.position); const trimmed = sql.trim(); - if (trimmed) context.output.push(trimmed); + if (trimmed) context.pushOutput(trimmed); } -export function splitQuery(sql: string, options: SplitterOptions = null): string[] { - const usedOptions = { - ...defaultSplitterOptions, - ...options, - }; - - if (usedOptions.noSplit) { - return [sql]; - } - - const context: SplitExecutionContext = { - source: sql, - end: sql.length, - currentDelimiter: options?.allowSemicolon === false ? null : SEMICOLON, - position: 0, - currentCommandStart: 0, - output: [], - wasDataOnLine: false, - options: usedOptions, - }; - +function splitQueryLine(context: SplitLineContext) { while (context.position < context.end) { const token = scanToken(context); if (!token) { @@ -211,17 +196,20 @@ export function splitQuery(sql: string, options: SplitterOptions = null): string break; case 'set_delimiter': pushQuery(context); + context.commandPart = ''; context.currentDelimiter = token.value; context.position += token.length; context.currentCommandStart = context.position; break; case 'go_delimiter': pushQuery(context); + context.commandPart = ''; context.position += token.length; context.currentCommandStart = context.position; break; case 'delimiter': pushQuery(context); + context.commandPart = ''; context.position += token.length; context.currentCommandStart = context.position; break; @@ -229,29 +217,36 @@ export function splitQuery(sql: string, options: SplitterOptions = null): string } if (context.end > context.currentCommandStart) { - pushQuery(context); + context.commandPart += context.source.slice(context.currentCommandStart, context.position); + } +} + +export function splitQuery(sql: string, options: SplitterOptions = null): string[] { + const usedOptions = { + ...defaultSplitterOptions, + ...options, + }; + + if (usedOptions.noSplit) { + return [sql]; } - // 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); + const output = []; + const context: SplitLineContext = { + source: sql, + end: sql.length, + currentDelimiter: options?.allowSemicolon === false ? null : SEMICOLON, + position: 0, + currentCommandStart: 0, + pushOutput: cmd => output.push(cmd), + wasDataOnLine: false, + options: usedOptions, + commandPart: '', + }; - // console.log('RESULT', context.output); + splitQueryLine(context); - return context.output; + pushQuery(context); + + return output; }