Skip to content

Commit 7654a29

Browse files
authored
Merge pull request #672 from actiontech/feature/rewrite-sql-progress
[feature](SqlRewrittenDrawer): add rewrite progress display during SQL rewriting pending state
2 parents ce0008b + 2de069a commit 7654a29

File tree

32 files changed

+6097
-209
lines changed

32 files changed

+6097
-209
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"icon:build": "pnpm --filter @actiontech/icons build",
3333
"dms:g": "pnpm --filter @actiontech/cli-create-dms-page build && create-dms-page",
3434
"api_client:g": "npm_config_registry=http://10.186.18.19:4873 pnpx @actiontech/cli api-client -y",
35-
"api_mocks:g": "npm_config_registry=http://10.186.18.19:4873 pnpx @actiontech/cli api-mocks -y"
35+
"api_mocks:g": "npm_config_registry=http://10.186.18.19:4873 pnpx @actiontech/cli api-mocks -y",
36+
"ai-doc": "npm_config_registry=http://10.186.18.19:4873 pnpx @actiontech/cli ai-doc"
3637
},
3738
"keywords": [],
3839
"author": "",

packages/shared/lib/api/sqle/service/common.d.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
RuleCategoryStatisticCategoryEnum,
33
AssociateWorkflowsStatusEnum,
4+
AsyncRewriteTaskStatusEnum,
45
AuditPlanParamResV1TypeEnum,
56
AuditPlanReportResV1AuditLevelEnum,
67
AuditPlanSQLHeadV1TypeEnum,
@@ -44,6 +45,7 @@ import {
4445
ReportPushConfigListPushUserTypeEnum,
4546
ReportPushConfigListTriggerTypeEnum,
4647
RewriteSuggestionAuditLevelEnum,
48+
RewriteSuggestionStatusEnum,
4749
RewriteSuggestionTypeEnum,
4850
RuleParamResV1TypeEnum,
4951
RuleResV1LevelEnum,
@@ -154,6 +156,30 @@ export interface IAssociateWorkflows {
154156
workflow_name?: string;
155157
}
156158

159+
export interface IAsyncRewriteTask {
160+
end_time?: string;
161+
162+
error_message?: string;
163+
164+
result?: IRewriteSQLData;
165+
166+
sql_number?: string;
167+
168+
start_time?: string;
169+
170+
status?: AsyncRewriteTaskStatusEnum;
171+
172+
task_id?: string;
173+
}
174+
175+
export interface IAsyncRewriteTaskStatusRes {
176+
code?: number;
177+
178+
data?: IAsyncRewriteTask;
179+
180+
message?: string;
181+
}
182+
157183
export interface IAuditFileResp {
158184
file_name?: string;
159185
}
@@ -2710,14 +2736,6 @@ export interface IRewriteSQLReq {
27102736
enable_structure_type?: boolean;
27112737
}
27122738

2713-
export interface IRewriteSQLRes {
2714-
code?: number;
2715-
2716-
data?: IRewriteSQLData;
2717-
2718-
message?: string;
2719-
}
2720-
27212739
export interface IRewriteSuggestion {
27222740
audit_level?: RewriteSuggestionAuditLevelEnum;
27232741

@@ -2731,6 +2749,8 @@ export interface IRewriteSuggestion {
27312749

27322750
rule_name?: string;
27332751

2752+
status?: RewriteSuggestionStatusEnum;
2753+
27342754
type?: RewriteSuggestionTypeEnum;
27352755
}
27362756

packages/shared/lib/api/sqle/service/common.enum.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ export enum AssociateWorkflowsStatusEnum {
2424
'finished' = 'finished'
2525
}
2626

27+
export enum AsyncRewriteTaskStatusEnum {
28+
'pending' = 'pending',
29+
30+
'running' = 'running',
31+
32+
'completed' = 'completed',
33+
34+
'failed' = 'failed'
35+
}
36+
2737
export enum AuditPlanParamResV1TypeEnum {
2838
'string' = 'string',
2939

@@ -412,6 +422,12 @@ export enum RewriteSuggestionAuditLevelEnum {
412422
'error' = 'error'
413423
}
414424

425+
export enum RewriteSuggestionStatusEnum {
426+
'initial' = 'initial',
427+
428+
'processed' = 'processed'
429+
}
430+
415431
export enum RewriteSuggestionTypeEnum {
416432
'statement' = 'statement',
417433

packages/shared/lib/api/sqle/service/task/index.d.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
IUpdateAuditTaskSQLsReqV1,
1313
IGetTaskAnalysisDataResV1,
1414
IRewriteSQLReq,
15-
IRewriteSQLRes,
15+
IAsyncRewriteTaskStatusRes,
1616
IGetAuditFileListRes,
1717
IGetAuditFileExecStatisticRes,
1818
IGetAuditTaskSQLsResV2,
@@ -170,7 +170,16 @@ export interface IRewriteSQLParams extends IRewriteSQLReq {
170170
number: number;
171171
}
172172

173-
export interface IRewriteSQLReturn extends IRewriteSQLRes {}
173+
export interface IRewriteSQLReturn extends IAsyncRewriteTaskStatusRes {}
174+
175+
export interface IGetAsyncRewriteTaskStatusParams {
176+
task_id: string;
177+
178+
number: number;
179+
}
180+
181+
export interface IGetAsyncRewriteTaskStatusReturn
182+
extends IAsyncRewriteTaskStatusRes {}
174183

175184
export interface IGetSqlFileOrderMethodV1Return
176185
extends IGetSqlFileOrderMethodResV1 {}

packages/shared/lib/api/sqle/service/task/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import {
3232
IGetTaskAnalysisDataReturn,
3333
IRewriteSQLParams,
3434
IRewriteSQLReturn,
35+
IGetAsyncRewriteTaskStatusParams,
36+
IGetAsyncRewriteTaskStatusReturn,
3537
IGetSqlFileOrderMethodV1Return,
3638
IGetAuditFileListParams,
3739
IGetAuditFileListReturn,
@@ -364,6 +366,24 @@ class TaskService extends ServiceBase {
364366
);
365367
}
366368

369+
public GetAsyncRewriteTaskStatus(
370+
params: IGetAsyncRewriteTaskStatusParams,
371+
options?: AxiosRequestConfig
372+
) {
373+
const paramsData = this.cloneDeep(params);
374+
const task_id = paramsData.task_id;
375+
delete paramsData.task_id;
376+
377+
const number = paramsData.number;
378+
delete paramsData.number;
379+
380+
return this.get<IGetAsyncRewriteTaskStatusReturn>(
381+
`/v1/tasks/audits/${task_id}/sqls/${number}/rewrite/status`,
382+
paramsData,
383+
options
384+
);
385+
}
386+
367387
public getSqlFileOrderMethodV1(options?: AxiosRequestConfig) {
368388
return this.get<IGetSqlFileOrderMethodV1Return>(
369389
'/v1/tasks/file_order_methods',

packages/shared/lib/testUtil/mockApi/sqle/task/data.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
} from '../../../../api/sqle/service/common';
55
import {
66
AuditTaskSQLResV2BackupStrategyEnum,
7-
AuditTaskSQLResV2BackupStatusEnum
7+
AuditTaskSQLResV2BackupStatusEnum,
8+
RewriteSuggestionStatusEnum
89
} from '../../../../api/sqle/service/common.enum';
910

1011
export const AuditTaskSQLsMockData: IAuditTaskSQLResV2[] = [
@@ -745,3 +746,58 @@ export const SqlRewrittenMockDataWithNotRewriter = {
745746
business_non_equivalent_desc:
746747
'- **记录数的不确定性**: 原始 SQL 使用 `ORDER BY RAND()` 可能会导致记录数的不确定性,因为随机排序可能导致不同的记录被选中。而优化后的 SQL 使用 `u.id IN (SELECT id FROM random_ids)`,虽然也实现了随机选择,但具体的记录选择可能会不同,导致记录数的不确定性。\n- **数据内容的差异**: 由于记录的选择可能不同,因此数据内容也可能不同。\n- **数据顺序的差异**: 虽然两种方法都实现了随机选择,但具体的选择顺序可能会不同,导致数据顺序的差异。'
747748
} as IRewriteSQLData;
749+
750+
export const AsyncRewriteTaskStatusMockData = {
751+
task_id: 'mock_task_123',
752+
sql_number: '1',
753+
status: 'running',
754+
start_time: '2023-12-01T10:00:00.000Z',
755+
end_time: undefined,
756+
error_message: undefined,
757+
result: {
758+
...SqlRewrittenMockDataNoDDL,
759+
suggestions: SqlRewrittenMockDataNoDDL.suggestions!.map((item, index) => ({
760+
...item,
761+
status:
762+
index % 2 === 0
763+
? RewriteSuggestionStatusEnum.processed
764+
: RewriteSuggestionStatusEnum.initial
765+
}))
766+
}
767+
};
768+
769+
export const AsyncRewriteTaskStatusCompletedMockData = {
770+
task_id: 'mock_task_123',
771+
sql_number: '1',
772+
status: 'completed',
773+
start_time: '2023-12-01T10:00:00.000Z',
774+
end_time: '2023-12-01T10:05:30.000Z',
775+
error_message: undefined,
776+
result: {
777+
...SqlRewrittenMockDataNoDDL,
778+
suggestions: SqlRewrittenMockDataNoDDL.suggestions!.map((item) => ({
779+
...item,
780+
status: RewriteSuggestionStatusEnum.processed
781+
}))
782+
}
783+
};
784+
785+
export const AsyncRewriteTaskStatusFailedMockData = {
786+
task_id: 'mock_task_123',
787+
sql_number: '1',
788+
status: 'failed',
789+
start_time: '2023-12-01T10:00:00.000Z',
790+
end_time: '2023-12-01T10:02:15.000Z',
791+
error_message: 'SQL rewrite failed due to syntax error',
792+
result: undefined
793+
};
794+
795+
export const AsyncRewriteTaskStatusPendingMockData = {
796+
task_id: 'mock_task_123',
797+
sql_number: '1',
798+
status: 'pending',
799+
start_time: undefined,
800+
end_time: undefined,
801+
error_message: undefined,
802+
result: undefined
803+
};

packages/shared/lib/testUtil/mockApi/sqle/task/index.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import {
44
AuditTaskSQLsMockData,
55
SqlRewrittenMockDataNoDDL,
66
TaskFileListMockData,
7-
workflowTaskDetailMockData
7+
workflowTaskDetailMockData,
8+
AsyncRewriteTaskStatusMockData,
9+
AsyncRewriteTaskStatusCompletedMockData,
10+
AsyncRewriteTaskStatusFailedMockData,
11+
AsyncRewriteTaskStatusPendingMockData
812
} from './data';
913

1014
class TaskMockApi implements MockSpyApy {
@@ -14,6 +18,9 @@ class TaskMockApi implements MockSpyApy {
1418
this.getAuditTask();
1519
this.getAuditFileList();
1620
this.getSqlFileOrderMethod();
21+
this.updateSqlFileOrder();
22+
this.getTaskSQLRewritten();
23+
this.getAsyncRewriteTaskStatus();
1724
}
1825

1926
public getAuditTaskSQLs() {
@@ -84,7 +91,41 @@ class TaskMockApi implements MockSpyApy {
8491
public getTaskSQLRewritten() {
8592
const spy = jest.spyOn(task, 'RewriteSQL');
8693
spy.mockImplementation(() =>
87-
createSpySuccessResponse({ data: SqlRewrittenMockDataNoDDL })
94+
createSpySuccessResponse({ data: AsyncRewriteTaskStatusMockData })
95+
);
96+
return spy;
97+
}
98+
99+
public getAsyncRewriteTaskStatus() {
100+
const spy = jest.spyOn(task, 'GetAsyncRewriteTaskStatus');
101+
spy.mockImplementation(() =>
102+
createSpySuccessResponse({ data: AsyncRewriteTaskStatusMockData })
103+
);
104+
return spy;
105+
}
106+
107+
public getAsyncRewriteTaskStatusCompleted() {
108+
const spy = jest.spyOn(task, 'GetAsyncRewriteTaskStatus');
109+
spy.mockImplementation(() =>
110+
createSpySuccessResponse({
111+
data: AsyncRewriteTaskStatusCompletedMockData
112+
})
113+
);
114+
return spy;
115+
}
116+
117+
public getAsyncRewriteTaskStatusFailed() {
118+
const spy = jest.spyOn(task, 'GetAsyncRewriteTaskStatus');
119+
spy.mockImplementation(() =>
120+
createSpySuccessResponse({ data: AsyncRewriteTaskStatusFailedMockData })
121+
);
122+
return spy;
123+
}
124+
125+
public getAsyncRewriteTaskStatusPending() {
126+
const spy = jest.spyOn(task, 'GetAsyncRewriteTaskStatus');
127+
spy.mockImplementation(() =>
128+
createSpySuccessResponse({ data: AsyncRewriteTaskStatusPendingMockData })
88129
);
89130
return spy;
90131
}

packages/sqle/src/components/SqlRewrittenDrawer/__tests__/__snapshots__/index.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exports[`SqlRewrittenDrawer should match snapshot 1`] = `
44
<Fragment>
55
<SqlRewrittenDrawerEE
6-
maskClosable={true}
6+
maskClosable={false}
77
onClose={[MockFunction]}
88
open={true}
99
originSqlInfo={

packages/sqle/src/components/SqlRewrittenDrawer/__tests__/components/OverallRewrittenSuggestion.test.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ describe('OverallRewrittenSuggestion', () => {
2727
businessDesc: SqlRewrittenMockDataNoDDL.business_desc!,
2828
sqlLogicDesc: SqlRewrittenMockDataWithLogic.logic_desc!,
2929
rewrittenSqlLogicDesc:
30-
SqlRewrittenMockDataWithLogic.rewritten_sql_logic_desc!
30+
SqlRewrittenMockDataWithLogic.rewritten_sql_logic_desc!,
31+
isRewriting: false
3132
};
3233

3334
ignoreConsoleErrors([
@@ -56,6 +57,25 @@ describe('OverallRewrittenSuggestion', () => {
5657
expect(screen.getByText(mockProps.businessDesc)).toBeInTheDocument();
5758
});
5859

60+
it('should render rewriting in progress message when isRewriting is true', () => {
61+
sqleSuperRender(
62+
<OverallRewrittenSuggestion {...mockProps} isRewriting={true} />
63+
);
64+
65+
expect(screen.getByText('总结')).toBeInTheDocument();
66+
expect(
67+
screen.getByText(
68+
'SQL重写过程进行中,系统将逐步应用优化规则并展示每个步骤的详细信息...'
69+
)
70+
).toBeInTheDocument();
71+
expect(
72+
screen.queryByText(
73+
`本次 SQL 重写基于 ${mockProps.optimizedCount} 条规则进行了优化,目前还有 ${mockProps.remainingCount} 条规则有待进一步优化。此外,有 ${mockProps.businessCount} 条规则需要人工处理。`
74+
)
75+
).not.toBeInTheDocument();
76+
expect(screen.queryByText(mockProps.businessDesc)).not.toBeInTheDocument();
77+
});
78+
5979
it('should render database structure change statement section when overallDDL exists', () => {
6080
sqleSuperRender(
6181
<OverallRewrittenSuggestion
@@ -165,7 +185,8 @@ describe('OverallRewrittenSuggestion', () => {
165185
...mockProps,
166186
suggestions: [],
167187
rewrittenSql: undefined,
168-
businessNonEquivalentDesc: ''
188+
businessNonEquivalentDesc: '',
189+
isRewriting: false
169190
};
170191

171192
sqleSuperRender(<OverallRewrittenSuggestion {...mockEmptyProps} />);

0 commit comments

Comments
 (0)