update 优化匹配子查询的方法,支持匹配多层级括号

pull/3/head
yupi 2 years ago
parent a0065e01f2
commit 391bac0b45

@ -7,12 +7,25 @@ import {format} from "sql-formatter";
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
self.MonacoEnvironment = {
getWorker(_, label) {
// @ts-ignore
(self as any).MonacoEnvironment = {
getWorker(_: any, label: any) {
if (label === 'json') {
return new jsonWorker()
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new cssWorker()
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new htmlWorker()
}
if (label === 'typescript' || label === 'javascript') {
return new tsWorker()
}
return new editorWorker()
}
}
@ -33,6 +46,10 @@ const getSQL = () => {
}
}
const getInvokeTree = () => {
}
const initJSONValue = "{\n" +
" \"main\": {\n" +
" \"sql\": \"select * from @union_all_layer(分区 = 2021) where 分区 = #{分区}\",\n" +
@ -82,8 +99,13 @@ onMounted(() => {
<template>
<h1>
SQL 生成器
<t-button size="large" theme="primary" @click="getSQL" style="float: right"> 生成 SQL</t-button>
SQL 生成器 - JSON 来写 SQL
<div style="float: right">
<t-button size="large" theme="primary" @click="getSQL" > 生成 SQL</t-button>
<t-divider theme="vertical" />
<t-button size="large" theme="default" @click="getInvokeTree"> </t-button>
</div>
<t-tree :data="[]" activable hover />
</h1>
<t-row :gutter="24">
<t-col :xs="12" :sm="6">
@ -93,7 +115,10 @@ onMounted(() => {
<div id="outputContainer" ref="outputContainer" style="height: 80vh; max-width: 100%"/>
</t-col>
</t-row>
<div>yupi你能体会手写 1500 SQL牵一发而动全身的恐惧么</div>
<br/>
<div>
yupi你能体会手写 1500 SQL牵一发而动全身的恐惧么
</div>
</template>
<style>

@ -51,10 +51,9 @@ function replaceSubSql(sql: string, context: InputJSON): string {
if (!sql) {
return "";
}
const regExp = /@([\u4e00-\u9fa5_a-zA-Z0-9]+)\((.*?)\)/;
let result = sql;
result = String(result);
let regExpMatchArray = result.match(regExp);
let regExpMatchArray = matchSubQuery(result);
// 依次替换
while (regExpMatchArray && regExpMatchArray.length > 2) {
// 找到结果
@ -72,11 +71,12 @@ function replaceSubSql(sql: string, context: InputJSON): string {
paramsStr = paramsStr.trim();
}
// e.g. ["a = b", "c = d"]
const singleParamsStrArray = paramsStr.split(',');
const singleParamsStrArray = paramsStr.split('|||');
// string => object
const params: Record<string, string> = {};
for (const singleParamsStr of singleParamsStrArray) {
const keyValueArray = singleParamsStr.split('=');
// 必须分成 2 段
const keyValueArray = singleParamsStr.split('=', 2);
if (keyValueArray.length < 2) {
continue;
}
@ -85,7 +85,51 @@ function replaceSubSql(sql: string, context: InputJSON): string {
}
const replacement = replaceParams(replacementNode, context, params);
result = result.replaceAll(regExpMatchArray[0], replacement);
regExpMatchArray = result.match(regExp);
regExpMatchArray = matchSubQuery(result);
}
return result;
}
/**
*
* @param str
*/
function matchSubQuery(str: string) {
if (!str) {
return null;
}
const regExp = /@([\u4e00-\u9fa5_a-zA-Z0-9]+)\((.*?)\)/;
let regExpMatchArray = str.match(regExp);
if (!regExpMatchArray || regExpMatchArray.index === undefined) {
return null;
}
// @ 开始位置
let startPos = regExpMatchArray.index;
// 左括号右侧
let leftParenthesisPos = startPos + regExpMatchArray[1].length + 2;
// 遍历游标
let currPos = leftParenthesisPos;
// 默认匹配结束位置,需要对此结果进行修正
let endPos = startPos + regExpMatchArray[0].length;
// 剩余待匹配左括号数量
let leftCount = 1;
while (currPos < str.length) {
const currentChar = str.charAt(currPos);
if (currentChar === '(') {
leftCount++;
} else if (currentChar === ')') {
leftCount--;
}
// 匹配结束
if (leftCount == 0) {
endPos = currPos + 1;
break;
}
currPos++;
}
return [
str.slice(startPos, endPos),
regExpMatchArray[1],
str.slice(leftParenthesisPos, endPos - 1)
]
}
Loading…
Cancel
Save