dbeaver/pro#7854 feat: display query with parameters (#4064)

* dbeaver/pro#7854 feat: display query with parameters

* fix: use replaceAll instead of replace

* dbeaver/pro#7854 fix: support parameters and variables

---------

Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
This commit is contained in:
Alexey Potsetsuev
2026-01-22 00:18:25 +08:00
committed by GitHub
co-authored by Daria Marutkina
parent 1deffb984b
commit 90fcbe6b7f
39 changed files with 286 additions and 89 deletions
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ export interface ConfirmationDialogPayload {
showSkipConfirmations?: boolean;
showExtraAction?: boolean;
bigIcon?: boolean;
noOverflow?: boolean;
viewBox?: string;
message: TLocalizationToken;
confirmActionText?: TLocalizationToken;
@@ -60,6 +61,7 @@ export const ConfirmationDialog: DialogComponent<ConfirmationDialogPayload, Conf
children,
size = 'small',
bigIcon,
noOverflow,
viewBox,
message,
confirmActionText,
@@ -90,7 +92,7 @@ export const ConfirmationDialog: DialogComponent<ConfirmationDialogPayload, Conf
return (
<CommonDialogWrapper size={size} className={className} fixedWidth>
<CommonDialogHeader title={title} subTitle={subTitle} icon={icon} viewBox={viewBox} bigIcon={bigIcon} onReject={reject} />
<CommonDialogBody>
<CommonDialogBody noOverflow={noOverflow}>
<Translate token={message} />
{children && children?.()}
</CommonDialogBody>
@@ -34,8 +34,8 @@
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"@cloudbeaver/plugin-data-viewer": "workspace:*",
"@cloudbeaver/plugin-sql-editor": "workspace:*",
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*",
"@cloudbeaver/plugin-sql-editor-navigation-tab": "workspace:*",
"@cloudbeaver/plugin-sql-editor-new": "workspace:*",
"@dbeaver/js-helpers": "workspace:*",
"@dbeaver/ui-kit": "workspace:*",
"mobx": "^6",
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import type { DialogComponent } from '@cloudbeaver/core-dialogs';
import { useService } from '@cloudbeaver/core-di';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { LocalStorageSqlDataSource } from '@cloudbeaver/plugin-sql-editor';
import { SQLCodeEditorLoader, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-new';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
import { ConnectionDialectResource, ConnectionInfoResource, type IConnectionInfoParams } from '@cloudbeaver/core-connections';
import { NavNodeManagerService, NodeManagerUtils } from '@cloudbeaver/core-navigation-tree';
import { SqlEditorNavigatorService } from '@cloudbeaver/plugin-sql-editor-navigation-tab';
@@ -67,7 +67,7 @@ export const DataViewerRequestQueryViewerDialog: DialogComponent<IPayload> = obs
<CommonDialogWrapper size="large" fixedWidth>
<CommonDialogHeader title="SQL" onReject={props.rejectDialog} />
<CommonDialogBody noBodyPadding noOverflow>
<SQLCodeEditorLoader value={props.payload.query} extensions={extensions} readonly />
<SQLCodeEditor value={props.payload.query} extensions={extensions} readonly />
</CommonDialogBody>
<CommonDialogFooter className="tw:flex tw:justify-between">
<Button variant="secondary" onClick={() => props.rejectDialog()}>
@@ -56,10 +56,10 @@
"path": "../plugin-sql-editor"
},
{
"path": "../plugin-sql-editor-navigation-tab"
"path": "../plugin-sql-editor-codemirror"
},
{
"path": "../plugin-sql-editor-new"
"path": "../plugin-sql-editor-navigation-tab"
}
],
"include": [
@@ -39,7 +39,7 @@
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"@cloudbeaver/plugin-data-grid": "workspace:*",
"@cloudbeaver/plugin-datasource-context-switch": "workspace:*",
"@cloudbeaver/plugin-sql-editor-new": "workspace:*",
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*",
"@cloudbeaver/plugin-tools-panel": "workspace:*",
"@cloudbeaver/plugin-top-app-bar": "workspace:*",
"@dbeaver/js-helpers": "workspace:*",
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -10,7 +10,7 @@ import { observer } from 'mobx-react-lite';
import { Button, CommonDialogBody, CommonDialogFooter, CommonDialogHeader, CommonDialogWrapper, useTranslate } from '@cloudbeaver/core-blocks';
import type { DialogComponent } from '@cloudbeaver/core-dialogs';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { SQLCodeEditorLoader, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-new';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
interface IPayload {
text: string;
@@ -18,7 +18,7 @@ interface IPayload {
export const QueryDetailsDialog: DialogComponent<IPayload> = observer(function QueryDetailsDialog(props) {
const translate = useTranslate();
const sqlDialect = useSqlDialectExtension(undefined);
const sqlDialect = useSqlDialectExtension();
const extensions = useCodemirrorExtensions();
if (sqlDialect) {
extensions.set(...sqlDialect);
@@ -28,7 +28,7 @@ export const QueryDetailsDialog: DialogComponent<IPayload> = observer(function Q
<CommonDialogWrapper size="large" fixedWidth>
<CommonDialogHeader title={translate('plugin_datasource_transaction_manager_logs_table_column_text')} onReject={props.rejectDialog} />
<CommonDialogBody noBodyPadding noOverflow>
<SQLCodeEditorLoader value={props.payload.text} extensions={extensions} readonly />
<SQLCodeEditor value={props.payload.text} extensions={extensions} readonly />
</CommonDialogBody>
<CommonDialogFooter>
<Button variant="secondary" onClick={() => props.rejectDialog()}>
@@ -65,7 +65,7 @@
"path": "../plugin-datasource-context-switch"
},
{
"path": "../plugin-sql-editor-new"
"path": "../plugin-sql-editor-codemirror"
},
{
"path": "../plugin-tools-panel"
@@ -35,8 +35,8 @@
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"@cloudbeaver/plugin-navigation-tree": "workspace:*",
"@cloudbeaver/plugin-sql-editor": "workspace:*",
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*",
"@cloudbeaver/plugin-sql-editor-navigation-tab": "workspace:*",
"@cloudbeaver/plugin-sql-editor-new": "workspace:*",
"mobx": "^6",
"mobx-react-lite": "^4",
"react": "^19",
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ import { MenuBar, MenuBarGroupStyles, MenuBarItemStyles, MenuBarStyles } from '@
import { useMenu } from '@cloudbeaver/core-view';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import type { NavNodeTransformViewComponent } from '@cloudbeaver/plugin-navigation-tree';
import { SQLCodeEditorLoader, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-new';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
import { DATA_CONTEXT_DDL_VIEWER_NODE } from './DATA_CONTEXT_DDL_VIEWER_NODE.js';
import { DATA_CONTEXT_DDL_VIEWER_VALUE } from './DATA_CONTEXT_DDL_VIEWER_VALUE.js';
@@ -51,7 +51,7 @@ export const DDLViewerTabPanel: NavNodeTransformViewComponent = observer(functio
return (
<div className={s(styles, { wrapper: true })}>
<SQLCodeEditorLoader className={s(styles, { sqlCodeEditorLoader: true })} value={ddlResource.data ?? ''} extensions={extensions} readonly />
<SQLCodeEditor className={s(styles, { sqlCodeEditorLoader: true })} value={ddlResource.data ?? ''} extensions={extensions} readonly />
<MenuBar className={s(styles, { menuBar: true, floating: true, withLabel: true })} menu={menu} compact={false} />
</div>
);
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ import { MenuBar } from '@cloudbeaver/core-ui';
import { useMenu } from '@cloudbeaver/core-view';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import type { NavNodeTransformViewComponent } from '@cloudbeaver/plugin-navigation-tree';
import { SQLCodeEditorLoader, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-new';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
import { DATA_CONTEXT_DDL_VIEWER_NODE } from '../DdlViewer/DATA_CONTEXT_DDL_VIEWER_NODE.js';
import { DATA_CONTEXT_DDL_VIEWER_VALUE } from '../DdlViewer/DATA_CONTEXT_DDL_VIEWER_VALUE.js';
@@ -51,7 +51,7 @@ export const ExtendedDDLViewerTabPanel: NavNodeTransformViewComponent = observer
return (
<div className={s(styles, { wrapper: true })}>
<SQLCodeEditorLoader className={s(styles, { sqlCodeEditorLoader: true })} value={extendedDDlData ?? ''} extensions={extensions} readonly />
<SQLCodeEditor className={s(styles, { sqlCodeEditorLoader: true })} value={extendedDDlData ?? ''} extensions={extensions} readonly />
<MenuBar className={s(styles, { menuBar: true })} menu={menu} />
</div>
);
@@ -50,10 +50,10 @@
"path": "../plugin-sql-editor"
},
{
"path": "../plugin-sql-editor-navigation-tab"
"path": "../plugin-sql-editor-codemirror"
},
{
"path": "../plugin-sql-editor-new"
"path": "../plugin-sql-editor-navigation-tab"
}
],
"include": [
@@ -31,7 +31,7 @@
"@cloudbeaver/core-root": "workspace:*",
"@cloudbeaver/core-sdk": "workspace:*",
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"@cloudbeaver/plugin-sql-editor-new": "workspace:*",
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*",
"mobx": "^6",
"mobx-react-lite": "^4",
"react": "^19",
@@ -1,13 +1,13 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 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 { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { SQLCodeEditorLoader, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-new';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
import { observer } from 'mobx-react-lite';
export function renderQueryForConfirmation(query: string): React.ReactElement {
@@ -15,11 +15,11 @@ export function renderQueryForConfirmation(query: string): React.ReactElement {
}
const RenderQuery = observer(function RenderQuery({ query }: { query: string }) {
const sqlDialect = useSqlDialectExtension(undefined);
const sqlDialect = useSqlDialectExtension();
const extensions = useCodemirrorExtensions();
if (sqlDialect) {
extensions.set(...sqlDialect);
}
return <SQLCodeEditorLoader className="tw:mt-4" value={query} extensions={extensions} lineWrapping readonly />;
return <SQLCodeEditor className="tw:mt-4" value={query} extensions={extensions} lineWrapping readonly />;
});
@@ -38,7 +38,7 @@
"path": "../plugin-codemirror6"
},
{
"path": "../plugin-sql-editor-new"
"path": "../plugin-sql-editor-codemirror"
}
],
"include": [
@@ -0,0 +1,18 @@
# dependencies
/node_modules
# testing
/coverage
# production
lib
dist
# misc
.DS_Store
.env*
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
@@ -0,0 +1,42 @@
{
"name": "@cloudbeaver/plugin-sql-editor-codemirror",
"type": "module",
"sideEffects": [
"./lib/module.js",
"./lib/index.js",
"src/**/*.css",
"src/**/*.scss",
"public/**/*"
],
"version": "0.1.0",
"description": "",
"license": "Apache-2.0",
"exports": {
".": "./lib/index.js",
"./module": "./lib/module.js"
},
"scripts": {
"build": "tsc -b",
"clean": "rimraf --glob lib",
"lint": "eslint ./src/ --ext .ts,.tsx",
"validate-dependencies": "core-cli-validate-dependencies"
},
"dependencies": {
"@cloudbeaver/core-blocks": "workspace:*",
"@cloudbeaver/core-sdk": "workspace:*",
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"mobx": "^6",
"mobx-react-lite": "^4",
"react": "^19",
"react-dom": "^19",
"tslib": "^2"
},
"devDependencies": {
"@cloudbeaver/core-cli": "workspace:*",
"@cloudbeaver/tsconfig": "workspace:*",
"@types/react": "^19",
"rimraf": "^6",
"typescript": "^5",
"typescript-plugin-css-modules": "^5"
}
}
@@ -1,10 +1,10 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 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 { importLazyComponent } from '@cloudbeaver/core-blocks';
export const SQLCodeEditorLoader = importLazyComponent(() => import('./SQLCodeEditor.js').then(m => m.SQLCodeEditor));
export const SQLCodeEditor = importLazyComponent(() => import('./SQLCodeEditor.js').then(m => m.SQLCodeEditor));
@@ -0,0 +1,13 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
export * from './SQLCodeEditor/SQLCodeEditorLoader.js';
export * from './SQLCodeEditor/useSQLCodeEditor.js';
export * from './useSqlDialectExtension.js';
export * from './ACTIVE_QUERY_EXTENSION.js';
export * from './QUERY_STATUS_GUTTER_EXTENSION.js';
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@ import type { Compartment, Extension } from '@cloudbeaver/plugin-codemirror6';
const codemirrorPluginLoader = createLazyLoader(() => import('@cloudbeaver/plugin-codemirror6'));
export function useSqlDialectExtension(dialectInfo: SqlDialectInfo | undefined): [Compartment, Extension] | null {
export function useSqlDialectExtension(dialectInfo?: SqlDialectInfo): [Compartment, Extension] | null {
const codemirror = useLazyImport(codemirrorPluginLoader);
const loader = getDialectLoader(codemirror, dialectInfo?.name);
const dialect = useLazyImport(loader);
@@ -0,0 +1,34 @@
{
"extends": "@cloudbeaver/tsconfig/tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib",
"tsBuildInfoFile": "lib/tsconfig.tsbuildinfo",
"composite": true
},
"references": [
{
"path": "../core-blocks"
},
{
"path": "../core-cli"
},
{
"path": "../core-sdk"
},
{
"path": "../plugin-codemirror6"
}
],
"include": [
"__custom_mocks__/**/*",
"src/**/*",
"src/**/*.json",
"src/**/*.css",
"src/**/*.scss"
],
"exclude": [
"**/node_modules",
"lib/**/*"
]
}
@@ -32,6 +32,7 @@
"@cloudbeaver/core-utils": "workspace:*",
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"@cloudbeaver/plugin-sql-editor": "workspace:*",
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*",
"mobx": "^6",
"mobx-react-lite": "^4",
"react": "^19",
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -16,13 +16,15 @@ import { type TabContainerPanelComponent, useDNDBox } from '@cloudbeaver/core-ui
import { closeCompletion, type IEditorRef, Prec, ReactCodemirrorPanel, useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { SqlEditorSettingsService, type ISqlEditorModeProps } from '@cloudbeaver/plugin-sql-editor';
import { ACTIVE_QUERY_EXTENSION } from '../ACTIVE_QUERY_EXTENSION.js';
import { QUERY_STATUS_GUTTER_EXTENSION } from '../QUERY_STATUS_GUTTER_EXTENSION.js';
import { SQLCodeEditorLoader } from '../SQLCodeEditor/SQLCodeEditorLoader.js';
import { useSQLCodeEditor } from '../SQLCodeEditor/useSQLCodeEditor.js';
import {
ACTIVE_QUERY_EXTENSION,
QUERY_STATUS_GUTTER_EXTENSION,
SQLCodeEditor,
useSQLCodeEditor,
useSqlDialectExtension,
} from '@cloudbeaver/plugin-sql-editor-codemirror';
import { useHighlightExtensions } from '../useHighlightExtensions.js';
import { useSqlDialectAutocompletion } from '../useSqlDialectAutocompletion.js';
import { useSqlDialectExtension } from '../useSqlDialectExtension.js';
import style from './SQLCodeEditorPanel.module.css';
import { SqlEditorInfoBar } from './SqlEditorInfoBar.js';
import { useSQLCodeEditorPanel } from './useSQLCodeEditorPanel.js';
@@ -109,7 +111,7 @@ export const SQLCodeEditorPanel: TabContainerPanelComponent<ISqlEditorModeProps>
return (
<div ref={dndBox.setRef} className={styles['box']}>
<SQLCodeEditorLoader
<SQLCodeEditor
ref={setEditorRef}
getValue={() => data.value}
cursor={{
@@ -143,7 +145,7 @@ export const SQLCodeEditorPanel: TabContainerPanelComponent<ISqlEditorModeProps>
<SqlEditorInfoBar state={editor.state} />
</ReactCodemirrorPanel>
)}
</SQLCodeEditorLoader>
</SQLCodeEditor>
</div>
);
});
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -10,13 +10,14 @@ import { useCallback } from 'react';
import { useExecutor, useObservableRef } from '@cloudbeaver/core-blocks';
import { throttle } from '@cloudbeaver/core-utils';
import type { ISqlEditorCursor, ISQLEditorData } from '@cloudbeaver/plugin-sql-editor';
import type { ISQLEditorData } from '@cloudbeaver/plugin-sql-editor';
import type { IEditor } from '../SQLCodeEditor/useSQLCodeEditor.js';
import type { IEditor } from '@cloudbeaver/plugin-sql-editor-codemirror';
import type { SelectionRange } from '@cloudbeaver/plugin-codemirror6';
interface State {
highlightActiveQuery: () => void;
onQueryChange: (query: string, selection: ISqlEditorCursor) => void;
onQueryChange: (query: string, selection: SelectionRange) => void;
onCursorChange: (anchor: number, head?: number) => void;
}
@@ -34,9 +35,8 @@ export function useSQLCodeEditorPanel(data: ISQLEditorData, editor: IEditor) {
this.editor.highlightActiveQuery(segment.begin, segment.end);
}
},
onQueryChange(query: string, selection: ISqlEditorCursor) {
this.data.setScript(query, ON_QUERY_CHANGE_SOURCE, selection);
this.onCursorChange(selection.anchor, selection.head);
onQueryChange(query: string, selection: SelectionRange) {
this.data.setScript(query, ON_QUERY_CHANGE_SOURCE, { anchor: selection.anchor, head: selection.head }); // do not pass selection directly because anchor and head are getters
},
onCursorChange(anchor: number, head?: number) {
this.data.setCursor(anchor, head);
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -8,6 +8,4 @@
import './module.js';
export * from './SQLEditor/SQLCodeEditor/SQLCodeEditorLoader.js';
export * from './SQLEditor/useSqlDialectAutocompletion.js';
export * from './SQLEditor/useSqlDialectExtension.js';
@@ -39,6 +39,9 @@
},
{
"path": "../plugin-sql-editor"
},
{
"path": "../plugin-sql-editor-codemirror"
}
],
"include": [
@@ -45,6 +45,7 @@
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"@cloudbeaver/plugin-data-viewer": "workspace:*",
"@cloudbeaver/plugin-navigation-tabs": "workspace:*",
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*",
"@dbeaver/js-helpers": "workspace:^",
"mobx": "^6",
"mobx-react-lite": "^4",
@@ -1,13 +1,13 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 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 { makeObservable, observable } from 'mobx';
import type { IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections';
import { createConnectionParam, type IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections';
import type { IServiceProvider } from '@cloudbeaver/core-di';
import { executorHandlerFilter, type IExecutorHandler, type ITask } from '@cloudbeaver/core-executor';
import {
@@ -306,12 +306,18 @@ export class QueryDataSource<TOptions extends IDataQueryOptions = IDataQueryOpti
const parametersState = observable({
...Object.fromEntries(Object.entries(queryParamsEvent.parameters).map(([key, value]) => [key, this.previousQueryParameters?.[key] ?? value])),
});
const connectionKey = this.executionContext?.context
? createConnectionParam(this.executionContext.context.projectId, this.executionContext.context.connectionId)
: null;
// TODO: this UI thing should be moved outside of the `plugin-sql-editor` package to use sql editor component for preview
// it is partially fixed, but still this UI code should be somewhere else
const dialogPromise = this.commonDialogService.open(ConfirmationDialog, {
title: queryParamsEvent.title,
message: queryParamsEvent.message,
size: 'large',
children: () => renderQueryParamsForConfirmation(parametersState, queryParamsEvent.query),
noOverflow: true,
children: () => renderQueryParamsForConfirmation(connectionKey, parametersState, queryParamsEvent.query),
});
const { status } = await dialogPromise;
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -57,6 +57,8 @@ const defaultSettings = schema.object({
'plugin.sql-editor.disabled': schemaExtra.stringedBoolean().default(false),
'plugin.sql-editor.autoSave': schemaExtra.stringedBoolean().default(true),
'plugin.sql-editor.highlightWhitespace': schemaExtra.stringedBoolean().default(false),
'sql.parameter.enabled': schemaExtra.stringedBoolean().default(true),
'sql.variables.enabled': schemaExtra.stringedBoolean().default(true),
'sql.proposals.insert.table.alias': schema.coerce
.string()
.transform(value => {
@@ -117,6 +119,14 @@ export class SqlEditorSettingsService {
return this.settings.getValue('sql.proposals.insert.table.alias');
}
get parameterEnabled(): boolean {
return this.settings.getValue('sql.parameter.enabled');
}
get variablesEnabled(): boolean {
return this.settings.getValue('sql.variables.enabled');
}
get longNameProposals(): boolean {
return this.settings.getValue('SQLEditor.ContentAssistant.proposals.long.name');
}
@@ -1,29 +1,76 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 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 { PropertiesTable } from '@cloudbeaver/core-blocks';
import { PropertiesTable, useResource } from '@cloudbeaver/core-blocks';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { observer } from 'mobx-react-lite';
import { useService } from '@cloudbeaver/core-di';
import { SqlEditorSettingsService } from './SqlEditorSettingsService.js';
import { ConnectionDialectResource, type IConnectionInfoParams } from '@cloudbeaver/core-connections';
export function renderQueryParamsForConfirmation(parameters: Record<string, any>, query: string): React.ReactElement {
return <RenderParametersForm parameters={parameters} query={query} />;
export function renderQueryParamsForConfirmation(
connectionKey: IConnectionInfoParams | null,
parameters: Record<string, any>,
query: string,
): React.ReactElement {
return <RenderParametersForm parameters={parameters} query={query} connectionKey={connectionKey} />;
}
const RenderParametersForm = observer(function RenderParametersForm({ parameters }: { query: string; parameters: Record<string, any> }) {
const RenderParametersForm = observer(function RenderParametersForm({
parameters,
query,
connectionKey,
}: {
query: string;
parameters: Record<string, any>;
connectionKey: IConnectionInfoParams | null;
}) {
const sqlEditorSettingsService = useService(SqlEditorSettingsService);
const connectionDialectResource = useResource(RenderParametersForm, ConnectionDialectResource, connectionKey);
const sqlDialect = useSqlDialectExtension(connectionDialectResource.data);
const extensions = useCodemirrorExtensions();
if (sqlDialect) {
extensions.set(...sqlDialect);
}
for (const [paramName, paramValue] of Object.entries(parameters)) {
const paramValueString = String(paramValue);
if (paramValueString) {
if (sqlEditorSettingsService.parameterEnabled) {
query = query.replaceAll(`:${paramName}`, paramValueString);
}
if (sqlEditorSettingsService.variablesEnabled) {
query = query.replaceAll(`$\{${paramName}}`, paramValueString);
}
}
}
return (
<PropertiesTable
properties={Object.keys(parameters).map(paramName => ({
id: paramName,
key: paramName,
displayName: paramName,
defaultValue: '',
}))}
propertiesState={parameters}
staticProperties
/>
<div className="tw:flex tw:flex-col tw:overflow-auto tw:gap-3 tw:min-h-full">
<div className="tw:overflow-auto tw:flex-auto tw:flex">
<PropertiesTable
properties={Object.keys(parameters).map(paramName => ({
id: paramName,
key: paramName,
displayName: paramName,
defaultValue: '',
}))}
propertiesState={parameters}
className="tw:overflow-auto"
staticProperties
/>
</div>
{!sqlEditorSettingsService.disabled && (
<SQLCodeEditor value={query} extensions={extensions} className="tw:overflow-auto tw:flex-1/3" readonly />
)}
</div>
);
});
@@ -84,6 +84,9 @@
},
{
"path": "../plugin-navigation-tabs"
},
{
"path": "../plugin-sql-editor-codemirror"
}
],
"include": [
@@ -36,7 +36,7 @@
"@cloudbeaver/plugin-codemirror6": "workspace:*",
"@cloudbeaver/plugin-data-viewer": "workspace:*",
"@cloudbeaver/plugin-sql-editor": "workspace:*",
"@cloudbeaver/plugin-sql-editor-new": "workspace:*",
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*",
"mobx": "^6",
"mobx-react-lite": "^4",
"react": "^19",
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import {
import { ConnectionDialectResource, type IConnectionInfoParams } from '@cloudbeaver/core-connections';
import type { DialogComponentProps } from '@cloudbeaver/core-dialogs';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { SQLCodeEditorLoader, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-new';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
import style from './ScriptPreviewDialog.module.css';
@@ -57,13 +57,7 @@ export const ScriptPreviewDialog = observer<DialogComponentProps<Payload>>(funct
<CommonDialogHeader title="data_viewer_script_preview_dialog_title" icon="sql-script" onReject={rejectDialog} />
<CommonDialogBody noBodyPadding noOverflow>
<div className={s(styles, { wrapper: true })}>
<SQLCodeEditorLoader
className={s(styles, { sqlCodeEditorLoader: true })}
value={payload.script}
extensions={extensions}
lineNumbers
readonly
/>
<SQLCodeEditor className={s(styles, { sqlCodeEditorLoader: true })} value={payload.script} extensions={extensions} lineNumbers readonly />
</div>
</CommonDialogBody>
<CommonDialogFooter className={s(styles, { footer: true })}>
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@ import { useService } from '@cloudbeaver/core-di';
import type { DialogComponentProps } from '@cloudbeaver/core-dialogs';
import { GQLErrorCatcher } from '@cloudbeaver/core-sdk';
import { useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
import { SQLCodeEditorLoader, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-new';
import { SQLCodeEditor, useSqlDialectExtension } from '@cloudbeaver/plugin-sql-editor-codemirror';
import style from './GeneratedSqlDialog.module.css';
import { SqlGeneratorsResource } from './SqlGeneratorsResource.js';
@@ -92,7 +92,7 @@ export const GeneratedSqlDialog = observer<DialogComponentProps<Payload>>(functi
<CommonDialogBody noOverflow noBodyPadding>
<div className={s(styles, { wrapper: true })}>
<Loader loading={state.loading}>
{() => <SQLCodeEditorLoader className={s(styles, { sqlCodeEditorLoader: true })} value={state.query} extensions={extensions} readonly />}
{() => <SQLCodeEditor className={s(styles, { sqlCodeEditorLoader: true })} value={state.query} extensions={extensions} readonly />}
</Loader>
</div>
</CommonDialogBody>
@@ -53,7 +53,7 @@
"path": "../plugin-sql-editor"
},
{
"path": "../plugin-sql-editor-new"
"path": "../plugin-sql-editor-codemirror"
}
],
"include": [
+28 -5
View File
@@ -2968,8 +2968,8 @@ __metadata:
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/plugin-data-viewer": "workspace:*"
"@cloudbeaver/plugin-sql-editor": "workspace:*"
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*"
"@cloudbeaver/plugin-sql-editor-navigation-tab": "workspace:*"
"@cloudbeaver/plugin-sql-editor-new": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@dbeaver/cli": "workspace:*"
"@dbeaver/js-helpers": "workspace:*"
@@ -3145,7 +3145,7 @@ __metadata:
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/plugin-data-grid": "workspace:*"
"@cloudbeaver/plugin-datasource-context-switch": "workspace:*"
"@cloudbeaver/plugin-sql-editor-new": "workspace:*"
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*"
"@cloudbeaver/plugin-tools-panel": "workspace:*"
"@cloudbeaver/plugin-top-app-bar": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
@@ -3180,8 +3180,8 @@ __metadata:
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/plugin-navigation-tree": "workspace:*"
"@cloudbeaver/plugin-sql-editor": "workspace:*"
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*"
"@cloudbeaver/plugin-sql-editor-navigation-tab": "workspace:*"
"@cloudbeaver/plugin-sql-editor-new": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@types/react": "npm:^19"
mobx: "npm:^6"
@@ -4024,7 +4024,28 @@ __metadata:
"@cloudbeaver/core-root": "workspace:*"
"@cloudbeaver/core-sdk": "workspace:*"
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/plugin-sql-editor-new": "workspace:*"
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@types/react": "npm:^19"
mobx: "npm:^6"
mobx-react-lite: "npm:^4"
react: "npm:^19"
react-dom: "npm:^19"
rimraf: "npm:^6"
tslib: "npm:^2"
typescript: "npm:^5"
typescript-plugin-css-modules: "npm:^5"
languageName: unknown
linkType: soft
"@cloudbeaver/plugin-sql-editor-codemirror@workspace:*, @cloudbeaver/plugin-sql-editor-codemirror@workspace:packages/plugin-sql-editor-codemirror":
version: 0.0.0-use.local
resolution: "@cloudbeaver/plugin-sql-editor-codemirror@workspace:packages/plugin-sql-editor-codemirror"
dependencies:
"@cloudbeaver/core-blocks": "workspace:*"
"@cloudbeaver/core-cli": "workspace:*"
"@cloudbeaver/core-sdk": "workspace:*"
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@types/react": "npm:^19"
mobx: "npm:^6"
@@ -4129,6 +4150,7 @@ __metadata:
"@cloudbeaver/core-utils": "workspace:*"
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/plugin-sql-editor": "workspace:*"
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@types/react": "npm:^19"
mobx: "npm:^6"
@@ -4201,6 +4223,7 @@ __metadata:
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/plugin-data-viewer": "workspace:*"
"@cloudbeaver/plugin-navigation-tabs": "workspace:*"
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@dbeaver/cli": "workspace:*"
"@dbeaver/js-helpers": "workspace:^"
@@ -4236,7 +4259,7 @@ __metadata:
"@cloudbeaver/plugin-codemirror6": "workspace:*"
"@cloudbeaver/plugin-data-viewer": "workspace:*"
"@cloudbeaver/plugin-sql-editor": "workspace:*"
"@cloudbeaver/plugin-sql-editor-new": "workspace:*"
"@cloudbeaver/plugin-sql-editor-codemirror": "workspace:*"
"@cloudbeaver/tsconfig": "workspace:*"
"@dbeaver/cli": "workspace:*"
"@types/react": "npm:^19"