Skip to content

Commit

Permalink
refactor(metadata): refactoring the way to obtain the tables
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Jan 8, 2025
1 parent 45e5863 commit 651dda3
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ public MetadataController(MetadataService service)
this.service = service;
}

@PostMapping(value = "database/{code}")
public CommonResponse<Response> fetchByDatabase(@PathVariable String code)
@PostMapping(value = "databases/{code}")
public CommonResponse<Response> fetchDatabases(@PathVariable String code)
{
return this.service.getDatabaseSchema(code);
return this.service.getDatabases(code);
}

@PostMapping(value = "{code}/tables/{database}")
public CommonResponse<Response> fetchTables(@PathVariable String code, @PathVariable String database)
{
return this.service.getTables(code, database);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@

public interface MetadataService
{
CommonResponse<Response> getDatabaseSchema(String code);
CommonResponse<Response> getDatabases(String code);

CommonResponse<Response> getTables(String code, String database);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public MetadataServiceImpl(PluginManager pluginManager, SourceRepository reposit
}

@Override
public CommonResponse<Response> getDatabaseSchema(String code)
public CommonResponse<Response> getDatabases(String code)
{
return repository.findByCode(code)
.map(entity -> pluginManager.getPlugin(entity.getType())
Expand All @@ -37,4 +37,17 @@ public CommonResponse<Response> getDatabaseSchema(String code)
.orElseGet(() -> CommonResponse.failure(String.format("Plugin [ %s ] not found", entity.getType()))))
.orElseGet(() -> CommonResponse.failure(String.format("Resource [ %s ] not found", code)));
}

@Override
public CommonResponse<Response> getTables(String code, String database)
{
return repository.findByCode(code)
.map(entity -> pluginManager.getPlugin(entity.getType())
.map(plugin -> {
PluginService service = plugin.getService(PluginService.class);
return CommonResponse.success(service.getTablesForTable(entity.toConfigure(pluginManager, plugin), database));
})
.orElseGet(() -> CommonResponse.failure(String.format("Plugin [ %s ] not found", entity.getType()))))
.orElseGet(() -> CommonResponse.failure(String.format("Resource [ %s ] not found", code)));
}
}
118 changes: 57 additions & 61 deletions core/datacap-spi/src/main/java/io/edurt/datacap/spi/PluginService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -167,66 +166,63 @@ default Response getDatabases(Configure configure)
*/
default Response getTablesForTable(Configure configure, String database)
{
String sql = MessageFormat.format(
"SELECT\n" +
" CASE\n" +
" WHEN type = 'BASE TABLE' THEN '表'\n" +
" WHEN type = 'VIEW' THEN '视图'\n" +
" WHEN type = 'FUNCTION' THEN '函数'\n" +
" WHEN type = 'PROCEDURE' THEN '存储过程'\n" +
" END AS type_name,\n" +
" object_name,\n" +
" object_comment\n" +
"FROM (\n" +
" -- 表\n" +
" SELECT\n" +
" 'BASE TABLE' as type,\n" +
" TABLE_NAME as object_name,\n" +
" TABLE_COMMENT as object_comment\n" +
" FROM information_schema.TABLES\n" +
" WHERE TABLE_SCHEMA = '{0}'\n" +
" AND TABLE_TYPE = 'BASE TABLE'\n" +
"\n" +
" UNION ALL\n" +
"\n" +
" -- 视图\n" +
" SELECT\n" +
" 'VIEW' as type,\n" +
" TABLE_NAME as object_name,\n" +
" TABLE_COMMENT as object_comment\n" +
" FROM information_schema.TABLES\n" +
" WHERE TABLE_SCHEMA = '{0}'\n" +
" AND TABLE_TYPE = 'VIEW'\n" +
"\n" +
" UNION ALL\n" +
"\n" +
" -- 函数\n" +
" SELECT\n" +
" 'FUNCTION' as type,\n" +
" ROUTINE_NAME as object_name,\n" +
" ROUTINE_COMMENT as object_comment\n" +
" FROM information_schema.ROUTINES\n" +
" WHERE ROUTINE_SCHEMA = '{0}'\n" +
" AND ROUTINE_TYPE = 'FUNCTION'\n" +
"\n" +
" UNION ALL\n" +
"\n" +
" -- 存储过程(查询)\n" +
" SELECT\n" +
" 'PROCEDURE' as type,\n" +
" ROUTINE_NAME as object_name,\n" +
" ROUTINE_COMMENT as object_comment\n" +
" FROM information_schema.ROUTINES\n" +
" WHERE ROUTINE_SCHEMA = '{0}'\n" +
" AND ROUTINE_TYPE = 'PROCEDURE'\n" +
") AS combined_objects\n" +
"ORDER BY\n" +
" FIELD(type, 'BASE TABLE', 'VIEW', 'FUNCTION', 'PROCEDURE'),\n" +
" object_name;",
database
);

return this.execute(configure, sql);
String sql = "SELECT\n" +
" CASE\n" +
" WHEN type = 'BASE TABLE' THEN '表'\n" +
" WHEN type = 'VIEW' THEN '视图'\n" +
" WHEN type = 'FUNCTION' THEN '函数'\n" +
" WHEN type = 'PROCEDURE' THEN '存储过程'\n" +
" END AS type_name,\n" +
" object_name,\n" +
" object_comment\n" +
"FROM (\n" +
" -- 表\n" +
" SELECT\n" +
" 'BASE TABLE' as type,\n" +
" TABLE_NAME as object_name,\n" +
" TABLE_COMMENT as object_comment\n" +
" FROM information_schema.TABLES\n" +
" WHERE TABLE_SCHEMA = '{0}'\n" +
" AND TABLE_TYPE = 'BASE TABLE'\n" +
"\n" +
" UNION ALL\n" +
"\n" +
" -- 视图\n" +
" SELECT\n" +
" 'VIEW' as type,\n" +
" TABLE_NAME as object_name,\n" +
" TABLE_COMMENT as object_comment\n" +
" FROM information_schema.TABLES\n" +
" WHERE TABLE_SCHEMA = '{0}'\n" +
" AND TABLE_TYPE = 'VIEW'\n" +
"\n" +
" UNION ALL\n" +
"\n" +
" -- 函数\n" +
" SELECT\n" +
" 'FUNCTION' as type,\n" +
" ROUTINE_NAME as object_name,\n" +
" ROUTINE_COMMENT as object_comment\n" +
" FROM information_schema.ROUTINES\n" +
" WHERE ROUTINE_SCHEMA = '{0}'\n" +
" AND ROUTINE_TYPE = 'FUNCTION'\n" +
"\n" +
" UNION ALL\n" +
"\n" +
" -- 存储过程(查询)\n" +
" SELECT\n" +
" 'PROCEDURE' as type,\n" +
" ROUTINE_NAME as object_name,\n" +
" ROUTINE_COMMENT as object_comment\n" +
" FROM information_schema.ROUTINES\n" +
" WHERE ROUTINE_SCHEMA = '{0}'\n" +
" AND ROUTINE_TYPE = 'PROCEDURE'\n" +
") AS combined_objects\n" +
"ORDER BY\n" +
" FIELD(type, 'BASE TABLE', 'VIEW', 'FUNCTION', 'PROCEDURE'),\n" +
" object_name;";

return this.execute(configure, sql.replace("{0}", database));
}

default void destroy()
Expand Down
1 change: 1 addition & 0 deletions core/datacap-ui/src/model/structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface StructureModel

export enum StructureEnum
{
TYPE,
CATALOG,
DATABASE,
TABLE,
Expand Down
7 changes: 6 additions & 1 deletion core/datacap-ui/src/services/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ class MetadataService

getDatabaseBySource(code: string): Promise<ResponseModel>
{
return HttpUtils.post(`${ DEFAULT_PATH }/database/${ code }`)
return HttpUtils.post(`${ DEFAULT_PATH }/databases/${ code }`)
}

getTablesByDatabase(code: string, database: string): Promise<ResponseModel>
{
return HttpUtils.post(`${ DEFAULT_PATH }/${ code }/tables/${ database }`)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,28 @@
@on-node-click="onNodeClick">
<template #label="{ node }">
<div class="flex items-center space-x-1" @contextmenu.prevent="visibleContextMenu($event, node)">
<ShadcnIcon class="text-xs font-semibold text-gray-500" size="16" :icon="node.level === 2 ? 'Table' : 'Columns'"/>
<ShadcnIcon v-if="node.level === StructureEnum.TYPE && node.type === '表'"
class="text-xs font-semibold text-gray-500"
size="16"
icon="Table"/>
<ShadcnIcon v-else-if="node.level === StructureEnum.TYPE && node.type === '视图'"
class="text-xs font-semibold text-gray-500"
size="16"
icon="View"/>
<ShadcnIcon v-else-if="node.level === StructureEnum.TYPE && node.type === '函数'"
class="text-xs font-semibold text-gray-500"
size="16"
icon="SquareFunction"/>
<ShadcnIcon v-else-if="node.level === StructureEnum.TYPE && node.type === '存储过程'"
class="text-xs font-semibold text-gray-500"
size="16"
icon="Cpu"/>

<span class="text-xs font-normal text-gray-900">
{{ node.title }}
</span>
<span v-if="node.level === 3" class="text-xs font-normal text-gray-500 ml-1">

<span v-if="node.level === StructureEnum.COLUMN" class="text-xs font-normal text-gray-500 ml-1">
{{ getColumnTitle(String(node.type), String(node.extra), String(node.isKey), String(node.defaultValue)) }}
</span>
</div>
Expand Down Expand Up @@ -131,6 +148,24 @@ import TableTruncate from '@/views/pages/admin/source/components/TableTruncate.v
import TableDrop from '@/views/pages/admin/source/components/TableDrop.vue'
import TableCreate from '@/views/pages/admin/source/components/TableCreate.vue'
interface MenuItem
{
type: string; // 节点类型(表、视图等)
title: string; // 节点名称
comment?: string; // 注释
isLeaf?: boolean;
level?: StructureEnum;
code?: string;
children?: MenuItem[]; // 子节点
}
interface SourceData
{
type_name: string;
object_name: string;
object_comment: string;
}
export default defineComponent({
name: 'MetadataSidebar',
computed: {
Expand Down Expand Up @@ -168,6 +203,7 @@ export default defineComponent({
},
created()
{
this.originalSource = this.$route.params?.source as string
this.handleInitialize()
},
methods: {
Expand All @@ -182,13 +218,13 @@ export default defineComponent({
.then(response => {
if (response.status) {
response.data.columns.forEach(item => {
const structure: StructureModel = {
title: item.object_name,
catalog: item.object_name,
code: item.object_name
}
this.databaseArray.push(structure)
})
const structure: StructureModel = {
title: item.object_name,
catalog: item.object_name,
code: item.object_name
}
this.databaseArray.push(structure)
})
if (database) {
this.originalDatabase = database
this.selectDatabase = database as any
Expand All @@ -209,41 +245,39 @@ export default defineComponent({
{
this.loading = true
this.dataTreeArray = []
TableService.getAllByDatabase(this.selectDatabase as any)
.then(response => {
if (response.status) {
response.data.forEach((item: any) => {
const structure = {
title: item.name, database: item.database.name, databaseId: item.database.id, catalog: item.catalog, value: item.code, type: item.type,
level: StructureEnum.TABLE, engine: item.engine, comment: item.comment, origin: item, contextmenu: true, children: [], isLeaf: false
}
this.dataTreeArray.push(structure)
})
}
else {
this.$Message.error({
content: response.message,
showIcon: true
})
}
})
.finally(() => {
this.loading = false
const table = String(this.$route.params?.table)
if (table) {
const node = this.dataTreeArray.find(item => item.code === table)
if (node) {
node.selected = true
this.handlerSelectNode([node])
}
}
else {
this.$router.push(`/admin/source/${ this.originalSource }/d/${ this.selectDatabase }`)
}
})
MetadataService.getTablesByDatabase(this.originalSource, this.selectDatabase as string)
.then(response => {
if (response.status) {
this.dataTreeArray = [...this.convertToTreeData(response.data.columns, StructureEnum.TABLE)]
}
else {
this.$Message.error({
content: response.message,
showIcon: true
})
}
})
.finally(() => {
this.loading = false
const table = this.$route.params?.table
if (table) {
const node = this.dataTreeArray.find(item => item.code === table)
if (node) {
node.selected = true
this.handlerSelectNode([node])
}
}
else {
this.$router.push(`/admin/source/${ this.originalSource }/d/${ this.selectDatabase }`)
}
})
},
onNodeClick(node: any)
{
if (node.level === StructureEnum.TYPE) {
return
}
const type = this.$route.meta.type
this.$router.push(`/admin/source/${ this.originalSource }/d/${ this.selectDatabase }/t/${ type ? type : 'info' }/${ node.value }`)
},
Expand Down Expand Up @@ -320,6 +354,32 @@ export default defineComponent({
title = `${ title }\u00A0=\u00A0${ defaultValue }`
}
return title
},
convertToTreeData(flatData: SourceData[], level: StructureEnum = StructureEnum.DATABASE): MenuItem[]
{
// 按type_name分组
const groupedData = flatData.reduce((acc, curr) => {
if (!acc[curr.type_name]) {
acc[curr.type_name] = []
}
acc[curr.type_name].push(curr)
return acc
}, {} as Record<string, SourceData[]>)
// 转换为树形结构
return Object.entries(groupedData).map(([type, items]) => ({
type,
title: `${ type } (${ items.length })`,
level: StructureEnum.TYPE,
children: items.map(item => ({
type: 'item',
title: item.object_name,
level: level,
isLeaf: false,
code: item.object_name,
comment: item.object_comment
}))
}))
}
}
})
Expand Down

0 comments on commit 651dda3

Please sign in to comment.