mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-19 03:41:40 +08:00
✨ feat(export-workbench): 支持批量导出工作台并优化 SQL 导出性能
- 侧边栏批量表/批量库入口改为直接打开导出工作台,统一导出配置与进度视图 - 导出工作台新增 batch-tables / batch-databases 模式,支持连接、数据库、对象选择与独立历史记录键 - 连接、数据库、对象下拉项补齐完整名展示与悬浮提示,避免长名称被截断后不可识别 - 后端新增批量对象/批量库导出 WithOptions 链路,统一返回输出文件/目录与进度信息 - SQL dump 数据导出改为按方言批量写入,MySQL/PG 等使用多值 VALUES,Oracle/达梦使用 INSERT ALL - 补充导出工作台与 SQL dump 的回归测试和 benchmark,覆盖批量模式与批量写入语义
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
buildBatchDatabaseExportWorkbenchTab,
|
||||
buildBatchTableExportWorkbenchTab,
|
||||
buildExportWorkbenchHistoryKey,
|
||||
buildTableExportHistoryKey,
|
||||
buildTableExportTab,
|
||||
DEFAULT_TABLE_EXPORT_SCOPE_OPTION,
|
||||
@@ -11,6 +14,20 @@ describe('tableExportTab', () => {
|
||||
expect(buildTableExportHistoryKey(' conn-1 ', ' app ', ' public.orders ')).toBe('conn-1::app::public.orders');
|
||||
});
|
||||
|
||||
it('builds batch workbench history keys by mode', () => {
|
||||
expect(buildExportWorkbenchHistoryKey({
|
||||
connectionId: ' conn-1 ',
|
||||
dbName: ' app ',
|
||||
tableName: 'orders',
|
||||
exportWorkbenchMode: 'batch-tables',
|
||||
})).toBe('conn-1::app::__batch_tables__');
|
||||
expect(buildExportWorkbenchHistoryKey({
|
||||
connectionId: ' conn-1 ',
|
||||
dbName: ' ignored ',
|
||||
exportWorkbenchMode: 'batch-databases',
|
||||
})).toBe('conn-1::__batch_databases__');
|
||||
});
|
||||
|
||||
it('builds a stable table export tab with normalized defaults', () => {
|
||||
const tab = buildTableExportTab({
|
||||
connectionId: 'conn-1',
|
||||
@@ -21,6 +38,7 @@ describe('tableExportTab', () => {
|
||||
expect(tab.id).toBe('table-export-conn-1-app-public.orders');
|
||||
expect(tab.type).toBe('table-export');
|
||||
expect(tab.title).toBe('导出 public.orders');
|
||||
expect(tab.exportWorkbenchMode).toBe('single');
|
||||
expect(tab.tableExportScopeOptions).toEqual([DEFAULT_TABLE_EXPORT_SCOPE_OPTION]);
|
||||
expect(tab.tableExportInitialScope).toBe('all');
|
||||
expect(tab.tableExportQueryByScope).toBeUndefined();
|
||||
@@ -60,4 +78,28 @@ describe('tableExportTab', () => {
|
||||
filteredAll: 42,
|
||||
});
|
||||
});
|
||||
|
||||
it('builds batch table export workbench tabs with stable ids', () => {
|
||||
const tab = buildBatchTableExportWorkbenchTab({
|
||||
connectionId: 'conn-1',
|
||||
dbName: 'SYS',
|
||||
});
|
||||
|
||||
expect(tab.id).toBe('table-export-batch-tables-conn-1-SYS');
|
||||
expect(tab.type).toBe('table-export');
|
||||
expect(tab.title).toBe('批量导出对象');
|
||||
expect(tab.exportWorkbenchMode).toBe('batch-tables');
|
||||
expect(tab.dbName).toBe('SYS');
|
||||
});
|
||||
|
||||
it('builds batch database export workbench tabs with stable ids', () => {
|
||||
const tab = buildBatchDatabaseExportWorkbenchTab({
|
||||
connectionId: 'conn-1',
|
||||
});
|
||||
|
||||
expect(tab.id).toBe('table-export-batch-databases-conn-1');
|
||||
expect(tab.type).toBe('table-export');
|
||||
expect(tab.title).toBe('批量导出库');
|
||||
expect(tab.exportWorkbenchMode).toBe('batch-databases');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,6 +18,21 @@ export const buildTableExportHistoryKey = (
|
||||
].join('::');
|
||||
};
|
||||
|
||||
export const buildExportWorkbenchHistoryKey = (
|
||||
input: Pick<TabData, 'connectionId' | 'dbName' | 'tableName' | 'exportWorkbenchMode'>,
|
||||
): string => {
|
||||
const mode = input.exportWorkbenchMode || 'single';
|
||||
const connectionId = String(input.connectionId || '').trim();
|
||||
const dbName = String(input.dbName || '').trim();
|
||||
if (mode === 'batch-tables') {
|
||||
return [connectionId, dbName, '__batch_tables__'].join('::');
|
||||
}
|
||||
if (mode === 'batch-databases') {
|
||||
return [connectionId, '__batch_databases__'].join('::');
|
||||
}
|
||||
return buildTableExportHistoryKey(connectionId, dbName, input.tableName);
|
||||
};
|
||||
|
||||
type BuildTableExportTabInput = {
|
||||
connectionId: string;
|
||||
dbName?: string;
|
||||
@@ -32,6 +47,17 @@ type BuildTableExportTabInput = {
|
||||
rowCountByScope?: Partial<Record<TableExportScope, number>>;
|
||||
};
|
||||
|
||||
type BuildBatchTableExportWorkbenchTabInput = {
|
||||
connectionId: string;
|
||||
dbName?: string;
|
||||
title?: string;
|
||||
};
|
||||
|
||||
type BuildBatchDatabaseExportWorkbenchTabInput = {
|
||||
connectionId: string;
|
||||
title?: string;
|
||||
};
|
||||
|
||||
const normalizeScopeOptions = (
|
||||
scopeOptions: TableExportScopeOption[] | undefined,
|
||||
): TableExportScopeOption[] => {
|
||||
@@ -108,6 +134,7 @@ export const buildTableExportTab = (input: BuildTableExportTabInput): TabData =>
|
||||
id: `table-export-${connectionId}-${dbName}-${tableName}`,
|
||||
title: String(input.title || `导出 ${objectLabel}`).trim() || `导出 ${objectLabel}`,
|
||||
type: 'table-export',
|
||||
exportWorkbenchMode: 'single',
|
||||
connectionId,
|
||||
dbName,
|
||||
tableName,
|
||||
@@ -121,3 +148,34 @@ export const buildTableExportTab = (input: BuildTableExportTabInput): TabData =>
|
||||
tableExportRowCountByScope: normalizeRowCountByScope(input.rowCountByScope),
|
||||
};
|
||||
};
|
||||
|
||||
export const buildBatchTableExportWorkbenchTab = (
|
||||
input: BuildBatchTableExportWorkbenchTabInput,
|
||||
): TabData => {
|
||||
const connectionId = String(input.connectionId || '').trim();
|
||||
const dbName = String(input.dbName || '').trim();
|
||||
const scopeSuffix = dbName || 'all';
|
||||
return {
|
||||
id: `table-export-batch-tables-${connectionId || 'none'}-${scopeSuffix}`,
|
||||
title: String(input.title || '批量导出对象').trim() || '批量导出对象',
|
||||
type: 'table-export',
|
||||
exportWorkbenchMode: 'batch-tables',
|
||||
connectionId,
|
||||
dbName: dbName || undefined,
|
||||
initialTab: 'config',
|
||||
};
|
||||
};
|
||||
|
||||
export const buildBatchDatabaseExportWorkbenchTab = (
|
||||
input: BuildBatchDatabaseExportWorkbenchTabInput,
|
||||
): TabData => {
|
||||
const connectionId = String(input.connectionId || '').trim();
|
||||
return {
|
||||
id: `table-export-batch-databases-${connectionId || 'none'}`,
|
||||
title: String(input.title || '批量导出库').trim() || '批量导出库',
|
||||
type: 'table-export',
|
||||
exportWorkbenchMode: 'batch-databases',
|
||||
connectionId,
|
||||
initialTab: 'config',
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user