Skip to content

Commit 03ddb01

Browse files
committed
support sqle audit
1 parent a4a2e73 commit 03ddb01

File tree

20 files changed

+496
-1
lines changed

20 files changed

+496
-1
lines changed

webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ export class SqlEditorTabService extends Bootstrap {
281281
!Array.isArray(tab.handlerState.modeState) ||
282282
!Array.isArray(tab.handlerState.tabs) ||
283283
!Array.isArray(tab.handlerState.executionPlanTabs) ||
284+
!Array.isArray(tab.handlerState.auditTabs) ||
284285
!Array.isArray(tab.handlerState.resultGroups) ||
285286
!Array.isArray(tab.handlerState.resultTabs) ||
286287
!Array.isArray(tab.handlerState.statisticsTabs)
@@ -308,6 +309,7 @@ export class SqlEditorTabService extends Bootstrap {
308309
tab.handlerState.resultGroups = observable([]);
309310
tab.handlerState.resultTabs = observable([]);
310311
tab.handlerState.executionPlanTabs = observable([]);
312+
tab.handlerState.auditTabs = observable([]);
311313
tab.handlerState.statisticsTabs = observable([]);
312314
tab.handlerState.outputLogsTab = undefined;
313315

webapp/packages/plugin-sql-editor/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
"@cloudbeaver/core-theming": "~0.1.0",
4040
"@cloudbeaver/core-ui": "~0.1.0",
4141
"@cloudbeaver/core-utils": "~0.1.0",
42-
"@cloudbeaver/core-view": "~0.1.0"
42+
"@cloudbeaver/core-view": "~0.1.0",
43+
"@ant-design/icons": "^5.2.6",
44+
"axios": "^1.5.1"
4345
},
4446
"peerDependencies": {
4547
"react": "~18.x.x",
Lines changed: 3 additions & 0 deletions
Loading

webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ export interface IExecutionPlanTab {
4242
options?: Record<string, any>;
4343
}
4444

45+
export interface IAuditTab {
46+
tabId: string;
47+
order: number;
48+
query: string;
49+
}
50+
4551
export interface IOutputLogsTab extends ISqlEditorResultTab {
4652
selectedLogTypes: IOutputLogType[];
4753
}
@@ -59,6 +65,7 @@ export interface ISqlEditorTabState {
5965
resultTabs: IResultTab[];
6066
statisticsTabs: IStatisticsTab[];
6167
executionPlanTabs: IExecutionPlanTab[];
68+
auditTabs: IAuditTab[];
6269
outputLogsTab?: IOutputLogsTab;
6370

6471
// mode

webapp/packages/plugin-sql-editor/src/MenuBootstrap.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ import { ACTION_SQL_EDITOR_EXECUTE_NEW } from './actions/ACTION_SQL_EDITOR_EXECU
2222
import { ACTION_SQL_EDITOR_EXECUTE_SCRIPT } from './actions/ACTION_SQL_EDITOR_EXECUTE_SCRIPT';
2323
import { ACTION_SQL_EDITOR_FORMAT } from './actions/ACTION_SQL_EDITOR_FORMAT';
2424
import { ACTION_SQL_EDITOR_SHOW_EXECUTION_PLAN } from './actions/ACTION_SQL_EDITOR_SHOW_EXECUTION_PLAN';
25+
import { ACTION_SQL_EDITOR_AUDIT } from './actions/ACTION_SQL_EDITOR_AUDIT';
2526
import { ACTION_SQL_EDITOR_SHOW_OUTPUT } from './actions/ACTION_SQL_EDITOR_SHOW_OUTPUT';
2627
import { KEY_BINDING_SQL_EDITOR_EXECUTE } from './actions/bindings/KEY_BINDING_SQL_EDITOR_EXECUTE';
2728
import { KEY_BINDING_SQL_EDITOR_EXECUTE_NEW } from './actions/bindings/KEY_BINDING_SQL_EDITOR_EXECUTE_NEW';
2829
import { KEY_BINDING_SQL_EDITOR_EXECUTE_SCRIPT } from './actions/bindings/KEY_BINDING_SQL_EDITOR_EXECUTE_SCRIPT';
2930
import { KEY_BINDING_SQL_EDITOR_FORMAT } from './actions/bindings/KEY_BINDING_SQL_EDITOR_FORMAT';
3031
import { KEY_BINDING_SQL_EDITOR_SHOW_EXECUTION_PLAN } from './actions/bindings/KEY_BINDING_SQL_EDITOR_SHOW_EXECUTION_PLAN';
32+
import { KEY_BINDING_SQL_EDITOR_AUDIT } from './actions/bindings/KEY_BINDING_SQL_EDITOR_AUDIT'
3133
import { KEY_BINDING_SQL_EDITOR_SHOW_OUTPUT } from './actions/bindings/KEY_BINDING_SQL_EDITOR_SHOW_OUTPUT';
3234
import { ESqlDataSourceFeatures } from './SqlDataSource/ESqlDataSourceFeatures';
3335
import { DATA_CONTEXT_SQL_EDITOR_DATA } from './SqlEditor/DATA_CONTEXT_SQL_EDITOR_DATA';
@@ -81,6 +83,7 @@ export class MenuBootstrap extends Bootstrap {
8183
ACTION_REDO,
8284
ACTION_UNDO,
8385
ACTION_SQL_EDITOR_SHOW_EXECUTION_PLAN,
86+
ACTION_SQL_EDITOR_AUDIT,
8487
ACTION_SQL_EDITOR_SHOW_OUTPUT,
8588
].includes(action);
8689
},
@@ -140,6 +143,13 @@ export class MenuBootstrap extends Bootstrap {
140143
handler: this.sqlEditorActionHandler.bind(this),
141144
});
142145

146+
this.keyBindingService.addKeyBindingHandler({
147+
id: 'sql-editor-audit',
148+
binding: KEY_BINDING_SQL_EDITOR_AUDIT,
149+
isBindingApplicable: (contexts, action) => action === ACTION_SQL_EDITOR_AUDIT,
150+
handler: this.sqlEditorActionHandler.bind(this),
151+
});
152+
143153
// this.menuService.addCreator({
144154
// isApplicable: context => (
145155
// context.tryGet(DATA_CONTEXT_SQL_EDITOR_DATA) !== undefined
@@ -185,6 +195,9 @@ export class MenuBootstrap extends Bootstrap {
185195
case ACTION_SQL_EDITOR_SHOW_EXECUTION_PLAN:
186196
data.showExecutionPlan();
187197
break;
198+
case ACTION_SQL_EDITOR_AUDIT:
199+
data.audit();
200+
break;
188201
}
189202
}
190203

webapp/packages/plugin-sql-editor/src/SqlEditor/ISQLEditorData.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface ISQLEditorData {
5656
executeQuery(): Promise<void>;
5757
executeQueryNewTab(): Promise<void>;
5858
showExecutionPlan(): Promise<void>;
59+
audit(): Promise<void>;
5960
executeScript(): Promise<void>;
6061
switchEditing(): Promise<void>;
6162
getHintProposals(position: number, simple: boolean): Promise<SQLProposal[]>;

webapp/packages/plugin-sql-editor/src/SqlEditor/SqlEditor.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
185185
<StaticImage icon="/icons/sql_execution_plan.svg" />
186186
</button>
187187
)}
188+
{isQuery && (
189+
<button disabled={disabled} title={translate('sql_editor_audit_button_tooltip')} onClick={data.audit}>
190+
<StaticImage icon="/icons/sql_audit.svg" />
191+
</button>
192+
)}
188193
</>
189194
)}
190195
<SqlEditorActionsMenu state={state} />

webapp/packages/plugin-sql-editor/src/SqlEditor/useSqlEditor.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { SqlDialectInfoService } from '../SqlDialectInfoService';
2525
import { SqlEditorService } from '../SqlEditorService';
2626
import { ISQLScriptSegment, SQLParser } from '../SQLParser';
2727
import { SqlExecutionPlanService } from '../SqlResultTabs/ExecutionPlan/SqlExecutionPlanService';
28+
import { SqlAuditService } from '../SqlResultTabs/SqlAudit/SqlAuditService';
2829
import { OUTPUT_LOGS_TAB_ID } from '../SqlResultTabs/OutputLogs/OUTPUT_LOGS_TAB_ID';
2930
import { OutputLogsService } from '../SqlResultTabs/OutputLogs/OutputLogsService';
3031
import { SqlQueryService } from '../SqlResultTabs/SqlQueryService';
@@ -39,6 +40,7 @@ interface ISQLEditorDataPrivate extends ISQLEditorData {
3940
readonly sqlEditorService: SqlEditorService;
4041
readonly notificationService: NotificationService;
4142
readonly sqlExecutionPlanService: SqlExecutionPlanService;
43+
readonly sqlAuditService: SqlAuditService;
4244
readonly commonDialogService: CommonDialogService;
4345
readonly sqlResultTabsService: SqlResultTabsService;
4446
readonly dataSource: ISqlDataSource | undefined;
@@ -67,6 +69,7 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
6769
const sqlEditorService = useService(SqlEditorService);
6870
const notificationService = useService(NotificationService);
6971
const sqlExecutionPlanService = useService(SqlExecutionPlanService);
72+
const sqlAuditService = useService(SqlAuditService);
7073
const sqlResultTabsService = useService(SqlResultTabsService);
7174
const commonDialogService = useService(CommonDialogService);
7275
const sqlDataSourceService = useService(SqlDataSourceService);
@@ -301,6 +304,23 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
301304
} catch {}
302305
},
303306

307+
async audit(): Promise<void> {
308+
const isQuery = this.dataSource?.hasFeature(ESqlDataSourceFeatures.query);
309+
const isExecutable = this.dataSource?.hasFeature(ESqlDataSourceFeatures.executable);
310+
311+
if (!isQuery || !isExecutable) {
312+
return;
313+
}
314+
315+
const query = this.getSubQuery();
316+
317+
try {
318+
await this.executeQueryAction(await this.executeQueryAction(query, () => this.getResolvedSegment()), query =>
319+
this.sqlAuditService.audit(this.state, query.query),
320+
);
321+
} catch {}
322+
},
323+
304324
async switchEditing(): Promise<void> {
305325
this.dataSource?.setEditing(!this.dataSource.isEditing());
306326
},
@@ -470,6 +490,7 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
470490
executeQuery: action.bound,
471491
executeQueryNewTab: action.bound,
472492
showExecutionPlan: action.bound,
493+
audit: action.bound,
473494
executeScript: action.bound,
474495
switchEditing: action.bound,
475496
dialect: computed,
@@ -489,6 +510,7 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
489510
sqlDialectInfoService,
490511
sqlEditorService,
491512
sqlExecutionPlanService,
513+
sqlAuditService,
492514
sqlResultTabsService,
493515
notificationService,
494516
commonDialogService,

webapp/packages/plugin-sql-editor/src/SqlEditorService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export class SqlEditorService {
7171
resultGroups: observable([]),
7272
resultTabs: observable([]),
7373
executionPlanTabs: observable([]),
74+
auditTabs: observable([]),
7475
statisticsTabs: observable([]),
7576
outputLogsTab: undefined,
7677
currentModeId: undefined,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { observer } from 'mobx-react-lite';
2+
import styled, { css } from 'reshadow';
3+
4+
import {
5+
CheckCircleOutlined,
6+
InfoCircleOutlined,
7+
WarningOutlined,
8+
CloseCircleOutlined
9+
} from '@ant-design/icons';
10+
11+
import { splitStyles } from '@cloudbeaver/core-blocks';
12+
13+
const styles = css`
14+
`;
15+
16+
interface Props {
17+
level: string;
18+
}
19+
20+
export const SqlAuditLevel = observer<Props>(function SqlAuditLevel({ level }) {
21+
switch (level) {
22+
case "error":
23+
return styled(
24+
styles,
25+
splitStyles,
26+
)(
27+
<CloseCircleOutlined style={{ fontSize: 20, color: '#f00000' }}/>
28+
);
29+
case "notice":
30+
return styled(
31+
styles,
32+
splitStyles,
33+
)(
34+
<InfoCircleOutlined style={{ fontSize: 20, color: '#3282e6' }}/>
35+
);
36+
case "warn":
37+
return styled(
38+
styles,
39+
splitStyles,
40+
)(
41+
<WarningOutlined style={{ fontSize: 20, color: '#ff8c00' }} />
42+
);
43+
default:
44+
return styled(
45+
styles,
46+
splitStyles,
47+
)(
48+
<CheckCircleOutlined style={{ fontSize: 20, color: '#52c41a' }} />
49+
);
50+
}
51+
});

0 commit comments

Comments
 (0)