Commit 0f7563ce authored by godkaikai's avatar godkaikai

新增数据源的Sql校验

parent f5742858
...@@ -130,6 +130,20 @@ ...@@ -130,6 +130,20 @@
<groupId>com.dlink</groupId> <groupId>com.dlink</groupId>
<artifactId>dlink-gateway</artifactId> <artifactId>dlink-gateway</artifactId>
</dependency> </dependency>
<!--<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-metadata-clickhouse</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.dlink</groupId>
<artifactId>dlink-metadata-mysql</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>-->
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
......
package com.dlink.dto; package com.dlink.dto;
import com.dlink.config.Dialect;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
...@@ -17,4 +18,5 @@ public class CatalogueTaskDTO { ...@@ -17,4 +18,5 @@ public class CatalogueTaskDTO {
private boolean isLeaf; private boolean isLeaf;
private String name; private String name;
private String alias; private String alias;
private String dialect = Dialect.DEFAULT.getValue();
} }
...@@ -22,6 +22,7 @@ import java.util.Map; ...@@ -22,6 +22,7 @@ import java.util.Map;
public class StudioExecuteDTO { public class StudioExecuteDTO {
// RUN_MODE // RUN_MODE
private String type; private String type;
private String dialect;
private boolean useResult; private boolean useResult;
private boolean statementSet; private boolean statementSet;
private boolean useSession; private boolean useSession;
...@@ -29,6 +30,7 @@ public class StudioExecuteDTO { ...@@ -29,6 +30,7 @@ public class StudioExecuteDTO {
private boolean useRemote; private boolean useRemote;
private Integer clusterId; private Integer clusterId;
private Integer clusterConfigurationId; private Integer clusterConfigurationId;
private Integer databaseId;
private Integer jarId; private Integer jarId;
private boolean fragment; private boolean fragment;
private String statement; private String statement;
......
...@@ -32,6 +32,8 @@ public class Task extends SuperEntity{ ...@@ -32,6 +32,8 @@ public class Task extends SuperEntity{
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
private String alias; private String alias;
private String dialect;
private String type; private String type;
private Integer checkPoint; private Integer checkPoint;
...@@ -50,6 +52,8 @@ public class Task extends SuperEntity{ ...@@ -50,6 +52,8 @@ public class Task extends SuperEntity{
private Integer clusterConfigurationId; private Integer clusterConfigurationId;
private Integer databaseId;
private Integer jarId; private Integer jarId;
private String configJson; private String configJson;
......
package com.dlink.service.impl; package com.dlink.service.impl;
import com.dlink.assertion.Assert; import com.dlink.assertion.Assert;
import com.dlink.assertion.Asserts;
import com.dlink.db.service.impl.SuperServiceImpl; import com.dlink.db.service.impl.SuperServiceImpl;
import com.dlink.dto.CatalogueTaskDTO; import com.dlink.dto.CatalogueTaskDTO;
import com.dlink.mapper.CatalogueMapper; import com.dlink.mapper.CatalogueMapper;
...@@ -40,11 +41,13 @@ public class CatalogueServiceImpl extends SuperServiceImpl<CatalogueMapper, Cata ...@@ -40,11 +41,13 @@ public class CatalogueServiceImpl extends SuperServiceImpl<CatalogueMapper, Cata
Task task = new Task(); Task task = new Task();
task.setName(catalogueTaskDTO.getName()); task.setName(catalogueTaskDTO.getName());
task.setAlias(catalogueTaskDTO.getAlias()); task.setAlias(catalogueTaskDTO.getAlias());
task.setDialect(catalogueTaskDTO.getDialect());
taskService.saveOrUpdateTask(task); taskService.saveOrUpdateTask(task);
Catalogue catalogue = new Catalogue(); Catalogue catalogue = new Catalogue();
catalogue.setName(catalogueTaskDTO.getAlias()); catalogue.setName(catalogueTaskDTO.getAlias());
catalogue.setIsLeaf(true); catalogue.setIsLeaf(true);
catalogue.setTaskId(task.getId()); catalogue.setTaskId(task.getId());
catalogue.setType(catalogueTaskDTO.getDialect());
catalogue.setParentId(catalogueTaskDTO.getParentId()); catalogue.setParentId(catalogueTaskDTO.getParentId());
this.save(catalogue); this.save(catalogue);
return catalogue; return catalogue;
......
package com.dlink.service.impl; package com.dlink.service.impl;
import com.dlink.api.FlinkAPI; import com.dlink.api.FlinkAPI;
import com.dlink.assertion.Assert;
import com.dlink.assertion.Asserts; import com.dlink.assertion.Asserts;
import com.dlink.config.Dialect;
import com.dlink.dto.SessionDTO; import com.dlink.dto.SessionDTO;
import com.dlink.dto.StudioDDLDTO; import com.dlink.dto.StudioDDLDTO;
import com.dlink.dto.StudioExecuteDTO; import com.dlink.dto.StudioExecuteDTO;
...@@ -14,7 +16,9 @@ import com.dlink.gateway.result.SavePointResult; ...@@ -14,7 +16,9 @@ import com.dlink.gateway.result.SavePointResult;
import com.dlink.job.JobConfig; import com.dlink.job.JobConfig;
import com.dlink.job.JobManager; import com.dlink.job.JobManager;
import com.dlink.job.JobResult; import com.dlink.job.JobResult;
import com.dlink.metadata.driver.Driver;
import com.dlink.model.Cluster; import com.dlink.model.Cluster;
import com.dlink.model.DataBase;
import com.dlink.model.Savepoints; import com.dlink.model.Savepoints;
import com.dlink.model.SystemConfiguration; import com.dlink.model.SystemConfiguration;
import com.dlink.result.IResult; import com.dlink.result.IResult;
...@@ -22,6 +26,7 @@ import com.dlink.result.SelectResult; ...@@ -22,6 +26,7 @@ import com.dlink.result.SelectResult;
import com.dlink.result.SqlExplainResult; import com.dlink.result.SqlExplainResult;
import com.dlink.service.ClusterConfigurationService; import com.dlink.service.ClusterConfigurationService;
import com.dlink.service.ClusterService; import com.dlink.service.ClusterService;
import com.dlink.service.DataBaseService;
import com.dlink.service.SavepointsService; import com.dlink.service.SavepointsService;
import com.dlink.service.StudioService; import com.dlink.service.StudioService;
import com.dlink.session.SessionConfig; import com.dlink.session.SessionConfig;
...@@ -59,6 +64,8 @@ public class StudioServiceImpl implements StudioService { ...@@ -59,6 +64,8 @@ public class StudioServiceImpl implements StudioService {
private ClusterConfigurationService clusterConfigurationService; private ClusterConfigurationService clusterConfigurationService;
@Autowired @Autowired
private SavepointsService savepointsService; private SavepointsService savepointsService;
@Autowired
private DataBaseService dataBaseService;
@Override @Override
public JobResult executeSql(StudioExecuteDTO studioExecuteDTO) { public JobResult executeSql(StudioExecuteDTO studioExecuteDTO) {
...@@ -85,6 +92,14 @@ public class StudioServiceImpl implements StudioService { ...@@ -85,6 +92,14 @@ public class StudioServiceImpl implements StudioService {
@Override @Override
public List<SqlExplainResult> explainSql(StudioExecuteDTO studioExecuteDTO) { public List<SqlExplainResult> explainSql(StudioExecuteDTO studioExecuteDTO) {
if( Dialect.SQL.equalsVal(studioExecuteDTO.getDialect())){
return explainCommonSql(studioExecuteDTO);
}else{
return explainFlinkSql(studioExecuteDTO);
}
}
private List<SqlExplainResult> explainFlinkSql(StudioExecuteDTO studioExecuteDTO) {
JobConfig config = studioExecuteDTO.getJobConfig(); JobConfig config = studioExecuteDTO.getJobConfig();
if(!config.isUseSession()) { if(!config.isUseSession()) {
config.setAddress(clusterService.buildEnvironmentAddress(config.isUseRemote(), studioExecuteDTO.getClusterId())); config.setAddress(clusterService.buildEnvironmentAddress(config.isUseRemote(), studioExecuteDTO.getClusterId()));
...@@ -93,6 +108,18 @@ public class StudioServiceImpl implements StudioService { ...@@ -93,6 +108,18 @@ public class StudioServiceImpl implements StudioService {
return jobManager.explainSql(studioExecuteDTO.getStatement()).getSqlExplainResults(); return jobManager.explainSql(studioExecuteDTO.getStatement()).getSqlExplainResults();
} }
private List<SqlExplainResult> explainCommonSql(StudioExecuteDTO studioExecuteDTO) {
if(Asserts.isNull(studioExecuteDTO.getDatabaseId())){
return new ArrayList<>();
}else{
DataBase dataBase = dataBaseService.getById(studioExecuteDTO.getDatabaseId());
SqlExplainResult explainResult = Driver.build(dataBase.getDriverConfig()).connect().explain(studioExecuteDTO.getStatement());
return new ArrayList<SqlExplainResult>(){{
add(explainResult);
}};
}
}
@Override @Override
public ObjectNode getStreamGraph(StudioExecuteDTO studioExecuteDTO) { public ObjectNode getStreamGraph(StudioExecuteDTO studioExecuteDTO) {
JobConfig config = studioExecuteDTO.getJobConfig(); JobConfig config = studioExecuteDTO.getJobConfig();
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<id column="id" property="id" /> <id column="id" property="id" />
<result column="name" property="name" /> <result column="name" property="name" />
<result column="alias" property="alias" /> <result column="alias" property="alias" />
<result column="dialect" property="dialect" />
<result column="type" property="type" /> <result column="type" property="type" />
<result column="check_point" property="checkPoint" /> <result column="check_point" property="checkPoint" />
<result column="save_point_strategy" property="savePointStrategy" /> <result column="save_point_strategy" property="savePointStrategy" />
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
<result column="statement_set" property="statementSet" /> <result column="statement_set" property="statementSet" />
<result column="cluster_id" property="clusterId" /> <result column="cluster_id" property="clusterId" />
<result column="cluster_configuration_id" property="clusterConfigurationId" /> <result column="cluster_configuration_id" property="clusterConfigurationId" />
<result column="database_id" property="databaseId" />
<result column="jar_id" property="jarId" /> <result column="jar_id" property="jarId" />
<result column="config_json" property="configJson" /> <result column="config_json" property="configJson" />
<result column="note" property="note" /> <result column="note" property="note" />
...@@ -26,7 +28,7 @@ ...@@ -26,7 +28,7 @@
<!-- 通用查询结果列 --> <!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, name, alias, type,check_point,save_point_strategy,save_point_path, parallelism,fragment,statement_set,cluster_id,cluster_configuration_id,jar_id,config_json,note, enabled, create_time, update_time id, name, alias,dialect, type,check_point,save_point_strategy,save_point_path, parallelism,fragment,statement_set,cluster_id,cluster_configuration_id,database_id,jar_id,config_json,note, enabled, create_time, update_time
</sql> </sql>
......
...@@ -20,6 +20,29 @@ public class SqlExplainResult { ...@@ -20,6 +20,29 @@ public class SqlExplainResult {
private boolean explainTrue; private boolean explainTrue;
private LocalDateTime explainTime; private LocalDateTime explainTime;
public SqlExplainResult() {
}
public SqlExplainResult(Integer index, String type, String sql, String parse, String explain, String error, boolean parseTrue, boolean explainTrue, LocalDateTime explainTime) {
this.index = index;
this.type = type;
this.sql = sql;
this.parse = parse;
this.explain = explain;
this.error = error;
this.parseTrue = parseTrue;
this.explainTrue = explainTrue;
this.explainTime = explainTime;
}
public static SqlExplainResult success(String type,String sql,String explain){
return new SqlExplainResult(1,type,sql,null,explain,null,true,true,LocalDateTime.now());
}
public static SqlExplainResult fail(String sql,String error){
return new SqlExplainResult(1,null,sql,null,null,error,false,false,LocalDateTime.now());
}
public Integer getIndex() { public Integer getIndex() {
return index; return index;
} }
......
package com.dlink.config;
import com.dlink.assertion.Asserts;
/**
* Dialect
*
* @author wenmo
* @since 2021/12/13
**/
public enum Dialect {
FLINKSQL("FlinkSql"),SQL("Sql"),JAVA("Java");
private String value;
public static final Dialect DEFAULT = Dialect.FLINKSQL;
Dialect(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public boolean equalsVal(String valueText){
return Asserts.isEqualsIgnoreCase(value,valueText);
}
public static Dialect get(String value){
for (Dialect type : Dialect.values()) {
if(Asserts.isEqualsIgnoreCase(type.getValue(),value)){
return type;
}
}
return Dialect.FLINKSQL;
}
}
...@@ -221,6 +221,7 @@ CREATE TABLE `dlink_task` ( ...@@ -221,6 +221,7 @@ CREATE TABLE `dlink_task` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '名称', `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '名称',
`alias` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '别名', `alias` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '别名',
`dialect` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '方言',
`type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '类型', `type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '类型',
`check_point` int(11) NULL DEFAULT NULL COMMENT 'CheckPoint ', `check_point` int(11) NULL DEFAULT NULL COMMENT 'CheckPoint ',
`save_point_strategy` int(1) UNSIGNED ZEROFILL NULL DEFAULT NULL COMMENT 'SavePoint策略', `save_point_strategy` int(1) UNSIGNED ZEROFILL NULL DEFAULT NULL COMMENT 'SavePoint策略',
...@@ -230,6 +231,7 @@ CREATE TABLE `dlink_task` ( ...@@ -230,6 +231,7 @@ CREATE TABLE `dlink_task` (
`statement_set` tinyint(1) NULL DEFAULT NULL COMMENT '启用语句集', `statement_set` tinyint(1) NULL DEFAULT NULL COMMENT '启用语句集',
`cluster_id` int(11) NULL DEFAULT NULL COMMENT 'Flink集群ID', `cluster_id` int(11) NULL DEFAULT NULL COMMENT 'Flink集群ID',
`cluster_configuration_id` int(11) NULL DEFAULT NULL COMMENT '集群配置ID', `cluster_configuration_id` int(11) NULL DEFAULT NULL COMMENT '集群配置ID',
`database_id` int(11) NULL DEFAULT NULL COMMENT '数据源ID',
`jar_id` int(11) NULL DEFAULT NULL COMMENT 'jarID', `jar_id` int(11) NULL DEFAULT NULL COMMENT 'jarID',
`config_json` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '配置JSON', `config_json` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '配置JSON',
`note` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '注释', `note` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '注释',
......
...@@ -471,4 +471,12 @@ INSERT INTO `dlink_user`(`id`, `username`, `password`, `nickname`, `worknum`, `a ...@@ -471,4 +471,12 @@ INSERT INTO `dlink_user`(`id`, `username`, `password`, `nickname`, `worknum`, `a
ALTER TABLE `dlink_task` ALTER TABLE `dlink_task`
CHANGE COLUMN `config` `config_json` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '配置JSON' AFTER `jar_id`; CHANGE COLUMN `config` `config_json` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '配置JSON' AFTER `jar_id`;
-- ----------------------------
-- 0.5.0-SNAPSHOT 2021-12-13
-- ----------------------------
ALTER TABLE `dlink_task`
ADD COLUMN `dialect` varchar(50) NULL COMMENT '方言' AFTER `alias`;
ALTER TABLE `dlink_task`
ADD COLUMN `database_id` int(11) NULL COMMENT '数据源ID' AFTER `cluster_configuration_id`;
SET FOREIGN_KEY_CHECKS = 1; SET FOREIGN_KEY_CHECKS = 1;
...@@ -23,7 +23,7 @@ public enum SavePointType{ ...@@ -23,7 +23,7 @@ public enum SavePointType{
public static SavePointType get(String value){ public static SavePointType get(String value){
for (SavePointType type : SavePointType.values()) { for (SavePointType type : SavePointType.values()) {
if(Asserts.isEquals(type.getValue(),value)){ if(Asserts.isEqualsIgnoreCase(type.getValue(),value)){
return type; return type;
} }
} }
......
...@@ -5,6 +5,7 @@ import com.dlink.constant.CommonConstant; ...@@ -5,6 +5,7 @@ import com.dlink.constant.CommonConstant;
import com.dlink.model.Column; import com.dlink.model.Column;
import com.dlink.model.Schema; import com.dlink.model.Schema;
import com.dlink.model.Table; import com.dlink.model.Table;
import com.dlink.result.SqlExplainResult;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -270,4 +271,30 @@ public abstract class AbstractJdbcDriver extends AbstractDriver { ...@@ -270,4 +271,30 @@ public abstract class AbstractJdbcDriver extends AbstractDriver {
} }
return datas; return datas;
} }
@Override
public SqlExplainResult explain(String sql){
boolean correct = true;
String error = null;
PreparedStatement preparedStatement = null;
ResultSet results = null;
try {
preparedStatement = conn.prepareStatement("explain "+sql);
results = preparedStatement.executeQuery();
if(!results.next()){
correct = false;
}
} catch (SQLException e) {
e.printStackTrace();
correct = false;
error = e.getMessage();
} finally {
close(preparedStatement, results);
}
if(correct) {
return SqlExplainResult.success(null, sql, null);
}else {
return SqlExplainResult.fail(sql,error);
}
}
} }
...@@ -6,6 +6,7 @@ import com.dlink.metadata.result.SelectResult; ...@@ -6,6 +6,7 @@ import com.dlink.metadata.result.SelectResult;
import com.dlink.model.Column; import com.dlink.model.Column;
import com.dlink.model.Schema; import com.dlink.model.Schema;
import com.dlink.model.Table; import com.dlink.model.Table;
import com.dlink.result.SqlExplainResult;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import sun.misc.Service; import sun.misc.Service;
...@@ -91,4 +92,6 @@ public interface Driver { ...@@ -91,4 +92,6 @@ public interface Driver {
List query(String sql); List query(String sql);
SqlExplainResult explain(String sql);
} }
package com.dlink.metadata.result;
/**
* ExplainResult
*
* @author qiwenkai
* @since 2021/12/13 19:14
**/
public class ExplainResult {
private String sql;
}
...@@ -5,6 +5,11 @@ import com.dlink.metadata.convert.ITypeConvert; ...@@ -5,6 +5,11 @@ import com.dlink.metadata.convert.ITypeConvert;
import com.dlink.metadata.query.ClickHouseQuery; import com.dlink.metadata.query.ClickHouseQuery;
import com.dlink.metadata.query.IDBQuery; import com.dlink.metadata.query.IDBQuery;
import com.dlink.model.Table; import com.dlink.model.Table;
import com.dlink.result.SqlExplainResult;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/** /**
* ClickHouseDriver * ClickHouseDriver
...@@ -42,4 +47,30 @@ public class ClickHouseDriver extends AbstractJdbcDriver { ...@@ -42,4 +47,30 @@ public class ClickHouseDriver extends AbstractJdbcDriver {
public String getCreateTableSql(Table table) { public String getCreateTableSql(Table table) {
return null; return null;
} }
@Override
public SqlExplainResult explain(String sql){
boolean correct = true;
String error = null;
StringBuilder explain = new StringBuilder();
PreparedStatement preparedStatement = null;
ResultSet results = null;
try {
preparedStatement = conn.prepareStatement("explain "+sql);
results = preparedStatement.executeQuery();
while(results.next()){
explain.append(getTypeConvert().convertValue(results,"explain", "string")+"\r\n");
}
} catch (SQLException e) {
correct = false;
error = e.getMessage();
} finally {
close(preparedStatement, results);
}
if(correct) {
return SqlExplainResult.success("ClickHouseSql", sql, explain.toString());
}else {
return SqlExplainResult.fail(sql,error);
}
}
} }
...@@ -7,7 +7,7 @@ import {useEffect} from "react"; ...@@ -7,7 +7,7 @@ import {useEffect} from "react";
import {showTables} from "@/components/Studio/StudioEvent/DDL"; import {showTables} from "@/components/Studio/StudioEvent/DDL";
import {JarStateType} from "@/pages/Jar/model"; import {JarStateType} from "@/pages/Jar/model";
import {Scrollbars} from "react-custom-scrollbars"; import {Scrollbars} from "react-custom-scrollbars";
import {RUN_MODE} from "@/components/Studio/StudioRightTool/StudioSetting/conf"; import {RUN_MODE} from "@/components/Studio/conf";
const {Option} = Select; const {Option} = Select;
const {Text} = Typography; const {Text} = Typography;
...@@ -124,7 +124,6 @@ const StudioSetting = (props: any) => { ...@@ -124,7 +124,6 @@ const StudioSetting = (props: any) => {
) : (<Select ) : (<Select
style={{width: '100%'}} style={{width: '100%'}}
placeholder="选择Flink集群" placeholder="选择Flink集群"
defaultValue={0}
optionLabelProp="label" optionLabelProp="label"
onChange={onChangeClusterSession} onChange={onChangeClusterSession}
> >
...@@ -143,7 +142,6 @@ const StudioSetting = (props: any) => { ...@@ -143,7 +142,6 @@ const StudioSetting = (props: any) => {
<Select <Select
style={{width: '100%'}} style={{width: '100%'}}
placeholder="选择Flink集群配置" placeholder="选择Flink集群配置"
defaultValue={0}
optionLabelProp="label" optionLabelProp="label"
> >
{getClusterConfigurationOptions()} {getClusterConfigurationOptions()}
......
@import '~antd/es/style/themes/default.less';
.form_setting{
padding-left: 10px;
}
.form_item{
margin-bottom: 5px;
}
import {connect} from "umi";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {
Form, InputNumber, Select, Tag, Row, Col, Tooltip, Button,
} from "antd";
import {MinusSquareOutlined} from "@ant-design/icons";
import styles from "./index.less";
import {useEffect, useState} from "react";
import { Scrollbars } from 'react-custom-scrollbars';
const { Option } = Select;
const StudioSqlConfig = (props: any) => {
const {current,form,dispatch,tabs,database,toolHeight} = props;
form.setFieldsValue(current.task);
const onValuesChange = (change:any,all:any)=>{
let newTabs = tabs;
for(let i=0;i<newTabs.panes.length;i++){
if(newTabs.panes[i].key==newTabs.activeKey){
for(let key in change){
newTabs.panes[i].task[key]=change[key];
}
break;
}
}
dispatch&&dispatch({
type: "Studio/saveTabs",
payload: newTabs,
});
};
const getDataBaseOptions = () => {
const itemList = [];
for (const item of database) {
const tag = (<><Tag color={item.enabled ? "processing" : "error"}>{item.type}</Tag>{item.alias}</>);
itemList.push(<Option key={item.id} value={item.id} label={tag}>
{tag}
</Option>)
}
return itemList;
};
return (
<>
<Row>
<Col span={24}>
<div style={{float: "right"}}>
<Tooltip title="最小化">
<Button
type="text"
icon={<MinusSquareOutlined />}
/>
</Tooltip>
</div>
</Col>
</Row>
<Scrollbars style={{height:(toolHeight-32)}}>
<Form
form={form}
layout="vertical"
className={styles.form_setting}
onValuesChange={onValuesChange}
>
<Row>
<Col span={24}>
<Form.Item label="数据源" tooltip={`选择 Sql 语句执行的数据源`}
name="databaseId"
className={styles.form_item}>
<Select
style={{width: '100%'}}
placeholder="选择数据源"
optionLabelProp="label"
>
{getDataBaseOptions()}
</Select>
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="最大行数" className={styles.form_item} name="maxRowNum"
tooltip='预览数据的最大行数'
>
<InputNumber min={1} max={9999} defaultValue={100} />
</Form.Item>
</Col>
</Row>
</Form>
</Scrollbars>
</>
);
};
export default connect(({Studio}: { Studio: StateType }) => ({
database: Studio.database,
current: Studio.current,
tabs: Studio.tabs,
toolHeight: Studio.toolHeight,
}))(StudioSqlConfig);
...@@ -6,19 +6,29 @@ import styles from "./index.less"; ...@@ -6,19 +6,29 @@ import styles from "./index.less";
import StudioConfig from "./StudioConfig"; import StudioConfig from "./StudioConfig";
import StudioSetting from "./StudioSetting"; import StudioSetting from "./StudioSetting";
import StudioSavePoint from "./StudioSavePoint"; import StudioSavePoint from "./StudioSavePoint";
import StudioSqlConfig from "./StudioSqlConfig";
import {DIALECT} from "@/components/Studio/conf";
const { TabPane } = Tabs; const { TabPane } = Tabs;
const StudioRightTool = (props:any) => { const StudioRightTool = (props:any) => {
// const [form] = Form.useForm();
const {form,toolHeight} = props; const {current,form,toolHeight} = props;
return (
<Tabs defaultActiveKey="1" size="small" tabPosition="right" style={{ height: toolHeight}}> const renderSqlContent = () => {
<TabPane tab={<span><SettingOutlined /> 作业配置</span>} key="StudioSetting" > return (<>
<StudioSetting form={form} /> <TabPane tab={<span><ScheduleOutlined /> 执行配置</span>} key="StudioConfig" >
<StudioSqlConfig form={form}/>
</TabPane> </TabPane>
</>)
};
const renderFlinkSqlContent = () => {
return (<><TabPane tab={<span><SettingOutlined /> 作业配置</span>} key="StudioSetting" >
<StudioSetting form={form} />
</TabPane>
<TabPane tab={<span><ScheduleOutlined /> 执行配置</span>} key="StudioConfig" > <TabPane tab={<span><ScheduleOutlined /> 执行配置</span>} key="StudioConfig" >
<StudioConfig form={form}/> <StudioConfig form={form}/>
</TabPane> </TabPane>
...@@ -27,7 +37,12 @@ const StudioRightTool = (props:any) => { ...@@ -27,7 +37,12 @@ const StudioRightTool = (props:any) => {
</TabPane> </TabPane>
<TabPane tab={<span><AuditOutlined /> 审计</span>} key="4" > <TabPane tab={<span><AuditOutlined /> 审计</span>} key="4" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane> </TabPane></>)
};
return (
<Tabs defaultActiveKey="1" size="small" tabPosition="right" style={{ height: toolHeight}}>
{current.task.dialect === DIALECT.SQL ? renderSqlContent(): renderFlinkSqlContent()}
</Tabs> </Tabs>
); );
}; };
...@@ -35,4 +50,5 @@ const StudioRightTool = (props:any) => { ...@@ -35,4 +50,5 @@ const StudioRightTool = (props:any) => {
export default connect(({ Studio }: { Studio: StateType }) => ({ export default connect(({ Studio }: { Studio: StateType }) => ({
sql: Studio.sql, sql: Studio.sql,
toolHeight: Studio.toolHeight, toolHeight: Studio.toolHeight,
current: Studio.current,
}))(StudioRightTool); }))(StudioRightTool);
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import {Form, Button, Input, Modal} from 'antd'; import {Form, Button, Input, Modal,Select} from 'antd';
import type {TaskTableListItem} from '../data.d'; import type {TaskTableListItem} from '../data.d';
import {DIALECT} from "@/components/Studio/conf";
const {Option} = Select;
export type UpdateFormProps = { export type UpdateFormProps = {
onCancel: (flag?: boolean, formVals?: Partial<TaskTableListItem>) => void; onCancel: (flag?: boolean, formVals?: Partial<TaskTableListItem>) => void;
...@@ -11,14 +14,12 @@ export type UpdateFormProps = { ...@@ -11,14 +14,12 @@ export type UpdateFormProps = {
values: Partial<TaskTableListItem>; values: Partial<TaskTableListItem>;
}; };
const FormItem = Form.Item;
const formLayout = { const formLayout = {
labelCol: {span: 7}, labelCol: {span: 7},
wrapperCol: {span: 13}, wrapperCol: {span: 13},
}; };
const UpdateTaskForm: React.FC<UpdateFormProps> = (props) => { const SimpleTaskForm: React.FC<UpdateFormProps> = (props) => {
const [formVals, setFormVals] = useState<Partial<TaskTableListItem>>({ const [formVals, setFormVals] = useState<Partial<TaskTableListItem>>({
id: props.values.id, id: props.values.id,
name: props.values.name, name: props.values.name,
...@@ -45,18 +46,28 @@ const UpdateTaskForm: React.FC<UpdateFormProps> = (props) => { ...@@ -45,18 +46,28 @@ const UpdateTaskForm: React.FC<UpdateFormProps> = (props) => {
const renderContent = () => { const renderContent = () => {
return ( return (
<> <>
<FormItem {isCreate?(<Form.Item
label="作业类型" name="dialect"
tooltip='指定作业类型,默认为 FlinkSql'
>
<Select defaultValue={DIALECT.FLINKSQL} value={DIALECT.FLINKSQL}>
<Option value={DIALECT.FLINKSQL}>FlinkSql</Option>
<Option value={DIALECT.SQL}>Sql</Option>
<Option value={DIALECT.JAVA}>Java</Option>
</Select>
</Form.Item>):undefined}
<Form.Item
name="name" name="name"
label="名称" label="名称"
rules={[{required: true, message: '请输入唯一名称!'}]}> rules={[{required: true, message: '请输入唯一名称!'}]}>
<Input placeholder="请输入"/> <Input placeholder="请输入"/>
</FormItem> </Form.Item>
<FormItem <Form.Item
name="alias" name="alias"
label="别名" label="别名"
rules={[{required: true, message: '请输入别名!'}]}> rules={[{required: true, message: '请输入别名!'}]}>
<Input placeholder="请输入"/> <Input placeholder="请输入"/>
</FormItem> </Form.Item>
</> </>
); );
}; };
...@@ -89,6 +100,7 @@ const UpdateTaskForm: React.FC<UpdateFormProps> = (props) => { ...@@ -89,6 +100,7 @@ const UpdateTaskForm: React.FC<UpdateFormProps> = (props) => {
id: formVals.id, id: formVals.id,
name: formVals.name, name: formVals.name,
alias: formVals.alias, alias: formVals.alias,
dialect: formVals.dialect,
parentId: formVals.parentId, parentId: formVals.parentId,
}} }}
> >
...@@ -98,4 +110,4 @@ const UpdateTaskForm: React.FC<UpdateFormProps> = (props) => { ...@@ -98,4 +110,4 @@ const UpdateTaskForm: React.FC<UpdateFormProps> = (props) => {
); );
}; };
export default UpdateTaskForm; export default SimpleTaskForm;
...@@ -9,5 +9,6 @@ export type TaskTableListItem = { ...@@ -9,5 +9,6 @@ export type TaskTableListItem = {
id: number, id: number,
name: string, name: string,
alias: string, alias: string,
dialect: string,
parentId: number, parentId: number,
}; };
...@@ -12,7 +12,7 @@ import { ...@@ -12,7 +12,7 @@ import {
} from "@/components/Common/crud"; } from "@/components/Common/crud";
import UpdateCatalogueForm from './components/UpdateCatalogueForm'; import UpdateCatalogueForm from './components/UpdateCatalogueForm';
import {ActionType} from "@ant-design/pro-table"; import {ActionType} from "@ant-design/pro-table";
import UpdateTaskForm from "@/components/Studio/StudioTree/components/UpdateTaskForm"; import SimpleTaskForm from "@/components/Studio/StudioTree/components/SimpleTaskForm";
import { Scrollbars } from 'react-custom-scrollbars'; import { Scrollbars } from 'react-custom-scrollbars';
const { DirectoryTree } = Tree; const { DirectoryTree } = Tree;
const {Search} = Input; const {Search} = Input;
...@@ -392,7 +392,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => { ...@@ -392,7 +392,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
/> />
) : null} ) : null}
{updateTaskModalVisible? ( {updateTaskModalVisible? (
<UpdateTaskForm <SimpleTaskForm
onSubmit={async (value) => { onSubmit={async (value) => {
const datas = await handleAddOrUpdateWithResult('/api/catalogue/createTask',value); const datas = await handleAddOrUpdateWithResult('/api/catalogue/createTask',value);
if (datas) { if (datas) {
......
...@@ -5,3 +5,9 @@ export const RUN_MODE = { ...@@ -5,3 +5,9 @@ export const RUN_MODE = {
YARN_PER_JOB:'yarn-per-job', YARN_PER_JOB:'yarn-per-job',
YARN_APPLICATION:'yarn-application', YARN_APPLICATION:'yarn-application',
}; };
export const DIALECT = {
FLINKSQL:'FlinkSql',
SQL:'Sql',
JAVA:'Java',
};
...@@ -55,6 +55,7 @@ export type TaskType = { ...@@ -55,6 +55,7 @@ export type TaskType = {
catalogueId?: number, catalogueId?: number,
name?: string, name?: string,
alias?: string, alias?: string,
dialect?: string,
type?: string, type?: string,
checkPoint?: number, checkPoint?: number,
savePointStrategy?: number, savePointStrategy?: number,
...@@ -67,6 +68,8 @@ export type TaskType = { ...@@ -67,6 +68,8 @@ export type TaskType = {
clusterName?: string, clusterName?: string,
clusterConfigurationId?: number, clusterConfigurationId?: number,
clusterConfigurationName?: string, clusterConfigurationName?: string,
databaseId?: number,
databaseName?: string,
jarId?: number, jarId?: number,
note?: string, note?: string,
enabled?: boolean, enabled?: boolean,
...@@ -194,7 +197,7 @@ const Model: ModelType = { ...@@ -194,7 +197,7 @@ const Model: ModelType = {
isModified: false, isModified: false,
task: { task: {
jobName: '草稿', jobName: '草稿',
// type: 'standalone', type: 'local',
checkPoint: 0, checkPoint: 0,
savePointStrategy: 0, savePointStrategy: 0,
savePointPath: '', savePointPath: '',
...@@ -205,11 +208,14 @@ const Model: ModelType = { ...@@ -205,11 +208,14 @@ const Model: ModelType = {
clusterName: "本地环境", clusterName: "本地环境",
clusterConfigurationId:undefined, clusterConfigurationId:undefined,
clusterConfigurationName:undefined, clusterConfigurationName:undefined,
databaseId:undefined,
databaseName:undefined,
jarId:undefined, jarId:undefined,
maxRowNum: 100, maxRowNum: 100,
config: [], config: [],
session: '', session: '',
alias: '草稿', alias: '草稿',
dialect: 'FlinkSql',
useResult:true, useResult:true,
useSession:false, useSession:false,
useRemote:false, useRemote:false,
...@@ -234,7 +240,7 @@ const Model: ModelType = { ...@@ -234,7 +240,7 @@ const Model: ModelType = {
path: ['草稿'], path: ['草稿'],
task: { task: {
jobName: '草稿', jobName: '草稿',
// type: 'standalone', type: 'local',
checkPoint: 0, checkPoint: 0,
savePointStrategy: 0, savePointStrategy: 0,
savePointPath: '', savePointPath: '',
...@@ -245,11 +251,14 @@ const Model: ModelType = { ...@@ -245,11 +251,14 @@ const Model: ModelType = {
clusterName: "本地环境", clusterName: "本地环境",
clusterConfigurationId:undefined, clusterConfigurationId:undefined,
clusterConfigurationName:undefined, clusterConfigurationName:undefined,
databaseId:undefined,
databaseName:undefined,
jarId:undefined, jarId:undefined,
session: '', session: '',
config: [], config: [],
maxRowNum: 100, maxRowNum: 100,
alias: '草稿', alias: '草稿',
dialect: 'FlinkSql',
useResult:true, useResult:true,
useSession:false, useSession:false,
useRemote:false, useRemote:false,
......
...@@ -2,6 +2,7 @@ export type TaskTableListItem = { ...@@ -2,6 +2,7 @@ export type TaskTableListItem = {
id: number, id: number,
name: string, name: string,
alias: string, alias: string,
dialect: string,
type: string, type: string,
checkPoint: number, checkPoint: number,
savePointPath: string, savePointPath: string,
...@@ -9,6 +10,10 @@ export type TaskTableListItem = { ...@@ -9,6 +10,10 @@ export type TaskTableListItem = {
fragment: boolean, fragment: boolean,
clusterId: number, clusterId: number,
clusterName: string, clusterName: string,
clusterConfigurationId: number,
clusterConfigurationName: string,
databaseId: number,
databaseName: string,
note: string, note: string,
enabled: boolean, enabled: boolean,
createTime: Date, createTime: Date,
......
...@@ -478,6 +478,9 @@ export default (): React.ReactNode => { ...@@ -478,6 +478,9 @@ export default (): React.ReactNode => {
<li> <li>
<Link>新增 OpenAPI 的执行Jar、停止、SavePoint接口</Link> <Link>新增 OpenAPI 的执行Jar、停止、SavePoint接口</Link>
</li> </li>
<li>
<Link>新增数据源的 Sql 作业语法校验</Link>
</li>
</ul> </ul>
</Paragraph> </Paragraph>
</Timeline.Item> </Timeline.Item>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment