mirror of
https://gitee.com/dromara/dbswitch.git
synced 2025-10-15 06:10:23 +00:00
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
DBSWITCH_VERSION=1.9.6
|
||||
DBSWITCH_VERSION=1.9.7
|
||||
BUILD_DOCKER_DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
PROJECT_ROOT_DIR=$( dirname "$BUILD_DOCKER_DIR")
|
||||
DOCKER_DBSWITCH_DIR=$BUILD_DOCKER_DIR/dbswitch
|
||||
|
@@ -18,7 +18,7 @@ services:
|
||||
start_period: 30s
|
||||
dbswitch:
|
||||
container_name: dbswitch_webui
|
||||
image: inrgihc/dbswitch:1.9.6
|
||||
image: inrgihc/dbswitch:1.9.7
|
||||
environment:
|
||||
MYSQLDB_HOST: dbswitch_mysqldb
|
||||
MYSQLDB_PORT: 3306
|
||||
|
12840
dbswitch-admin-ui/package-lock.json
generated
12840
dbswitch-admin-ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -17,10 +17,12 @@
|
||||
"qs": "^6.11.2",
|
||||
"urlencode": "^1.1.0",
|
||||
"vue": "^2.5.2",
|
||||
"vue-codemirror": "^4.0.6",
|
||||
"vue-count-to": "^1.0.13",
|
||||
"vue-cron": "^1.0.9",
|
||||
"vue-hot-reload-api": "^2.3.4",
|
||||
"vue-router": "^3.0.1"
|
||||
"vue-router": "^3.0.1",
|
||||
"vue2-ace-editor": "^0.0.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
|
@@ -27,131 +27,141 @@
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<span>当前表:{{currentNode.schemaName}} / {{currentNode.tableName}}</span>
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="基本信息"
|
||||
name="first">
|
||||
<el-descriptions title="元数据"
|
||||
size="small"
|
||||
:column="1"
|
||||
colon
|
||||
border>
|
||||
<el-descriptions-item label="表名称">{{tableMeta.tableName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="表类型">{{tableMeta.type}}</el-descriptions-item>
|
||||
<el-descriptions-item label="模式名">{{tableMeta.schemaName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="表注释">
|
||||
<el-input type="textarea"
|
||||
:rows="2"
|
||||
v-model="tableMeta.remarks"
|
||||
auto-complete="off"
|
||||
:readonly=true></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="建表DDL">
|
||||
<el-input type="textarea"
|
||||
:rows="16"
|
||||
v-model="tableMeta.createSql"
|
||||
auto-complete="off"
|
||||
:readonly=true></el-input>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="字段信息"
|
||||
name="seconde">
|
||||
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
|
||||
:data="tableMeta.columns"
|
||||
size="small"
|
||||
border
|
||||
style="width: 100%">
|
||||
<template slot="empty">
|
||||
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
|
||||
</template>
|
||||
<el-table-column prop="fieldName"
|
||||
min-width="20%"
|
||||
show-overflow-tooltip
|
||||
label="名称">
|
||||
</el-table-column>
|
||||
<el-table-column prop="typeName"
|
||||
min-width="20%"
|
||||
label="类型">
|
||||
</el-table-column>
|
||||
<el-table-column prop="fieldType"
|
||||
min-width="7%"
|
||||
label="jdbcType">
|
||||
</el-table-column>
|
||||
<el-table-column prop="displaySize"
|
||||
min-width="7%"
|
||||
label="长度">
|
||||
</el-table-column>
|
||||
<el-table-column prop="precision"
|
||||
min-width="5%"
|
||||
label="精度">
|
||||
</el-table-column>
|
||||
<el-table-column prop="scale"
|
||||
min-width="5%"
|
||||
label="位数">
|
||||
</el-table-column>
|
||||
<el-table-column prop="isPrimaryKey"
|
||||
min-width="5%"
|
||||
label="主键">
|
||||
</el-table-column>
|
||||
<el-table-column prop="isAutoIncrement"
|
||||
min-width="5%"
|
||||
label="自增">
|
||||
</el-table-column>
|
||||
<el-table-column prop="isNullable"
|
||||
min-width="5%"
|
||||
label="可空">
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks"
|
||||
min-width="20%"
|
||||
show-overflow-tooltip
|
||||
label="注释">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="索引信息"
|
||||
name="third">
|
||||
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
|
||||
:data="tableMeta.indexes"
|
||||
size="small"
|
||||
border
|
||||
style="width: 100%">
|
||||
<template slot="empty">
|
||||
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
|
||||
</template>
|
||||
<el-table-column prop="indexType"
|
||||
min-width="20%"
|
||||
label="索引类型">
|
||||
</el-table-column>
|
||||
<el-table-column prop="indexName"
|
||||
min-width="20%"
|
||||
label="索引名称">
|
||||
</el-table-column>
|
||||
<el-table-column prop="indexFields"
|
||||
:formatter="formatIndexFields"
|
||||
show-overflow-tooltip
|
||||
min-width="60%"
|
||||
label="索引字段">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane class="table-container-data-table"
|
||||
label="取样数据"
|
||||
name="fourth">
|
||||
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
|
||||
:data="sampleData.rows"
|
||||
border>
|
||||
<template slot="empty">
|
||||
<span>单击左侧展开"数据源导航树"来查看表的数据记录</span>
|
||||
</template>
|
||||
<el-table-column v-for="(item,index) in sampleData.columns"
|
||||
:prop="item"
|
||||
:label="item"
|
||||
:key="index"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-tabs v-model="tabActiveTabName"
|
||||
type="border-card">
|
||||
<el-tab-pane label="元数据"
|
||||
name="metadata">
|
||||
<el-tag size="medium">当前表:{{currentNode.schemaName}} / {{currentNode.tableName}}</el-tag>
|
||||
<el-tabs v-model="metadataActiveTabName">
|
||||
<el-tab-pane label="基本信息"
|
||||
name="first">
|
||||
<el-descriptions title="元数据"
|
||||
size="small"
|
||||
:column="1"
|
||||
colon
|
||||
border>
|
||||
<el-descriptions-item label="表名称">{{tableMeta.tableName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="表类型">{{tableMeta.type}}</el-descriptions-item>
|
||||
<el-descriptions-item label="模式名">{{tableMeta.schemaName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="表注释">
|
||||
<el-input type="textarea"
|
||||
:rows="2"
|
||||
v-model="tableMeta.remarks"
|
||||
auto-complete="off"
|
||||
:readonly=true></el-input>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="建表DDL">
|
||||
<el-input type="textarea"
|
||||
:rows="16"
|
||||
v-model="tableMeta.createSql"
|
||||
auto-complete="off"
|
||||
:readonly=true></el-input>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="字段信息"
|
||||
name="seconde">
|
||||
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
|
||||
:data="tableMeta.columns"
|
||||
size="small"
|
||||
border
|
||||
style="width: 100%">
|
||||
<template slot="empty">
|
||||
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
|
||||
</template>
|
||||
<el-table-column prop="fieldName"
|
||||
min-width="20%"
|
||||
show-overflow-tooltip
|
||||
label="名称">
|
||||
</el-table-column>
|
||||
<el-table-column prop="typeName"
|
||||
min-width="20%"
|
||||
label="类型">
|
||||
</el-table-column>
|
||||
<el-table-column prop="fieldType"
|
||||
min-width="7%"
|
||||
label="jdbcType">
|
||||
</el-table-column>
|
||||
<el-table-column prop="displaySize"
|
||||
min-width="7%"
|
||||
label="长度">
|
||||
</el-table-column>
|
||||
<el-table-column prop="precision"
|
||||
min-width="5%"
|
||||
label="精度">
|
||||
</el-table-column>
|
||||
<el-table-column prop="scale"
|
||||
min-width="5%"
|
||||
label="位数">
|
||||
</el-table-column>
|
||||
<el-table-column prop="isPrimaryKey"
|
||||
min-width="5%"
|
||||
label="主键">
|
||||
</el-table-column>
|
||||
<el-table-column prop="isAutoIncrement"
|
||||
min-width="5%"
|
||||
label="自增">
|
||||
</el-table-column>
|
||||
<el-table-column prop="isNullable"
|
||||
min-width="5%"
|
||||
label="可空">
|
||||
</el-table-column>
|
||||
<el-table-column prop="remarks"
|
||||
min-width="20%"
|
||||
show-overflow-tooltip
|
||||
label="注释">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="索引信息"
|
||||
name="third">
|
||||
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
|
||||
:data="tableMeta.indexes"
|
||||
size="small"
|
||||
border
|
||||
style="width: 100%">
|
||||
<template slot="empty">
|
||||
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
|
||||
</template>
|
||||
<el-table-column prop="indexType"
|
||||
min-width="20%"
|
||||
label="索引类型">
|
||||
</el-table-column>
|
||||
<el-table-column prop="indexName"
|
||||
min-width="20%"
|
||||
label="索引名称">
|
||||
</el-table-column>
|
||||
<el-table-column prop="indexFields"
|
||||
:formatter="formatIndexFields"
|
||||
show-overflow-tooltip
|
||||
min-width="60%"
|
||||
label="索引字段">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane class="table-container-data-table"
|
||||
label="取样数据"
|
||||
name="fourth">
|
||||
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
|
||||
:data="sampleData.rows"
|
||||
border>
|
||||
<template slot="empty">
|
||||
<span>单击左侧展开"数据源导航树"来查看表的数据记录</span>
|
||||
</template>
|
||||
<el-table-column v-for="(item,index) in sampleData.columns"
|
||||
:prop="item"
|
||||
:label="item"
|
||||
:key="index"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-tab-pane>
|
||||
<!-- <el-tab-pane label="SQL在线"
|
||||
name="sqlQuery">
|
||||
<multi-sql-editor ref="sqlEditors"></multi-sql-editor>
|
||||
</el-tab-pane> -->
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
@@ -161,10 +171,13 @@
|
||||
|
||||
<script>
|
||||
import urlencode from "urlencode";
|
||||
import multiSqlEditor from '@/views/metadata/sqlEditor'
|
||||
|
||||
// 参考文章:https://blog.csdn.net/m0_50255772/article/details/109484828
|
||||
export default {
|
||||
components: {},
|
||||
components: {
|
||||
multiSqlEditor
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
props: {
|
||||
@@ -180,7 +193,8 @@ export default {
|
||||
tableName: '-',
|
||||
schemaName: '-'
|
||||
},
|
||||
activeName: 'first',
|
||||
tabActiveTabName: 'metadata',
|
||||
metadataActiveTabName: 'first',
|
||||
tableMeta: {
|
||||
tableName: '-',
|
||||
schemaName: '-',
|
||||
@@ -369,7 +383,8 @@ export default {
|
||||
var schema = data.value;
|
||||
var table = data.label;
|
||||
if (!data.hasChild && datasourceId && schema && table) {
|
||||
this.activeName = 'first';
|
||||
this.tabActiveTabName = 'metadata';
|
||||
this.metadataActiveTabName = 'first';
|
||||
this.getTableMeta(datasourceId, schema, table);
|
||||
this.getTableData(datasourceId, schema, table);
|
||||
}
|
||||
@@ -477,21 +492,49 @@ export default {
|
||||
min-width: 350px;
|
||||
position: relative;
|
||||
cursor: default;
|
||||
color: black;
|
||||
}
|
||||
.el-tree-node__content {
|
||||
font-size: small;
|
||||
height: 16px;
|
||||
background-color: blanchedalmond;
|
||||
}
|
||||
.custom-tree-node {
|
||||
font-size: 16px;
|
||||
background-size: 16px;
|
||||
}
|
||||
|
||||
.scroller {
|
||||
min-width: 200px;
|
||||
max-height: calc(90vh);
|
||||
}
|
||||
.el-select {
|
||||
display: inline;
|
||||
}
|
||||
.tree-container .tree {
|
||||
overflow: auto;
|
||||
}
|
||||
.table-container {
|
||||
width: 80%;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
.table-container-data-table {
|
||||
height: 90%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
el-tabs--border-card > .el-tabs__header .el-tabs__item {
|
||||
margin-left: 8px;
|
||||
border: none;
|
||||
border-radius: 8px 8px 0 0;
|
||||
background-color: #f3f7fe;
|
||||
padding: 4px 20px;
|
||||
color: #0065d5;
|
||||
line-height: 22px;
|
||||
height: 30px;
|
||||
}
|
||||
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
|
||||
background-color: #0065d5;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
121
dbswitch-admin-ui/src/views/metadata/sqlEditor.vue
Normal file
121
dbswitch-admin-ui/src/views/metadata/sqlEditor.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="tool">
|
||||
<div class="item-button"><i class="iconfont icon-play"></i><span>执行</span></div>
|
||||
<div class="item-button"><i class="iconfont icon-play"></i><span>执行选中</span></div>
|
||||
<div class="item-button"><i class="iconfont icon-play"></i><span>格式化</span></div>
|
||||
</div>
|
||||
<ace ref="editor"
|
||||
:value="content"
|
||||
@init="initEditor"
|
||||
:lang="lang"
|
||||
:height="height === 0 ? '100%' : height"
|
||||
:theme="theme"
|
||||
:options="options"
|
||||
width="100%"
|
||||
v-bind="config">
|
||||
</ace>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ace from 'vue2-ace-editor'
|
||||
|
||||
export default {
|
||||
name: "multiSqlEditer",
|
||||
components: {
|
||||
ace
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 300
|
||||
},
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'monokai'
|
||||
},
|
||||
lang: {
|
||||
type: String,
|
||||
default: 'sql'
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
font_size: 16,
|
||||
sql_atom: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options () {
|
||||
if (this.readOnly) {
|
||||
return {
|
||||
enableBasicAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
enableLiveAutocompletion: this.config.sql_atom,
|
||||
showPrintMargin: false,
|
||||
fontSize: this.config.font_size,
|
||||
readOnly: true
|
||||
}
|
||||
}
|
||||
return {
|
||||
enableBasicAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
enableLiveAutocompletion: this.config.sql_atom,
|
||||
showPrintMargin: false,
|
||||
fontSize: this.config.font_size
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initEditor (editor) {
|
||||
require('brace/ext/language_tools')
|
||||
// 设置语言
|
||||
require('brace/mode/sql')
|
||||
require('brace/snippets/sql')
|
||||
// 设置主题 按需加载
|
||||
require('brace/theme/monokai')
|
||||
require('brace/theme/chrome')
|
||||
require('brace/theme/crimson_editor')
|
||||
// 监听值的变化
|
||||
editor.getSession().on('change', val => {
|
||||
this.$emit('change', editor.getValue())
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
created () {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tool .item-button {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
color: #009966;
|
||||
margin: 0 20px 0 0;
|
||||
line-height: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tool .item-button span {
|
||||
color: #000;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
@@ -33,6 +33,7 @@
|
||||
</el-card>
|
||||
|
||||
<div class="contentBox">
|
||||
<el-tag v-if="taskId && taskId>0">当前任务:[{{taskId}}]{{taskName}}</el-tag>
|
||||
<div class="right-refresh-button">
|
||||
<el-button type="primary"
|
||||
plain
|
||||
@@ -165,6 +166,7 @@ export default {
|
||||
pageTaskAssignments: [],
|
||||
pageTaskAssignmentsTotalCount: 0,
|
||||
taskId: 0,
|
||||
taskName: "",
|
||||
jobTableData: [],
|
||||
jobScheduleTime: '',
|
||||
isActive: -1,
|
||||
@@ -225,25 +227,43 @@ export default {
|
||||
this.currentPage = currentPage;
|
||||
this.loadJobsData();
|
||||
},
|
||||
loadJobsData: function () {
|
||||
this.$http.get(
|
||||
"/dbswitch/admin/api/v1/ops/jobs/list/" + this.currentPage + "/" + this.pageSize + "?id=" + this.taskId
|
||||
).then(res => {
|
||||
if (0 === res.data.code) {
|
||||
this.currentPage = res.data.pagination.page;
|
||||
this.pageSize = res.data.pagination.size;
|
||||
this.totalCount = res.data.pagination.total;
|
||||
this.jobTableData = res.data.data;
|
||||
} else {
|
||||
if (res.data.message) {
|
||||
alert("查询JOB执行历史纪录失败," + res.data.message);
|
||||
loadTaskInfo: function () {
|
||||
if (this.taskId && this.taskId > 0) {
|
||||
this.$http.get(
|
||||
"/dbswitch/admin/api/v1/assignment/info/id/" + this.taskId
|
||||
).then(res => {
|
||||
if (0 === res.data.code) {
|
||||
this.taskName = res.data.data.name;
|
||||
} else {
|
||||
if (res.data.message) {
|
||||
alert("查询任务详情失败," + res.data.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
loadJobsData: function () {
|
||||
if (this.taskId && this.taskId > 0) {
|
||||
this.$http.get(
|
||||
"/dbswitch/admin/api/v1/ops/jobs/list/" + this.currentPage + "/" + this.pageSize + "?id=" + this.taskId
|
||||
).then(res => {
|
||||
if (0 === res.data.code) {
|
||||
this.currentPage = res.data.pagination.page;
|
||||
this.pageSize = res.data.pagination.size;
|
||||
this.totalCount = res.data.pagination.total;
|
||||
this.jobTableData = res.data.data;
|
||||
} else {
|
||||
if (res.data.message) {
|
||||
alert("查询JOB执行历史纪录失败," + res.data.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
handleChooseClick: function (taskId, index) {
|
||||
this.isActive = index;
|
||||
this.taskId = taskId;
|
||||
this.loadTaskInfo();
|
||||
this.loadJobsData();
|
||||
},
|
||||
handleClickRefresh () {
|
||||
@@ -251,6 +271,7 @@ export default {
|
||||
alert("请先在左侧选择一个任务来");
|
||||
return;
|
||||
}
|
||||
this.loadTaskInfo();
|
||||
this.loadJobsData();
|
||||
},
|
||||
handleCancelJob: function (jobId) {
|
||||
@@ -333,6 +354,7 @@ export default {
|
||||
this.loadPageTaskAssignments();
|
||||
if (this.$route.query.id) {
|
||||
this.taskId = this.$route.query.id
|
||||
this.loadTaskInfo();
|
||||
this.loadJobsData();
|
||||
}
|
||||
},
|
||||
|
@@ -25,7 +25,6 @@ import io.swagger.annotations.ApiOperation;
|
||||
import java.util.List;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -86,6 +85,14 @@ public class AssignmentController {
|
||||
return assignmentService.detailAssignment(id);
|
||||
}
|
||||
|
||||
@TokenCheck
|
||||
@ApiOperation(value = "任务信息")
|
||||
@GetMapping(value = "/info/id/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Result<AssignmentInfoResponse> infoAssignment(
|
||||
@PathVariable("id") Long id) {
|
||||
return assignmentService.infoAssignment(id);
|
||||
}
|
||||
|
||||
@TokenCheck
|
||||
@LogOperate(name = "发布任务", description = "'发布任务的ID为:'+#ids")
|
||||
@ApiOperation(value = "发布")
|
||||
|
@@ -4,9 +4,11 @@ import com.gitee.dbswitch.admin.common.annotation.TokenCheck;
|
||||
import com.gitee.dbswitch.admin.common.response.PageResult;
|
||||
import com.gitee.dbswitch.admin.common.response.Result;
|
||||
import com.gitee.dbswitch.admin.config.SwaggerConfig;
|
||||
import com.gitee.dbswitch.admin.model.request.OnlineSqlDataRequest;
|
||||
import com.gitee.dbswitch.admin.model.response.MetadataSchemaDetailResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.MetadataTableDetailResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.MetadataTableInfoResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.OnlineSqlDataResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.SchemaTableDataResponse;
|
||||
import com.gitee.dbswitch.admin.service.MetaDataService;
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -15,6 +17,8 @@ import javax.annotation.Resource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -68,4 +72,13 @@ public class MetaDataController {
|
||||
return metaDataService.tableData(id, schema, table);
|
||||
}
|
||||
|
||||
@TokenCheck
|
||||
@ApiOperation(value = "SQL脚本结果集数据内容")
|
||||
@PostMapping(value = "/data/sql/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Result<OnlineSqlDataResponse> sqlData(
|
||||
@PathVariable("id") Long id,
|
||||
@RequestBody OnlineSqlDataRequest request) {
|
||||
return metaDataService.sqlData(id, request);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,15 @@
|
||||
package com.gitee.dbswitch.admin.model.request;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class OnlineSqlDataRequest {
|
||||
|
||||
private String script;
|
||||
|
||||
private Integer page;
|
||||
|
||||
private Integer size;
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package com.gitee.dbswitch.admin.model.response;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@ApiModel("SQL脚本结果数据内容")
|
||||
public class OnlineSqlDataResponse {
|
||||
|
||||
private List<SqlInput> summaries;
|
||||
|
||||
private List<SqlResult> results;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class SqlInput {
|
||||
|
||||
private String sql;
|
||||
|
||||
private String summary;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class SqlResult {
|
||||
|
||||
private List<ColumnItem> columns;
|
||||
|
||||
private List<Map<String, Object>> rows;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class ColumnItem {
|
||||
|
||||
private String columnName;
|
||||
|
||||
private String columnType;
|
||||
}
|
||||
}
|
@@ -158,6 +158,17 @@ public class AssignmentService {
|
||||
return Result.success(detailResponse);
|
||||
}
|
||||
|
||||
public Result<AssignmentInfoResponse> infoAssignment(Long id) {
|
||||
AssignmentTaskEntity assignmentTaskEntity = assignmentTaskDAO.getById(id);
|
||||
if (Objects.isNull(assignmentTaskEntity)) {
|
||||
return Result.failed(ResultCode.ERROR_RESOURCE_NOT_EXISTS, "ID=" + id);
|
||||
}
|
||||
|
||||
AssignmentInfoResponse infoResponse = ConverterFactory
|
||||
.getConverter(AssignmentInfoConverter.class).convert(assignmentTaskEntity);
|
||||
return Result.success(infoResponse);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deployAssignments(List<Long> ids) {
|
||||
checkAssignmentAllExist(ids);
|
||||
|
@@ -52,7 +52,11 @@ public class ConnectionService {
|
||||
@Resource
|
||||
private DatabaseConnectionDAO databaseConnectionDAO;
|
||||
|
||||
public MetadataService getMetaDataCoreService(DatabaseConnectionEntity dbConn) {
|
||||
public CloseableDataSource getDataSource(Long id) {
|
||||
return getDataSource(getDatabaseConnectionById(id));
|
||||
}
|
||||
|
||||
public CloseableDataSource getDataSource(DatabaseConnectionEntity dbConn) {
|
||||
String typeName = dbConn.getType().getName().toUpperCase();
|
||||
ProductTypeEnum supportDbType = ProductTypeEnum.valueOf(typeName);
|
||||
if (supportDbType.hasAddress()) {
|
||||
@@ -79,8 +83,16 @@ public class ConnectionService {
|
||||
}
|
||||
File driverVersionFile = driverLoadService.getVersionDriverFile(dbConn.getType(), dbConn.getVersion());
|
||||
String driverPath = driverVersionFile.getAbsolutePath();
|
||||
CloseableDataSource dataSource = DataSourceUtils.createCommonDataSource(dbConn.getUrl(), dbConn.getDriver(),
|
||||
return DataSourceUtils.createCommonDataSource(dbConn.getUrl(), dbConn.getDriver(),
|
||||
driverPath, dbConn.getUsername(), dbConn.getPassword());
|
||||
}
|
||||
|
||||
public MetadataService getMetaDataCoreService(Long id) {
|
||||
return getMetaDataCoreService(getDatabaseConnectionById(id));
|
||||
}
|
||||
|
||||
public MetadataService getMetaDataCoreService(DatabaseConnectionEntity dbConn) {
|
||||
CloseableDataSource dataSource = getDataSource(dbConn);
|
||||
MetadataService metaDataService = new DefaultMetadataService(dataSource);
|
||||
return metaDataService;
|
||||
}
|
||||
@@ -149,8 +161,7 @@ public class ConnectionService {
|
||||
}
|
||||
|
||||
public Result<List<String>> getSchemas(Long id) {
|
||||
DatabaseConnectionEntity dbConn = getDatabaseConnectionById(id);
|
||||
MetadataService metaDataService = getMetaDataCoreService(dbConn);
|
||||
MetadataService metaDataService = getMetaDataCoreService(id);
|
||||
try {
|
||||
List<String> schemas = metaDataService.querySchemaList();
|
||||
return Result.success(schemas);
|
||||
@@ -160,11 +171,10 @@ public class ConnectionService {
|
||||
}
|
||||
|
||||
public Result<List<String>> getSchemaTables(Long id, String schema) {
|
||||
DatabaseConnectionEntity dbConn = getDatabaseConnectionById(id);
|
||||
MetadataService metaDataService = getMetaDataCoreService(dbConn);
|
||||
MetadataService metaDataService = getMetaDataCoreService(id);
|
||||
try {
|
||||
List<String> tables = Optional.ofNullable(
|
||||
metaDataService.queryTableList(schema))
|
||||
metaDataService.queryTableList(schema))
|
||||
.orElseGet(ArrayList::new).stream()
|
||||
.filter(t -> !t.isViewTable())
|
||||
.map(t -> t.getTableName())
|
||||
@@ -176,11 +186,10 @@ public class ConnectionService {
|
||||
}
|
||||
|
||||
public Result<List<String>> getSchemaViews(Long id, String schema) {
|
||||
DatabaseConnectionEntity dbConn = getDatabaseConnectionById(id);
|
||||
MetadataService metaDataService = getMetaDataCoreService(dbConn);
|
||||
MetadataService metaDataService = getMetaDataCoreService(id);
|
||||
try {
|
||||
List<String> tables = Optional.ofNullable(
|
||||
metaDataService.queryTableList(schema))
|
||||
metaDataService.queryTableList(schema))
|
||||
.orElseGet(ArrayList::new).stream()
|
||||
.filter(t -> t.isViewTable())
|
||||
.map(t -> t.getTableName())
|
||||
|
@@ -3,25 +3,36 @@ package com.gitee.dbswitch.admin.service;
|
||||
import com.gitee.dbswitch.admin.common.response.PageResult;
|
||||
import com.gitee.dbswitch.admin.common.response.Result;
|
||||
import com.gitee.dbswitch.admin.entity.DatabaseConnectionEntity;
|
||||
import com.gitee.dbswitch.admin.model.request.OnlineSqlDataRequest;
|
||||
import com.gitee.dbswitch.admin.model.response.MetadataColumnDetailResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.MetadataSchemaDetailResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.MetadataTableDetailResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.MetadataTableInfoResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.OnlineSqlDataResponse;
|
||||
import com.gitee.dbswitch.admin.model.response.OnlineSqlDataResponse.ColumnItem;
|
||||
import com.gitee.dbswitch.admin.model.response.OnlineSqlDataResponse.SqlInput;
|
||||
import com.gitee.dbswitch.admin.model.response.OnlineSqlDataResponse.SqlResult;
|
||||
import com.gitee.dbswitch.admin.model.response.SchemaTableDataResponse;
|
||||
import com.gitee.dbswitch.admin.util.ExecuteSqlUtils;
|
||||
import com.gitee.dbswitch.admin.util.ExecuteSqlUtils.ScriptExecuteResult;
|
||||
import com.gitee.dbswitch.admin.util.PageUtils;
|
||||
import com.gitee.dbswitch.common.entity.CloseableDataSource;
|
||||
import com.gitee.dbswitch.schema.SchemaTableData;
|
||||
import com.gitee.dbswitch.schema.SchemaTableMeta;
|
||||
import com.gitee.dbswitch.schema.TableDescription;
|
||||
import com.gitee.dbswitch.service.MetadataService;
|
||||
import java.sql.Connection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.jdbc.datasource.init.ScriptUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@@ -46,8 +57,7 @@ public class MetaDataService {
|
||||
|
||||
public PageResult<MetadataTableInfoResponse> allTables(Long id, String schema, Integer page,
|
||||
Integer size) {
|
||||
DatabaseConnectionEntity dbConn = connectionService.getDatabaseConnectionById(id);
|
||||
MetadataService metaDataService = connectionService.getMetaDataCoreService(dbConn);
|
||||
MetadataService metaDataService = connectionService.getMetaDataCoreService(id);
|
||||
try {
|
||||
List<TableDescription> tables = metaDataService.queryTableList(schema);
|
||||
List<MetadataTableInfoResponse> responses = tables.stream()
|
||||
@@ -65,8 +75,7 @@ public class MetaDataService {
|
||||
}
|
||||
|
||||
public Result<MetadataTableDetailResponse> tableDetail(Long id, String schema, String table) {
|
||||
DatabaseConnectionEntity dbConn = connectionService.getDatabaseConnectionById(id);
|
||||
MetadataService metaDataService = connectionService.getMetaDataCoreService(dbConn);
|
||||
MetadataService metaDataService = connectionService.getMetaDataCoreService(id);
|
||||
try {
|
||||
SchemaTableMeta tableMeta = metaDataService.queryTableMeta(schema, table);
|
||||
List<String> pks = tableMeta.getPrimaryKeys();
|
||||
@@ -104,13 +113,11 @@ public class MetaDataService {
|
||||
}
|
||||
|
||||
public Result<SchemaTableDataResponse> tableData(Long id, String schema, String table) {
|
||||
DatabaseConnectionEntity dbConn = connectionService.getDatabaseConnectionById(id);
|
||||
MetadataService metaDataService = connectionService.getMetaDataCoreService(dbConn);
|
||||
MetadataService metaDataService = connectionService.getMetaDataCoreService(id);
|
||||
try {
|
||||
SchemaTableData data = metaDataService.queryTableData(schema, table, 10);
|
||||
// el-table问题:https://www.cnblogs.com/LanTianYou/p/9649735.html
|
||||
List<String> headers = data.getColumns().stream()
|
||||
.map(one -> one.replaceAll("\\.", "_"))
|
||||
.map(one -> specialReplace(one))
|
||||
.collect(Collectors.toList());
|
||||
return Result.success(SchemaTableDataResponse.builder()
|
||||
.schemaName(data.getSchemaName())
|
||||
@@ -124,6 +131,69 @@ public class MetaDataService {
|
||||
}
|
||||
}
|
||||
|
||||
public Result<OnlineSqlDataResponse> sqlData(Long id, OnlineSqlDataRequest request) {
|
||||
List<String> statements = new ArrayList<>();
|
||||
ScriptUtils.splitSqlScript(
|
||||
null,
|
||||
request.getScript(),
|
||||
ScriptUtils.DEFAULT_STATEMENT_SEPARATOR,
|
||||
ScriptUtils.DEFAULT_COMMENT_PREFIX,
|
||||
ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
||||
ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER,
|
||||
statements);
|
||||
Integer page = Optional.ofNullable(request.getPage()).orElse(1);
|
||||
Integer size = Optional.ofNullable(request.getSize()).orElse(100);
|
||||
try (CloseableDataSource dataSource = connectionService.getDataSource(id)) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
List<SqlInput> summaries = new ArrayList<>(statements.size());
|
||||
List<SqlResult> results = new ArrayList<>(statements.size());
|
||||
for (String sql : statements) {
|
||||
try {
|
||||
ScriptExecuteResult result = ExecuteSqlUtils.execute(connection, sql, page, size);
|
||||
summaries.add(SqlInput.builder().sql(sql).summary(result.getResultSummary()).build());
|
||||
results.add(
|
||||
SqlResult.builder()
|
||||
.columns(result.getResultHeader().stream()
|
||||
.map(one ->
|
||||
ColumnItem.builder()
|
||||
.columnName(specialReplace(one.getKey()))
|
||||
.columnType(one.getValue())
|
||||
.build()
|
||||
).collect(Collectors.toList()))
|
||||
.rows(result.getResultData())
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
summaries.add(
|
||||
SqlInput.builder()
|
||||
.sql(sql)
|
||||
.summary(e.getMessage())
|
||||
.build());
|
||||
results.add(
|
||||
SqlResult.builder()
|
||||
.columns(Collections.emptyList())
|
||||
.rows(Collections.emptyList())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
return Result.success(
|
||||
OnlineSqlDataResponse.builder()
|
||||
.summaries(summaries)
|
||||
.results(results)
|
||||
.build());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// el-table问题:https://www.cnblogs.com/LanTianYou/p/9649735.html
|
||||
private String specialReplace(String str) {
|
||||
if (null == str || str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
return str.replaceAll("\\.", "_");
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> convertRows(List<String> columns, List<List<Object>> rows) {
|
||||
if (null == rows || rows.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
|
@@ -3,7 +3,6 @@ package com.gitee.dbswitch.admin.service;
|
||||
import com.gitee.dbswitch.admin.common.exception.DbswitchException;
|
||||
import com.gitee.dbswitch.admin.common.response.Result;
|
||||
import com.gitee.dbswitch.admin.common.response.ResultCode;
|
||||
import com.gitee.dbswitch.admin.entity.DatabaseConnectionEntity;
|
||||
import com.gitee.dbswitch.admin.model.request.PreviewColumnNameMapperRequest;
|
||||
import com.gitee.dbswitch.admin.model.request.PreviewTableNameMapperRequest;
|
||||
import com.gitee.dbswitch.admin.model.response.PreviewNameMapperResponse;
|
||||
@@ -83,12 +82,7 @@ public class PatternMapperService {
|
||||
}
|
||||
|
||||
List<PreviewNameMapperResponse> result = new ArrayList<>();
|
||||
Long connectionId = request.getId();
|
||||
DatabaseConnectionEntity dbConn = connectionService.getDatabaseConnectionById(connectionId);
|
||||
if (null == dbConn) {
|
||||
throw new DbswitchException(ResultCode.ERROR_RESOURCE_NOT_EXISTS, "id=" + request.getId());
|
||||
}
|
||||
MetadataService service = connectionService.getMetaDataCoreService(dbConn);
|
||||
MetadataService service = connectionService.getMetaDataCoreService(request.getId());
|
||||
try {
|
||||
List<ColumnDescription> tables = service.queryTableColumnMeta(request.getSchemaName(),
|
||||
request.getTableName());
|
||||
@@ -120,14 +114,7 @@ public class PatternMapperService {
|
||||
if (null == request.getId() || StringUtils.isBlank(request.getSchemaName())) {
|
||||
throw new DbswitchException(ResultCode.ERROR_INVALID_ARGUMENT, "id or schemaName");
|
||||
}
|
||||
|
||||
Long connectionId = request.getId();
|
||||
DatabaseConnectionEntity dbConn = connectionService.getDatabaseConnectionById(connectionId);
|
||||
if (null == dbConn) {
|
||||
throw new DbswitchException(ResultCode.ERROR_RESOURCE_NOT_EXISTS, "id=" + request.getId());
|
||||
}
|
||||
|
||||
MetadataService service = connectionService.getMetaDataCoreService(dbConn);
|
||||
MetadataService service = connectionService.getMetaDataCoreService(request.getId());
|
||||
try {
|
||||
return service.queryTableList(request.getSchemaName()).stream().filter(td -> !td.isViewTable())
|
||||
.collect(Collectors.toList());
|
||||
|
@@ -0,0 +1,104 @@
|
||||
package com.gitee.dbswitch.admin.util;
|
||||
|
||||
import cn.hutool.core.date.StopWatch;
|
||||
import cn.hutool.core.lang.Pair;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@UtilityClass
|
||||
public final class ExecuteSqlUtils {
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class ScriptExecuteResult {
|
||||
|
||||
private boolean isSelect;
|
||||
private String sql;
|
||||
private String resultSummary;
|
||||
private List<Pair<String, String>> resultHeader;
|
||||
private List<Map<String, Object>> resultData;
|
||||
}
|
||||
|
||||
public static ScriptExecuteResult execute(Connection connection, String sql, int page, int size)
|
||||
throws SQLException {
|
||||
PreparedStatement statement = connection.prepareStatement(sql);
|
||||
statement.setQueryTimeout(300);
|
||||
statement.setFetchSize(isMySqlConnection(connection) ? Integer.MIN_VALUE : (size < 10) ? 100 : size);
|
||||
log.info("ExecuteSQL:{}\n{}", sql);
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
boolean b = statement.execute();
|
||||
stopWatch.stop();
|
||||
String seconds = String.format("%.6f s", stopWatch.getTotalTimeSeconds());
|
||||
if (b) {
|
||||
int skipNumber = size * (page - 1);
|
||||
try (ResultSet rs = statement.getResultSet()) {
|
||||
List<Pair<String, String>> columns = new ArrayList<>();
|
||||
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
|
||||
String columnName = rs.getMetaData().getColumnLabel(i);
|
||||
String columnTypeName = rs.getMetaData().getColumnTypeName(i);
|
||||
columns.add(Pair.of(columnName, columnTypeName));
|
||||
}
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
Map<String, Object> row = new LinkedHashMap<>();
|
||||
for (Pair<String, String> column : columns) {
|
||||
String columnName = column.getKey();
|
||||
Object columnValue = null;
|
||||
try {
|
||||
columnValue = rs.getObject(columnName);
|
||||
} catch (SQLException se) {
|
||||
log.warn("Failed to call jdbc ResultSet::getObject(): {}", se.getMessage(), se);
|
||||
}
|
||||
row.put(columnName, columnValue);
|
||||
}
|
||||
if (skipNumber <= 0) {
|
||||
list.add(row);
|
||||
if (list.size() >= size) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
skipNumber--;
|
||||
}
|
||||
}
|
||||
return ScriptExecuteResult.builder()
|
||||
.isSelect(true)
|
||||
.sql(sql)
|
||||
.resultSummary("Time: " + seconds)
|
||||
.resultHeader(columns)
|
||||
.resultData(list)
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
int updateCount = statement.getUpdateCount();
|
||||
return ScriptExecuteResult.builder()
|
||||
.isSelect(false)
|
||||
.sql(sql)
|
||||
.resultSummary("affected : " + updateCount + ", Time: " + seconds)
|
||||
.resultHeader(Collections.emptyList())
|
||||
.resultData(Collections.emptyList())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMySqlConnection(Connection connection) {
|
||||
try {
|
||||
String productName = connection.getMetaData().getDatabaseProductName();
|
||||
return productName.contains("MySQL") || productName.contains("MariaDB");
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>异构数据迁移工具</title><link href=/static/css/app.3d890810ce3c3f17fdc205b537abc619.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2fb37960f7959eb139b0.js></script><script type=text/javascript src=/static/js/vendor.b9bd12276a8d544208ad.js></script><script type=text/javascript src=/static/js/app.2d06c37438cd4d03dc6f.js></script></body></html>
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>异构数据迁移工具</title><link href=/static/css/app.01a417d6ceadacbc5f419b7ca49a3b8e.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.bf67a9f5837c2101612d.js></script><script type=text/javascript src=/static/js/vendor.804b029d66a1d9f36ac1.js></script><script type=text/javascript src=/static/js/app.510de779934f2bc79267.js></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
webpackJsonp([10],{"0eSS":function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var l={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var e=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/2/"+this.currentPage+"/"+this.pageSize).then(function(t){e.loading=!1,0===t.data.code?(e.currentPage=t.data.pagination.page,e.pageSize=t.data.pagination.size,e.totalCount=t.data.pagination.total,e.lists=t.data.data):alert("加载数据失败:"+t.data.message)},function(t){e.$message({showClose:!0,message:"数据加载错误",type:"error"})})},boolFormat:function(e,t){return!0===e.failed?"是":"否"},handleSizeChange:function(e){this.loading=!0,this.pageSize=e,this.loadData()},handleCurrentChange:function(e){this.loading=!0,this.currentPage=e,this.loadData()},handleDetail:function(e,t){this.$message({showClose:!0,message:"查看日志详情"+e+" "+t,type:"info"})}},created:function(){this.loadData()}},o={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:e.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{type:"expand"},scopedSlots:e._u([{key:"default",fn:function(t){return[a("el-form",{staticClass:"demo-table-expand",attrs:{"label-position":"left",inline:""}},[a("el-form-item",{attrs:{label:"日志编号:"}},[a("span",[e._v(e._s(t.row.id))])]),e._v(" "),a("el-form-item",{attrs:{label:"日志时间:"}},[a("span",[e._v(e._s(t.row.createTime))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作用户:"}},[a("span",[e._v(e._s(t.row.username))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求IP地址:"}},[a("span",[e._v(e._s(t.row.ipAddress))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作模块:"}},[a("span",[e._v(e._s(t.row.moduleName))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作描述:"}},[a("span",[e._v(e._s(t.row.content))])]),e._v(" "),a("el-form-item",{attrs:{label:"处理耗时(ms):"}},[a("span",[e._v(e._s(t.row.elapseSeconds))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求路径:"}},[a("span",[e._v(e._s(t.row.urlPath))])]),e._v(" "),a("el-form-item",{attrs:{label:"异常状态:"}},[a("span",[e._v(e._s(t.row.failed))])]),e._v(" "),a("el-form-item",{attrs:{label:""}},[a("span")]),e._v(" "),a("el-form-item",{attrs:{label:"异常日志:"}},[a("el-input",{staticStyle:{"font-size":"12px",width:"700px"},attrs:{type:"textarea",autosize:{minRows:2,maxRows:5}},model:{value:t.row.exception,callback:function(a){e.$set(t.row,"exception",a)},expression:"props.row.exception"}})],1)],1)]}}])}),e._v(" "),a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"username",label:"操作用户","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"moduleName",label:"操作类型","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"elapseSeconds",label:"耗时(ms)","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"urlPath",label:"请求路径","min-width":"20%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"failed",label:"异常",formatter:e.boolFormat,"min-width":"10%","show-overflow-tooltip":!0}})],1),e._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":e.currentPage,"page-sizes":[5,10,20,40],"page-size":e.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:e.totalCount},on:{"size-change":e.handleSizeChange,"current-change":e.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var n=a("VU/8")(l,o,!1,function(e){a("6FHX")},"data-v-aee4e92e",null);t.default=n.exports},"6FHX":function(e,t){}});
|
||||
//# sourceMappingURL=10.cbb9f8f0701ddf5b03fa.js.map
|
||||
webpackJsonp([11],{"0eSS":function(e,t,a){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var l={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var e=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/2/"+this.currentPage+"/"+this.pageSize).then(function(t){e.loading=!1,0===t.data.code?(e.currentPage=t.data.pagination.page,e.pageSize=t.data.pagination.size,e.totalCount=t.data.pagination.total,e.lists=t.data.data):alert("加载数据失败:"+t.data.message)},function(t){e.$message({showClose:!0,message:"数据加载错误",type:"error"})})},boolFormat:function(e,t){return!0===e.failed?"是":"否"},handleSizeChange:function(e){this.loading=!0,this.pageSize=e,this.loadData()},handleCurrentChange:function(e){this.loading=!0,this.currentPage=e,this.loadData()},handleDetail:function(e,t){this.$message({showClose:!0,message:"查看日志详情"+e+" "+t,type:"info"})}},created:function(){this.loadData()}},o={render:function(){var e=this,t=e.$createElement,a=e._self._c||t;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:e.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:e.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{type:"expand"},scopedSlots:e._u([{key:"default",fn:function(t){return[a("el-form",{staticClass:"demo-table-expand",attrs:{"label-position":"left",inline:""}},[a("el-form-item",{attrs:{label:"日志编号:"}},[a("span",[e._v(e._s(t.row.id))])]),e._v(" "),a("el-form-item",{attrs:{label:"日志时间:"}},[a("span",[e._v(e._s(t.row.createTime))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作用户:"}},[a("span",[e._v(e._s(t.row.username))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求IP地址:"}},[a("span",[e._v(e._s(t.row.ipAddress))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作模块:"}},[a("span",[e._v(e._s(t.row.moduleName))])]),e._v(" "),a("el-form-item",{attrs:{label:"操作描述:"}},[a("span",[e._v(e._s(t.row.content))])]),e._v(" "),a("el-form-item",{attrs:{label:"处理耗时(ms):"}},[a("span",[e._v(e._s(t.row.elapseSeconds))])]),e._v(" "),a("el-form-item",{attrs:{label:"请求路径:"}},[a("span",[e._v(e._s(t.row.urlPath))])]),e._v(" "),a("el-form-item",{attrs:{label:"异常状态:"}},[a("span",[e._v(e._s(t.row.failed))])]),e._v(" "),a("el-form-item",{attrs:{label:""}},[a("span")]),e._v(" "),a("el-form-item",{attrs:{label:"异常日志:"}},[a("el-input",{staticStyle:{"font-size":"12px",width:"700px"},attrs:{type:"textarea",autosize:{minRows:2,maxRows:5}},model:{value:t.row.exception,callback:function(a){e.$set(t.row,"exception",a)},expression:"props.row.exception"}})],1)],1)]}}])}),e._v(" "),a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"username",label:"操作用户","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"moduleName",label:"操作类型","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"elapseSeconds",label:"耗时(ms)","min-width":"10%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"urlPath",label:"请求路径","min-width":"20%","show-overflow-tooltip":!0}}),e._v(" "),a("el-table-column",{attrs:{prop:"failed",label:"异常",formatter:e.boolFormat,"min-width":"10%","show-overflow-tooltip":!0}})],1),e._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":e.currentPage,"page-sizes":[5,10,20,40],"page-size":e.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:e.totalCount},on:{"size-change":e.handleSizeChange,"current-change":e.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var n=a("VU/8")(l,o,!1,function(e){a("6FHX")},"data-v-aee4e92e",null);t.default=n.exports},"6FHX":function(e,t){}});
|
||||
//# sourceMappingURL=11.9ea92898e3919b2a671f.js.map
|
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
webpackJsonp([11],{WfA7:function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a={data:function(){return{dialogVisible:!1,loading:!0,connectionTypes:[],versionDrivers:[],isActive:-1}},methods:{loadConnectionTypes:function(){var t=this;this.$http({method:"GET",url:"/dbswitch/admin/api/v1/connection/types"}).then(function(e){0===e.data.code?(t.connectionTypes=e.data.data,t.handleChooseClick("MYSQL",0)):e.data.message&&alert("初始化数据库类型信息失败:"+e.data.message)})},handleChooseClick:function(t,e){var i=this;this.isActive=e,this.$http.get("/dbswitch/admin/api/v1/connection/"+t+"/drivers").then(function(t){0===t.data.code?i.versionDrivers=t.data.data:t.data.message&&alert("查询驱动版本信息失败,"+t.data.message)})},handleClose:function(t){this.$confirm("确认关闭?").then(function(e){t()}).catch(function(t){})},formatJarFileList:function(t,e){return t[e.property].join(";\n")}},created:function(){this.loadConnectionTypes()},beforeDestroy:function(){}},n={render:function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",[i("el-card",[i("div",{staticClass:"container"},[i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header",align:"center"},slot:"header"},[i("span",[i("b",[t._v("数据库产品类型列表")])])]),t._v(" "),i("div",{staticClass:"navsBox"},[i("ul",t._l(t.connectionTypes,function(e,a){return i("li",{key:a,class:{active:a==t.isActive},on:{click:function(i){return t.handleChooseClick(e.type,a)}}},[t._v("["+t._s(e.id)+"] "+t._s(e.type))])}),0)])]),t._v(" "),i("div",{staticClass:"contentBox"},[i("div",{staticStyle:{margin:"10px 5px"},attrs:{align:"right",width:"95%"}},[i("el-button",{attrs:{type:"primary",size:"mini",icon:"el-icon-document-add"},on:{click:function(e){t.dialogVisible=!0}}},[t._v("添加")])],1),t._v(" "),i("el-table",{attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},data:t.versionDrivers,size:"small",stripe:"",border:""}},[i("template",{slot:"empty"},[i("span",[t._v("单击左侧数据库类型来查看对应的驱动版本信息")])]),t._v(" "),i("el-table-column",{attrs:{property:"driverVersion",label:"驱动版本号","min-width":"15%"}}),t._v(" "),i("el-table-column",{attrs:{property:"driverClass",label:"驱动类名","min-width":"20%"}}),t._v(" "),i("el-table-column",{attrs:{property:"jarFiles",formatter:t.formatJarFileList,label:"驱动JAR名称","min-width":"30%"}}),t._v(" "),i("el-table-column",{attrs:{property:"driverPath",label:"驱动版本路径","min-width":"50%"}})],2)],1)],1)]),t._v(" "),i("el-dialog",{attrs:{title:"添加数据库驱动JAR说明",visible:t.dialogVisible,width:"40%","before-close":t.handleClose},on:{"update:visible":function(e){t.dialogVisible=e}}},[i("span",[t._v("请按照驱动路径所在的目录${DBSWITCH_HOME}/drivers下,在数据库类型为名称的目录下,以驱动版本号为名称创建目录并放置对应的驱动jar文件,然后重启即可生效。具体可参考https://gitee.com/inrgihc/dbswitch/tree/master/drivers下的目录结构。")]),t._v(" "),i("span"),t._v(" "),i("span",[t._v("特殊说明:驱动版本目录下的所有JAR必须无任何外部依赖,否则,也需将其依赖JAR一起放置到对应的目录下。")]),t._v(" "),i("span",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[i("el-button",{on:{click:function(e){t.dialogVisible=!1}}},[t._v("取 消")]),t._v(" "),i("el-button",{attrs:{type:"primary"},on:{click:function(e){t.dialogVisible=!1}}},[t._v("确 定")])],1)])],1)},staticRenderFns:[]};var s=i("VU/8")(a,n,!1,function(t){i("ru48")},"data-v-8a3240f4",null);e.default=s.exports},ru48:function(t,e){}});
|
||||
//# sourceMappingURL=11.6ced88118ea38e1f3c61.js.map
|
||||
webpackJsonp([12],{WfA7:function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a={data:function(){return{dialogVisible:!1,loading:!0,connectionTypes:[],versionDrivers:[],isActive:-1}},methods:{loadConnectionTypes:function(){var t=this;this.$http({method:"GET",url:"/dbswitch/admin/api/v1/connection/types"}).then(function(e){0===e.data.code?(t.connectionTypes=e.data.data,t.handleChooseClick("MYSQL",0)):e.data.message&&alert("初始化数据库类型信息失败:"+e.data.message)})},handleChooseClick:function(t,e){var i=this;this.isActive=e,this.$http.get("/dbswitch/admin/api/v1/connection/"+t+"/drivers").then(function(t){0===t.data.code?i.versionDrivers=t.data.data:t.data.message&&alert("查询驱动版本信息失败,"+t.data.message)})},handleClose:function(t){this.$confirm("确认关闭?").then(function(e){t()}).catch(function(t){})},formatJarFileList:function(t,e){return t[e.property].join(";\n")}},created:function(){this.loadConnectionTypes()},beforeDestroy:function(){}},n={render:function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",[i("el-card",[i("div",{staticClass:"container"},[i("el-card",{staticClass:"box-card"},[i("div",{staticClass:"clearfix",attrs:{slot:"header",align:"center"},slot:"header"},[i("span",[i("b",[t._v("数据库产品类型列表")])])]),t._v(" "),i("div",{staticClass:"navsBox"},[i("ul",t._l(t.connectionTypes,function(e,a){return i("li",{key:a,class:{active:a==t.isActive},on:{click:function(i){return t.handleChooseClick(e.type,a)}}},[t._v("["+t._s(e.id)+"] "+t._s(e.type))])}),0)])]),t._v(" "),i("div",{staticClass:"contentBox"},[i("div",{staticStyle:{margin:"10px 5px"},attrs:{align:"right",width:"95%"}},[i("el-button",{attrs:{type:"primary",size:"mini",icon:"el-icon-document-add"},on:{click:function(e){t.dialogVisible=!0}}},[t._v("添加")])],1),t._v(" "),i("el-table",{attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},data:t.versionDrivers,size:"small",stripe:"",border:""}},[i("template",{slot:"empty"},[i("span",[t._v("单击左侧数据库类型来查看对应的驱动版本信息")])]),t._v(" "),i("el-table-column",{attrs:{property:"driverVersion",label:"驱动版本号","min-width":"15%"}}),t._v(" "),i("el-table-column",{attrs:{property:"driverClass",label:"驱动类名","min-width":"20%"}}),t._v(" "),i("el-table-column",{attrs:{property:"jarFiles",formatter:t.formatJarFileList,label:"驱动JAR名称","min-width":"30%"}}),t._v(" "),i("el-table-column",{attrs:{property:"driverPath",label:"驱动版本路径","min-width":"50%"}})],2)],1)],1)]),t._v(" "),i("el-dialog",{attrs:{title:"添加数据库驱动JAR说明",visible:t.dialogVisible,width:"40%","before-close":t.handleClose},on:{"update:visible":function(e){t.dialogVisible=e}}},[i("span",[t._v("请按照驱动路径所在的目录${DBSWITCH_HOME}/drivers下,在数据库类型为名称的目录下,以驱动版本号为名称创建目录并放置对应的驱动jar文件,然后重启即可生效。具体可参考https://gitee.com/inrgihc/dbswitch/tree/master/drivers下的目录结构。")]),t._v(" "),i("span"),t._v(" "),i("span",[t._v("特殊说明:驱动版本目录下的所有JAR必须无任何外部依赖,否则,也需将其依赖JAR一起放置到对应的目录下。")]),t._v(" "),i("span",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[i("el-button",{on:{click:function(e){t.dialogVisible=!1}}},[t._v("取 消")]),t._v(" "),i("el-button",{attrs:{type:"primary"},on:{click:function(e){t.dialogVisible=!1}}},[t._v("确 定")])],1)])],1)},staticRenderFns:[]};var s=i("VU/8")(a,n,!1,function(t){i("ru48")},"data-v-8a3240f4",null);e.default=s.exports},ru48:function(t,e){}});
|
||||
//# sourceMappingURL=12.9f1bc065d4fb5d823725.js.map
|
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
webpackJsonp([12],{"2PhG":function(t,e){},oQRv:function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var t=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/1/"+this.currentPage+"/"+this.pageSize).then(function(e){t.loading=!1,0===e.data.code?(t.currentPage=e.data.pagination.page,t.pageSize=e.data.pagination.size,t.totalCount=e.data.pagination.total,t.lists=e.data.data):alert("加载数据失败:"+e.data.message)},function(e){t.$message({showClose:!0,message:"数据加载错误",type:"error"})})},handleSizeChange:function(t){this.loading=!0,this.pageSize=t,this.loadData()},handleCurrentChange:function(t){this.loading=!0,this.currentPage=t,this.loadData()}},created:function(){this.loadData()}},i={render:function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:t.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:t.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"content",label:"操作内容","min-width":"20%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"userAgent",label:"请求代理","min-width":"50%","show-overflow-tooltip":!0}})],1),t._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":t.currentPage,"page-sizes":[5,10,20,40],"page-size":t.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:t.totalCount},on:{"size-change":t.handleSizeChange,"current-change":t.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var o=a("VU/8")(n,i,!1,function(t){a("2PhG")},"data-v-86686ab2",null);e.default=o.exports}});
|
||||
//# sourceMappingURL=12.269df902c9e09c7f1624.js.map
|
||||
webpackJsonp([13],{"2PhG":function(t,e){},oQRv:function(t,e,a){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n={data:function(){return{loading:!0,lists:[],currentPage:1,pageSize:10,totalCount:0}},methods:{loadData:function(){var t=this;this.$http.get("/dbswitch/admin/api/v1/syslog/list/1/"+this.currentPage+"/"+this.pageSize).then(function(e){t.loading=!1,0===e.data.code?(t.currentPage=e.data.pagination.page,t.pageSize=e.data.pagination.size,t.totalCount=e.data.pagination.total,t.lists=e.data.data):alert("加载数据失败:"+e.data.message)},function(e){t.$message({showClose:!0,message:"数据加载错误",type:"error"})})},handleSizeChange:function(t){this.loading=!0,this.pageSize=t,this.loadData()},handleCurrentChange:function(t){this.loading=!0,this.currentPage=t,this.loadData()}},created:function(){this.loadData()}},i={render:function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticStyle:{"margin-top":"15px"}},[a("el-table",{directives:[{name:"loading",rawName:"v-loading",value:t.loading,expression:"loading"}],staticStyle:{width:"100%"},attrs:{"header-cell-style":{background:"#eef1f6",color:"#606266"},"element-loading-text":"拼命加载中","element-loading-spinner":"el-icon-loading","element-loading-background":"rgba(0, 0, 0, 0.8)",data:t.lists,stripe:"",size:"small",border:""}},[a("el-table-column",{attrs:{prop:"createTime",label:"日志时间","min-width":"15%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"ipAddress",label:"请求IP","min-width":"10%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"content",label:"操作内容","min-width":"20%","show-overflow-tooltip":!0}}),t._v(" "),a("el-table-column",{attrs:{prop:"userAgent",label:"请求代理","min-width":"50%","show-overflow-tooltip":!0}})],1),t._v(" "),a("div",{staticClass:"page",attrs:{align:"right"}},[a("el-pagination",{attrs:{"current-page":t.currentPage,"page-sizes":[5,10,20,40],"page-size":t.pageSize,layout:"total, sizes, prev, pager, next, jumper",total:t.totalCount},on:{"size-change":t.handleSizeChange,"current-change":t.handleCurrentChange}})],1)],1)},staticRenderFns:[]};var o=a("VU/8")(n,i,!1,function(t){a("2PhG")},"data-v-86686ab2",null);e.default=o.exports}});
|
||||
//# sourceMappingURL=13.522b8e9b509523953170.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
webpackJsonp([24],{NHnr:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=t("//Fk"),i=t.n(o),c=t("7+uW"),a={render:function(){var n=this.$createElement,e=this._self._c||n;return e("div",{staticClass:"body-wrapper"},[e("router-view")],1)},staticRenderFns:[]};var r=t("VU/8")({name:"App"},a,!1,function(n){t("O8ez")},"data-v-a97617c2",null).exports,u=t("/ocq");c.default.use(u.a);var l=new u.a({routes:[{path:"/",name:"首页",component:function(){return t.e(5).then(t.bind(null,"4er+"))},redirect:"/dashboard",children:[{path:"/dashboard",name:"系统概览",icon:"el-icon-menu",component:function(){return Promise.all([t.e(0),t.e(9)]).then(t.bind(null,"ARoL"))}},{path:"/connection",name:"连接管理",icon:"el-icon-s-order",component:function(){return t.e(8).then(t.bind(null,"Hoc+"))},children:[{path:"/connection/list",name:"数据源",icon:"el-icon-bank-card",component:function(){return Promise.all([t.e(0),t.e(16)]).then(t.bind(null,"qdtB"))}},{path:"/connection/driver",name:"驱动配置",icon:"el-icon-help",component:function(){return t.e(11).then(t.bind(null,"WfA7"))}}]},{path:"/metadata",name:"数据导航",icon:"el-icon-coin",component:function(){return t.e(1).then(t.bind(null,"PJ2q"))}},{path:"/task",name:"数据接入",icon:"el-icon-s-tools",component:function(){return t.e(6).then(t.bind(null,"4KEO"))},children:[{path:"/task/assignment",name:"任务管理",icon:"el-icon-eleme",component:function(){return Promise.all([t.e(0),t.e(21)]).then(t.bind(null,"D0I9"))}},{path:"/task/schedule",name:"监控调度",icon:"el-icon-pie-chart",component:function(){return Promise.all([t.e(0),t.e(14)]).then(t.bind(null,"mKp/"))}}]},{path:"/log",name:"审计日志",icon:"el-icon-platform-eleme",component:function(){return t.e(7).then(t.bind(null,"QWih"))},children:[{path:"/log/access",name:"登录日志",icon:"el-icon-place",component:function(){return t.e(12).then(t.bind(null,"oQRv"))}},{path:"/log/action",name:"操作日志",icon:"el-icon-s-check",component:function(){return t.e(10).then(t.bind(null,"0eSS"))}}]},{path:"/about",name:"关于系统",icon:"el-icon-s-custom",component:function(){return t.e(4).then(t.bind(null,"m25N"))}},{path:"/user/personal",name:"个人中心",hidden:!0,component:function(){return t.e(2).then(t.bind(null,"uTKz"))}},{path:"/task/create",name:"创建任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(13)]).then(t.bind(null,"/rCC"))}},{path:"/task/update",name:"修改任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(15)]).then(t.bind(null,"txod"))}},{path:"/task/detail",name:"查看任务",hidden:!0,component:function(){return t.e(19).then(t.bind(null,"nrt7"))}},{path:"/connection/list/addDataSource1",name:"接入数据源",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(22)]).then(t.bind(null,"Vr+S"))}},{path:"/connection/list/addDataSource2",name:"接入数据源",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(20)]).then(t.bind(null,"7aEP"))}},{path:"/connection/list/dataSourceInfo",name:"数据源详情",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(17)]).then(t.bind(null,"+HtE"))}},{path:"/connection/list/updateDataSource",name:"编辑数据源",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(18)]).then(t.bind(null,"QTjM"))}}]},{path:"/login",name:"登录",component:function(){return t.e(3).then(t.bind(null,"T+/8"))}}]}),d=t("mtWM"),p=t.n(d).a.create();p.interceptors.request.use(function(n){return n.url=""+n.url,n});var m=p,s=t("zL8q"),h=t.n(s),f=(t("muQq"),t("tvR6"),t("7Vno")),b=t.n(f),v=t("XLwt"),P=t.n(v);c.default.use(m),c.default.use(h.a),c.default.use(b.a),c.default.prototype.$http=m,c.default.config.productionTip=!1,c.default.prototype.$echarts=P.a,m.interceptors.request.use(function(n){var e=sessionStorage.getItem("token");return e&&(n.headers.Authorization="Bearer "+e),n},function(n){return i.a.reject(n)}),m.interceptors.response.use(function(n){return!n.data||401!==n.data.code&&403!==n.data.code&&404!==n.data.code||l.push({path:"/login"}),n},function(n){return console.log(n),i.a.reject(n.response)}),new c.default({el:"#app",router:l,components:{App:r},template:"<App/>"})},O8ez:function(n,e){},muQq:function(n,e){},tvR6:function(n,e){}},["NHnr"]);
|
||||
//# sourceMappingURL=app.2d06c37438cd4d03dc6f.js.map
|
||||
webpackJsonp([24],{NHnr:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=t("//Fk"),i=t.n(o),c=t("7+uW"),a={render:function(){var n=this.$createElement,e=this._self._c||n;return e("div",{staticClass:"body-wrapper"},[e("router-view")],1)},staticRenderFns:[]};var r=t("VU/8")({name:"App"},a,!1,function(n){t("O8ez")},"data-v-a97617c2",null).exports,u=t("/ocq");c.default.use(u.a);var l=new u.a({routes:[{path:"/",name:"首页",component:function(){return t.e(5).then(t.bind(null,"4er+"))},redirect:"/dashboard",children:[{path:"/dashboard",name:"系统概览",icon:"el-icon-menu",component:function(){return Promise.all([t.e(0),t.e(9)]).then(t.bind(null,"ARoL"))}},{path:"/connection",name:"连接管理",icon:"el-icon-s-order",component:function(){return t.e(8).then(t.bind(null,"Hoc+"))},children:[{path:"/connection/list",name:"数据源",icon:"el-icon-bank-card",component:function(){return Promise.all([t.e(0),t.e(16)]).then(t.bind(null,"qdtB"))}},{path:"/connection/driver",name:"驱动配置",icon:"el-icon-help",component:function(){return t.e(12).then(t.bind(null,"WfA7"))}}]},{path:"/metadata",name:"数据导航",icon:"el-icon-coin",component:function(){return t.e(1).then(t.bind(null,"PJ2q"))}},{path:"/task",name:"数据接入",icon:"el-icon-s-tools",component:function(){return t.e(6).then(t.bind(null,"4KEO"))},children:[{path:"/task/assignment",name:"任务管理",icon:"el-icon-eleme",component:function(){return Promise.all([t.e(0),t.e(21)]).then(t.bind(null,"D0I9"))}},{path:"/task/schedule",name:"监控调度",icon:"el-icon-pie-chart",component:function(){return Promise.all([t.e(0),t.e(10)]).then(t.bind(null,"mKp/"))}}]},{path:"/log",name:"审计日志",icon:"el-icon-platform-eleme",component:function(){return t.e(7).then(t.bind(null,"QWih"))},children:[{path:"/log/access",name:"登录日志",icon:"el-icon-place",component:function(){return t.e(13).then(t.bind(null,"oQRv"))}},{path:"/log/action",name:"操作日志",icon:"el-icon-s-check",component:function(){return t.e(11).then(t.bind(null,"0eSS"))}}]},{path:"/about",name:"关于系统",icon:"el-icon-s-custom",component:function(){return t.e(4).then(t.bind(null,"m25N"))}},{path:"/user/personal",name:"个人中心",hidden:!0,component:function(){return t.e(2).then(t.bind(null,"uTKz"))}},{path:"/task/create",name:"创建任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(14)]).then(t.bind(null,"/rCC"))}},{path:"/task/update",name:"修改任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(15)]).then(t.bind(null,"txod"))}},{path:"/task/detail",name:"查看任务",hidden:!0,component:function(){return t.e(19).then(t.bind(null,"nrt7"))}},{path:"/connection/list/addDataSource1",name:"接入数据源",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(22)]).then(t.bind(null,"Vr+S"))}},{path:"/connection/list/addDataSource2",name:"接入数据源",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(20)]).then(t.bind(null,"7aEP"))}},{path:"/connection/list/dataSourceInfo",name:"数据源详情",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(17)]).then(t.bind(null,"+HtE"))}},{path:"/connection/list/updateDataSource",name:"编辑数据源",icon:"el-icon-menu",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(18)]).then(t.bind(null,"QTjM"))}}]},{path:"/login",name:"登录",component:function(){return t.e(3).then(t.bind(null,"T+/8"))}}]}),d=t("mtWM"),p=t.n(d).a.create();p.interceptors.request.use(function(n){return n.url=""+n.url,n});var m=p,s=t("zL8q"),h=t.n(s),f=(t("muQq"),t("tvR6"),t("7Vno")),b=t.n(f),v=t("XLwt"),P=t.n(v);c.default.use(m),c.default.use(h.a),c.default.use(b.a),c.default.prototype.$http=m,c.default.config.productionTip=!1,c.default.prototype.$echarts=P.a,m.interceptors.request.use(function(n){var e=sessionStorage.getItem("token");return e&&(n.headers.Authorization="Bearer "+e),n},function(n){return i.a.reject(n)}),m.interceptors.response.use(function(n){return!n.data||401!==n.data.code&&403!==n.data.code&&404!==n.data.code||l.push({path:"/login"}),n},function(n){return console.log(n),i.a.reject(n.response)}),new c.default({el:"#app",router:l,components:{App:r},template:"<App/>"})},O8ez:function(n,e){},muQq:function(n,e){},tvR6:function(n,e){}},["NHnr"]);
|
||||
//# sourceMappingURL=app.510de779934f2bc79267.js.map
|
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,a,o){for(var f,d,b,i=0,u=[];i<r.length;i++)d=r[i],t[d]&&u.push(t[d][0]),t[d]=0;for(f in a)Object.prototype.hasOwnProperty.call(a,f)&&(e[f]=a[f]);for(n&&n(r,a,o);u.length;)u.shift()();if(o)for(i=0;i<o.length;i++)b=c(c.s=o[i]);return b};var r={},t={25:0};function c(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,c),t.l=!0,t.exports}c.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,c){n=t[e]=[r,c]});n[2]=r;var a=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.timeout=12e4,c.nc&&o.setAttribute("nonce",c.nc),o.src=c.p+"static/js/"+e+"."+{0:"1fb1af5aa27eaf2b8ade",1:"7141c29414ee793b7048",2:"5d102c48d5747fb106e0",3:"79ef72d8ee0d78957693",4:"c08b2c8b16b2d0d50f62",5:"de32c8bd9fcd7cba61b2",6:"d7f3aa182a9403e7c6f6",7:"2c3ef6028bafee6fbaca",8:"535ff4d6dbb1131433ea",9:"4590fe5acd44e077ba19",10:"cbb9f8f0701ddf5b03fa",11:"6ced88118ea38e1f3c61",12:"269df902c9e09c7f1624",13:"e882fd7fb85cc62fe038",14:"2d117d01900191600329",15:"fefb5f8ed908101124ea",16:"4685d9de4b41bb601703",17:"3d6c2ceca6cfacb5839e",18:"50d7d00bb23d9bdc4fce",19:"56c4e47b2b21dcdd31c1",20:"d09d39413af7b0a23b59",21:"6634e9a79f246174acb5",22:"b623f8b56b9a9aa1c02b"}[e]+".js";var f=setTimeout(d,12e4);function d(){o.onerror=o.onload=null,clearTimeout(f);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return o.onerror=o.onload=d,a.appendChild(o),r},c.m=e,c.c=r,c.d=function(e,n,r){c.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},c.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(n,"a",n),n},c.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},c.p="/",c.oe=function(e){throw console.error(e),e}}([]);
|
||||
//# sourceMappingURL=manifest.2fb37960f7959eb139b0.js.map
|
||||
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,a,o){for(var f,d,b,i=0,u=[];i<r.length;i++)d=r[i],t[d]&&u.push(t[d][0]),t[d]=0;for(f in a)Object.prototype.hasOwnProperty.call(a,f)&&(e[f]=a[f]);for(n&&n(r,a,o);u.length;)u.shift()();if(o)for(i=0;i<o.length;i++)b=c(c.s=o[i]);return b};var r={},t={25:0};function c(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,c),t.l=!0,t.exports}c.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,c){n=t[e]=[r,c]});n[2]=r;var a=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.timeout=12e4,c.nc&&o.setAttribute("nonce",c.nc),o.src=c.p+"static/js/"+e+"."+{0:"3b7f8081fc55ac124770",1:"4d0d71cf223fb51aef41",2:"5d102c48d5747fb106e0",3:"ef5e983cf9ad9dc27899",4:"c08b2c8b16b2d0d50f62",5:"de32c8bd9fcd7cba61b2",6:"d7f3aa182a9403e7c6f6",7:"2c3ef6028bafee6fbaca",8:"535ff4d6dbb1131433ea",9:"4590fe5acd44e077ba19",10:"1d1a99a89d92bca35121",11:"9ea92898e3919b2a671f",12:"9f1bc065d4fb5d823725",13:"522b8e9b509523953170",14:"738015ac6e8a94eade30",15:"fefb5f8ed908101124ea",16:"4685d9de4b41bb601703",17:"3d6c2ceca6cfacb5839e",18:"50d7d00bb23d9bdc4fce",19:"56c4e47b2b21dcdd31c1",20:"d09d39413af7b0a23b59",21:"f9fd831656eab671bdc4",22:"b623f8b56b9a9aa1c02b"}[e]+".js";var f=setTimeout(d,12e4);function d(){o.onerror=o.onload=null,clearTimeout(f);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return o.onerror=o.onload=d,a.appendChild(o),r},c.m=e,c.c=r,c.d=function(e,n,r){c.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},c.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(n,"a",n),n},c.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},c.p="/",c.oe=function(e){throw console.error(e),e}}([]);
|
||||
//# sourceMappingURL=manifest.bf67a9f5837c2101612d.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -23,16 +23,6 @@ import org.apache.commons.lang3.StringUtils;
|
||||
@AllArgsConstructor
|
||||
public enum ProductTypeEnum {
|
||||
|
||||
/**
|
||||
* StarRocks数据库类型
|
||||
*/
|
||||
STARROCKS(19, "`", "StarRocks", "com.mysql.cj.jdbc.Driver", 9030,
|
||||
"/* ping */ SELECT 1",
|
||||
"jdbc:mysql://",
|
||||
new String[]{"jdbc:mysql://{host}[:{port}]/[{database}][\\?{params}]"},
|
||||
"jdbc:mysql://127.0.0.1:9030/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&tinyInt1isBit=false&rewriteBatchedStatements=true&useCompression=true"),
|
||||
|
||||
|
||||
/**
|
||||
* MySQL数据库类型
|
||||
*/
|
||||
@@ -196,6 +186,16 @@ public enum ProductTypeEnum {
|
||||
"jdbc:jest://",
|
||||
new String[]{"jdbc:jest://{host}[:{port}][\\?{params}]"},
|
||||
"jdbc:jest://172.17.2.12:9200?useHttps=false"),
|
||||
|
||||
/**
|
||||
* StarRocks数据库类型
|
||||
*/
|
||||
STARROCKS(19, "`", "StarRocks", "com.mysql.cj.jdbc.Driver", 9030,
|
||||
"/* ping */ SELECT 1",
|
||||
"jdbc:mysql://",
|
||||
new String[]{"jdbc:mysql://{host}[:{port}]/[{database}][\\?{params}]"},
|
||||
"jdbc:mysql://127.0.0.1:9030/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&tinyInt1isBit=false&rewriteBatchedStatements=true&useCompression=true"),
|
||||
|
||||
;
|
||||
|
||||
private int id;
|
||||
@@ -256,6 +256,7 @@ public enum ProductTypeEnum {
|
||||
public boolean isLikeStarRocks() {
|
||||
return this == STARROCKS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 类似于MySQL系列的数据库类型
|
||||
*
|
||||
|
@@ -9,7 +9,6 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
package com.gitee.dbswitch.common.util;
|
||||
|
||||
import cn.hutool.log.StaticLog;
|
||||
import com.gitee.dbswitch.common.type.ProductTypeEnum;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -19,12 +18,14 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 数据库类型识别工具类
|
||||
*
|
||||
* @author tang
|
||||
*/
|
||||
@Slf4j
|
||||
@UtilityClass
|
||||
public final class DatabaseAwareUtils {
|
||||
|
||||
@@ -41,7 +42,6 @@ public final class DatabaseAwareUtils {
|
||||
productNameMap.put("KingbaseES", ProductTypeEnum.KINGBASE);
|
||||
productNameMap.put("Apache Hive", ProductTypeEnum.HIVE);
|
||||
productNameMap.put("MySQL", ProductTypeEnum.MYSQL);
|
||||
// productNameMap.put("StarRocks", ProductTypeEnum.STARROCKS);
|
||||
productNameMap.put("MariaDB", ProductTypeEnum.MARIADB);
|
||||
productNameMap.put("Oracle", ProductTypeEnum.ORACLE);
|
||||
productNameMap.put("PostgreSQL", ProductTypeEnum.POSTGRESQL);
|
||||
@@ -93,11 +93,11 @@ public final class DatabaseAwareUtils {
|
||||
return productType;
|
||||
}
|
||||
boolean haveStarRocks = false;
|
||||
try{
|
||||
// 此查询语句是Starrocks查询be节点是否存活,可以用来判断是否是Starrocks数据源
|
||||
haveStarRocks = connection.createStatement().execute("show backends");
|
||||
}catch (SQLException sqlException){
|
||||
StaticLog.info("执行show backends失败,代表不是MySQL数据源");
|
||||
try {
|
||||
// 此查询语句是Starrocks查询be节点是否存活,可以用来判断是否是Starrocks数据源
|
||||
haveStarRocks = connection.createStatement().execute("show backends");
|
||||
} catch (Exception sqlException) {
|
||||
log.info("Failed to execute sql :show backends, so guesses it is mysql datasource!");
|
||||
}
|
||||
if (haveStarRocks) {
|
||||
return ProductTypeEnum.STARROCKS;
|
||||
|
@@ -12,11 +12,6 @@
|
||||
<artifactId>dbswitch-register-product</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.dbswitch</groupId>
|
||||
<artifactId>dbswitch-product-starrocks</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.dbswitch</groupId>
|
||||
<artifactId>dbswitch-product-mysql</artifactId>
|
||||
@@ -108,6 +103,11 @@
|
||||
<artifactId>dbswitch-product-elasticsearch</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.dbswitch</groupId>
|
||||
<artifactId>dbswitch-product-starrocks</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@@ -13,7 +13,6 @@
|
||||
|
||||
<modules>
|
||||
<module>dbswitch-product-mysql</module>
|
||||
<module>dbswitch-product-starrocks</module>
|
||||
<module>dbswitch-product-oracle</module>
|
||||
<module>dbswitch-product-postgresql</module>
|
||||
<module>dbswitch-product-sqlserver</module>
|
||||
@@ -32,6 +31,7 @@
|
||||
<module>dbswitch-product-clickhouse</module>
|
||||
<module>dbswitch-product-elasticsearch</module>
|
||||
<module>dbswitch-product-highgo</module>
|
||||
<module>dbswitch-product-starrocks</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
Reference in New Issue
Block a user