#187 streamable split query

This commit is contained in:
Jan Prochazka 2021-10-28 10:18:05 +02:00
parent b474bd109b
commit ea84ec3439

View File

@ -2,12 +2,17 @@ import { SplitterOptions, defaultSplitterOptions } from './options';
const SEMICOLON = ';'; const SEMICOLON = ';';
interface SplitExecutionContext { interface SplitStreamContext {
options: SplitterOptions; options: SplitterOptions;
currentDelimiter: string;
pushOutput: (sql: string) => void;
commandPart: string;
}
interface SplitLineContext extends SplitStreamContext {
source: string; source: string;
position: number; position: number;
currentDelimiter: string; // output: string[];
output: string[];
end: number; end: number;
wasDataOnLine: boolean; wasDataOnLine: boolean;
currentCommandStart: number; currentCommandStart: number;
@ -47,7 +52,7 @@ const DATA_TOKEN: Token = {
length: 1, length: 1,
}; };
function scanDollarQuotedString(context: SplitExecutionContext): Token { function scanDollarQuotedString(context: SplitLineContext): Token {
if (!context.options.allowDollarDollarString) return null; if (!context.options.allowDollarDollarString) return null;
let pos = context.position; let pos = context.position;
@ -71,7 +76,7 @@ function scanDollarQuotedString(context: SplitExecutionContext): Token {
return null; return null;
} }
function scanToken(context: SplitExecutionContext): Token { function scanToken(context: SplitLineContext): Token {
let pos = context.position; let pos = context.position;
const s = context.source; const s = context.source;
const ch = s[pos]; const ch = s[pos];
@ -155,33 +160,13 @@ function scanToken(context: SplitExecutionContext): Token {
return DATA_TOKEN; return DATA_TOKEN;
} }
function pushQuery(context) { function pushQuery(context: SplitLineContext) {
const sql = context.source.slice(context.currentCommandStart, context.position); const sql = (context.commandPart || '') + context.source.slice(context.currentCommandStart, context.position);
const trimmed = sql.trim(); const trimmed = sql.trim();
if (trimmed) context.output.push(trimmed); if (trimmed) context.pushOutput(trimmed);
} }
export function splitQuery(sql: string, options: SplitterOptions = null): string[] { function splitQueryLine(context: SplitLineContext) {
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,
};
while (context.position < context.end) { while (context.position < context.end) {
const token = scanToken(context); const token = scanToken(context);
if (!token) { if (!token) {
@ -211,17 +196,20 @@ export function splitQuery(sql: string, options: SplitterOptions = null): string
break; break;
case 'set_delimiter': case 'set_delimiter':
pushQuery(context); pushQuery(context);
context.commandPart = '';
context.currentDelimiter = token.value; context.currentDelimiter = token.value;
context.position += token.length; context.position += token.length;
context.currentCommandStart = context.position; context.currentCommandStart = context.position;
break; break;
case 'go_delimiter': case 'go_delimiter':
pushQuery(context); pushQuery(context);
context.commandPart = '';
context.position += token.length; context.position += token.length;
context.currentCommandStart = context.position; context.currentCommandStart = context.position;
break; break;
case 'delimiter': case 'delimiter':
pushQuery(context); pushQuery(context);
context.commandPart = '';
context.position += token.length; context.position += token.length;
context.currentCommandStart = context.position; context.currentCommandStart = context.position;
break; break;
@ -229,29 +217,36 @@ export function splitQuery(sql: string, options: SplitterOptions = null): string
} }
if (context.end > context.currentCommandStart) { 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); const output = [];
// let findResult: FindExpResult = { const context: SplitLineContext = {
// expIndex: -1, source: sql,
// exp: null, end: sql.length,
// nextIndex: 0, currentDelimiter: options?.allowSemicolon === false ? null : SEMICOLON,
// }; position: 0,
// let lastUnreadLength; currentCommandStart: 0,
// do { pushOutput: cmd => output.push(cmd),
// // console.log('context.unread', context.unread); wasDataOnLine: false,
// lastUnreadLength = context.unread.length; options: usedOptions,
// findResult = findKeyToken(context.unread, context.currentDelimiter, context); commandPart: '',
// 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); splitQueryLine(context);
return context.output; pushQuery(context);
return output;
} }