dbgate-query-splitter
Advanced tools
Comparing version 4.11.2 to 4.11.3
@@ -20,2 +20,3 @@ export declare type QueryParameterStyle = null | '?' | '$' | '@' | ':' | '#'; | ||
javaScriptComments: boolean; | ||
skipSeparatorBeginEnd: boolean; | ||
ignoreComments: boolean; | ||
@@ -22,0 +23,0 @@ preventSingleLineSplit: boolean; |
@@ -15,2 +15,3 @@ "use strict"; | ||
noSplit: false, | ||
skipSeparatorBeginEnd: false, | ||
doubleDashComments: true, | ||
@@ -30,3 +31,3 @@ multilineComments: true, | ||
exports.postgreSplitterOptions = Object.assign(Object.assign({}, exports.defaultSplitterOptions), { allowDollarDollarString: true, stringsBegins: ["'", '"'], stringsEnds: { "'": "'", '"': '"' }, stringEscapes: { "'": "'", '"': '"' } }); | ||
exports.sqliteSplitterOptions = Object.assign(Object.assign({}, exports.defaultSplitterOptions), { stringsBegins: ["'", '"'], stringsEnds: { "'": "'", '"': '"' }, stringEscapes: { "'": "'", '"': '"' } }); | ||
exports.sqliteSplitterOptions = Object.assign(Object.assign({}, exports.defaultSplitterOptions), { skipSeparatorBeginEnd: true, stringsBegins: ["'", '"'], stringsEnds: { "'": "'", '"': '"' }, stringEscapes: { "'": "'", '"': '"' } }); | ||
exports.mongoSplitterOptions = Object.assign(Object.assign({}, exports.defaultSplitterOptions), { stringsBegins: ["'", '"'], stringsEnds: { "'": "'", '"': '"' }, stringEscapes: { "'": '\\', '"': '\\' } }); | ||
@@ -33,0 +34,0 @@ exports.noSplitSplitterOptions = Object.assign(Object.assign({}, exports.defaultSplitterOptions), { noSplit: true }); |
@@ -15,2 +15,3 @@ "use strict"; | ||
isCopyFromStdinCandidate: false, | ||
beginEndIdentLevel: 0, | ||
}; | ||
@@ -17,0 +18,0 @@ } |
@@ -33,2 +33,3 @@ import { SplitterOptions } from './options'; | ||
readonly isCopyFromStdinCandidate: boolean; | ||
readonly beginEndIdentLevel: number; | ||
} | ||
@@ -41,2 +42,3 @@ export interface SplitLineContext extends SplitStreamContext { | ||
currentCommandStart: number; | ||
beginEndIdentLevel: number; | ||
} | ||
@@ -58,3 +60,3 @@ export interface SplitPositionDefinition { | ||
interface Token { | ||
type: 'string' | 'delimiter' | 'whitespace' | 'eoln' | 'data' | 'slash_delimiter' | 'set_delimiter' | 'set_sqlterminator' | 'comment' | 'go_delimiter' | 'create_routine' | 'copy' | 'copy_stdin_start' | 'copy_stdin_end' | 'copy_stdin_line' | 'parameter'; | ||
type: 'string' | 'delimiter' | 'end' | 'begin' | 'whitespace' | 'eoln' | 'data' | 'slash_delimiter' | 'set_delimiter' | 'set_sqlterminator' | 'comment' | 'go_delimiter' | 'create_routine' | 'copy' | 'copy_stdin_start' | 'copy_stdin_end' | 'copy_stdin_line' | 'parameter'; | ||
length: number; | ||
@@ -61,0 +63,0 @@ lengthWithoutWhitespace?: number; |
@@ -6,2 +6,6 @@ "use strict"; | ||
const SEMICOLON = ';'; | ||
const BEGIN_EXTRA_KEYWORDS = ['DEFERRED', 'IMMEDIATE', 'EXCLUSIVE', 'TRANSACTION']; | ||
const BEGIN_EXTRA_KEYWORDS_REGEX = new RegExp(`^(?:${BEGIN_EXTRA_KEYWORDS.join('|')})`, 'i'); | ||
const END_EXTRA_KEYWORDS = ['TRANSACTION', 'IF']; | ||
const END_EXTRA_KEYWORDS_REGEX = new RegExp(`^(?:${END_EXTRA_KEYWORDS.join('|')})`, 'i'); | ||
function movePosition(context, count, isWhite) { | ||
@@ -131,3 +135,4 @@ let { source, position, line, column, streamPosition } = context; | ||
} | ||
if (context.currentDelimiter && s.slice(pos).startsWith(context.currentDelimiter)) { | ||
const isInBeginEnd = context.options.skipSeparatorBeginEnd && context.beginEndIdentLevel > 0; | ||
if (context.currentDelimiter && s.slice(pos).startsWith(context.currentDelimiter) && !isInBeginEnd) { | ||
return { | ||
@@ -246,2 +251,27 @@ type: 'delimiter', | ||
} | ||
if (context.options.skipSeparatorBeginEnd && s.slice(pos).match(/^begin/i)) { | ||
let pos2 = pos + 'BEGIN'.length; | ||
let pos0 = pos2; | ||
while (pos0 < context.end && /[^a-zA-Z0-9]/.test(s[pos0])) | ||
pos0++; | ||
if (!BEGIN_EXTRA_KEYWORDS_REGEX.test(s.slice(pos0))) { | ||
return { | ||
type: 'begin', | ||
length: pos2 - pos, | ||
lengthWithoutWhitespace: pos0 - pos, | ||
}; | ||
} | ||
} | ||
if (context.options.skipSeparatorBeginEnd && s.slice(pos).match(/^end/i)) { | ||
let pos2 = pos + 'END'.length; | ||
let pos0 = pos2; | ||
while (pos0 < context.end && /[^a-zA-Z0-9]/.test(s[pos0])) | ||
pos0++; | ||
if (!END_EXTRA_KEYWORDS_REGEX.test(s.slice(pos0))) { | ||
return { | ||
type: 'end', | ||
length: pos2 - pos, | ||
}; | ||
} | ||
} | ||
const dollarString = scanDollarQuotedString(context); | ||
@@ -264,2 +294,3 @@ if (dollarString) | ||
isCopyFromStdin: context.isCopyFromStdin, | ||
beginEndIdentLevel: context.beginEndIdentLevel, | ||
}; | ||
@@ -468,2 +499,14 @@ cloned.position += delimiter.length; | ||
break; | ||
case 'begin': | ||
if (context.options.skipSeparatorBeginEnd) { | ||
context.beginEndIdentLevel++; | ||
} | ||
movePosition(context, token.length, false); | ||
break; | ||
case 'end': | ||
if (context.options.skipSeparatorBeginEnd && context.beginEndIdentLevel > 0) { | ||
context.beginEndIdentLevel--; | ||
} | ||
movePosition(context, token.length, false); | ||
break; | ||
} | ||
@@ -529,2 +572,3 @@ } | ||
trimCommandStartColumn: 0, | ||
beginEndIdentLevel: 0, | ||
wasDataInCommand: false, | ||
@@ -531,0 +575,0 @@ isCopyFromStdin: false, |
@@ -36,3 +36,3 @@ "use strict"; | ||
flushBuffer() { | ||
const lineContext = Object.assign(Object.assign({}, this.context), { position: 0, currentCommandStart: 0, wasDataOnLine: false, source: this.lineBuffer, end: this.lineBuffer.length, streamPosition: this.context.streamPosition, line: this.context.line, column: this.context.column, commandStartPosition: this.context.commandStartPosition, commandStartLine: this.context.commandStartLine, commandStartColumn: this.context.commandStartColumn, noWhitePosition: this.context.noWhitePosition, noWhiteLine: this.context.noWhiteLine, noWhiteColumn: this.context.noWhiteColumn, trimCommandStartPosition: this.context.trimCommandStartPosition, trimCommandStartLine: this.context.trimCommandStartLine, trimCommandStartColumn: this.context.trimCommandStartColumn, wasDataInCommand: this.context.wasDataInCommand, isCopyFromStdin: this.context.isCopyFromStdin, isCopyFromStdinCandidate: this.context.isCopyFromStdinCandidate }); | ||
const lineContext = Object.assign(Object.assign({}, this.context), { beginEndIdentLevel: 0, position: 0, currentCommandStart: 0, wasDataOnLine: false, source: this.lineBuffer, end: this.lineBuffer.length, streamPosition: this.context.streamPosition, line: this.context.line, column: this.context.column, commandStartPosition: this.context.commandStartPosition, commandStartLine: this.context.commandStartLine, commandStartColumn: this.context.commandStartColumn, noWhitePosition: this.context.noWhitePosition, noWhiteLine: this.context.noWhiteLine, noWhiteColumn: this.context.noWhiteColumn, trimCommandStartPosition: this.context.trimCommandStartPosition, trimCommandStartLine: this.context.trimCommandStartLine, trimCommandStartColumn: this.context.trimCommandStartColumn, wasDataInCommand: this.context.wasDataInCommand, isCopyFromStdin: this.context.isCopyFromStdin, isCopyFromStdinCandidate: this.context.isCopyFromStdinCandidate }); | ||
(0, splitQuery_1.splitQueryLine)(lineContext); | ||
@@ -39,0 +39,0 @@ this.context.commandPart = lineContext.commandPart; |
@@ -22,4 +22,4 @@ "use strict"; | ||
test('incorrect used escape', () => { | ||
const output = (0, splitQuery_1.splitQuery)("query1\\", options_1.mysqlSplitterOptions); | ||
expect(output).toEqual(["query1\\"]); | ||
const output = (0, splitQuery_1.splitQuery)('query1\\', options_1.mysqlSplitterOptions); | ||
expect(output).toEqual(['query1\\']); | ||
}); | ||
@@ -220,1 +220,29 @@ test('delete empty query', () => { | ||
}); | ||
test('sqlite skipSeparatorBeginEnd', () => { | ||
const input = 'CREATE TRIGGER obj1 AFTER INSERT ON t1 FOR EACH ROW BEGIN SELECT * FROM t1; END'; | ||
const output = (0, splitQuery_1.splitQuery)(input, Object.assign({}, options_1.sqliteSplitterOptions)); | ||
expect(output.length).toBe(1); | ||
expect(output[0]).toEqual(input); | ||
}); | ||
test('sqlite skipSeparatorBeginEnd in lowercase', () => { | ||
const input = 'create trigger obj1 after insert on t1 for each row begin select * from t1; end'; | ||
const output = (0, splitQuery_1.splitQuery)(input, Object.assign({}, options_1.sqliteSplitterOptions)); | ||
expect(output.length).toBe(1); | ||
expect(output[0]).toEqual(input); | ||
}); | ||
test('sqlite skipSeparatorBeginEnd in TRANSACTION', () => { | ||
const input = `BEGIN TRANSACTION; UPDATE t1 SET x=0;; END;`; | ||
const output = (0, splitQuery_1.splitQuery)(input, Object.assign({}, options_1.sqliteSplitterOptions)); | ||
expect(output.length).toBe(3); | ||
expect(output[0]).toEqual('BEGIN TRANSACTION'); | ||
expect(output[1]).toEqual('UPDATE t1 SET x=0'); | ||
expect(output[2]).toEqual('END'); | ||
}); | ||
test('sqlite skipSeparatorBeginEnd in TRANSACTION in lowercase', () => { | ||
const input = `begin transaction; update t1 set x=0;; end;`; | ||
const output = (0, splitQuery_1.splitQuery)(input, Object.assign({}, options_1.sqliteSplitterOptions)); | ||
expect(output.length).toBe(3); | ||
expect(output[0]).toEqual('begin transaction'); | ||
expect(output[1]).toEqual('update t1 set x=0'); | ||
expect(output[2]).toEqual('end'); | ||
}); |
{ | ||
"version": "4.11.2", | ||
"version": "4.11.3", | ||
"name": "dbgate-query-splitter", | ||
@@ -4,0 +4,0 @@ "main": "lib/index.js", |
59034
1264