mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-08-06 01:36:46 +08:00
Merge remote-tracking branch 'origin/developing' into developing
This commit is contained in:
@ -1,3 +1,11 @@
|
||||
# 2.0.4
|
||||
|
||||
## 🐞 Bug Fixes
|
||||
- Default return alias for returned results [Issue #270](https://github.com/chat2db/Chat2DB/issues/270)
|
||||
|
||||
## 🐞 问题修复
|
||||
- 返回结果默认返回别名 [Issue #270](https://github.com/chat2db/Chat2DB/issues/270)
|
||||
|
||||
# 2.0.4
|
||||
## ⭐ New Features
|
||||
- Support DB2 database
|
||||
|
@ -1,9 +1,9 @@
|
||||
/* 在线链接服务仅供平台体验和调试使用,平台不承诺服务的稳定性,企业客户需下载字体包自行发布使用并做好备份。 */
|
||||
@font-face {
|
||||
font-family: 'iconfont';
|
||||
/* Project id 3633546 */
|
||||
src: url('../../assets/font/iconfont.woff2') format('woff2'),
|
||||
url('../../assets/font/iconfont.woff') format('woff'),
|
||||
url('../../assets/font/iconfont.ttf') format('truetype');
|
||||
font-family: 'iconfont'; /* Project id 3633546 */
|
||||
src: url('//at.alicdn.com/t/c/font_3633546_fu54vhe509d.woff2?t=1689606758277') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_3633546_fu54vhe509d.woff?t=1689606758277') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_3633546_fu54vhe509d.ttf?t=1689606758277') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -77,19 +77,19 @@ export const databaseMap: {
|
||||
icon: '\ue655',
|
||||
},
|
||||
[DatabaseTypeCode.PRESTO]: {
|
||||
name: 'Presto',
|
||||
img: moreDBLogo,
|
||||
code: DatabaseTypeCode.PRESTO,
|
||||
port: 8080,
|
||||
icon: '\ue60b',
|
||||
},
|
||||
[DatabaseTypeCode.DB2]: {
|
||||
name: 'DB2',
|
||||
img: moreDBLogo,
|
||||
code: DatabaseTypeCode.DB2,
|
||||
port: 50000,
|
||||
icon: '\ue60a',
|
||||
},
|
||||
name: 'Presto',
|
||||
img: moreDBLogo,
|
||||
code: DatabaseTypeCode.PRESTO,
|
||||
// port: 8080,
|
||||
icon: '\ue60b',
|
||||
},
|
||||
[DatabaseTypeCode.DB2]: {
|
||||
name: 'DB2',
|
||||
img: moreDBLogo,
|
||||
code: DatabaseTypeCode.DB2,
|
||||
// port: 50000,
|
||||
icon: '\ue60a',
|
||||
},
|
||||
[DatabaseTypeCode.OCEANBASE]: {
|
||||
name: 'OceanBase',
|
||||
img: moreDBLogo,
|
||||
|
@ -2,7 +2,7 @@ export default {
|
||||
'setting.title.setting': 'Setting',
|
||||
'setting.nav.basic': 'Basic',
|
||||
'setting.nav.customAi': 'Custom Ai',
|
||||
'setting.nav.proxy': 'Proxy',
|
||||
'setting.nav.proxy': 'Service Path',
|
||||
'setting.nav.aboutUs': 'About Us',
|
||||
'setting.title.backgroundColor': 'Background Color',
|
||||
'setting.title.themeColor': 'Theme Color',
|
||||
|
@ -2,7 +2,7 @@ export default {
|
||||
'setting.title.setting': '设置',
|
||||
'setting.nav.basic': '基础设置',
|
||||
'setting.nav.customAi': '自定义AI',
|
||||
'setting.nav.proxy': '代理设置',
|
||||
'setting.nav.proxy': '服务端地址',
|
||||
'setting.nav.aboutUs': '关于我们',
|
||||
'setting.title.backgroundColor': '背景色',
|
||||
'setting.title.themeColor': '主题色',
|
||||
|
@ -48,13 +48,16 @@ const ConnectionModel: IConnectionModelType = {
|
||||
},
|
||||
|
||||
effects: {
|
||||
*fetchConnectionList(_, { call, put }) {
|
||||
*fetchConnectionList({ callback }, { call, put }) {
|
||||
try {
|
||||
const res = (yield connectionService.getList({ pageNo: 1, pageSize: 999 })) as IPageResponse<IConnectionDetails>;
|
||||
yield put({
|
||||
type: 'setConnectionList',
|
||||
payload: res.data,
|
||||
});
|
||||
if (callback && typeof callback === 'function') {
|
||||
callback(res);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
width: 220px;
|
||||
overflow: hidden;
|
||||
background-color: var(--color-bg-elevated);
|
||||
border: 1px solid var(--color-border-secondary);
|
||||
border-right: 1px solid var(--color-border-secondary);
|
||||
border-top: 0px;
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ function Connections(props: IProps) {
|
||||
getConnectionList();
|
||||
}, []);
|
||||
|
||||
const getConnectionList = async () => {
|
||||
const getConnectionList = () => {
|
||||
dispatch({
|
||||
type: 'connection/fetchConnectionList',
|
||||
});
|
||||
@ -133,15 +133,18 @@ function Connections(props: IProps) {
|
||||
<div ref={volatileRef} className={styles.layoutLeft}>
|
||||
<div className={styles.pageTitle}>{i18n('connection.title.connections')}</div>
|
||||
{renderMenu()}
|
||||
<Button
|
||||
type="primary"
|
||||
className={styles.addConnection}
|
||||
onClick={() => {
|
||||
setCurConnection({});
|
||||
}}
|
||||
>
|
||||
{i18n('connection.button.addConnection')}
|
||||
</Button>
|
||||
{
|
||||
curConnection && Object.keys(curConnection).length &&
|
||||
<Button
|
||||
type="primary"
|
||||
className={styles.addConnection}
|
||||
onClick={() => {
|
||||
setCurConnection({});
|
||||
}}
|
||||
>
|
||||
{i18n('connection.button.addConnection')}
|
||||
</Button>
|
||||
}
|
||||
</div>
|
||||
<div className={styles.layoutRight}>
|
||||
{curConnection && Object.keys(curConnection).length ? (
|
||||
@ -159,29 +162,29 @@ function Connections(props: IProps) {
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.dataBaseList}>
|
||||
{databaseTypeList.map((t) => {
|
||||
return (
|
||||
<div key={t.code} className={styles.databaseItem} onClick={handleCreateConnections.bind(null, t)}>
|
||||
<div className={styles.databaseItemMain}>
|
||||
<div className={styles.databaseItemLeft}>
|
||||
<div className={styles.logoBox}>
|
||||
<Iconfont code={t.icon} />
|
||||
</div>
|
||||
{t.name}
|
||||
</div>
|
||||
<div className={styles.databaseItemRight}>
|
||||
<Iconfont code="" />
|
||||
<div className={styles.dataBaseList}>
|
||||
{databaseTypeList.map((t) => {
|
||||
return (
|
||||
<div key={t.code} className={styles.databaseItem} onClick={handleCreateConnections.bind(null, t)}>
|
||||
<div className={styles.databaseItemMain}>
|
||||
<div className={styles.databaseItemLeft}>
|
||||
<div className={styles.logoBox}>
|
||||
<Iconfont code={t.icon} />
|
||||
</div>
|
||||
{t.name}
|
||||
</div>
|
||||
<div className={styles.databaseItemRight}>
|
||||
<Iconfont code="" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{Array.from({ length: 20 }).map((t, index) => {
|
||||
return <div key={index} className={styles.databaseItemSpacer}></div>;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{Array.from({ length: 20 }).map((t, index) => {
|
||||
return <div key={index} className={styles.databaseItemSpacer}></div>;
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -10,7 +10,7 @@
|
||||
width: 220px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border-secondary);
|
||||
border-right: 1px solid var(--color-border-secondary);
|
||||
border-top: 0px;
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
align-items: center;
|
||||
width: 68px;
|
||||
background-color: var(--color-bg-elevated);
|
||||
border-right: 1px solid var(--color-border-secondary);
|
||||
user-select: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
@import '../../../../../styles/var.less';
|
||||
|
||||
.workspaceHeader{
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
background-color: var(--color-bg-elevated);
|
||||
border-bottom: 1px solid var(--color-border-secondary);
|
||||
}
|
||||
|
||||
.databaseLogo{
|
||||
margin-right: 10px;
|
||||
overflow: hidden;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.refreshBox{
|
||||
cursor: pointer;
|
||||
}
|
||||
.spin{
|
||||
transform: scale(0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.crumbsItem{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.typeIcon{
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.arrow{
|
||||
font-size: 10px;
|
||||
margin: 0px 10px;
|
||||
transform: translateY(1px);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,148 @@
|
||||
import React, { memo, useEffect, useMemo, useState } from 'react';
|
||||
import { connect } from 'umi';
|
||||
import { IConnectionModelType } from '@/models/connection';
|
||||
import { IWorkspaceModelType } from '@/models/workspace';
|
||||
import styles from './index.less';
|
||||
import classnames from 'classnames';
|
||||
import { Cascader, Spin } from 'antd';
|
||||
import Iconfont from '@/components/Iconfont';
|
||||
import { databaseMap } from '@/constants';
|
||||
import { useSafeState } from 'ahooks';
|
||||
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
cascaderOptions: any;
|
||||
connectionModel: IConnectionModelType['state'];
|
||||
workspaceModel: IWorkspaceModelType['state'];
|
||||
dispatch: any;
|
||||
}
|
||||
|
||||
const WorkspaceHeader = memo<IProps>((props) => {
|
||||
const { className, cascaderOptions, connectionModel, workspaceModel, dispatch } = props;
|
||||
const { connectionList, curConnection } = connectionModel;
|
||||
const { curWorkspaceParams } = workspaceModel;
|
||||
const [curSchemaOptions, setCurSchemaOptions] = useState<any>([]);
|
||||
const [cascaderLoading, setCascaderLoading] = useState(false);
|
||||
const connectionListOptions = useMemo(() => {
|
||||
return connectionList?.map(t => {
|
||||
return {
|
||||
value: t.id,
|
||||
label: t.alias
|
||||
}
|
||||
})
|
||||
}, [connectionList])
|
||||
|
||||
useEffect(() => {
|
||||
getConnectionList();
|
||||
}, []);
|
||||
|
||||
const getConnectionList = () => {
|
||||
setCascaderLoading(true)
|
||||
dispatch({
|
||||
type: 'connection/fetchConnectionList',
|
||||
callback: () => {
|
||||
setTimeout(() => {
|
||||
setCascaderLoading(false)
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function connectionChange(id: any, data: any) {
|
||||
connectionList.map(t => {
|
||||
if (t.id === id[0]) {
|
||||
dispatch({
|
||||
type: 'connection/setCurConnection',
|
||||
payload: t
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const databaseChange: any = (valueArr: any, selectedOptions: any) => {
|
||||
|
||||
const curWorkspaceParams = {
|
||||
dataSourceId: curConnection?.id,
|
||||
databaseSourceName: curConnection?.alias,
|
||||
databaseName: selectedOptions[0].value,
|
||||
schemaName: selectedOptions?.[0]?.next?.[0]?.value,
|
||||
databaseType: curConnection?.type,
|
||||
};
|
||||
|
||||
dispatch({
|
||||
type: 'workspace/setCurWorkspaceParams',
|
||||
payload: curWorkspaceParams,
|
||||
});
|
||||
|
||||
setCurSchemaOptions(selectedOptions[0].next)
|
||||
};
|
||||
|
||||
const schemaChange: any = (valueArr: any, selectedOptions: any) => {
|
||||
dispatch({
|
||||
type: 'workspace/setCurWorkspaceParams',
|
||||
payload: { ...curWorkspaceParams, schemaName: selectedOptions[0].value },
|
||||
});
|
||||
}
|
||||
|
||||
function handelRefresh() {
|
||||
getConnectionList()
|
||||
}
|
||||
|
||||
return <div className={styles.workspaceHeader}>
|
||||
<div className={styles.databaseLogo}>
|
||||
{curConnection?.type ?
|
||||
<div className={styles.refreshBox} onClick={handelRefresh}>
|
||||
{cascaderLoading ? <Spin className={styles.spin} /> : <Iconfont className={styles.typeIcon} code={databaseMap[curConnection.type]?.icon} />}
|
||||
</div>
|
||||
:
|
||||
<Iconfont className={styles.typeIcon} code="" />}
|
||||
</div>
|
||||
<Cascader
|
||||
popupClassName={styles.cascaderPopup}
|
||||
options={connectionListOptions}
|
||||
onChange={connectionChange}
|
||||
bordered={false}
|
||||
>
|
||||
<div className={styles.crumbsItem}>
|
||||
<div>{curConnection?.alias}</div>
|
||||
<Iconfont className={styles.arrow} code="" />
|
||||
</div>
|
||||
</Cascader>
|
||||
|
||||
<Cascader
|
||||
popupClassName={styles.cascaderPopup}
|
||||
options={cascaderOptions}
|
||||
onChange={databaseChange}
|
||||
bordered={false}
|
||||
>
|
||||
<div className={styles.crumbsItem}>
|
||||
<div>{curWorkspaceParams.databaseName}</div>
|
||||
{
|
||||
!!curSchemaOptions.length && <Iconfont className={styles.arrow} code="" />
|
||||
}
|
||||
</div>
|
||||
</Cascader>
|
||||
{
|
||||
!!curSchemaOptions.length &&
|
||||
<Cascader
|
||||
popupClassName={styles.cascaderPopup}
|
||||
options={curSchemaOptions}
|
||||
onChange={schemaChange}
|
||||
bordered={false}
|
||||
>
|
||||
<div className={styles.crumbsItem}>
|
||||
<div>{curWorkspaceParams.schemaName}</div>
|
||||
</div>
|
||||
</Cascader>
|
||||
}
|
||||
|
||||
</div >
|
||||
})
|
||||
|
||||
export default connect(
|
||||
({ connection, workspace }: { connection: IConnectionModelType; workspace: IWorkspaceModelType }) => ({
|
||||
connectionModel: connection,
|
||||
workspaceModel: workspace,
|
||||
}),
|
||||
)(WorkspaceHeader);
|
@ -81,9 +81,9 @@ const WorkspaceLeft = memo<IProps>(function (props) {
|
||||
|
||||
return (
|
||||
<div className={classnames(styles.box, className)}>
|
||||
<div className={styles.header}>
|
||||
{/* <div className={styles.header}>
|
||||
<RenderSelectDatabase cascaderOptions={cascaderOptions} />
|
||||
</div>
|
||||
</div> */}
|
||||
<RenderSaveBox></RenderSaveBox>
|
||||
<Divider className={styles.divider} />
|
||||
<RenderTableBox />
|
||||
@ -109,82 +109,81 @@ interface IProps {
|
||||
dispatch: any;
|
||||
}
|
||||
|
||||
const RenderSelectDatabase = dvaModel(function (props: IProps) {
|
||||
const { connectionModel, workspaceModel, dispatch, cascaderOptions } = props;
|
||||
const { curWorkspaceParams } = workspaceModel;
|
||||
const { curConnection } = connectionModel;
|
||||
const [currentSelectedName, setCurrentSelectedName] = useState('');
|
||||
const [cascaderLoading, setCascaderLoading] = useState(false)
|
||||
// const RenderSelectDatabase = dvaModel(function (props: IProps) {
|
||||
// const { connectionModel, workspaceModel, dispatch, cascaderOptions } = props;
|
||||
// const { curWorkspaceParams } = workspaceModel;
|
||||
// const { curConnection } = connectionModel;
|
||||
// const [currentSelectedName, setCurrentSelectedName] = useState('');
|
||||
// const [cascaderLoading, setCascaderLoading] = useState(false);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (curWorkspaceParams) {
|
||||
// const { databaseName, schemaName, databaseSourceName } = curWorkspaceParams;
|
||||
// const currentSelectedArr = [databaseSourceName, databaseName, schemaName].filter((t) => t);
|
||||
// setCurrentSelectedName(currentSelectedArr.join('/'));
|
||||
// }
|
||||
// }, [curWorkspaceParams]);
|
||||
|
||||
useEffect(() => {
|
||||
if (curWorkspaceParams) {
|
||||
const { databaseName, schemaName, databaseSourceName } = curWorkspaceParams;
|
||||
const currentSelectedArr = [databaseSourceName, databaseName, schemaName].filter((t) => t);
|
||||
setCurrentSelectedName(currentSelectedArr.join('/'));
|
||||
}
|
||||
}, [curWorkspaceParams]);
|
||||
// const onChange: any = (valueArr: any, selectedOptions: any) => {
|
||||
// let labelArr: string[] = [];
|
||||
// labelArr = selectedOptions.map((t: any) => {
|
||||
// return t.label;
|
||||
// });
|
||||
|
||||
const onChange: any = (valueArr: any, selectedOptions: any) => {
|
||||
let labelArr: string[] = [];
|
||||
labelArr = selectedOptions.map((t: any) => {
|
||||
return t.label;
|
||||
});
|
||||
// const curWorkspaceParams = {
|
||||
// dataSourceId: curConnection?.id,
|
||||
// databaseSourceName: curConnection?.alias,
|
||||
// databaseName: labelArr[0],
|
||||
// schemaName: labelArr[1],
|
||||
// databaseType: curConnection?.type,
|
||||
// };
|
||||
|
||||
const curWorkspaceParams = {
|
||||
dataSourceId: curConnection?.id,
|
||||
databaseSourceName: curConnection?.alias,
|
||||
databaseName: labelArr[0],
|
||||
schemaName: labelArr[1],
|
||||
databaseType: curConnection?.type,
|
||||
};
|
||||
// dispatch({
|
||||
// type: 'workspace/setCurWorkspaceParams',
|
||||
// payload: curWorkspaceParams,
|
||||
// });
|
||||
// };
|
||||
|
||||
dispatch({
|
||||
type: 'workspace/setCurWorkspaceParams',
|
||||
payload: curWorkspaceParams,
|
||||
});
|
||||
};
|
||||
// const dropdownRender = (menus: React.ReactNode) => <div>{menus}</div>;
|
||||
|
||||
const dropdownRender = (menus: React.ReactNode) => <div>{menus}</div>;
|
||||
// function handleRefresh() {
|
||||
// setCascaderLoading(true)
|
||||
// dispatch({
|
||||
// type: 'workspace/fetchDatabaseAndSchema',
|
||||
// payload: {
|
||||
// dataSourceId: curConnection?.id,
|
||||
// refresh: true
|
||||
// },
|
||||
// callback: () => {
|
||||
// setCascaderLoading(false)
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
function handleRefresh() {
|
||||
setCascaderLoading(true)
|
||||
dispatch({
|
||||
type: 'workspace/fetchDatabaseAndSchema',
|
||||
payload: {
|
||||
dataSourceId: curConnection?.id,
|
||||
refresh: true
|
||||
},
|
||||
callback: () => {
|
||||
setCascaderLoading(false)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.selectDatabaseBox}>
|
||||
<Cascader
|
||||
popupClassName={styles.cascaderPopup}
|
||||
options={cascaderOptions}
|
||||
onChange={onChange}
|
||||
bordered={false}
|
||||
dropdownRender={dropdownRender}
|
||||
>
|
||||
<div className={styles.currentDatabase}>
|
||||
<div className={styles.name}>
|
||||
{currentSelectedName || <span style={{ opacity: 0.8 }}>{i18n('workspace.cascader.placeholder')}</span>}{' '}
|
||||
</div>
|
||||
<Iconfont code="" />
|
||||
</div>
|
||||
</Cascader>
|
||||
<div className={styles.otherOperations}>
|
||||
<div className={classnames(styles.refreshIconBox, styles.iconBox)} onClick={handleRefresh}>
|
||||
{cascaderLoading ? <Spin /> : <Iconfont code="" />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
// return (
|
||||
// <div className={styles.selectDatabaseBox}>
|
||||
// <Cascader
|
||||
// popupClassName={styles.cascaderPopup}
|
||||
// options={cascaderOptions}
|
||||
// onChange={onChange}
|
||||
// bordered={false}
|
||||
// dropdownRender={dropdownRender}
|
||||
// >
|
||||
// <div className={styles.currentDatabase}>
|
||||
// <div className={styles.name}>
|
||||
// {currentSelectedName || <span style={{ opacity: 0.8 }}>{i18n('workspace.cascader.placeholder')}</span>}{' '}
|
||||
// </div>
|
||||
// <Iconfont code="" />
|
||||
// </div>
|
||||
// </Cascader>
|
||||
// <div className={styles.otherOperations}>
|
||||
// <div className={classnames(styles.refreshIconBox, styles.iconBox)} onClick={handleRefresh}>
|
||||
// {cascaderLoading ? <Spin /> : <Iconfont code="" />}
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
// });
|
||||
|
||||
const RenderTableBox = dvaModel(function (props: any) {
|
||||
const { workspaceModel, dispatch, tableLoading } = props;
|
||||
@ -375,7 +374,7 @@ const RenderSaveBox = dvaModel(function (props: any) {
|
||||
type: 'workspace/fetchGetSavedConsole',
|
||||
payload: {
|
||||
status: ConsoleStatus.RELEASE,
|
||||
orderByDesc: false,
|
||||
orderByDesc: Boolean,
|
||||
...curWorkspaceParams
|
||||
},
|
||||
callback: (res: any) => {
|
||||
|
@ -1,15 +1,21 @@
|
||||
@import '../../../styles/var.less';
|
||||
|
||||
.box {
|
||||
.workspace {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.workspaceMain{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.boxLeft {
|
||||
width: 220px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--color-border-secondary);
|
||||
border-right: 1px solid var(--color-border-secondary);
|
||||
border-top: 0px;
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
@ -4,10 +4,12 @@ import styles from './index.less';
|
||||
import DraggableContainer from '@/components/DraggableContainer';
|
||||
import WorkspaceLeft from './components/WorkspaceLeft';
|
||||
import WorkspaceRight from './components/WorkspaceRight';
|
||||
import WorkspaceHeader from './components/WorkspaceHeader';
|
||||
import { IConnectionModelType } from '@/models/connection';
|
||||
import { IWorkspaceModelType } from '@/models/workspace';
|
||||
import LoadingContent from '@/components/Loading/LoadingContent';
|
||||
import { ConsoleOpenedStatus } from '@/constants';
|
||||
import Iconfont from '@/components/Iconfont';
|
||||
|
||||
interface IProps {
|
||||
className?: string;
|
||||
@ -47,7 +49,7 @@ function handleDatabaseAndSchema(databaseAndSchema: IWorkspaceModelType['state']
|
||||
return {
|
||||
value: t.name,
|
||||
label: t.name,
|
||||
children: schemasList,
|
||||
next: schemasList,
|
||||
};
|
||||
});
|
||||
} else if (databaseAndSchema?.schemas) {
|
||||
@ -70,15 +72,12 @@ const workspace = memo<IProps>((props) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (pageLoading === true) {
|
||||
setLoading(true)
|
||||
setLoading(true);
|
||||
} else {
|
||||
setLoading(false)
|
||||
setLoading(false);
|
||||
}
|
||||
}, [pageLoading])
|
||||
|
||||
console.log('pageLoading', pageLoading)
|
||||
|
||||
|
||||
const cascaderOptions = useMemo(() => {
|
||||
if (!databaseAndSchema) {
|
||||
return
|
||||
@ -113,7 +112,6 @@ const workspace = memo<IProps>((props) => {
|
||||
clearData();
|
||||
}, [curConnection]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (curWorkspaceParams.dataSourceId) {
|
||||
getConsoleList();
|
||||
@ -162,17 +160,21 @@ const workspace = memo<IProps>((props) => {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<LoadingContent isLoading={loading}>
|
||||
<DraggableContainer className={styles.box}>
|
||||
<div ref={draggableRef} className={styles.boxLeft}>
|
||||
<WorkspaceLeft cascaderOptions={cascaderOptions} />
|
||||
</div>
|
||||
<div className={styles.boxRight}>
|
||||
<WorkspaceRight />
|
||||
</div>
|
||||
</DraggableContainer>
|
||||
</LoadingContent>
|
||||
<div className={styles.workspace}>
|
||||
<WorkspaceHeader cascaderOptions={cascaderOptions}></WorkspaceHeader>
|
||||
<LoadingContent isLoading={loading}>
|
||||
<DraggableContainer className={styles.workspaceMain}>
|
||||
<div ref={draggableRef} className={styles.boxLeft}>
|
||||
<WorkspaceLeft cascaderOptions={cascaderOptions} />
|
||||
</div>
|
||||
<div className={styles.boxRight}>
|
||||
<WorkspaceRight />
|
||||
</div>
|
||||
</DraggableContainer>
|
||||
</LoadingContent >
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -14,6 +14,7 @@ import java.util.stream.Collectors;
|
||||
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
|
||||
import ai.chat2db.spi.model.*;
|
||||
|
||||
import ai.chat2db.spi.util.ResultSetUtils;
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -57,13 +58,14 @@ public class SQLExecutor {
|
||||
|
||||
/**
|
||||
* 执行sql
|
||||
*
|
||||
* @param connection
|
||||
* @param sql
|
||||
* @param function
|
||||
* @return
|
||||
*/
|
||||
|
||||
public <R> R executeSql(Connection connection,String sql, Function<ResultSet, R> function) {
|
||||
public <R> R executeSql(Connection connection, String sql, Function<ResultSet, R> function) {
|
||||
if (StringUtils.isEmpty(sql)) {
|
||||
return null;
|
||||
}
|
||||
@ -115,7 +117,7 @@ public class SQLExecutor {
|
||||
headerList.add(Header.builder()
|
||||
.dataType(ai.chat2db.spi.util.JdbcUtils.resolveDataType(
|
||||
resultSetMetaData.getColumnTypeName(i), resultSetMetaData.getColumnType(i)).getCode())
|
||||
.name(resultSetMetaData.getColumnName(i))
|
||||
.name(ResultSetUtils.getColumnName(resultSetMetaData, i))
|
||||
.build());
|
||||
}
|
||||
|
||||
@ -153,12 +155,13 @@ public class SQLExecutor {
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public ExecuteResult execute(Connection connection,String sql) throws SQLException {
|
||||
public ExecuteResult execute(Connection connection, String sql) throws SQLException {
|
||||
return execute(sql, connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的数据库
|
||||
*
|
||||
* @param connection
|
||||
* @return
|
||||
*/
|
||||
@ -178,12 +181,13 @@ public class SQLExecutor {
|
||||
|
||||
/**
|
||||
* 获取所有的schema
|
||||
*
|
||||
* @param connection
|
||||
* @param databaseName
|
||||
* @param schemaName
|
||||
* @return
|
||||
*/
|
||||
public List<Map<String, String>> schemas(Connection connection,String databaseName, String schemaName) {
|
||||
public List<Map<String, String>> schemas(Connection connection, String databaseName, String schemaName) {
|
||||
List<Map<String, String>> schemaList = Lists.newArrayList();
|
||||
if (StringUtils.isEmpty(databaseName) && StringUtils.isEmpty(schemaName)) {
|
||||
try (ResultSet resultSet = connection.getMetaData().getSchemas()) {
|
||||
@ -217,6 +221,7 @@ public class SQLExecutor {
|
||||
|
||||
/**
|
||||
* 获取所有的数据库表
|
||||
*
|
||||
* @param connection
|
||||
* @param databaseName
|
||||
* @param schemaName
|
||||
@ -224,7 +229,8 @@ public class SQLExecutor {
|
||||
* @param types
|
||||
* @return
|
||||
*/
|
||||
public List<Table> tables(Connection connection,String databaseName, String schemaName, String tableName, String types[]) {
|
||||
public List<Table> tables(Connection connection, String databaseName, String schemaName, String tableName,
|
||||
String types[]) {
|
||||
List<Table> tables = Lists.newArrayList();
|
||||
int n = 0;
|
||||
try (ResultSet resultSet = connection.getMetaData().getTables(databaseName, schemaName, tableName,
|
||||
@ -246,6 +252,7 @@ public class SQLExecutor {
|
||||
|
||||
/**
|
||||
* 获取所有的数据库表列
|
||||
*
|
||||
* @param connection
|
||||
* @param databaseName
|
||||
* @param schemaName
|
||||
@ -253,7 +260,8 @@ public class SQLExecutor {
|
||||
* @param columnName
|
||||
* @return
|
||||
*/
|
||||
public List<TableColumn> columns(Connection connection,String databaseName, String schemaName, String tableName, String columnName) {
|
||||
public List<TableColumn> columns(Connection connection, String databaseName, String schemaName, String tableName,
|
||||
String columnName) {
|
||||
List<TableColumn> tableColumns = Lists.newArrayList();
|
||||
try (ResultSet resultSet = connection.getMetaData().getColumns(databaseName, schemaName, tableName,
|
||||
columnName)) {
|
||||
@ -270,13 +278,14 @@ public class SQLExecutor {
|
||||
|
||||
/**
|
||||
* 获取所有的数据库表索引
|
||||
*
|
||||
* @param connection
|
||||
* @param databaseName
|
||||
* @param schemaName
|
||||
* @param tableName
|
||||
* @return
|
||||
*/
|
||||
public List<TableIndex> indexes(Connection connection,String databaseName, String schemaName, String tableName) {
|
||||
public List<TableIndex> indexes(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
List<TableIndex> tableIndices = Lists.newArrayList();
|
||||
try (ResultSet resultSet = connection.getMetaData().getIndexInfo(databaseName, schemaName, tableName,
|
||||
false,
|
||||
@ -308,12 +317,13 @@ public class SQLExecutor {
|
||||
|
||||
/**
|
||||
* 获取所有的函数
|
||||
*
|
||||
* @param connection
|
||||
* @param databaseName
|
||||
* @param schemaName
|
||||
* @return
|
||||
*/
|
||||
public List<ai.chat2db.spi.model.Function> functions(Connection connection,String databaseName,
|
||||
public List<ai.chat2db.spi.model.Function> functions(Connection connection, String databaseName,
|
||||
String schemaName) {
|
||||
List<ai.chat2db.spi.model.Function> functions = Lists.newArrayList();
|
||||
try (ResultSet resultSet = connection.getMetaData().getFunctions(databaseName, schemaName, null);) {
|
||||
@ -328,12 +338,13 @@ public class SQLExecutor {
|
||||
|
||||
/**
|
||||
* 获取所有的存储过程
|
||||
*
|
||||
* @param connection
|
||||
* @param databaseName
|
||||
* @param schemaName
|
||||
* @return
|
||||
*/
|
||||
public List<Procedure> procedures(Connection connection,String databaseName, String schemaName) {
|
||||
public List<Procedure> procedures(Connection connection, String databaseName, String schemaName) {
|
||||
List<Procedure> procedures = Lists.newArrayList();
|
||||
try (ResultSet resultSet = connection.getMetaData().getProcedures(databaseName, schemaName, null)) {
|
||||
while (resultSet != null && resultSet.next()) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
package ai.chat2db.spi.util;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import ai.chat2db.spi.model.*;
|
||||
@ -16,12 +17,12 @@ public class ResultSetUtils {
|
||||
ai.chat2db.spi.model.Function function
|
||||
= new ai.chat2db.spi.model.Function();
|
||||
try {
|
||||
function.setDatabaseName(getString(resultSet,"FUNCTION_CAT"));
|
||||
function.setSchemaName(getString(resultSet,"FUNCTION_SCHEM"));
|
||||
function.setFunctionName(getString(resultSet,"FUNCTION_NAME"));
|
||||
function.setRemarks(getString(resultSet,"REMARKS"));
|
||||
function.setDatabaseName(getString(resultSet, "FUNCTION_CAT"));
|
||||
function.setSchemaName(getString(resultSet, "FUNCTION_SCHEM"));
|
||||
function.setFunctionName(getString(resultSet, "FUNCTION_NAME"));
|
||||
function.setRemarks(getString(resultSet, "REMARKS"));
|
||||
function.setFunctionType(resultSet.getShort("FUNCTION_TYPE"));
|
||||
function.setSpecificName(getString(resultSet,"SPECIFIC_NAME"));
|
||||
function.setSpecificName(getString(resultSet, "SPECIFIC_NAME"));
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -31,12 +32,12 @@ public class ResultSetUtils {
|
||||
public static Procedure buildProcedure(ResultSet resultSet) {
|
||||
Procedure procedure = new Procedure();
|
||||
try {
|
||||
procedure.setDatabaseName(getString(resultSet,"PROCEDURE_CAT"));
|
||||
procedure.setSchemaName(getString(resultSet,"PROCEDURE_SCHEM"));
|
||||
procedure.setProcedureName(getString(resultSet,"PROCEDURE_NAME"));
|
||||
procedure.setRemarks(getString(resultSet,"REMARKS"));
|
||||
procedure.setDatabaseName(getString(resultSet, "PROCEDURE_CAT"));
|
||||
procedure.setSchemaName(getString(resultSet, "PROCEDURE_SCHEM"));
|
||||
procedure.setProcedureName(getString(resultSet, "PROCEDURE_NAME"));
|
||||
procedure.setRemarks(getString(resultSet, "REMARKS"));
|
||||
procedure.setProcedureType(resultSet.getShort("PROCEDURE_TYPE"));
|
||||
procedure.setSpecificName(getString(resultSet,"SPECIFIC_NAME"));
|
||||
procedure.setSpecificName(getString(resultSet, "SPECIFIC_NAME"));
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -45,31 +46,31 @@ public class ResultSetUtils {
|
||||
|
||||
public static TableIndexColumn buildTableIndexColumn(ResultSet resultSet) throws SQLException {
|
||||
TableIndexColumn tableIndexColumn = new TableIndexColumn();
|
||||
tableIndexColumn.setColumnName(getString(resultSet,"COLUMN_NAME"));
|
||||
tableIndexColumn.setIndexName(getString(resultSet,"INDEX_NAME"));
|
||||
tableIndexColumn.setAscOrDesc(getString(resultSet,"ASC_OR_DESC"));
|
||||
tableIndexColumn.setColumnName(getString(resultSet, "COLUMN_NAME"));
|
||||
tableIndexColumn.setIndexName(getString(resultSet, "INDEX_NAME"));
|
||||
tableIndexColumn.setAscOrDesc(getString(resultSet, "ASC_OR_DESC"));
|
||||
tableIndexColumn.setCardinality(resultSet.getLong("CARDINALITY"));
|
||||
tableIndexColumn.setPages(resultSet.getLong("PAGES"));
|
||||
tableIndexColumn.setFilterCondition(getString(resultSet,"FILTER_CONDITION"));
|
||||
tableIndexColumn.setIndexQualifier(getString(resultSet,"INDEX_QUALIFIER"));
|
||||
tableIndexColumn.setFilterCondition(getString(resultSet, "FILTER_CONDITION"));
|
||||
tableIndexColumn.setIndexQualifier(getString(resultSet, "INDEX_QUALIFIER"));
|
||||
// tableIndexColumn.setIndexType(resultSet.getShort("TYPE"));
|
||||
tableIndexColumn.setNonUnique(resultSet.getBoolean("NON_UNIQUE"));
|
||||
tableIndexColumn.setOrdinalPosition(resultSet.getShort("ORDINAL_POSITION"));
|
||||
tableIndexColumn.setDatabaseName(getString(resultSet,"TABLE_CAT"));
|
||||
tableIndexColumn.setSchemaName(getString(resultSet,"TABLE_SCHEM"));
|
||||
tableIndexColumn.setTableName(getString(resultSet,"TABLE_NAME"));
|
||||
tableIndexColumn.setDatabaseName(getString(resultSet, "TABLE_CAT"));
|
||||
tableIndexColumn.setSchemaName(getString(resultSet, "TABLE_SCHEM"));
|
||||
tableIndexColumn.setTableName(getString(resultSet, "TABLE_NAME"));
|
||||
return tableIndexColumn;
|
||||
}
|
||||
|
||||
public static TableColumn buildColumn(ResultSet resultSet) throws SQLException {
|
||||
TableColumn tableColumn = new TableColumn();
|
||||
tableColumn.setDatabaseName(getString(resultSet,"TABLE_CAT"));
|
||||
tableColumn.setSchemaName(getString(resultSet,"TABLE_SCHEM"));
|
||||
tableColumn.setTableName(getString(resultSet,"TABLE_NAME"));
|
||||
tableColumn.setName(getString(resultSet,"COLUMN_NAME"));
|
||||
tableColumn.setComment(getString(resultSet,"REMARKS"));
|
||||
tableColumn.setDefaultValue(getString(resultSet,"COLUMN_DEF"));
|
||||
tableColumn.setTypeName(getString(resultSet,"TYPE_NAME"));
|
||||
tableColumn.setDatabaseName(getString(resultSet, "TABLE_CAT"));
|
||||
tableColumn.setSchemaName(getString(resultSet, "TABLE_SCHEM"));
|
||||
tableColumn.setTableName(getString(resultSet, "TABLE_NAME"));
|
||||
tableColumn.setName(getString(resultSet, "COLUMN_NAME"));
|
||||
tableColumn.setComment(getString(resultSet, "REMARKS"));
|
||||
tableColumn.setDefaultValue(getString(resultSet, "COLUMN_DEF"));
|
||||
tableColumn.setTypeName(getString(resultSet, "TYPE_NAME"));
|
||||
tableColumn.setColumnSize(resultSet.getInt("COLUMN_SIZE"));
|
||||
tableColumn.setDataType(resultSet.getInt("DATA_TYPE"));
|
||||
tableColumn.setNullable(resultSet.getInt("NULLABLE") == 1);
|
||||
@ -85,22 +86,30 @@ public class ResultSetUtils {
|
||||
|
||||
public static Table buildTable(ResultSet resultSet) throws SQLException {
|
||||
Table table = new Table();
|
||||
table.setName(getString(resultSet,"TABLE_NAME"));
|
||||
table.setComment(getString(resultSet,"REMARKS"));
|
||||
table.setDatabaseName(getString(resultSet,"TABLE_CAT"));
|
||||
table.setSchemaName(getString(resultSet,"TABLE_SCHEM"));
|
||||
table.setType(getString(resultSet,"TABLE_TYPE"));
|
||||
table.setName(getString(resultSet, "TABLE_NAME"));
|
||||
table.setComment(getString(resultSet, "REMARKS"));
|
||||
table.setDatabaseName(getString(resultSet, "TABLE_CAT"));
|
||||
table.setSchemaName(getString(resultSet, "TABLE_SCHEM"));
|
||||
table.setType(getString(resultSet, "TABLE_TYPE"));
|
||||
return table;
|
||||
}
|
||||
|
||||
private static String getString(ResultSet resultSet,String name){
|
||||
if(resultSet == null){
|
||||
private static String getString(ResultSet resultSet, String name) {
|
||||
if (resultSet == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return resultSet.getString(name);
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getColumnName(ResultSetMetaData resultSetMetaData, int column) throws SQLException {
|
||||
String columnLabel = resultSetMetaData.getColumnLabel(column);
|
||||
if (columnLabel != null) {
|
||||
return columnLabel;
|
||||
}
|
||||
return resultSetMetaData.getColumnName(column);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user