diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts index a2d22e475a..2f4ab40f48 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorNavigatorService.ts @@ -12,7 +12,7 @@ import { NotificationService } from '@cloudbeaver/core-events'; import { IExecutor, Executor, IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { NavigationService } from '@cloudbeaver/core-ui'; import { uuid } from '@cloudbeaver/core-utils'; -import { ISqlEditorTabState, SqlResultTabsService } from '@cloudbeaver/plugin-sql-editor'; +import { ISqlEditorTabState, MemorySqlDataSource, SqlResultTabsService } from '@cloudbeaver/plugin-sql-editor'; import { SQL_EDITOR_SOURCE_ACTION } from './SQL_EDITOR_SOURCE_ACTION'; import { SqlEditorTabService, isSQLEditorTab } from './SqlEditorTabService'; @@ -28,6 +28,7 @@ export interface SQLEditorActionContext { } export interface ISQLEditorOptions { + dataSourceKey?: string; name?: string; connectionId?: string; catalogId?: string; @@ -111,6 +112,7 @@ export class SqlEditorNavigatorService { const tabOptions = this.sqlEditorTabService.createNewEditor( editorId, + data.dataSourceKey ?? MemorySqlDataSource.key, data.name, data.source, data.query, diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts index 3ef11a5c7b..9412ae1667 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts @@ -103,6 +103,7 @@ export class SqlEditorTabService extends Bootstrap { createNewEditor( editorId: string, + dataSourceKey: string, name?: string, source?: string, query?: string, @@ -113,7 +114,15 @@ export class SqlEditorTabService extends Bootstrap { return { id: editorId, handlerId: sqlEditorTabHandlerKey, - handlerState: this.sqlEditorService.getState(editorId, order, name, source, query, undefined), + handlerState: this.sqlEditorService.getState( + editorId, + dataSourceKey, + order, + name, + source, + query, + undefined + ), }; } diff --git a/webapp/packages/plugin-sql-editor-screen/src/Screen/SqlEditorScreen.tsx b/webapp/packages/plugin-sql-editor-screen/src/Screen/SqlEditorScreen.tsx index e4da9980f0..76d6aff874 100644 --- a/webapp/packages/plugin-sql-editor-screen/src/Screen/SqlEditorScreen.tsx +++ b/webapp/packages/plugin-sql-editor-screen/src/Screen/SqlEditorScreen.tsx @@ -16,7 +16,7 @@ import { useTranslate } from '@cloudbeaver/core-localization'; import type { ScreenComponent } from '@cloudbeaver/core-routing'; import { CachedMapAllKey } from '@cloudbeaver/core-sdk'; import { uuid } from '@cloudbeaver/core-utils'; -import { ISqlEditorTabState, SqlEditor, SqlEditorService } from '@cloudbeaver/plugin-sql-editor'; +import { ISqlEditorTabState, MemorySqlDataSource, SqlEditor, SqlEditorService } from '@cloudbeaver/plugin-sql-editor'; import type { ISqlEditorScreenParams } from './ISqlEditorScreenParams'; @@ -37,7 +37,15 @@ export const SqlEditorScreen: ScreenComponent = observer state: null as null | ISqlEditorTabState, setState(contextInfo: IConnectionExecutionContextInfo | undefined) { if (contextInfo) { - this.state = sqlEditorService.getState(uuid(), 0, undefined, undefined, undefined, contextInfo); + this.state = sqlEditorService.getState( + uuid(), + MemorySqlDataSource.key, + 0, + undefined, + undefined, + undefined, + contextInfo + ); } else { this.state = null; } diff --git a/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts b/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts index 8157cea4c9..bb1afd6aa9 100644 --- a/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts +++ b/webapp/packages/plugin-sql-editor/src/ISqlEditorTabState.ts @@ -45,6 +45,7 @@ export interface IExecutionPlanTab { export interface ISqlEditorTabState { editorId: string; + datasourceKey: string; name?: string; source?: string; diff --git a/webapp/packages/plugin-sql-editor/src/SqlDataSource/ISqlDataSource.ts b/webapp/packages/plugin-sql-editor/src/SqlDataSource/ISqlDataSource.ts new file mode 100644 index 0000000000..e881e87702 --- /dev/null +++ b/webapp/packages/plugin-sql-editor/src/SqlDataSource/ISqlDataSource.ts @@ -0,0 +1,17 @@ +/* + * 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 { IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections'; + +export interface ISqlDataSource { + readonly script: string; + readonly executionContext?: IConnectionExecutionContextInfo; + + setScript(script: string): void; + setExecutionContext(executionContext?: IConnectionExecutionContextInfo): void; +} \ No newline at end of file diff --git a/webapp/packages/plugin-sql-editor/src/SqlDataSource/MemorySqlDataSource.ts b/webapp/packages/plugin-sql-editor/src/SqlDataSource/MemorySqlDataSource.ts new file mode 100644 index 0000000000..ee414dded0 --- /dev/null +++ b/webapp/packages/plugin-sql-editor/src/SqlDataSource/MemorySqlDataSource.ts @@ -0,0 +1,31 @@ +/* + * 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 { IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections'; + +import type { ISqlDataSource } from './ISqlDataSource'; + +export class MemorySqlDataSource implements ISqlDataSource { + static key = 'memory'; + + script: string; + executionContext?: IConnectionExecutionContextInfo; + + constructor(script = '', executionContext?: IConnectionExecutionContextInfo) { + this.script = script; + this.executionContext = executionContext; + } + + setScript(script: string): void { + this.script = script; + } + + setExecutionContext(executionContext?: IConnectionExecutionContextInfo): void { + this.executionContext = executionContext; + } +} \ No newline at end of file diff --git a/webapp/packages/plugin-sql-editor/src/SqlDataSource/SqlDataSourceService.ts b/webapp/packages/plugin-sql-editor/src/SqlDataSource/SqlDataSourceService.ts new file mode 100644 index 0000000000..664ec5c22d --- /dev/null +++ b/webapp/packages/plugin-sql-editor/src/SqlDataSource/SqlDataSourceService.ts @@ -0,0 +1,74 @@ +/* + * 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 { injectable } from '@cloudbeaver/core-di'; + +import type { ISqlDataSource } from './ISqlDataSource'; +import { MemorySqlDataSource } from './MemorySqlDataSource'; + +type ISqlDataSourceFabric = (editorId: string) => ISqlDataSource; + +interface ISqlDataSourceOptions { + key: string; + fabric: ISqlDataSourceFabric; + onDestroy?: (editorId: string)=> void; + canDestroy?: (editorId: string)=> Promise; +} + +interface ISqlDataSourceProvider { + provider: ISqlDataSourceOptions; + dataSource: ISqlDataSource; +} + +@injectable() +export class SqlDataSourceService { + private readonly dataSourceProviders: Map; + private readonly providers: Map; + + constructor() { + this.dataSourceProviders = new Map(); + this.providers = new Map(); + + this.register({ + key: MemorySqlDataSource.key, + fabric: () => new MemorySqlDataSource(), + }); + } + + get(editorId: string): ISqlDataSource | undefined { + return this.providers.get(editorId)?.dataSource; + } + + create(editorId: string, key: string): ISqlDataSource { + const provider = this.dataSourceProviders.get(key); + + if (!provider) { + throw new Error(`SQL Data Source Provider with key (${key}) not found`); + } + + let activeProvider = this.providers.get(editorId); + + if (activeProvider?.provider.key !== key) { + activeProvider?.provider.onDestroy?.(editorId); + activeProvider = { + provider, + dataSource: provider.fabric(editorId), + }; + } + + return activeProvider.dataSource; + } + + register(dataSourceOptions: ISqlDataSourceOptions) { + if (this.dataSourceProviders.has(dataSourceOptions.key)) { + throw new Error(`SQL Data Source with key (${dataSourceOptions.key}) already registered`); + } + + this.dataSourceProviders.set(dataSourceOptions.key, dataSourceOptions); + } +} \ No newline at end of file diff --git a/webapp/packages/plugin-sql-editor/src/SqlEditorService.ts b/webapp/packages/plugin-sql-editor/src/SqlEditorService.ts index 846d58e003..c482c9d9c4 100644 --- a/webapp/packages/plugin-sql-editor/src/SqlEditorService.ts +++ b/webapp/packages/plugin-sql-editor/src/SqlEditorService.ts @@ -37,6 +37,7 @@ export class SqlEditorService { getState( editorId: string, + datasourceKey: string, order: number, name?: string, source?: string, @@ -45,6 +46,7 @@ export class SqlEditorService { ): ISqlEditorTabState { return { editorId, + datasourceKey, name, source, query: query ?? '', diff --git a/webapp/packages/plugin-sql-editor/src/index.ts b/webapp/packages/plugin-sql-editor/src/index.ts index 8abf62ffde..25335b9907 100644 --- a/webapp/packages/plugin-sql-editor/src/index.ts +++ b/webapp/packages/plugin-sql-editor/src/index.ts @@ -1,4 +1,7 @@ import { sqlEditorPluginManifest } from './manifest'; +export * from './SqlDataSource/ISqlDataSource'; +export * from './SqlDataSource/SqlDataSourceService'; +export * from './SqlDataSource/MemorySqlDataSource'; export * from './SqlEditor/SQLCodeEditor/SQLCodeEditorLoader'; export * from './SqlEditor/ISQLEditorData'; export * from './SqlEditor/DATA_CONTEXT_SQL_EDITOR_DATA'; diff --git a/webapp/packages/plugin-sql-editor/src/manifest.ts b/webapp/packages/plugin-sql-editor/src/manifest.ts index 8b8f9b8de3..2f3d1144fb 100644 --- a/webapp/packages/plugin-sql-editor/src/manifest.ts +++ b/webapp/packages/plugin-sql-editor/src/manifest.ts @@ -10,6 +10,7 @@ import type { PluginManifest } from '@cloudbeaver/core-di'; import { LocaleService } from './LocaleService'; import { MenuBootstrap } from './MenuBootstrap'; +import { SqlDataSourceService } from './SqlDataSource/SqlDataSourceService'; import { SqlDialectInfoService } from './SqlDialectInfoService'; import { SQLCodeEditorPanelBootstrap } from './SqlEditor/SQLCodeEditorPanel/SQLCodeEditorPanelBootstrap'; import { SqlEditorModeService } from './SqlEditorModeService'; @@ -39,5 +40,6 @@ export const sqlEditorPluginManifest: PluginManifest = { SQLCodeEditorPanelBootstrap, SqlEditorView, MenuBootstrap, + SqlDataSourceService, ], };