mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-07-30 19:22:58 +08:00
Merge remote-tracking branch 'origin/developing' into developing
This commit is contained in:
@ -24,8 +24,8 @@ enum DownloadStatus {
|
||||
|
||||
export default memo<IProps>(function Driver(props) {
|
||||
const { className, backfillData, onChange } = props;
|
||||
const [downloadStatus, setDownloadStatus] = useState<DownloadStatus>();
|
||||
const [driveForm] = Form.useForm();
|
||||
const [downloadStatus, setDownloadStatus] = useState<DownloadStatus>(DownloadStatus.Default);
|
||||
const [driverForm] = Form.useForm();
|
||||
const [driverObj, setDriverObj] = useState<IDriverResponse>();
|
||||
const [uploadDriverModal, setUploadDriverModal] = useState(false);
|
||||
const [driverSaved, setDriverSaved] = useState<any>({});
|
||||
@ -38,7 +38,7 @@ export default memo<IProps>(function Driver(props) {
|
||||
|
||||
useEffect(() => {
|
||||
if (backfillData) {
|
||||
driveForm.setFieldsValue({
|
||||
driverForm.setFieldsValue({
|
||||
jdbcDriverClass: backfillData?.driverConfig?.jdbcDriverClass,
|
||||
jdbcDriver: backfillData?.driverConfig?.jdbcDriver
|
||||
})
|
||||
@ -47,7 +47,16 @@ export default memo<IProps>(function Driver(props) {
|
||||
|
||||
function getDriverList() {
|
||||
connectionService.getDriverList({ dbType: backfillData.type }).then(res => {
|
||||
setDriverObj(res)
|
||||
setDriverObj({
|
||||
...res,
|
||||
driverConfigList: res.driverConfigList || []
|
||||
});
|
||||
if (res.driverConfigList?.length && !backfillData?.driverConfig?.jdbcDriver) {
|
||||
driverForm.setFieldsValue({
|
||||
jdbcDriverClass: res.driverConfigList[0].jdbcDriverClass,
|
||||
jdbcDriver: res.driverConfigList[0].jdbcDriver
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -65,7 +74,7 @@ export default memo<IProps>(function Driver(props) {
|
||||
function downloadDrive() {
|
||||
setDownloadStatus(DownloadStatus.Loading)
|
||||
connectionService.downloadDriver({ dbType: backfillData.type }).then(res => {
|
||||
// setDownloadStatus(DownloadStatus.Success)
|
||||
setDownloadStatus(DownloadStatus.Success);
|
||||
getDriverList();
|
||||
}).catch(() => {
|
||||
setDownloadStatus(DownloadStatus.Error)
|
||||
@ -74,7 +83,7 @@ export default memo<IProps>(function Driver(props) {
|
||||
|
||||
function onValuesChange(data: any) {
|
||||
const selected = driverObj?.driverConfigList.find(t => t.jdbcDriver === data.jdbcDriver);
|
||||
driveForm.setFieldsValue({
|
||||
driverForm.setFieldsValue({
|
||||
jdbcDriverClass: selected?.jdbcDriverClass
|
||||
});
|
||||
onChange({
|
||||
@ -85,7 +94,7 @@ export default memo<IProps>(function Driver(props) {
|
||||
|
||||
return <div className={classnames(styles.box, className)}>
|
||||
<Form
|
||||
form={driveForm}
|
||||
form={driverForm}
|
||||
onValuesChange={onValuesChange}
|
||||
colon={false}
|
||||
>
|
||||
@ -104,7 +113,7 @@ export default memo<IProps>(function Driver(props) {
|
||||
</Form>
|
||||
<div className={styles.downloadDriveFooter}>
|
||||
{
|
||||
(!driverObj?.driverConfigList?.length || downloadStatus === DownloadStatus.Success) ? <div onClick={downloadDrive} className={styles.downloadDrive}>
|
||||
((driverObj?.driverConfigList && !driverObj?.driverConfigList?.length) || downloadStatus === DownloadStatus.Success) ? <div onClick={downloadDrive} className={styles.downloadDrive}>
|
||||
{
|
||||
(downloadStatus === DownloadStatus.Default) && <div className={classnames(styles.downloadText, styles.downloadTextDownload)}>{i18n('connection.text.downloadDriver')}</div>
|
||||
}
|
||||
@ -124,7 +133,7 @@ export default memo<IProps>(function Driver(props) {
|
||||
(downloadStatus === DownloadStatus.Success) && <div className={classnames(styles.downloadText, styles.downloadTextSuccess)}>{i18n('connection.text.downloadSuccess')}</div>
|
||||
}
|
||||
|
||||
</div> : <div></div>
|
||||
</div> : <div />
|
||||
}
|
||||
|
||||
<div
|
||||
|
@ -5,7 +5,7 @@ import { InputType, AuthenticationType, SSHAuthenticationType, OperationColumn }
|
||||
export const sshConfig: IConnectionConfig['ssh'] = {
|
||||
items: [
|
||||
{
|
||||
defaultValue: 'false',
|
||||
defaultValue: false,
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '使用SSH',
|
||||
labelNameEN: 'USE SSH',
|
||||
@ -13,10 +13,12 @@ export const sshConfig: IConnectionConfig['ssh'] = {
|
||||
required: false,
|
||||
selects: [
|
||||
{
|
||||
value: 'false',
|
||||
label: 'false',
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
value: 'true',
|
||||
label: 'true',
|
||||
value: true,
|
||||
},
|
||||
],
|
||||
|
||||
@ -33,7 +35,7 @@ export const sshConfig: IConnectionConfig['ssh'] = {
|
||||
}
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
defaultValue: '22',
|
||||
inputType: InputType.INPUT,
|
||||
labelNameCN: 'SSH 端口',
|
||||
labelNameEN: 'Port',
|
||||
@ -55,7 +57,6 @@ export const sshConfig: IConnectionConfig['ssh'] = {
|
||||
required: false,
|
||||
styles: {
|
||||
width: '70%',
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -64,6 +65,8 @@ export const sshConfig: IConnectionConfig['ssh'] = {
|
||||
labelNameCN: '本地端口',
|
||||
labelNameEN: 'LocalPort',
|
||||
name: 'localPort',
|
||||
placeholder: '不必填',
|
||||
placeholderEN: 'Need not fill in',
|
||||
required: false,
|
||||
styles: {
|
||||
width: '30%',
|
||||
@ -71,14 +74,57 @@ export const sshConfig: IConnectionConfig['ssh'] = {
|
||||
}
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.PASSWORD,
|
||||
labelNameCN: '密码',
|
||||
labelNameEN: 'Password',
|
||||
name: 'password',
|
||||
defaultValue: 'password',
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
|
||||
selects: [
|
||||
{
|
||||
items: [
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.PASSWORD,
|
||||
labelNameCN: '密码',
|
||||
labelNameEN: 'Password',
|
||||
name: 'password',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
label: 'password',
|
||||
value: 'password',
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.INPUT,
|
||||
labelNameCN: '密钥文件',
|
||||
labelNameEN: 'Private key file',
|
||||
name: 'keyFile',
|
||||
required: true,
|
||||
placeholder: '/user/userName/.ssh/xxxx',
|
||||
placeholderEN: '/user/userName/.ssh/xxxx',
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.INPUT,
|
||||
labelNameCN: '密码短语',
|
||||
labelNameEN: 'Passphrase',
|
||||
name: 'passphrase',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
label: 'Private key',
|
||||
value: 'keyFile',
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
width: '50%',
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
@ -126,7 +172,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -154,6 +200,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -235,7 +283,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -266,6 +314,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -295,85 +345,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
pattern: /jdbc:postgresql:\/\/(.*):(\d+)(\/(\w+))?/,
|
||||
template: 'jdbc:postgresql://{host}:{port}/{database}',
|
||||
},
|
||||
ssh: {
|
||||
items: [
|
||||
{
|
||||
defaultValue: 'false',
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '使用SSH',
|
||||
labelNameEN: 'USE SSH',
|
||||
name: 'use',
|
||||
required: false,
|
||||
selects: [
|
||||
{
|
||||
value: 'false',
|
||||
},
|
||||
{
|
||||
value: 'true',
|
||||
},
|
||||
],
|
||||
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.INPUT,
|
||||
labelNameCN: 'SSH 主机',
|
||||
labelNameEN: 'SSH Hostname',
|
||||
name: 'hostName',
|
||||
required: false,
|
||||
styles: {
|
||||
width: '70%',
|
||||
}
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.INPUT,
|
||||
labelNameCN: 'SSH 端口',
|
||||
labelNameEN: 'Port',
|
||||
name: 'port',
|
||||
required: false,
|
||||
styles: {
|
||||
width: '30%',
|
||||
labelWidthEN: '40px',
|
||||
labelWidthCN: '40px',
|
||||
labelAlign: 'right'
|
||||
}
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.INPUT,
|
||||
labelNameCN: '用户名',
|
||||
labelNameEN: 'SSH UserName',
|
||||
name: 'userName',
|
||||
required: false,
|
||||
styles: {
|
||||
width: '70%',
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.INPUT,
|
||||
labelNameCN: '本地端口',
|
||||
labelNameEN: 'LocalPort',
|
||||
name: 'localPort',
|
||||
required: false,
|
||||
styles: {
|
||||
width: '30%',
|
||||
labelAlign: 'right'
|
||||
}
|
||||
},
|
||||
{
|
||||
defaultValue: '',
|
||||
inputType: InputType.PASSWORD,
|
||||
labelNameCN: '密码',
|
||||
labelNameEN: 'Password',
|
||||
name: 'password',
|
||||
required: true,
|
||||
|
||||
},
|
||||
]
|
||||
},
|
||||
ssh: sshConfig,
|
||||
},
|
||||
// ORACLE
|
||||
{
|
||||
@ -459,7 +431,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -490,6 +462,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -558,7 +532,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -590,6 +564,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -694,7 +670,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -726,6 +702,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -841,7 +819,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -873,6 +851,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -950,7 +930,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -981,7 +961,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1059,7 +1040,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1080,7 +1061,6 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
labelNameEN: 'Password',
|
||||
name: 'password',
|
||||
required: true,
|
||||
|
||||
},
|
||||
],
|
||||
label: 'User&Password',
|
||||
@ -1089,6 +1069,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1173,7 +1154,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1207,6 +1188,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1292,7 +1275,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1326,6 +1309,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1411,7 +1396,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1445,6 +1430,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1530,7 +1517,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1564,6 +1551,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1649,7 +1638,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1683,6 +1672,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1768,7 +1759,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1802,6 +1793,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
@ -1887,7 +1880,7 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
inputType: InputType.SELECT,
|
||||
labelNameCN: '身份验证',
|
||||
labelNameEN: 'Authentication',
|
||||
name: 'authentication',
|
||||
name: 'authenticationType',
|
||||
required: true,
|
||||
selects: [
|
||||
{
|
||||
@ -1921,6 +1914,8 @@ export const dataSourceFormConfigs: IConnectionConfig[] = [
|
||||
{
|
||||
label: 'NONE',
|
||||
value: AuthenticationType.NONE,
|
||||
items: [],
|
||||
|
||||
},
|
||||
],
|
||||
styles: {
|
||||
|
@ -5,8 +5,8 @@ export enum InputType {
|
||||
}
|
||||
|
||||
export enum AuthenticationType {
|
||||
USERANDPASSWORD = 1,
|
||||
NONE = 2,
|
||||
USERANDPASSWORD = '1',
|
||||
NONE = '2',
|
||||
}
|
||||
|
||||
export enum SSHAuthenticationType {
|
||||
|
@ -2,7 +2,7 @@ import { InputType, AuthenticationType, SSHAuthenticationType } from './enum';
|
||||
import { DatabaseTypeCode, OperationColumn } from '@/constants';
|
||||
|
||||
export type ISelect = {
|
||||
value?: AuthenticationType | SSHAuthenticationType | string;
|
||||
value?: AuthenticationType | SSHAuthenticationType | string | boolean;
|
||||
label?: string;
|
||||
rest?: {
|
||||
[key in string]: any
|
||||
@ -20,6 +20,8 @@ export interface IFormItem {
|
||||
selected?: any;
|
||||
selects?: ISelect[];
|
||||
labelTextAlign?: 'right';
|
||||
placeholder?: string;
|
||||
placeholderEN?: string;
|
||||
styles?: {
|
||||
width?: string; // 表单占用的长度 推荐百分比 默认值为 100%
|
||||
labelWidthEN?: string; // 英文环境下表单label的长度 推荐px 默认值为 70px
|
||||
|
@ -103,6 +103,7 @@
|
||||
color: var(--success-color);
|
||||
}
|
||||
.testSSHConnectText {
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--color-primary);
|
||||
cursor: pointer;
|
||||
|
@ -3,17 +3,19 @@ import { i18n, isEn } from '@/i18n';
|
||||
import styles from './index.less';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import connectionService, { IDriverResponse } from '@/service/connection';
|
||||
import connectionService from '@/service/connection';
|
||||
|
||||
import { DatabaseTypeCode, ConnectionEnvType, databaseMap } from '@/constants';
|
||||
import { dataSourceFormConfigs } from './config/dataSource';
|
||||
import { IConnectionConfig, IFormItem, ISelect } from './config/types';
|
||||
import { AuthenticationType } from './config/enum';
|
||||
import { IConnectionDetails } from '@/typings';
|
||||
import { InputType } from './config/enum';
|
||||
import { deepClone } from '@/utils';
|
||||
import { Select, Form, Input, message, Table, Button, Collapse, Modal } from 'antd';
|
||||
import Iconfont from '@/components/Iconfont';
|
||||
import LoadingContent from '@/components/Loading/LoadingContent';
|
||||
import LoadingGracile from '@/components/Loading/LoadingGracile';
|
||||
import Driver from './components/Driver';
|
||||
|
||||
const { Option } = Select;
|
||||
@ -33,13 +35,6 @@ interface IProps {
|
||||
submitCallback?: Function;
|
||||
}
|
||||
|
||||
enum DownloadStatus {
|
||||
Default,
|
||||
Loading,
|
||||
Error,
|
||||
Success
|
||||
}
|
||||
|
||||
export default function CreateConnection(props: IProps) {
|
||||
const { className, closeCreateConnection, submitCallback, connectionData } = props;
|
||||
const [baseInfoForm] = Form.useForm();
|
||||
@ -49,7 +44,8 @@ export default function CreateConnection(props: IProps) {
|
||||
const [loadings, setLoading] = useState({
|
||||
confirmButton: false,
|
||||
testButton: false,
|
||||
backfillDataLoading: false
|
||||
backfillDataLoading: false,
|
||||
sshTestLoading: false
|
||||
});
|
||||
const dataSourceFormConfigPropsMemo = useMemo<IConnectionConfig>(() => {
|
||||
const deepCloneDataSourceFormConfigs = deepClone(dataSourceFormConfigs)
|
||||
@ -80,11 +76,6 @@ export default function CreateConnection(props: IProps) {
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
if (res.user) {
|
||||
res.authentication = 1;
|
||||
} else {
|
||||
res.authentication = 2;
|
||||
}
|
||||
setBackfillData(res);
|
||||
}).finally(() => {
|
||||
setTimeout(() => {
|
||||
@ -102,12 +93,14 @@ export default function CreateConnection(props: IProps) {
|
||||
|
||||
const getItems = () => [
|
||||
{
|
||||
forceRender: true,
|
||||
key: 'driver',
|
||||
label: i18n('connection.title.driver'),
|
||||
children: <Driver backfillData={backfillData} onChange={driverFormChange}></Driver>,
|
||||
},
|
||||
{
|
||||
key: 'ssh',
|
||||
forceRender: true,
|
||||
label: i18n('connection.label.sshConfiguration'),
|
||||
children: (
|
||||
<div className={styles.sshBox}>
|
||||
@ -118,6 +111,7 @@ export default function CreateConnection(props: IProps) {
|
||||
tab="ssh"
|
||||
/>
|
||||
<div className={styles.testSSHConnect}>
|
||||
{loadings.sshTestLoading && <LoadingGracile></LoadingGracile>}
|
||||
<div onClick={testSSH} className={styles.testSSHConnectText}>
|
||||
{i18n('connection.message.testSshConnection')}
|
||||
</div>
|
||||
@ -126,6 +120,7 @@ export default function CreateConnection(props: IProps) {
|
||||
),
|
||||
},
|
||||
{
|
||||
forceRender: true,
|
||||
key: 'extendInfo',
|
||||
label: i18n('connection.label.advancedConfiguration'),
|
||||
children: (
|
||||
@ -209,9 +204,19 @@ export default function CreateConnection(props: IProps) {
|
||||
}
|
||||
|
||||
function testSSH() {
|
||||
|
||||
let p = sshForm.getFieldsValue();
|
||||
setLoading({
|
||||
...loadings,
|
||||
sshTestLoading: true
|
||||
})
|
||||
connectionService.testSSH(p).then((res) => {
|
||||
message.success(i18n('connection.message.testConnectResult', i18n('common.text.successful')));
|
||||
}).finally(() => {
|
||||
setLoading({
|
||||
...loadings,
|
||||
sshTestLoading: false
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
@ -269,7 +274,8 @@ interface IRenderFormProps {
|
||||
function RenderForm(props: IRenderFormProps) {
|
||||
const { tab, form, backfillData, dataSourceFormConfigProps } = props;
|
||||
useEffect(() => {
|
||||
form.resetFields()
|
||||
form.resetFields();
|
||||
changeDataSourceFormConfig(backfillData);
|
||||
}, [backfillData.id, backfillData.type])
|
||||
|
||||
let aliasChanged = false;
|
||||
@ -291,8 +297,6 @@ function RenderForm(props: IRenderFormProps) {
|
||||
return;
|
||||
}
|
||||
if (tab === 'baseInfo') {
|
||||
// TODO:
|
||||
// selectChange({ name: 'authentication', value: backfillData.user ? 1 : 2 });
|
||||
regEXFormatting({ url: backfillData.url }, backfillData);
|
||||
}
|
||||
|
||||
@ -304,6 +308,21 @@ function RenderForm(props: IRenderFormProps) {
|
||||
}
|
||||
}, [backfillData]);
|
||||
|
||||
function changeDataSourceFormConfig(backfillData: any) {
|
||||
// TODO: select 联动下级只处理了ssh和baseInfo 这种方法也待改造
|
||||
dataSourceFormConfig.ssh.items.forEach((t: IFormItem) => {
|
||||
if (t.selects) {
|
||||
t.defaultValue = backfillData?.ssh?.[t.name] || 'password'
|
||||
}
|
||||
});
|
||||
dataSourceFormConfig.baseInfo.items.forEach((t: IFormItem) => {
|
||||
if (t.selects) {
|
||||
t.defaultValue = backfillData[t.name] || AuthenticationType.USERANDPASSWORD
|
||||
}
|
||||
});
|
||||
setDataSourceFormConfig({ ...dataSourceFormConfig })
|
||||
}
|
||||
|
||||
function initialFormData(dataSourceFormConfig: IFormItem[] | undefined) {
|
||||
let initValue: any = {};
|
||||
dataSourceFormConfig?.map((t) => {
|
||||
@ -407,6 +426,7 @@ function RenderForm(props: IRenderFormProps) {
|
||||
const name = t.name;
|
||||
const width = t?.styles?.width || '100%';
|
||||
const labelWidth = isEn ? t?.styles?.labelWidthEN || '100px' : t?.styles?.labelWidthCN || '70px';
|
||||
const placeholder = isEn ? t.placeholderEN : t.placeholder;
|
||||
const labelAlign = t?.styles?.labelAlign || 'left';
|
||||
|
||||
const FormItemTypes: { [key in InputType]: () => React.ReactNode } = {
|
||||
@ -417,7 +437,7 @@ function RenderForm(props: IRenderFormProps) {
|
||||
style={{ '--form-label-width': labelWidth } as any}
|
||||
labelAlign={labelAlign}
|
||||
>
|
||||
<Input />
|
||||
<Input placeholder={placeholder} />
|
||||
</Form.Item>
|
||||
),
|
||||
|
||||
@ -429,13 +449,14 @@ function RenderForm(props: IRenderFormProps) {
|
||||
labelAlign={labelAlign}
|
||||
>
|
||||
<Select
|
||||
placeholder={placeholder}
|
||||
value={t.defaultValue}
|
||||
onChange={(e) => {
|
||||
selectChange({ name: name, value: e });
|
||||
}}
|
||||
>
|
||||
{t.selects?.map((t: ISelect) => (
|
||||
<Option key={t.value} value={t.value}>
|
||||
<Option key={t.value?.toString()} value={t.value}>
|
||||
{t.label}
|
||||
</Option>
|
||||
))}
|
||||
@ -465,6 +486,7 @@ function RenderForm(props: IRenderFormProps) {
|
||||
{FormItemTypes[t.inputType]()}
|
||||
</div>
|
||||
{t.selects?.map((item) => {
|
||||
console.log(t.defaultValue,)
|
||||
if (t.defaultValue === item.value) {
|
||||
return item.items?.map((t) => renderFormItem(t));
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ export default memo<IProps>(function UploadDriver(props) {
|
||||
return <div className={classnames(styles.box, className)}>
|
||||
<div>
|
||||
<Form
|
||||
labelCol={{ span: 5 }}
|
||||
labelCol={{ span: 3 }}
|
||||
wrapperCol={{ span: 16 }}
|
||||
>
|
||||
<Form.Item label="Class">
|
||||
|
@ -17,7 +17,7 @@ export default {
|
||||
'connection.message.testSshConnection': 'Test the ssh connection',
|
||||
'connection.tableHeader.name': 'Name',
|
||||
'connection.tableHeader.value': 'Value',
|
||||
'connection.title.uploadDriver': 'Upload Driver',
|
||||
'connection.title.uploadDriver': 'Upload',
|
||||
'connection.tips.customUpload': "Upload driver",
|
||||
'connection.title.driver': 'Driver',
|
||||
'connection.button.clickUpload': 'Click to Upload',
|
||||
|
@ -17,7 +17,7 @@ export default {
|
||||
'connection.message.testSshConnection': '测试ssh连接',
|
||||
'connection.tableHeader.name': '名称',
|
||||
'connection.tableHeader.value': '值',
|
||||
'connection.title.uploadDriver': '上传驱动',
|
||||
'connection.title.uploadDriver': '上传',
|
||||
'connection.tips.customUpload': '上传驱动',
|
||||
'connection.title.driver': '驱动',
|
||||
'connection.button.clickUpload': '点击上传',
|
||||
|
@ -24,7 +24,7 @@ import registerMessage from './init/registerMessage';
|
||||
import registerNotification from './init/registerNotification';
|
||||
import { NotificationInstance } from 'antd/es/notification/interface';
|
||||
import { ModalStaticFunctions } from 'antd/es/modal/confirm';
|
||||
import Sub from './sub'
|
||||
import Sub from './sub';
|
||||
declare global {
|
||||
interface Window {
|
||||
_Lang: string;
|
||||
@ -81,7 +81,6 @@ const restartCount = 200;
|
||||
|
||||
let staticNotification: NotificationInstance;
|
||||
|
||||
|
||||
function AppContainer() {
|
||||
const { token } = useToken();
|
||||
const [initEnd, setInitEnd] = useState(false);
|
||||
@ -92,7 +91,6 @@ function AppContainer() {
|
||||
|
||||
// staticNotification = staticFunction.notification
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let date = new Date('2030-12-30 12:30:00').toUTCString();
|
||||
document.cookie = `CHAT2DB.LOCALE=${getLang()};Expires=${date}`;
|
||||
@ -196,12 +194,12 @@ function AppContainer() {
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.hint}>
|
||||
<Setting text={i18n('common.text.setting')} />
|
||||
<Setting />
|
||||
</div>
|
||||
{serviceFail && (
|
||||
<>
|
||||
<div className={styles.github}>
|
||||
{i18n('common.text.contactUs')}-github:
|
||||
{i18n('common.text.contactUs')}:
|
||||
<a target="_blank" href="https://github.com/chat2db/Chat2DB">
|
||||
github
|
||||
</a>
|
||||
@ -220,4 +218,4 @@ function AppContainer() {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
11
chat2db-client/src/styles/antd.less
Normal file
11
chat2db-client/src/styles/antd.less
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
:root{
|
||||
:global{
|
||||
.ant-modal-header{
|
||||
border-bottom: 0px;
|
||||
}
|
||||
.ant-modal-footer{
|
||||
border-top: 0px;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
@import '../theme/custom/dark.less';
|
||||
@import '../theme/custom/light.less';
|
||||
@import './antd.less';
|
||||
|
||||
html,
|
||||
body {
|
||||
|
@ -10,7 +10,7 @@ export function setLang(lang: LangType) {
|
||||
}
|
||||
|
||||
export function getTheme(): ThemeType {
|
||||
return (localStorage.getItem('theme') as ThemeType) || ThemeType.Dark;
|
||||
return (localStorage.getItem('theme') as ThemeType) || ThemeType.Light;
|
||||
}
|
||||
|
||||
export function setTheme(theme: ThemeType) {
|
||||
|
@ -6,4 +6,7 @@ common.paramError=The parameter is incorrect
|
||||
common.paramDetailError=The parameter: {0} is incorrect
|
||||
common.paramCheckError=The following parameters are not valid:
|
||||
common.maxUploadSize=The file exceeds the maximum limit
|
||||
dataSource.sqlAnalysisError=Invalid statements
|
||||
dataSource.sqlAnalysisError=Invalid statements
|
||||
connection.error=Connection failed, please check the connection information
|
||||
connection.ssh.error=SSH connection failed, please check the connection information
|
||||
connection.driver.load.error=Failed to load driver class, please check the driver jar package
|
@ -6,4 +6,7 @@ common.paramError=The parameter is incorrect
|
||||
common.paramDetailError=The parameter: {0} is incorrect
|
||||
common.paramCheckError=The following parameters are not valid
|
||||
common.maxUploadSize=The file exceeds the maximum limit
|
||||
dataSource.sqlAnalysisError=Invalid statements
|
||||
dataSource.sqlAnalysisError=Invalid statements
|
||||
connection.error=Connection failed, please check the connection information
|
||||
connection.ssh.error=SSH connection failed, please check the connection information
|
||||
connection.driver.load.error=Failed to load driver class, please check the driver jar package
|
@ -8,4 +8,7 @@ common.paramCheckError=请检查以下参数:
|
||||
common.maxUploadSize=您输入的文件超过最大限制
|
||||
|
||||
|
||||
dataSource.sqlAnalysisError=不合法的执行语句
|
||||
dataSource.sqlAnalysisError=不合法的执行语句
|
||||
connection.error=数据库链接异常,请检查数据库配置
|
||||
connection.ssh.error=SSH 链接异常,请检查SSH配置
|
||||
connection.driver.load.error=数据库驱动加载异常,请检查驱动配置
|
@ -0,0 +1,25 @@
|
||||
package ai.chat2db.server.tools.common.exception;
|
||||
|
||||
import ai.chat2db.server.tools.base.excption.BusinessException;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class ConnectionException extends BusinessException {
|
||||
|
||||
|
||||
public ConnectionException() {
|
||||
this("connection.error");
|
||||
}
|
||||
|
||||
public ConnectionException(String code) {
|
||||
this(code, null);
|
||||
}
|
||||
|
||||
public ConnectionException(String code, Object[] args) {
|
||||
super(code,args);
|
||||
}
|
||||
|
||||
public ConnectionException(String code, Object[] args, Throwable throwable) {
|
||||
super(code,args, throwable);
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package ai.chat2db.server.tools.common.util;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@ -9,8 +11,6 @@ import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* i18n utility
|
||||
*
|
||||
@ -19,7 +19,7 @@ import java.util.Locale;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class I18nUtils implements InitializingBean {
|
||||
public static final String DEFAULT_message_Code="";
|
||||
public static final String DEFAULT_message_Code="common.systemError";
|
||||
@Resource
|
||||
private MessageSource messageSource;
|
||||
private static MessageSource messageSourceStatic;
|
||||
@ -34,7 +34,7 @@ public class I18nUtils implements InitializingBean {
|
||||
} catch (NoSuchMessageException e) {
|
||||
log.error("no message.", e);
|
||||
}
|
||||
return messageSourceStatic.getMessage(messageCode, args, LocaleContextHolder.getLocale());
|
||||
return messageSourceStatic.getMessage(DEFAULT_message_Code, args, LocaleContextHolder.getLocale());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,7 @@ import com.jcraft.jsch.Session;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -179,6 +180,11 @@ public class DataSourceController {
|
||||
public DataResult<DataSourceVO> queryById(@PathVariable("id") Long id) {
|
||||
DataResult<DataSource> dataResult = dataSourceService.queryById(id);
|
||||
DataSourceVO dataSourceVO = dataSourceWebConverter.dto2vo(dataResult.getData());
|
||||
if(StringUtils.isNotBlank(dataSourceVO.getUser())){
|
||||
dataSourceVO.setAuthenticationType("1");
|
||||
}else {
|
||||
dataSourceVO.setAuthenticationType("2");
|
||||
}
|
||||
return DataResult.of(dataSourceVO);
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,13 @@ public class DataSourceCreateRequest {
|
||||
@NotNull
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 认证类型
|
||||
*/
|
||||
private String authenticationType;
|
||||
|
||||
/**
|
||||
* 连接类型
|
||||
* @see DbTypeEnum
|
||||
*/
|
||||
@NotNull
|
||||
private String type;
|
||||
@ -100,4 +104,7 @@ public class DataSourceCreateRequest {
|
||||
* 驱动配置
|
||||
*/
|
||||
private DriverConfig driverConfig;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -47,7 +47,10 @@ public class DataSourceTestRequest {
|
||||
@NotNull
|
||||
private String type;
|
||||
|
||||
|
||||
/**
|
||||
* 认证类型
|
||||
*/
|
||||
private String authenticationType;
|
||||
|
||||
/**
|
||||
* host
|
||||
|
@ -40,6 +40,10 @@ public class DataSourceVO {
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 认证类型
|
||||
*/
|
||||
private String authenticationType;
|
||||
/**
|
||||
* 连接类型
|
||||
*/
|
||||
|
@ -8,6 +8,8 @@ import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import ai.chat2db.server.tools.base.excption.BusinessException;
|
||||
import ai.chat2db.server.tools.common.exception.ConnectionException;
|
||||
import ai.chat2db.spi.DBManage;
|
||||
import ai.chat2db.spi.MetaData;
|
||||
import ai.chat2db.spi.Plugin;
|
||||
@ -101,6 +103,10 @@ public class Chat2DBContext {
|
||||
if (session != null) {
|
||||
url = url.replace(host, "127.0.0.1").replace(port, ssh.getLocalPort());
|
||||
}
|
||||
}catch (Exception e){
|
||||
throw new ConnectionException("connection.ssh.error",null,e);
|
||||
}
|
||||
try {
|
||||
DriverConfig config = connectInfo.getDriverConfig();
|
||||
if (config == null) {
|
||||
config = getDefaultDriverConfig(connectInfo.getDbType());
|
||||
@ -111,27 +117,23 @@ public class Chat2DBContext {
|
||||
connectInfo.getDriverConfig(), connectInfo.getExtendMap());
|
||||
|
||||
} catch (Exception e1) {
|
||||
log.error("GetConnect error", e1);
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
log.error("session close error", e);
|
||||
}
|
||||
}
|
||||
if (session != null) {
|
||||
try {
|
||||
session.delPortForwardingL(Integer.parseInt(ssh.getLocalPort()));
|
||||
} catch (JSchException e) {
|
||||
log.error("session delPortForwardingL error", e);
|
||||
}
|
||||
try {
|
||||
session.disconnect();
|
||||
} catch (Exception e) {
|
||||
log.error("session disconnect error", e);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("GetConnect error", e1);
|
||||
throw new BusinessException("connection.error",null,e1);
|
||||
}
|
||||
connectInfo.setSession(session);
|
||||
connectInfo.setConnection(connection);
|
||||
|
@ -1,12 +1,12 @@
|
||||
|
||||
package ai.chat2db.spi.sql;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.Driver;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@ -14,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
|
||||
import ai.chat2db.server.tools.common.exception.ConnectionException;
|
||||
import ai.chat2db.spi.config.DriverConfig;
|
||||
import ai.chat2db.spi.model.DriverEntry;
|
||||
import ai.chat2db.spi.util.JdbcJarUtils;
|
||||
@ -62,7 +63,13 @@ public class IDriverManager {
|
||||
if (StringUtils.isNotEmpty(password)) {
|
||||
info.put("password", password);
|
||||
}
|
||||
info.putAll(properties);
|
||||
if (properties != null && !properties.isEmpty()) {
|
||||
for (Map.Entry<String, Object> entry : properties.entrySet()) {
|
||||
if (entry.getKey() != null && entry.getValue() != null) {
|
||||
info.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return getConnection(url, info, driver);
|
||||
}
|
||||
|
||||
@ -91,10 +98,8 @@ public class IDriverManager {
|
||||
}
|
||||
|
||||
if (reason != null) {
|
||||
DriverManager.println("getConnection failed: " + reason);
|
||||
throw reason;
|
||||
} else {
|
||||
DriverManager.println("getConnection: no suitable driver found for " + url);
|
||||
throw new SQLException("No suitable driver found for " + url, "08001");
|
||||
}
|
||||
}
|
||||
@ -123,8 +128,7 @@ public class IDriverManager {
|
||||
DRIVER_ENTRY_MAP.put(driver.getJdbcDriver(), driverEntry);
|
||||
return driverEntry;
|
||||
} catch (Exception e) {
|
||||
log.error("getJDBCDriver error", e);
|
||||
throw new SQLException("getJDBCDriver error", "08001");
|
||||
throw new ConnectionException("connection.driver.load.error", null, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,26 +173,4 @@ public class IDriverManager {
|
||||
}
|
||||
}
|
||||
|
||||
//private static List<Class> loadClass(String jarPath, ClassLoader classLoader) throws IOException {
|
||||
// Long s1 = System.currentTimeMillis();
|
||||
// JarFile jarFile = new JarFile(getFullPath(jarPath));
|
||||
// Enumeration<JarEntry> entries = jarFile.entries();
|
||||
// List<Class> classes = new ArrayList();
|
||||
// while (entries.hasMoreElements()) {
|
||||
// JarEntry jarEntry = entries.nextElement();
|
||||
// if (jarEntry.getName().endsWith(".class") && !jarEntry.getName().contains("$")) {
|
||||
// String className = jarEntry.getName().substring(0, jarEntry.getName().length() - 6).replaceAll("/",
|
||||
// ".");
|
||||
// try {
|
||||
// classes.add(classLoader.loadClass(className));
|
||||
// // log.info("loadClass:{}", className);
|
||||
// } catch (Throwable var7) {
|
||||
// //log.error("getClasses error "+className, var7);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// log.info("loadClass cost:{}", System.currentTimeMillis() - s1);
|
||||
// return classes;
|
||||
//}
|
||||
|
||||
}
|
@ -11,6 +11,7 @@ import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ai.chat2db.server.tools.base.constant.EasyToolsConstant;
|
||||
import ai.chat2db.spi.model.*;
|
||||
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
@ -94,6 +95,7 @@ public class SQLExecutor {
|
||||
|
||||
ExecuteResult executeResult = ExecuteResult.builder().sql(sql).success(Boolean.TRUE).build();
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
stmt.setFetchSize(EasyToolsConstant.MAX_PAGE_SIZE);
|
||||
TimeInterval timeInterval = new TimeInterval();
|
||||
boolean query = stmt.execute(sql.replaceFirst(";", ""));
|
||||
executeResult.setDescription("执行成功");
|
||||
@ -121,7 +123,9 @@ public class SQLExecutor {
|
||||
List<List<String>> dataList = Lists.newArrayList();
|
||||
executeResult.setDataList(dataList);
|
||||
|
||||
while (rs.next()) {
|
||||
int n = 0;
|
||||
while (rs.next() && n < EasyToolsConstant.MAX_PAGE_SIZE) {
|
||||
n++;
|
||||
List<String> row = Lists.newArrayListWithExpectedSize(col);
|
||||
dataList.add(row);
|
||||
for (int i = 1; i <= col; i++) {
|
||||
|
Reference in New Issue
Block a user