Add delphi sql extract
This commit is contained in:
@@ -21,7 +21,8 @@
|
||||
"onCommand:extension.buildStringCsharp",
|
||||
"onCommand:extension.reverseBuildStringDoubleQuote",
|
||||
"onCommand:extension.reverseBuildStringSingleQuote",
|
||||
"onCommand:extension.createCsharpAutoProperty"
|
||||
"onCommand:extension.createCsharpAutoProperty",
|
||||
"onCommand:extension.reverseDelphiQuery"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"contributes": {
|
||||
@@ -69,6 +70,10 @@
|
||||
{
|
||||
"command": "extension.createCsharpAutoProperty",
|
||||
"title": "Solidt: Create autoproperty (C#)"
|
||||
},
|
||||
{
|
||||
"command": "extension.reverseDelphiQuery",
|
||||
"title": "Solidt: Reverse Query (Delphi)"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
155
src/delphi.ts
Normal file
155
src/delphi.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
|
||||
function* getLinesFromString(source: string) {
|
||||
let lines = String(source || "").matchAll(/^.+$/gm);
|
||||
for (const [line] of lines) yield line;
|
||||
}
|
||||
|
||||
interface IPart {
|
||||
isString: boolean;
|
||||
value: string;
|
||||
}
|
||||
|
||||
function* getNextStringPartFromLine(source: string, separator?: string): IterableIterator<IPart> {
|
||||
const line = String(source || "");
|
||||
const sep = "'";
|
||||
let inString = false;
|
||||
let start = 0;
|
||||
for (var i = 0; i < line.length; i++) {
|
||||
const char = line[i];
|
||||
|
||||
// if (char === sep) {
|
||||
// console.log("swithing in string");
|
||||
|
||||
// }
|
||||
|
||||
if (i + 1 === line.length) {
|
||||
yield {
|
||||
isString: inString,
|
||||
value: line.substring(start, i + 1)
|
||||
};
|
||||
} else if (char === sep) {
|
||||
yield {
|
||||
isString: inString,
|
||||
value: line.substring(start, i)
|
||||
};
|
||||
start = i + 1;
|
||||
inString = !inString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function trimAny(str: string, chars: string[]) {
|
||||
var start = 0,
|
||||
end = str.length;
|
||||
|
||||
while (start < end && chars.indexOf(str[start]) >= 0)
|
||||
++start;
|
||||
|
||||
while (end > start && chars.indexOf(str[end - 1]) >= 0)
|
||||
--end;
|
||||
|
||||
return (start > 0 || end < str.length) ? str.substring(start, end) : str;
|
||||
}
|
||||
|
||||
|
||||
const reSingleLineComment = /(\/\/.*)/g;
|
||||
const reMultiLineComment = /\{(.|[\r\n])*?\}/gm;
|
||||
const reEmptyOrBlankLines = /\n+\s*\n/gm;
|
||||
|
||||
const reJoinPlusLinesEnd = /\s*\+\s*?\n/gm;
|
||||
const reJoinPlusLinesStart = /\s*\n\s*?\+/gm;
|
||||
|
||||
function cleanUpCode(str: string) {
|
||||
str = String(str).replace(reSingleLineComment, "");
|
||||
str = String(str).replace(reMultiLineComment, "");
|
||||
str = String(str).replace(reEmptyOrBlankLines, "\n");
|
||||
|
||||
str = String(str).replace(reJoinPlusLinesStart, " + ");
|
||||
str = String(str).replace(reJoinPlusLinesEnd, " + ");
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
export function reverseDelphiQuery(input: string): string {
|
||||
const output: string[] = [];
|
||||
input = cleanUpCode(input);
|
||||
|
||||
for (const line of getLinesFromString(input)) {
|
||||
|
||||
const outputParts: string[] = [];
|
||||
|
||||
for (const part of getNextStringPartFromLine(line)) {
|
||||
|
||||
if (part.isString) {
|
||||
outputParts.push(part.value);
|
||||
} else {
|
||||
|
||||
const matches = part.value.matchAll(/[\+\(]\s*(.*)\s*[\+;]/gm);
|
||||
for (const match of matches) {
|
||||
const param = match[1];
|
||||
const rem = trimAny(param, [' ', '+', '\t', '\r']);
|
||||
if (rem.length > 0) {
|
||||
|
||||
const res = findStringBetweenMatchingBrace('(' + rem + ')', 0, '(', ')');
|
||||
if (res.trim().length > 0) {
|
||||
outputParts.push(`[[${res}]]`);
|
||||
} else {
|
||||
outputParts.push(`{{${res}}}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// const matches = part.value.matchAll(/\((.*)\)/gm);
|
||||
// for (const match of matches) {
|
||||
// const param = match[1];
|
||||
// const rem = trimAny(param, [' ', '+', '\t', '\r']);
|
||||
// if (rem.length > 0) {
|
||||
// outputParts.push(rem);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
//console.log(`part: ${part.isString ? "1" : "0"}`, part.value);
|
||||
}
|
||||
|
||||
output.push(outputParts.join(" "));
|
||||
}
|
||||
return input + '\n\n' + output.join("\n");
|
||||
};
|
||||
|
||||
function indexOfAny(str: string, anyOf: string[], startIndex: number): number {
|
||||
if (!str) return -1;
|
||||
if (!anyOf) return -1;
|
||||
let minIndex = -1;
|
||||
for (let j = 0; j < anyOf.length; j++) {
|
||||
let index = str.indexOf(anyOf[j], startIndex);
|
||||
if (index >= 0 && (minIndex === -1 || index < minIndex)) {
|
||||
minIndex = index;
|
||||
}
|
||||
}
|
||||
return minIndex;
|
||||
};
|
||||
|
||||
function findStringBetweenMatchingBrace(s: string, start: number, startBrace: string, endBrace: string) {
|
||||
const braces = [startBrace, endBrace];
|
||||
let pos = start;
|
||||
let end = start;
|
||||
let level = 0;
|
||||
let notStarted = true;
|
||||
while (true) {
|
||||
var index = indexOfAny(s, braces, pos);
|
||||
if (index < 0) break;
|
||||
if (notStarted) {
|
||||
notStarted = false;
|
||||
start = index + 1;
|
||||
}
|
||||
if (s[index] == startBrace) level++;
|
||||
if (s[index] == endBrace) level--;
|
||||
if (level <= 0) {
|
||||
end = index;
|
||||
break;
|
||||
}
|
||||
pos = index + 1;
|
||||
}
|
||||
return s.substring(start, end);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
const slash = "\\";
|
||||
const slashslash = "\\\\";
|
||||
|
||||
function getEscapeChars(quote: string, doubleEscape: boolean) : { [key: string]: string } {
|
||||
function getEscapeChars(quote: string, doubleEscape: boolean): { [key: string]: string } {
|
||||
const chars = {
|
||||
"\b": "\\b",
|
||||
"\n": "\\n",
|
||||
@@ -18,7 +18,7 @@ function getEscapeChars(quote: string, doubleEscape: boolean) : { [key: string]:
|
||||
return chars;
|
||||
}
|
||||
|
||||
function getUnescapeChars(quote: string, doubleEscape: boolean) : { [key: string]: string } {
|
||||
function getUnescapeChars(quote: string, doubleEscape: boolean): { [key: string]: string } {
|
||||
const chars = {
|
||||
"\\b": "\b",
|
||||
"\\n": "\n",
|
||||
@@ -38,23 +38,23 @@ function getUnescapeChars(quote: string, doubleEscape: boolean) : { [key: string
|
||||
export function escapeStr(str: string, quote: string, doubleEscape: boolean): string {
|
||||
let res = "";
|
||||
const chars = getEscapeChars(quote, doubleEscape)
|
||||
for (const c of String(str)) {
|
||||
if (c in chars) {
|
||||
res += chars[c];
|
||||
} else {
|
||||
res += c;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
for (const c of String(str)) {
|
||||
if (c in chars) {
|
||||
res += chars[c];
|
||||
} else {
|
||||
res += c;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export function unescapeStr(str: string, quote: string, doubleEscape: boolean): string {
|
||||
const chars = getUnescapeChars(quote, doubleEscape);
|
||||
let res = String(str).replace(/(\\.)/gm, (group) => {
|
||||
if (group in chars) {
|
||||
return chars[group];
|
||||
}
|
||||
return group;
|
||||
if (group in chars) {
|
||||
return chars[group];
|
||||
}
|
||||
return group;
|
||||
});
|
||||
if (doubleEscape)
|
||||
res = res.replace(quote + quote, quote);
|
||||
@@ -62,55 +62,58 @@ export function unescapeStr(str: string, quote: string, doubleEscape: boolean):
|
||||
}
|
||||
|
||||
export function buildString(text: string, quote: string, doubleEscape: boolean): string {
|
||||
var lines = text.split('\n');
|
||||
return lines.map(l => '\t' + quote + escapeStr(l, quote, doubleEscape) + quote).join(",\n");
|
||||
var lines = text.split('\n');
|
||||
return lines.map(l => '\t' + quote + escapeStr(l, quote, doubleEscape) + quote).join(",\n");
|
||||
};
|
||||
|
||||
export function buildStringCsharp(text: string): string {
|
||||
const prefix = "var str = string.Join(Environment.NewLine, new string[] {\n";
|
||||
const postfix = "\n});";
|
||||
return `${prefix}${buildString(text, '"', false)}${postfix}`;
|
||||
const prefix = "var str = string.Join(Environment.NewLine, new string[] {\n";
|
||||
const postfix = "\n});";
|
||||
return `${prefix}${buildString(text, '"', false)}${postfix}`;
|
||||
};
|
||||
|
||||
export function buildStringJavascript(text: string): string {
|
||||
const prefix = "var str = [\n";
|
||||
const postfix = "\n].join('\\n');";
|
||||
return `${prefix}${buildString(text, '"', false)}${postfix}`;
|
||||
const postfix = "\n].join('\\n');";
|
||||
return `${prefix}${buildString(text, '"', false)}${postfix}`;
|
||||
};
|
||||
|
||||
const getMatches = (re: RegExp, str: string): any[] => {
|
||||
let match, matches = [];
|
||||
while (match = re.exec(str)) {
|
||||
matches.push(match);
|
||||
}
|
||||
return matches;
|
||||
let match, matches = [];
|
||||
while (match = re.exec(str)) {
|
||||
matches.push(match);
|
||||
}
|
||||
return matches;
|
||||
};
|
||||
|
||||
export function reverseBuildString(text: string, quote: string, doubleEscape: boolean): string {
|
||||
let regEx = new RegExp(quote + "(.*[^"+ slashslash +"])" + quote, "gm");
|
||||
let regEx = new RegExp(quote + "(.*[^" + slashslash + "])" + quote, "gm");
|
||||
if (doubleEscape) {
|
||||
regEx = new RegExp(quote + "(.*[^" + quote + "])" + quote, "gm");
|
||||
regEx = new RegExp(quote + "(.*[^" + quote + "])" + quote, "gm");
|
||||
}
|
||||
return getMatches(regEx, text)
|
||||
.map(m => unescapeStr(m[1], quote, doubleEscape))
|
||||
.join("\n");
|
||||
return getMatches(regEx, text)
|
||||
.map(m => unescapeStr(m[1], quote, doubleEscape))
|
||||
.join("\n");
|
||||
};
|
||||
|
||||
|
||||
function lowerFirst(input: string) {
|
||||
return input.charAt(0).toLowerCase() + input.slice(1)
|
||||
}
|
||||
export function createCsharpAutoProperty(input: string)
|
||||
{
|
||||
const [type, name] = input.split(" ");
|
||||
const pname = "_" + lowerFirst(name);
|
||||
const output = [
|
||||
`private ${type} ${pname};`,
|
||||
`public ${type} ${name}`,
|
||||
"{",
|
||||
`\tget => ${pname};`,
|
||||
`\tset => SetPropertyValue(nameof(${name}), ref ${pname}, value);`,
|
||||
"}"
|
||||
].join("\n");
|
||||
return output;
|
||||
export function createCsharpAutoProperty(input: string) {
|
||||
const lines = input.split('\n');
|
||||
const output = [];
|
||||
for (const line of lines) {
|
||||
const [type, name] = line.split(" ").map(x => x.trim());
|
||||
const pname = "_" + lowerFirst(name);
|
||||
output.push([
|
||||
`private ${type} ${pname};`,
|
||||
`public ${type} ${name}`,
|
||||
"{",
|
||||
`\tget => ${pname};`,
|
||||
`\tset => SetPropertyValue(nameof(${name}), ref ${pname}, value);`,
|
||||
"}"
|
||||
].join("\n"));
|
||||
}
|
||||
return output.join("\n\n");
|
||||
};
|
||||
@@ -1,22 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { reverseDelphiQuery } from "./delphi";
|
||||
import { escapeStr, unescapeStr, buildString, reverseBuildString, buildStringJavascript, buildStringCsharp, createCsharpAutoProperty } from "./escape";
|
||||
|
||||
type Replacer = (a: string) => string;
|
||||
|
||||
function run(replacer: Replacer)
|
||||
{
|
||||
function run(replacer: Replacer) {
|
||||
// Get the active text editor
|
||||
let editor = vscode.window.activeTextEditor;
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
|
||||
if (editor) {
|
||||
let document = editor.document;
|
||||
let selection = editor.selection;
|
||||
let selectedText = document.getText(selection);
|
||||
let result = replacer(selectedText)
|
||||
if (editor && editor.document && editor.selection) {
|
||||
const selectedText = editor.document.getText(editor.selection);
|
||||
if (String(selectedText).length <= 0) return;
|
||||
const result = replacer(selectedText);
|
||||
editor.edit(editBuilder => {
|
||||
editBuilder.replace(selection, result);
|
||||
editBuilder.replace(editor!.selection, result);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -27,15 +26,16 @@ const escapeSingleQuote = (str: string): string => escapeStr(str, "'", false);
|
||||
// const escapeDoubleQuoteDoubled = (str: string): string => escapeStr(str, '"', true);
|
||||
// const escapeSingleQuoteDoubled = (str: string): string => escapeStr(str, "'", true);
|
||||
|
||||
const unescapeDoubleQuote = (str: string): string => unescapeStr(str, '"', false);
|
||||
const unescapeDoubleQuote = (str: string): string => unescapeStr(str, '"', false);
|
||||
const unescapeSingleQuote = (str: string): string => unescapeStr(str, "'", false);
|
||||
|
||||
const buildStringDoubleQuote = (str: string): string => buildString(str, '"', false);
|
||||
const buildStringDoubleQuote = (str: string): string => buildString(str, '"', false);
|
||||
const buildStringSingleQuote = (str: string): string => buildString(str, "'", false);
|
||||
|
||||
const reverseBuildStringDoubleQuote = (str: string): string => reverseBuildString(str, '"', false);
|
||||
const reverseBuildStringDoubleQuote = (str: string): string => reverseBuildString(str, '"', false);
|
||||
const reverseBuildStringSingleQuote = (str: string): string => reverseBuildString(str, "'", false);
|
||||
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(vscode.commands.registerCommand('extension.escapeDoubleQuote', () => run(escapeDoubleQuote)));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('extension.escapeSingleQuote', () => run(escapeSingleQuote)));
|
||||
@@ -53,6 +53,5 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(vscode.commands.registerCommand('extension.reverseBuildStringSingleQuote', () => run(reverseBuildStringSingleQuote)));
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('extension.createCsharpAutoProperty', () => run(createCsharpAutoProperty)));
|
||||
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('extension.reverseDelphiQuery', () => run(reverseDelphiQuery)));
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"target": "es2020",
|
||||
"outDir": "out",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"rootDir": "src"
|
||||
},
|
||||
"exclude": ["node_modules", ".vscode-test"]
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode-test"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user