feat(plugin-sql-editor): CB-1825 mode context

This commit is contained in:
Wroud
2022-04-15 16:08:13 +03:00
parent 3edb65c288
commit d65c1d526c
6 changed files with 78 additions and 18 deletions
@@ -6,6 +6,8 @@
* you may not use this file except in compliance with the License.
*/
import { makeObservable, observable } from 'mobx';
import type { IExecutorHandler } from './IExecutorHandler';
import type { ExecutorDataMap, IChainLink, IExecutorHandlersCollection } from './IExecutorHandlersCollection';
@@ -22,6 +24,14 @@ implements IExecutorHandlersCollection<T, TResult> {
this.links = new Map();
this.collections = [];
this.initialDataGetter = null;
makeObservable<this, 'links'>(this, {
handlers: observable.shallow,
postHandlers: observable.shallow,
chain: observable.shallow,
collections: observable.shallow,
links: observable.shallow,
});
}
setInitialDataGetter(getter: (() => T) | null): this {
@@ -20,13 +20,21 @@ import type { SqlDialectInfo } from '@cloudbeaver/core-sdk';
import type { SQLProposal } from '../SqlEditorService';
import type { SQLParser, ISQLScriptSegment } from '../SQLParser';
import type { ISQLEditorMode } from './SQLEditorModeContext';
export interface ISegmentExecutionData {
segment: ISQLScriptSegment;
type: 'start' | 'end' | 'error';
}
export interface ICursor {
begin: number;
end: number;
}
export interface ISQLEditorData {
readonly cursor: ICursor;
readonly activeSegmentMode: ISQLEditorMode;
readonly parser: SQLParser;
readonly dialect: SqlDialectInfo | undefined;
readonly activeSegment: ISQLScriptSegment | undefined;
@@ -39,6 +47,8 @@ export interface ISQLEditorData {
readonly onExecute: ISyncExecutor<boolean>;
readonly onSegmentExecute: ISyncExecutor<ISegmentExecutionData>;
readonly onUpdate: ISyncExecutor;
readonly onMode: ISyncExecutor<ISQLEditorData>;
updateParserScriptsThrottle(): Promise<void>;
setQuery(query: string): void;
init(): void;
@@ -0,0 +1,25 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2022 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import type { ISyncContextLoader } from '@cloudbeaver/core-executor';
import type { ISQLScriptSegment } from '../SQLParser';
import type { ISQLEditorData } from './ISQLEditorData';
export interface ISQLEditorMode {
activeSegment: ISQLScriptSegment | undefined;
activeSegmentMode: boolean;
}
export const SQLEditorModeContext: ISyncContextLoader<ISQLEditorMode, ISQLEditorData> = function SQLEditorModeContext(context, data) {
return {
activeSegment: data.parser.getSegment(data.cursor.begin, data.cursor.end),
activeSegmentMode: false,
};
};
@@ -167,6 +167,7 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
<button
disabled={data.isDisabled || data.isScriptEmpty}
title={translate('sql_editor_sql_execution_script_button_tooltip')}
hidden={data.activeSegmentMode.activeSegmentMode}
onClick={data.executeScript}
>
<StaticImage icon="/icons/sql_script_exec.svg" />
@@ -185,6 +186,7 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
<button
disabled={data.isDisabled || data.isScriptEmpty}
title={translate('sql_editor_sql_format_button_tooltip')}
hidden={data.activeSegmentMode.activeSegmentMode}
onClick={data.formatScript}
>
<StaticImage icon="/icons/sql_format_sm.svg" />
@@ -192,20 +194,23 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
<button
disabled={!trimmedValue}
title={translate('sql_editor_download_script_tooltip')}
hidden={data.activeSegmentMode.activeSegmentMode}
onClick={() => tools.downloadScript(trimmedValue)}
>
<StaticImage icon='/icons/save.svg' />
</button>
<UploadArea
accept='.sql'
title={translate('sql_editor_upload_script_tooltip')}
reset
onChange={handleScriptUpload}
>
<upload>
<StaticImage icon='/icons/load.svg' />
</upload>
</UploadArea>
{!data.activeSegmentMode.activeSegmentMode && (
<UploadArea
accept='.sql'
title={translate('sql_editor_upload_script_tooltip')}
reset
onChange={handleScriptUpload}
>
<upload>
<StaticImage icon='/icons/load.svg' />
</upload>
</UploadArea>
)}
</tools>
</container>
<TabPanelList />
@@ -24,12 +24,8 @@ import { ISQLScriptSegment, SQLParser } from '../SQLParser';
import { SqlExecutionPlanService } from '../SqlResultTabs/ExecutionPlan/SqlExecutionPlanService';
import { SqlQueryService } from '../SqlResultTabs/SqlQueryService';
import { SqlResultTabsService } from '../SqlResultTabs/SqlResultTabsService';
import type { ISQLEditorData } from './ISQLEditorData';
interface ICursor {
begin: number;
end: number;
}
import type { ICursor, ISQLEditorData } from './ISQLEditorData';
import { ISQLEditorMode, SQLEditorModeContext } from './SQLEditorModeContext';
interface ISQLEditorDataPrivate extends ISQLEditorData {
readonly sqlDialectInfoService: SqlDialectInfoService;
@@ -69,8 +65,15 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
return this.sqlDialectInfoService.getDialectInfo(this.state.executionContext.connectionId);
},
get activeSegmentMode(): ISQLEditorMode {
const contexts = this.onMode.execute(this);
const mode = contexts.getContext(SQLEditorModeContext);
return mode;
},
get activeSegment(): ISQLScriptSegment | undefined {
return this.parser.getSegment(this.cursor.begin, this.cursor.end);
return this.activeSegmentMode.activeSegment;
},
get cursorSegment(): ISQLScriptSegment | undefined {
@@ -103,6 +106,7 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
return this.state.query;
},
onMode: new SyncExecutor(),
onExecute: new SyncExecutor(),
onSegmentExecute: new SyncExecutor(),
onUpdate: new SyncExecutor(),
@@ -353,7 +357,7 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
return this.parser.getScriptSegment();
}
return this.parser.getSegment(this.cursor.begin, this.cursor.end);
return this.activeSegment;
},
async getResolvedSegment(): Promise<ISQLScriptSegment | undefined> {
@@ -363,6 +367,10 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
return this.getSubQuery();
}
if (this.activeSegmentMode.activeSegmentMode) {
return this.activeSegment;
}
const result = await this.sqlEditorService.parseSQLQuery(
connectionId,
@@ -401,6 +409,7 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
executeQueryNewTab: action.bound,
showExecutionPlan: action.bound,
executeScript: action.bound,
activeSegmentMode: computed,
dialect: computed,
activeSegment: computed,
isLineScriptEmpty: computed,
@@ -2,6 +2,7 @@ import { sqlEditorPluginManifest } from './manifest';
export * from './SqlEditor/SQLCodeEditor/SQLCodeEditorLoader';
export * from './SqlEditor/ISQLEditorData';
export * from './SqlEditor/DATA_CONTEXT_SQL_EDITOR_DATA';
export * from './SqlEditor/SQLEditorModeContext';
export * from './SqlResultTabs/DATA_CONTEXT_SQL_EDITOR_RESULT_ID';
export * from './SqlResultTabs/SqlResultTabsService';
export * from './DATA_CONTEXT_SQL_EDITOR_STATE';