Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
dlink
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhaowei
dlink
Commits
372436bd
Commit
372436bd
authored
Dec 29, 2021
by
wenmo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新增 Mysql,Oracle,PostGreSql,ClickHouse,Doris,Java 方言及图标
parent
a1bbe440
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
402 additions
and
99 deletions
+402
-99
README.md
README.md
+61
-50
SqlDTO.java
dlink-admin/src/main/java/com/dlink/dto/SqlDTO.java
+28
-0
StudioService.java
...-admin/src/main/java/com/dlink/service/StudioService.java
+3
-0
StudioServiceImpl.java
...c/main/java/com/dlink/service/impl/StudioServiceImpl.java
+10
-12
TaskServiceImpl.java
...src/main/java/com/dlink/service/impl/TaskServiceImpl.java
+7
-0
Dialect.java
dlink-core/src/main/java/com/dlink/config/Dialect.java
+13
-1
AbstractJdbcDriver.java
...in/java/com/dlink/metadata/driver/AbstractJdbcDriver.java
+3
-0
index.tsx
dlink-web/src/components/Studio/StudioMenu/index.tsx
+4
-4
index.tsx
...mponents/Studio/StudioRightTool/StudioSqlConfig/index.tsx
+6
-4
index.tsx
dlink-web/src/components/Studio/StudioRightTool/index.tsx
+10
-5
index.tsx
dlink-web/src/components/Studio/StudioTabs/index.tsx
+3
-1
Function.ts
dlink-web/src/components/Studio/StudioTree/Function.ts
+1
-2
SimpleTaskForm.tsx
...omponents/Studio/StudioTree/components/SimpleTaskForm.tsx
+6
-1
index.tsx
dlink-web/src/components/Studio/StudioTree/index.tsx
+9
-19
conf.ts
dlink-web/src/components/Studio/conf.ts
+19
-0
icon.tsx
dlink-web/src/components/Studio/icon.tsx
+216
-0
Welcome.tsx
dlink-web/src/pages/Welcome.tsx
+3
-0
No files found.
README.md
View file @
372436bd
This diff is collapsed.
Click to expand it.
dlink-admin/src/main/java/com/dlink/dto/SqlDTO.java
0 → 100644
View file @
372436bd
package
com
.
dlink
.
dto
;
import
lombok.Getter
;
import
lombok.Setter
;
/**
* SqlDTO
*
* @author wenmo
* @since 2021/12/29 19:42
*/
@Getter
@Setter
public
class
SqlDTO
{
private
String
statement
;
private
Integer
databaseId
;
private
Integer
maxRowNum
;
public
SqlDTO
(
String
statement
,
Integer
databaseId
,
Integer
maxRowNum
)
{
this
.
statement
=
statement
;
this
.
databaseId
=
databaseId
;
this
.
maxRowNum
=
maxRowNum
;
}
public
static
SqlDTO
build
(
String
statement
,
Integer
databaseId
,
Integer
maxRowNum
){
return
new
SqlDTO
(
statement
,
databaseId
,
maxRowNum
);
}
}
dlink-admin/src/main/java/com/dlink/service/StudioService.java
View file @
372436bd
package
com
.
dlink
.
service
;
import
com.dlink.dto.SessionDTO
;
import
com.dlink.dto.SqlDTO
;
import
com.dlink.dto.StudioDDLDTO
;
import
com.dlink.dto.StudioExecuteDTO
;
import
com.dlink.explainer.ca.ColumnCANode
;
...
...
@@ -25,6 +26,8 @@ public interface StudioService {
JobResult
executeSql
(
StudioExecuteDTO
studioExecuteDTO
);
JobResult
executeCommonSql
(
SqlDTO
sqlDTO
);
IResult
executeDDL
(
StudioDDLDTO
studioDDLDTO
);
List
<
SqlExplainResult
>
explainSql
(
StudioExecuteDTO
studioExecuteDTO
);
...
...
dlink-admin/src/main/java/com/dlink/service/impl/StudioServiceImpl.java
View file @
372436bd
...
...
@@ -3,10 +3,7 @@ package com.dlink.service.impl;
import
com.dlink.api.FlinkAPI
;
import
com.dlink.assertion.Asserts
;
import
com.dlink.config.Dialect
;
import
com.dlink.dto.AbstractStatementDTO
;
import
com.dlink.dto.SessionDTO
;
import
com.dlink.dto.StudioDDLDTO
;
import
com.dlink.dto.StudioExecuteDTO
;
import
com.dlink.dto.*
;
import
com.dlink.explainer.ca.CABuilder
;
import
com.dlink.explainer.ca.ColumnCANode
;
import
com.dlink.explainer.ca.TableCANode
;
...
...
@@ -77,8 +74,9 @@ public class StudioServiceImpl implements StudioService {
@Override
public
JobResult
executeSql
(
StudioExecuteDTO
studioExecuteDTO
)
{
if
(
Dialect
.
SQL
.
equalsVal
(
studioExecuteDTO
.
getDialect
())){
return
executeCommonSql
(
studioExecuteDTO
);
if
(
Dialect
.
isSql
(
studioExecuteDTO
.
getDialect
())){
return
executeCommonSql
(
SqlDTO
.
build
(
studioExecuteDTO
.
getStatement
(),
studioExecuteDTO
.
getDatabaseId
(),
studioExecuteDTO
.
getMaxRowNum
()));
}
else
{
return
executeFlinkSql
(
studioExecuteDTO
);
}
...
...
@@ -97,17 +95,17 @@ public class StudioServiceImpl implements StudioService {
return
jobResult
;
}
p
rivate
JobResult
executeCommonSql
(
StudioExecuteDTO
studioExecute
DTO
)
{
p
ublic
JobResult
executeCommonSql
(
SqlDTO
sql
DTO
)
{
JobResult
result
=
new
JobResult
();
result
.
setStatement
(
s
tudioExecute
DTO
.
getStatement
());
result
.
setStatement
(
s
ql
DTO
.
getStatement
());
result
.
setStartTime
(
LocalDateTime
.
now
());
if
(
Asserts
.
isNull
(
s
tudioExecute
DTO
.
getDatabaseId
())){
if
(
Asserts
.
isNull
(
s
ql
DTO
.
getDatabaseId
())){
result
.
setSuccess
(
false
);
result
.
setError
(
"请指定数据源"
);
result
.
setEndTime
(
LocalDateTime
.
now
());
return
result
;
}
else
{
DataBase
dataBase
=
dataBaseService
.
getById
(
s
tudioExecute
DTO
.
getDatabaseId
());
DataBase
dataBase
=
dataBaseService
.
getById
(
s
ql
DTO
.
getDatabaseId
());
if
(
Asserts
.
isNull
(
dataBase
)){
result
.
setSuccess
(
false
);
result
.
setError
(
"数据源不存在"
);
...
...
@@ -115,7 +113,7 @@ public class StudioServiceImpl implements StudioService {
return
result
;
}
Driver
driver
=
Driver
.
build
(
dataBase
.
getDriverConfig
()).
connect
();
JdbcSelectResult
selectResult
=
driver
.
query
(
s
tudioExecuteDTO
.
getStatement
(),
studioExecute
DTO
.
getMaxRowNum
());
JdbcSelectResult
selectResult
=
driver
.
query
(
s
qlDTO
.
getStatement
(),
sql
DTO
.
getMaxRowNum
());
driver
.
close
();
result
.
setResult
(
selectResult
);
if
(
selectResult
.
isSuccess
()){
...
...
@@ -141,7 +139,7 @@ public class StudioServiceImpl implements StudioService {
@Override
public
List
<
SqlExplainResult
>
explainSql
(
StudioExecuteDTO
studioExecuteDTO
)
{
if
(
Dialect
.
SQL
.
equalsVa
l
(
studioExecuteDTO
.
getDialect
())){
if
(
Dialect
.
isSq
l
(
studioExecuteDTO
.
getDialect
())){
return
explainCommonSql
(
studioExecuteDTO
);
}
else
{
return
explainFlinkSql
(
studioExecuteDTO
);
...
...
dlink-admin/src/main/java/com/dlink/service/impl/TaskServiceImpl.java
View file @
372436bd
...
...
@@ -6,6 +6,7 @@ import com.dlink.assertion.Asserts;
import
com.dlink.assertion.Tips
;
import
com.dlink.config.Dialect
;
import
com.dlink.db.service.impl.SuperServiceImpl
;
import
com.dlink.dto.SqlDTO
;
import
com.dlink.gateway.GatewayType
;
import
com.dlink.job.JobConfig
;
import
com.dlink.job.JobManager
;
...
...
@@ -39,6 +40,8 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
private
SavepointsService
savepointsService
;
@Autowired
private
JarService
jarService
;
@Autowired
private
StudioService
studioService
;
@Value
(
"${spring.datasource.driver-class-name}"
)
private
String
driver
;
...
...
@@ -57,6 +60,10 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
public
JobResult
submitByTaskId
(
Integer
id
)
{
Task
task
=
this
.
getTaskInfoById
(
id
);
Asserts
.
checkNull
(
task
,
Tips
.
TASK_NOT_EXIST
);
if
(
Dialect
.
isSql
(
task
.
getDialect
())){
return
studioService
.
executeCommonSql
(
SqlDTO
.
build
(
task
.
getStatement
(),
task
.
getDatabaseId
(),
null
));
}
boolean
isJarTask
=
isJarTask
(
task
);
if
(!
isJarTask
&&
Asserts
.
isNotNull
(
task
.
getEnvId
())){
Task
envTask
=
getTaskInfoById
(
task
.
getEnvId
());
...
...
dlink-core/src/main/java/com/dlink/config/Dialect.java
View file @
372436bd
...
...
@@ -10,7 +10,9 @@ import com.dlink.assertion.Asserts;
**/
public
enum
Dialect
{
FLINKSQL
(
"FlinkSql"
),
FLINKSQLENV
(
"FlinkSqlEnv"
),
SQL
(
"Sql"
),
JAVA
(
"Java"
);
FLINKSQL
(
"FlinkSql"
),
FLINKSQLENV
(
"FlinkSqlEnv"
),
SQL
(
"Sql"
),
JAVA
(
"Java"
),
MYSQL
(
"Mysql"
),
ORACLE
(
"Oracle"
),
POSTGRESQL
(
"PostGreSql"
),
CLICKHOUSE
(
"ClickHouse"
),
DORIS
(
"Doris"
);
private
String
value
;
...
...
@@ -36,5 +38,15 @@ public enum Dialect {
}
return
Dialect
.
FLINKSQL
;
}
public
static
boolean
isSql
(
String
value
){
Dialect
dialect
=
Dialect
.
get
(
value
);
switch
(
dialect
){
case
SQL:
case
MYSQL:
case
ORACLE:
case
POSTGRESQL:
case
CLICKHOUSE:
case
DORIS:
return
true
;
default
:
return
false
;
}
}
}
dlink-metadata/dlink-metadata-base/src/main/java/com/dlink/metadata/driver/AbstractJdbcDriver.java
View file @
372436bd
...
...
@@ -248,6 +248,9 @@ public abstract class AbstractJdbcDriver extends AbstractDriver {
@Override
public
JdbcSelectResult
query
(
String
sql
,
Integer
limit
)
{
if
(
Asserts
.
isNull
(
limit
)){
limit
=
100
;
}
JdbcSelectResult
result
=
new
JdbcSelectResult
();
List
<
HashMap
<
String
,
Object
>>
datas
=
new
ArrayList
<>();
List
<
Column
>
columns
=
new
ArrayList
<>();
...
...
dlink-web/src/components/Studio/StudioMenu/index.tsx
View file @
372436bd
...
...
@@ -18,7 +18,7 @@ import StudioGraph from "./StudioGraph";
import
{
showCluster
,
showTables
,
saveTask
}
from
"@/components/Studio/StudioEvent/DDL"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
StudioExplain
from
"../StudioConsole/StudioExplain"
;
import
{
DIALECT
}
from
"@/components/Studio/conf"
;
import
{
DIALECT
,
isSql
}
from
"@/components/Studio/conf"
;
const
menu
=
(
<
Menu
>
...
...
@@ -358,7 +358,7 @@ const StudioMenu = (props: any) => {
onClick=
{
onCheckSql
}
/>
</
Tooltip
>
{
current
.
task
.
dialect
==
DIALECT
.
FLINKSQL
&&
(
{
current
.
task
.
dialect
==
=
DIALECT
.
FLINKSQL
&&
(
<
Tooltip
title=
"获取当前的 FlinkSql 的执行图"
>
<
Button
type=
"text"
...
...
@@ -366,7 +366,7 @@ const StudioMenu = (props: any) => {
onClick=
{
onGetStreamGraph
}
/>
</
Tooltip
>)
}
{
(
current
.
task
.
dialect
==
DIALECT
.
FLINKSQL
||
current
.
task
.
dialect
==
DIALECT
.
SQL
)
&&
(
{
(
current
.
task
.
dialect
==
=
DIALECT
.
FLINKSQL
||
isSql
(
current
.
task
.
dialect
)
)
&&
(
<
Tooltip
title=
"执行当前的 FlinkSql"
>
<
Button
type=
"text"
...
...
@@ -375,7 +375,7 @@ const StudioMenu = (props: any) => {
onClick=
{
execute
}
/>
</
Tooltip
>)
}
{
current
.
task
.
dialect
==
DIALECT
.
FLINKSQL
&&
(<>
{
(
current
.
task
.
dialect
===
DIALECT
.
FLINKSQL
||
isSql
(
current
.
task
.
dialect
))
&&
(<>
<
Tooltip
title=
"提交当前的作业到集群"
>
<
Button
type=
"text"
...
...
dlink-web/src/components/Studio/StudioRightTool/StudioSqlConfig/index.tsx
View file @
372436bd
...
...
@@ -38,10 +38,12 @@ const StudioSqlConfig = (props: any) => {
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
>)
if
(
item
.
type
.
toUpperCase
()
===
current
.
task
.
dialect
.
toUpperCase
())
{
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
;
};
...
...
dlink-web/src/components/Studio/StudioRightTool/index.tsx
View file @
372436bd
...
...
@@ -8,7 +8,7 @@ import StudioSetting from "./StudioSetting";
import
StudioSavePoint
from
"./StudioSavePoint"
;
import
StudioEnvSetting
from
"./StudioEnvSetting"
;
import
StudioSqlConfig
from
"./StudioSqlConfig"
;
import
{
DIALECT
}
from
"@/components/Studio/conf"
;
import
{
DIALECT
,
isSql
}
from
"@/components/Studio/conf"
;
const
{
TabPane
}
=
Tabs
;
...
...
@@ -19,11 +19,16 @@ const StudioRightTool = (props:any) => {
const
{
current
,
form
,
toolHeight
}
=
props
;
const
renderContent
=
()
=>
{
switch
(
current
.
task
.
dialect
){
case
DIALECT
.
SQL
:
return
renderSqlContent
();
case
DIALECT
.
FLINKSQLENV
:
return
renderEnvContent
();
default
:
return
renderFlinkSqlContent
();
if
(
isSql
(
current
.
task
.
dialect
)){
return
renderSqlContent
();
}
if
(
DIALECT
.
FLINKSQLENV
===
current
.
task
.
dialect
){
return
renderEnvContent
();
}
if
(
DIALECT
.
JAVA
===
current
.
task
.
dialect
){
return
undefined
;
}
return
renderFlinkSqlContent
();
};
const
renderSqlContent
=
()
=>
{
...
...
dlink-web/src/components/Studio/StudioTabs/index.tsx
View file @
372436bd
...
...
@@ -5,6 +5,7 @@ import {StateType} from "@/pages/FlinkSqlStudio/model";
import
styles
from
'./index.less'
;
import
StudioEdit
from
'../StudioEdit'
;
import
{
saveTask
}
from
"@/components/Studio/StudioEvent/DDL"
;
import
{
DIALECT
}
from
'../conf'
;
const
{
TabPane
}
=
Tabs
;
...
...
@@ -79,7 +80,8 @@ const EditorTabs = (props: any) => {
>
{
tabs
.
panes
.
map
(
pane
=>
(
<
TabPane
tab=
{
pane
.
title
}
key=
{
pane
.
key
}
closable=
{
pane
.
closable
}
>
<
StudioEdit
tabsKey=
{
pane
.
key
}
height=
{
(
toolHeight
-
32
)
}
width=
{
width
}
/>
<
StudioEdit
tabsKey=
{
pane
.
key
}
height=
{
(
toolHeight
-
32
)
}
width=
{
width
}
language=
{
current
.
task
.
dialect
===
DIALECT
.
JAVA
?
'java'
:
'sql'
}
/>
</
TabPane
>
))
}
</
Tabs
>
...
...
dlink-web/src/components/Studio/StudioTree/Function.ts
View file @
372436bd
...
...
@@ -44,8 +44,7 @@ export function getTreeNodeByKey(node:any[], key:number) {
if
(
result
){
return
result
;
}
}
else
{
return
null
;
}
}
return
null
;
}
dlink-web/src/components/Studio/StudioTree/components/SimpleTaskForm.tsx
View file @
372436bd
...
...
@@ -53,8 +53,13 @@ const SimpleTaskForm: React.FC<UpdateFormProps> = (props) => {
<
Select
defaultValue=
{
DIALECT
.
FLINKSQL
}
value=
{
DIALECT
.
FLINKSQL
}
>
<
Option
value=
{
DIALECT
.
FLINKSQL
}
>
FlinkSql
</
Option
>
<
Option
value=
{
DIALECT
.
FLINKSQLENV
}
>
FlinkSql 环境
</
Option
>
<
Option
value=
{
DIALECT
.
SQL
}
>
Sql
</
Option
>
<
Option
value=
{
DIALECT
.
MYSQL
}
>
Mysql
</
Option
>
<
Option
value=
{
DIALECT
.
ORACLE
}
>
Oracle
</
Option
>
<
Option
value=
{
DIALECT
.
POSTGRESQL
}
>
PostGreSql
</
Option
>
<
Option
value=
{
DIALECT
.
CLICKHOUSE
}
>
ClickHouse
</
Option
>
<
Option
value=
{
DIALECT
.
DORIS
}
>
Doris
</
Option
>
<
Option
value=
{
DIALECT
.
JAVA
}
>
Java
</
Option
>
<
Option
value=
{
DIALECT
.
SQL
}
>
Sql
</
Option
>
</
Select
>
</
Form
.
Item
>):
undefined
}
<
Form
.
Item
...
...
dlink-web/src/components/Studio/StudioTree/index.tsx
View file @
372436bd
...
...
@@ -13,6 +13,8 @@ import {
import
UpdateCatalogueForm
from
'./components/UpdateCatalogueForm'
;
import
SimpleTaskForm
from
"@/components/Studio/StudioTree/components/SimpleTaskForm"
;
import
{
Scrollbars
}
from
"react-custom-scrollbars"
;
import
{
getIcon
}
from
"@/components/Studio/icon"
;
const
{
DirectoryTree
}
=
Tree
;
...
...
@@ -32,25 +34,9 @@ type RightClickMenu = {
categoryName
:
string
};
// const getParentKey = (key:any, tree:any) => {
// let parentKey;
// for (let i = 0; i < tree.length; i++) {
// const node = tree[i];
// if (node.children) {
// if (node.children.some((item:any) => item.key === key)) {
// parentKey = node.key;
// } else if (getParentKey(key, node.children)) {
// parentKey = getParentKey(key, node.children);
// }
// }
// }
// return parentKey;
// };
const
StudioTree
:
React
.
FC
<
StudioTreeProps
>
=
(
props
)
=>
{
const
{
rightClickMenu
,
dispatch
,
tabs
,
refs
,
toolHeight
}
=
props
;
const
[
treeData
,
setTreeData
]
=
useState
<
TreeDataNode
[]
>
();
//const [dataList, setDataList] = useState<[]>();
const
[
expandedKeys
,
setExpandedKeys
]
=
useState
<
Key
[]
>
();
const
[
rightClickNodeTreeItem
,
setRightClickNodeTreeItem
]
=
useState
<
RightClickMenu
>
();
const
[
updateCatalogueModalVisible
,
handleUpdateCatalogueModalVisible
]
=
useState
<
boolean
>
(
false
);
...
...
@@ -60,7 +46,7 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
const
[
taskFormValues
,
setTaskFormValues
]
=
useState
({});
const
[
rightClickNode
,
setRightClickNode
]
=
useState
<
TreeDataNode
>
();
const
[
available
,
setAvailable
]
=
useState
<
boolean
>
(
true
);
let
sref
:
any
=
React
.
createRef
<
Scrollbars
>
();
const
sref
:
any
=
React
.
createRef
<
Scrollbars
>
();
const
getTreeData
=
async
()
=>
{
const
result
=
await
getCatalogueTreeData
();
...
...
@@ -69,8 +55,10 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
){
list
[
i
].
title
=
list
[
i
].
name
;
list
[
i
].
key
=
list
[
i
].
id
;
if
(
list
[
i
].
isLeaf
){
list
[
i
].
icon
=
getIcon
(
list
[
i
].
type
);
}
}
// setDataList(list);
data
=
convertToTreeData
(
data
,
0
);
setTreeData
(
data
);
};
...
...
@@ -82,8 +70,10 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
){
list
[
i
].
title
=
list
[
i
].
name
;
list
[
i
].
key
=
list
[
i
].
id
;
if
(
list
[
i
].
isLeaf
){
list
[
i
].
icon
=
getIcon
(
list
[
i
].
type
);
}
}
//setDataList(list);
data
=
convertToTreeData
(
data
,
0
);
setTreeData
(
data
);
let
node
=
getTreeNodeByKey
(
data
,
key
);
...
...
dlink-web/src/components/Studio/conf.ts
View file @
372436bd
...
...
@@ -12,5 +12,24 @@ export const DIALECT = {
FLINKSQL
:
'FlinkSql'
,
FLINKSQLENV
:
'FlinkSqlEnv'
,
SQL
:
'Sql'
,
MYSQL
:
'Mysql'
,
ORACLE
:
'Oracle'
,
POSTGRESQL
:
'PostGreSql'
,
CLICKHOUSE
:
'ClickHouse'
,
DORIS
:
'Doris'
,
JAVA
:
'Java'
,
};
export
const
isSql
=
(
type
:
string
)
=>
{
switch
(
type
){
case
DIALECT
.
SQL
:
case
DIALECT
.
MYSQL
:
case
DIALECT
.
ORACLE
:
case
DIALECT
.
POSTGRESQL
:
case
DIALECT
.
CLICKHOUSE
:
case
DIALECT
.
DORIS
:
return
true
;
default
:
return
false
;
}
}
dlink-web/src/components/Studio/icon.tsx
0 → 100644
View file @
372436bd
This diff is collapsed.
Click to expand it.
dlink-web/src/pages/Welcome.tsx
View file @
372436bd
...
...
@@ -511,6 +511,9 @@ export default (): React.ReactNode => {
<
li
>
<
Link
>
新增 FlinkSQL 执行环境方言及其应用功能
</
Link
>
</
li
>
<
li
>
<
Link
>
新增 Mysql,Oracle,PostGreSql,ClickHouse,Doris,Java 方言及图标
</
Link
>
</
li
>
</
ul
>
</
Paragraph
>
</
Timeline
.
Item
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment