feat(ddl): 为 DDL 视图增加按方言格式化展示能力

- 新增通用 DDL 格式化工具
- DataGrid 查看 DDL 时按数据源方言输出可读 SQL
- 覆盖 DuckDB DDL 展示与工具层测试
This commit is contained in:
Syngnat
2026-06-05 22:21:40 +08:00
parent d2189e1442
commit a5b27820cb
5 changed files with 120 additions and 3 deletions

View File

@@ -1246,10 +1246,48 @@ describe('DataGrid DDL interactions', () => {
expect(editors).toHaveLength(1);
expect(editors[0].props['data-language']).toBe('sql');
expect(editors[0].props['data-read-only']).toBe('true');
expect(textContent(editors[0])).toContain('CREATE TABLE users');
expect(textContent(editors[0])).toContain('CREATE TABLE');
expect(textContent(editors[0])).toContain('users');
expect(renderer!.root.findAll((node) => node.type === 'pre' && textContent(node).includes('CREATE TABLE users'))).toHaveLength(0);
});
it('formats DuckDB DDL into readable multiline SQL in the v2 view', async () => {
storeState.appearance.uiVersion = 'v2';
storeState.connections[0].config.type = 'duckdb';
backendApp.DBShowCreateTable.mockResolvedValueOnce({
success: true,
data: 'CREATE TABLE customers(customer_id BIGINT, customer_code VARCHAR, city VARCHAR, tier VARCHAR, signup_date DATE, lifetime_value DECIMAL(12,2), PRIMARY KEY(customer_id));',
});
let renderer: ReactTestRenderer;
await act(async () => {
renderer = create(
<DataGrid
data={[{ __gonavi_row_key__: 'row-1', customer_id: 1 }]}
columnNames={['customer_id']}
loading={false}
tableName="example.main.customers"
dbName="main"
connectionId="conn-1"
/>,
);
});
await waitForEffects();
await act(async () => {
findButton(renderer!, '查看 DDL').props.onClick();
});
await waitForEffects();
const editors = renderer!.root.findAll((node) => node.props['data-monaco-editor'] === 'true');
expect(editors).toHaveLength(1);
const ddlText = textContent(editors[0]);
expect(ddlText).toContain('CREATE TABLE customers (');
expect(ddlText).toContain('customer_id BIGINT,');
expect(ddlText).toContain('PRIMARY KEY (customer_id)');
expect(ddlText).toContain('\n');
});
it('opens the v2 DDL view as a right sidebar while keeping the table visible', async () => {
storeState.appearance.uiVersion = 'v2';
backendApp.DBShowCreateTable.mockResolvedValueOnce({

View File

@@ -3214,6 +3214,7 @@ const DataGrid: React.FC<DataGridProps> = ({
canViewDdl,
currentConnConfig,
dbName,
dbType,
tableName,
isV2Ui,
cellEditMode,

View File

@@ -1,6 +1,7 @@
import React from 'react';
import { DBShowCreateTable } from '../../wailsjs/go/app/App';
import { buildRpcConnectionConfig } from '../utils/connectionRpcConfig';
import { formatDdlForDisplay } from '../utils/ddlFormat';
type GridViewMode = 'table' | 'json' | 'text' | 'fields' | 'ddl' | 'er';
type DdlViewLayoutMode = 'bottom' | 'side';
@@ -20,6 +21,7 @@ interface UseDataGridDdlViewParams {
messageApi: {
error: (content: string) => void;
};
dbType?: string;
}
export interface UseDataGridDdlViewResult {
@@ -54,6 +56,7 @@ export const useDataGridDdlView = ({
closeCellEditModeRef,
setTextRecordIndex,
messageApi,
dbType,
}: UseDataGridDdlViewParams): UseDataGridDdlViewResult => {
const [viewMode, setViewMode] = React.useState<GridViewMode>('table');
const [ddlModalOpen, setDdlModalOpen] = React.useState(false);
@@ -92,7 +95,7 @@ export const useDataGridDdlView = ({
const res = await DBShowCreateTable(buildRpcConnectionConfig(currentConnConfig as any) as any, dbName || '', tableName);
if (requestSeq !== ddlRequestSeqRef.current) return;
if (res.success) {
setDdlText(String(res.data ?? ''));
setDdlText(formatDdlForDisplay(res.data, dbType || String((currentConnConfig as any)?.type || '')));
return;
}
messageApi.error(res.message || '获取 DDL 失败');
@@ -104,7 +107,7 @@ export const useDataGridDdlView = ({
setDdlLoading(false);
}
}
}, [canViewDdl, currentConnConfig, dbName, isV2Ui, messageApi, tableName]);
}, [canViewDdl, currentConnConfig, dbName, dbType, isV2Ui, messageApi, tableName]);
React.useEffect(() => {
if (isV2Ui || (viewMode !== 'fields' && viewMode !== 'ddl' && viewMode !== 'er')) return;