Skip to content

Commit 90c518c

Browse files
committed
Catalog Table/view drop
1 parent 170b1cf commit 90c518c

File tree

14 files changed

+308
-15
lines changed

14 files changed

+308
-15
lines changed

dinky-admin/src/main/java/org/dinky/controller/StudioController.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,30 @@ public Result<Schema> getMSSchemaInfo(@RequestBody StudioMetaStoreDTO studioMeta
167167
public Result<List<Column>> getMSColumns(@RequestBody StudioMetaStoreDTO studioMetaStoreDTO) {
168168
return Result.succeed(studioService.getMSColumns(studioMetaStoreDTO));
169169
}
170+
171+
/** Drop Meta Store Flink Table */
172+
@PostMapping("/dropMSTable")
173+
@ApiOperation("Drop Flink Table")
174+
@ApiImplicitParams({
175+
@ApiImplicitParam(name = "envId", value = "envId", required = true, dataType = "Integer", paramType = "query"),
176+
@ApiImplicitParam(
177+
name = "catalog",
178+
value = "catalog",
179+
required = true,
180+
dataType = "String",
181+
paramType = "query"),
182+
@ApiImplicitParam(
183+
name = "database",
184+
value = "database",
185+
required = true,
186+
dataType = "String",
187+
paramType = "query"),
188+
@ApiImplicitParam(name = "table", value = "table", required = true, dataType = "String", paramType = "query")
189+
})
190+
public Result<List<Column>> dropMSTable(@RequestBody StudioMetaStoreDTO studioMetaStoreDTO) {
191+
if (studioService.dropMSTable(studioMetaStoreDTO)) {
192+
return Result.succeed();
193+
}
194+
return Result.failed();
195+
}
170196
}

dinky-admin/src/main/java/org/dinky/service/StudioService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@ public interface StudioService {
5353
Schema getMSSchemaInfo(StudioMetaStoreDTO studioMetaStoreDTO);
5454

5555
List<Column> getMSColumns(StudioMetaStoreDTO studioMetaStoreDTO);
56+
57+
boolean dropMSTable(StudioMetaStoreDTO studioMetaStoreDTO);
5658
}

dinky-admin/src/main/java/org/dinky/service/impl/StudioServiceImpl.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.dinky.data.dto.StudioLineageDTO;
2727
import org.dinky.data.dto.StudioMetaStoreDTO;
2828
import org.dinky.data.dto.TaskDTO;
29+
import org.dinky.data.enums.Status;
30+
import org.dinky.data.exception.BusException;
2931
import org.dinky.data.model.Catalog;
3032
import org.dinky.data.model.ClusterInstance;
3133
import org.dinky.data.model.Column;
@@ -49,9 +51,13 @@
4951
import org.dinky.utils.FlinkTableMetadataUtil;
5052
import org.dinky.utils.RunTimeUtil;
5153

54+
import org.apache.flink.table.catalog.ObjectPath;
55+
import org.apache.flink.table.catalog.exceptions.TableNotExistException;
56+
5257
import java.util.ArrayList;
5358
import java.util.List;
5459
import java.util.Map;
60+
import java.util.Optional;
5561

5662
import org.springframework.stereotype.Service;
5763

@@ -209,6 +215,32 @@ public List<Column> getMSColumns(StudioMetaStoreDTO studioMetaStoreDTO) {
209215
return columns;
210216
}
211217

218+
@Override
219+
public boolean dropMSTable(StudioMetaStoreDTO studioMetaStoreDTO) {
220+
String catalogName = studioMetaStoreDTO.getCatalog();
221+
String database = studioMetaStoreDTO.getDatabase();
222+
String tableName = studioMetaStoreDTO.getTable();
223+
if (Dialect.isCommonSql(studioMetaStoreDTO.getDialect())) {
224+
throw new BusException(Status.SYS_CATALOG_ONLY_SUPPORT_FLINK_SQL_OPERATION);
225+
} else {
226+
String envSql = taskService.buildEnvSql(studioMetaStoreDTO);
227+
JobManager jobManager = getJobManager(studioMetaStoreDTO, envSql);
228+
CustomTableEnvironment customTableEnvironment =
229+
jobManager.getExecutor().getCustomTableEnvironment();
230+
Optional<org.apache.flink.table.catalog.Catalog> catalogOptional =
231+
customTableEnvironment.getCatalogManager().getCatalog(catalogName);
232+
if (catalogOptional.isPresent()) {
233+
try {
234+
catalogOptional.get().dropTable(new ObjectPath(database, tableName), true);
235+
return true;
236+
} catch (TableNotExistException e) {
237+
log.error("Drop table {}.{}.{} error, detail {}", catalogName, database, tableName, e);
238+
}
239+
}
240+
}
241+
return false;
242+
}
243+
212244
private JobManager getJobManager(StudioMetaStoreDTO studioMetaStoreDTO, String envSql) {
213245
JobManager jobManager = jobManagerCache.get(envSql, () -> {
214246
JobConfig config = studioMetaStoreDTO.getJobConfig();

dinky-common/src/main/java/org/dinky/data/enums/Status.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,12 @@ public enum Status {
480480
SYS_APPROVAL_SETTINGS_TASK_REVIEWER_ROLES(210, "sys.approval.settings.taskReviewerRoles"),
481481
SYS_APPROVAL_SETTINGS_TASK_REVIEWER_ROLES_NOTE(211, "sys.approval.settings.taskReviewerRoles.note"),
482482
SYS_APPROVAL_TASK_NOT_APPROVED(212, "sys.approval.taskNotApproved"),
483-
SYS_APPROVAL_DUPLICATE_APPROVAL_IN_PROCESS(213, "sys.approval.duplicateInProcess");
483+
SYS_APPROVAL_DUPLICATE_APPROVAL_IN_PROCESS(213, "sys.approval.duplicateInProcess"),
484+
/**
485+
* Catalog
486+
*/
487+
SYS_CATALOG_ONLY_SUPPORT_FLINK_SQL_OPERATION(214, "sys.catalog.operationOnlySupportedOnFlinkSql");
488+
484489
private final int code;
485490
private final String key;
486491

dinky-common/src/main/resources/i18n/messages_en_US.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,7 @@ sys.approval.settings.enforceCrossReview.note=Submitter of an approval are not a
333333
sys.approval.settings.taskReviewerRoles=Reviewer Role Codes
334334
sys.approval.settings.taskReviewerRoles.note=Roles who can review tasks, different role codes should be divided by comma. For example: SuperAdmin,Reviewer
335335
sys.approval.taskNotApproved=Current task is not published or published version is not approved, please try again after task being published and approved
336-
sys.approval.duplicateInProcess=Already have an approval in process, please do not submit again
336+
sys.approval.duplicateInProcess=Already have an approval in process, please do not submit again
337+
338+
# catalog
339+
sys.catalog.operationOnlySupportedOnFlinkSql=Only supports operations on the catalog of Flink SQL jobs

dinky-common/src/main/resources/i18n/messages_zh_CN.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,6 @@ sys.approval.settings.taskReviewerRoles=具有审批权限的角色编码
335335
sys.approval.settings.taskReviewerRoles.note=具有审批权限的角色编码,多个角色用英文逗号隔开,例如:SuperAdmin,Reviewer
336336
sys.approval.taskNotApproved=当前作业未发布或发布版本未通过审核,不允许运行,请在任务发布且发布版本通过审核后重试
337337
sys.approval.duplicateInProcess=存在仍在进行的审批流程,请勿重复提交
338+
339+
# catalog
340+
sys.catalog.operationOnlySupportedOnFlinkSql=仅允许对FlinkSql作业的Catalog进行操作

dinky-web/src/locales/en-US/pages.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ export default {
166166
'datastudio.sqlTask.flinkJar.args.tip': 'Please enter the program running parameters (args)',
167167
'datastudio.sqlTask.flinkJar.allowNonRestoredState':
168168
'Ignore undeclared state (allowNonRestoredState)',
169+
'datastudio.project.delete.table': 'Drop [{catalog}.{database}.{table}]',
170+
'datastudio.project.delete.table.confirm':
171+
'Drop statement will be called to delete the table. \nPlease operate with caution! This operation is irreversible!!! \n\t\t\t\tConfirm to delete?',
172+
169173
/**
170174
*
171175
* devops

dinky-web/src/locales/zh-CN/pages.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ export default {
152152
'datastudio.sqlTask.flinkJar.args': '程序运行参数(args)',
153153
'datastudio.sqlTask.flinkJar.args.tip': '请输入程序运行参数(args)',
154154
'datastudio.sqlTask.flinkJar.allowNonRestoredState': '忽略未声明状态(allowNonRestoredState)',
155+
'datastudio.project.delete.table': '删除 [{catalog}.{database}.{table}]',
156+
'datastudio.project.delete.table.confirm':
157+
'此操作将执行Drop语句来删除当前表单.\n\t\t\t\t请谨慎操作! 该操作不可逆!!!\n\t\t\t\t\t确认删除吗?',
155158
/**
156159
*
157160
* devops
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
*
3+
* Licensed to the Apache Software Foundation (ASF) under one or more
4+
* contributor license agreements. See the NOTICE file distributed with
5+
* this work for additional information regarding copyright ownership.
6+
* The ASF licenses this file to You under the Apache License, Version 2.0
7+
* (the "License"); you may not use this file except in compliance with
8+
* the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
*/
19+
20+
import { MenuInfo } from 'rc-menu/es/interface';
21+
import React, { useEffect, useState } from 'react';
22+
import { InitProjectState } from '@/types/Studio/init.d';
23+
import { ProjectState } from '@/types/Studio/state';
24+
import { Modal, Typography } from 'antd';
25+
import { RightContextMenuState } from '@/pages/DataStudio/data.d';
26+
import { InitContextMenuPosition } from '@/pages/DataStudio/function';
27+
import RightContextMenu from '@/pages/DataStudio/RightContextMenu';
28+
import { l } from '@/utils/intl';
29+
import { dropMSTable } from "@/pages/DataStudio/Toolbar/Catalog/service";
30+
import { CatalogState } from "@/pages/DataStudio/Toolbar/Catalog/data";
31+
import { TABLE_RIGHT_MENU } from "@/pages/DataStudio/Toolbar/Catalog/constant";
32+
33+
const {Text} = Typography;
34+
export type RightContextProps = {
35+
refreshMetaStoreTables: () => Promise<any>;
36+
catalogState: CatalogState | undefined;
37+
};
38+
export const useRightContext = (props: RightContextProps) => {
39+
const {
40+
refreshMetaStoreTables,
41+
catalogState: CatalogState
42+
} = props;
43+
44+
const [rightContextMenuState, setRightContextMenuState] = useState<RightContextMenuState>({
45+
show: false,
46+
position: InitContextMenuPosition
47+
});
48+
const [projectState, setProjectState] = useState<ProjectState>(InitProjectState);
49+
useEffect(() => {
50+
setProjectState((prevState) => ({
51+
...prevState,
52+
menuItems: []
53+
}));
54+
}, [projectState.isCut, projectState.cutId]);
55+
/**
56+
* the right click event
57+
* @param info
58+
*/
59+
const handleProjectRightClick = (info: any) => {
60+
const {
61+
node: {isLeaf, key, fullInfo, isTable, isView},
62+
node,
63+
event
64+
} = info;
65+
setProjectState((prevState) => ({
66+
...prevState,
67+
isLeaf: isLeaf,
68+
menuItems: isTable || isView ? TABLE_RIGHT_MENU() : [],
69+
contextMenuOpen: true,
70+
rightClickedNode: {...node, ...fullInfo},
71+
value: fullInfo
72+
}));
73+
};
74+
75+
const handleContextCancel = () => {
76+
setProjectState((prevState) => ({
77+
...prevState,
78+
contextMenuOpen: false
79+
}));
80+
};
81+
82+
const handleDeleteSubmit = async () => {
83+
const {name, type, key: table, catalog, schema: database} = projectState.rightClickedNode;
84+
const {envId, dialect} = props.catalogState;
85+
86+
handleContextCancel();
87+
console.log(projectState.rightClickedNode);
88+
console.log(props.catalogState)
89+
Modal.confirm({
90+
title: l('datastudio.project.delete.table', '', {catalog, database, table}),
91+
width: '30%',
92+
content: (
93+
<Text className={'needWrap'} type='danger'>
94+
{l('datastudio.project.delete.table.confirm')}
95+
</Text>
96+
),
97+
okText: l('button.confirm'),
98+
cancelText: l('button.cancel'),
99+
onOk: async () => {
100+
await dropMSTable({
101+
envId,
102+
catalog,
103+
database,
104+
table,
105+
dialect
106+
});
107+
await refreshMetaStoreTables();
108+
}
109+
});
110+
};
111+
const handleMenuClick = async (node: MenuInfo) => {
112+
setProjectState((prevState) => ({...prevState, rightActiveKey: node.key}));
113+
switch (node.key) {
114+
case 'delete':
115+
await handleDeleteSubmit();
116+
break
117+
default:
118+
handleContextCancel();
119+
break;
120+
}
121+
};
122+
123+
return {
124+
RightContent: (
125+
<>
126+
<RightContextMenu
127+
contextMenuPosition={rightContextMenuState.position}
128+
open={rightContextMenuState.show}
129+
openChange={() =>
130+
setRightContextMenuState((prevState) => ({...prevState, show: false}))
131+
}
132+
items={projectState.menuItems}
133+
onClick={handleMenuClick}
134+
/>
135+
</>
136+
),
137+
setRightContextMenuState,
138+
handleProjectRightClick
139+
};
140+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
*
3+
* Licensed to the Apache Software Foundation (ASF) under one or more
4+
* contributor license agreements. See the NOTICE file distributed with
5+
* this work for additional information regarding copyright ownership.
6+
* The ASF licenses this file to You under the Apache License, Version 2.0
7+
* (the "License"); you may not use this file except in compliance with
8+
* the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
*/
19+
20+
import { MenuItemType } from "antd/es/menu/interface";
21+
import { DeleteTwoTone } from "@ant-design/icons";
22+
import { l } from "@/utils/intl";
23+
24+
export const TABLE_RIGHT_MENU = (): MenuItemType[] => [
25+
{
26+
key: 'delete',
27+
icon: <DeleteTwoTone twoToneColor={'red'}/>,
28+
label: l('button.delete')
29+
}
30+
];

0 commit comments

Comments
 (0)