update 优化调用树生成过程

add 支持查看调用节点详情
pull/3/head
yupi 2 years ago
parent caac5af5cd
commit 667585f10c

@ -13,7 +13,9 @@
1. 将 SQL 的编写逻辑 `结构化` ,像写文章大纲一样编写和阅读 SQL
2. 重复的 SQL 只需编写一次 SQL 变动时修改一处即可
3. 可以针对某部分 SQL 进行传参和调试
4. 查看 SQL 语句的引用树
4. 查看 SQL 语句的引用树和替换过程,便于分析理解 SQL
![查看调用树和替换过程](https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/1/image-20220514143425002.png)
## 应用场景
@ -63,7 +65,7 @@ from
3. 支持参数透传,比如 @a(xx = #{yy})yy 变量可传递给 @a 公式
4. 支持嵌套传参(将子查询作为参数),比如 @a(xx = @b(yy = 1))
5. 不限制用户在 JSON 中编写的内容,因此该工具也可以作为重复代码生成器来使用
6. 支持查看 SQL 语句的调用树,便于分析引用关系
6. 支持查看 SQL 语句的调用树和替换详情,便于分析引用关系
## 文档

@ -1,7 +1,7 @@
<script setup lang="ts">
import { doGenerateSQL } from "./generator";
import { importExample } from "./examples";
import { onMounted, ref, toRaw, watch } from "vue";
import { onMounted, ref, toRaw } from "vue";
import * as monaco from "monaco-editor";
import { format } from "sql-formatter";
import { GithubOutlined } from "@ant-design/icons-vue";
@ -56,6 +56,7 @@ const getSQL = () => {
toRaw(outputEditor.value).setValue(result);
//
invokeTree.value = [generateResult.invokeTree];
console.log(invokeTree.value);
};
const showInvokeTree = () => {
@ -120,7 +121,7 @@ onMounted(() => {
<a-button size="large" type="primary" ghost @click="showInvokeTree">
查看调用树
</a-button>
<a-button size="large" type="default" @click="importExample">
<a-button size="large" type="default" @click="importExample('init')">
导入例子
</a-button>
</a-space>

@ -13,13 +13,37 @@
:tree-data="tree"
@expand="onExpand"
>
<template #title="{ title }">
<span v-if="title.indexOf(searchValue) > -1">
{{ title.substr(0, title.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ title }}</span>
<template #title="{ title, sql, params, resultSQL }">
<a-popover title="详情" placement="top">
<template #content>
<div style="max-width: 600px">
<p>
<b>替换前语句</b>
<a-typography-paragraph copyable>
{{ sql }}
</a-typography-paragraph>
</p>
<p>
<b>替换参数</b>
<a-typography-paragraph copyable>
{{ params ?? "无" }}
</a-typography-paragraph>
</p>
<p>
<b>替换后语句</b>
<a-typography-paragraph copyable>
{{ resultSQL }}
</a-typography-paragraph>
</p>
</div>
</template>
<span v-if="title.indexOf(searchValue) > -1">
{{ title.substr(0, title.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ title.substr(title.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ title }}</span>
</a-popover>
</template>
</a-tree>
</div>

@ -19,35 +19,55 @@ export function doGenerateSQL(json: InputJSON) {
const rootInvokeTreeNode = { ...initTreeNode };
const context = json;
const resultSQL = generateSQL(
context.main,
"main",
context,
context.main?.params,
rootInvokeTreeNode
);
return {
resultSQL,
invokeTree: rootInvokeTreeNode,
invokeTree: rootInvokeTreeNode.children[0], // 取第一个作为根节点
};
}
/**
* SQL
* @param currentNode
* @param key
* @param context
* @param params
* @param invokeTreeNode
*/
function generateSQL(
currentNode: InputJSONValue,
key: string,
context: InputJSON,
params?: Record<string, string>,
invokeTreeNode?: InvokeTreeNode
): string {
const currentNode = context[key];
if (!currentNode) {
return "";
}
const result = replaceParams(currentNode, context, params, invokeTreeNode);
return replaceSubSql(result, context, invokeTreeNode);
let childInvokeTreeNode: InvokeTreeNode | undefined;
if (invokeTreeNode) {
childInvokeTreeNode = {
title: key,
sql: currentNode.sql ?? currentNode,
params,
children: [],
};
invokeTreeNode.children?.push(childInvokeTreeNode);
}
const result = replaceParams(
currentNode,
context,
params,
childInvokeTreeNode
);
const resultSQL = replaceSubSql(result, context, childInvokeTreeNode);
if (childInvokeTreeNode) {
childInvokeTreeNode.resultSQL = resultSQL;
}
return resultSQL;
}
/**
@ -140,23 +160,8 @@ function replaceSubSql(
const key = keyValueArray[0].trim();
params[key] = keyValueArray[1].trim();
}
let childInvokeTreeNode;
if (invokeTreeNode) {
childInvokeTreeNode = {
title: subKey,
sql,
params,
children: [],
};
invokeTreeNode.children?.push(childInvokeTreeNode);
}
// 递归解析被替换节点
const replacement = generateSQL(
replacementNode,
context,
params,
childInvokeTreeNode
);
const replacement = generateSQL(subKey, context, params, invokeTreeNode);
result = result.replace(regExpMatchArray[0], replacement);
regExpMatchArray = matchSubQuery(result);
}

@ -16,6 +16,7 @@ interface InvokeTreeNode {
sql: string;
key?: string;
params?: Record<string, string>;
resultSQL?: string;
children?: InvokeTreeNode[];
}

Loading…
Cancel
Save