dbeaver/pro#6201 feat: ai chat query insertion (#3578)

* dbeaver/pro#6201 feat: ai chat query insertion

* chore: remove confusing comment

* chore: query execution and replacement

---------

Co-authored-by: Evgenia <139753579+EvgeniaBzzz@users.noreply.github.com>
This commit is contained in:
Alexey Potsetsuev
2025-07-18 23:44:17 +08:00
committed by GitHub
co-authored by Evgenia
parent dcc13811e8
commit 36e8d1fac9
27 changed files with 267 additions and 45 deletions
+11 -1
View File
@@ -334,6 +334,7 @@ __metadata:
dependencies:
"@dbeaver/cli": "workspace:^"
"@dbeaver/tsconfig": "workspace:^"
async-mutex: "npm:^0"
rimraf: "npm:^6"
typescript: "npm:^5"
vitest: "npm:^3"
@@ -2197,6 +2198,15 @@ __metadata:
languageName: node
linkType: hard
"async-mutex@npm:^0":
version: 0.5.0
resolution: "async-mutex@npm:0.5.0"
dependencies:
tslib: "npm:^2.4.0"
checksum: 10c0/9096e6ad6b674c894d8ddd5aa4c512b09bb05931b8746ebd634952b05685608b2b0820ed5c406e6569919ff5fe237ab3c491e6f2887d6da6b6ba906db3ee9c32
languageName: node
linkType: hard
"axe-core@npm:^4.10.2":
version: 4.10.3
resolution: "axe-core@npm:4.10.3"
@@ -6910,7 +6920,7 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:^2, tslib@npm:^2.0.3, tslib@npm:^2.3.0":
"tslib@npm:^2, tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0":
version: 2.8.1
resolution: "tslib@npm:2.8.1"
checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
@@ -30,5 +30,8 @@
"rimraf": "^6",
"typescript": "^5",
"vitest": "^3"
},
"dependencies": {
"async-mutex": "^0"
}
}
@@ -1,2 +1,3 @@
export * from './isDefined.js';
export * from './isNotNullDefined.js';
export * from './mutex.js';
@@ -0,0 +1 @@
export * as mutex from 'async-mutex';
+11 -1
View File
@@ -144,6 +144,7 @@ __metadata:
dependencies:
"@dbeaver/cli": "workspace:^"
"@dbeaver/tsconfig": "workspace:^"
async-mutex: "npm:^0"
rimraf: "npm:^6"
typescript: "npm:^5"
vitest: "npm:^3"
@@ -989,6 +990,15 @@ __metadata:
languageName: node
linkType: hard
"async-mutex@npm:^0":
version: 0.5.0
resolution: "async-mutex@npm:0.5.0"
dependencies:
tslib: "npm:^2.4.0"
checksum: 10c0/9096e6ad6b674c894d8ddd5aa4c512b09bb05931b8746ebd634952b05685608b2b0820ed5c406e6569919ff5fe237ab3c491e6f2887d6da6b6ba906db3ee9c32
languageName: node
linkType: hard
"balanced-match@npm:^1.0.0":
version: 1.0.2
resolution: "balanced-match@npm:1.0.2"
@@ -2801,7 +2811,7 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:^2, tslib@npm:^2.3.0":
"tslib@npm:^2, tslib@npm:^2.3.0, tslib@npm:^2.4.0":
version: 2.8.1
resolution: "tslib@npm:2.8.1"
checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
@@ -34,6 +34,7 @@ export default [
['ui_custom', 'Custom'],
['ui_configure', 'Configure'],
['ui_apply', 'Apply'],
['ui_replace', 'Replace'],
['ui_cancel', 'Cancel'],
['ui_reject', 'Reject'],
['ui_ignore', 'Ignore'],
@@ -32,6 +32,7 @@ export default [
['ui_custom', 'Personnalisé'],
['ui_configure', 'Configurer'],
['ui_apply', 'Appliquer'],
['ui_replace', 'Remplacer'],
['ui_cancel', 'Annuler'],
['ui_reject', 'Reject'],
['ui_ignore', 'Ignorer'],
@@ -32,6 +32,7 @@ export default [
['ui_custom', 'Custom'],
['ui_configure', 'Configure'],
['ui_apply', 'Applica'],
['ui_replace', 'Sostituisci'],
['ui_cancel', 'Annulla'],
['ui_reject', 'Reject'],
['ui_ignore', 'Ignore'],
@@ -31,6 +31,7 @@ export default [
['ui_custom', 'Настроить'],
['ui_configure', 'Настроить'],
['ui_apply', 'Применить'],
['ui_replace', 'Заменить'],
['ui_cancel', 'Отменить'],
['ui_reject', 'Отклонить'],
['ui_ignore', 'Пропустить'],
@@ -34,6 +34,7 @@ export default [
['ui_custom', 'Tùy chỉnh'],
['ui_configure', 'Cấu hình'],
['ui_apply', 'Áp dụng'],
['ui_replace', 'Thay thế'],
['ui_cancel', 'Hủy'],
['ui_reject', 'Từ chối'],
['ui_ignore', 'Bỏ qua'],
@@ -32,8 +32,9 @@ export default [
['ui_custom', '个性化'],
['ui_configure', '配置'],
['ui_apply', '应用'],
['ui_cancel', 'Cancel'],
['ui_reject', 'Reject'],
['ui_replace', '替换'],
['ui_cancel', '取消'],
['ui_reject', '拒绝'],
['ui_ignore', '忽略'],
['ui_error', '错误'],
['ui_error_message', '错误:'],
@@ -42,6 +42,8 @@ export interface ISQLEditorOptions {
schemaId?: string;
source?: string;
query?: string;
dataSourceState?: Record<string, any>;
metadata?: Record<string, any>;
}
export interface SQLCreateAction extends SQLEditorActionContext, ISQLEditorOptions {
@@ -142,6 +144,8 @@ export class SqlEditorNavigatorService {
data.name,
data.source,
data.query,
data.dataSourceState,
data.metadata,
);
if (tabOptions) {
@@ -121,12 +121,20 @@ export class SqlEditorTabService extends Bootstrap {
this.connectionExecutionContextResource.onItemDelete.addHandler(this.handleExecutionContextDelete.bind(this));
}
createNewEditor(editorId: string, dataSourceKey: string, name?: string, source?: string, script?: string): ITabOptions<ISqlEditorTabState> | null {
createNewEditor(
editorId: string,
dataSourceKey: string,
name?: string,
source?: string,
script?: string,
dataSourceState?: Record<string, any>,
metadata?: Record<string, any>,
): ITabOptions<ISqlEditorTabState> | null {
const order = this.getFreeEditorId();
const handlerState = this.sqlEditorService.getState(editorId, dataSourceKey, order, source);
const handlerState = this.sqlEditorService.getState(editorId, dataSourceKey, order, source, metadata);
const datasource = this.sqlDataSourceService.create(handlerState, dataSourceKey, { name, script });
const datasource = this.sqlDataSourceService.create(handlerState, dataSourceKey, { name, script, dataSourceState });
return {
id: editorId,
@@ -160,7 +168,7 @@ export class SqlEditorTabService extends Bootstrap {
return createConnectionParam(context.projectId, context.connectionId);
}
private async handleConnectionDelete(key: ResourceKeySimple<IConnectionInfoParams>) {
private handleConnectionDelete(key: ResourceKeySimple<IConnectionInfoParams>) {
const tabs = this.navigationTabsService.findTabs<ISqlEditorTabState>(
isSQLEditorTab(tab => {
const dataSource = this.sqlDataSourceService.get(tab.handlerState.editorId);
@@ -225,7 +233,7 @@ export class SqlEditorTabService extends Bootstrap {
};
}
private async handleExecutionContextUpdate(key: ResourceKeySimple<string>) {
private handleExecutionContextUpdate(key: ResourceKeySimple<string>) {
const tabs = this.navigationTabsService.findTabs<ISqlEditorTabState>(
isSQLEditorTab(tab => {
const dataSource = this.sqlDataSourceService.get(tab.handlerState.editorId);
@@ -254,7 +262,7 @@ export class SqlEditorTabService extends Bootstrap {
}
}
private async handleExecutionContextDelete(key: ResourceKeySimple<string>) {
private handleExecutionContextDelete(key: ResourceKeySimple<string>) {
const tabs = this.navigationTabsService.findTabs<ISqlEditorTabState>(
isSQLEditorTab(tab => {
const dataSource = this.sqlDataSourceService.get(tab.handlerState.editorId);
@@ -437,7 +445,7 @@ export class SqlEditorTabService extends Bootstrap {
}
}
private async syncDatasourceUpdate(data: ISQLDatasourceUpdateData) {
private syncDatasourceUpdate(data: ISQLDatasourceUpdateData) {
const tab = this.sqlEditorTabs.find(tab => tab.handlerState.editorId === data.editorId);
if (tab) {
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* Copyright (C) 2020-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -74,6 +74,7 @@ export const SQL_EDITOR_TAB_STATE_SCHEMA = schema.object({
outputLogsTab: OUTPUT_LOGS_TAB_SCHEMA.optional(),
currentModeId: schema.string().optional(),
modeState: schema.array(schema.tuple([schema.string(), schema.any()])),
metadata: schema.record(schema.any()).optional(),
});
export type ISqlEditorTabState = schema.infer<typeof SQL_EDITOR_TAB_STATE_SCHEMA>;
@@ -153,6 +153,9 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
}
setScript(script: string, source?: string, cursor?: ISqlEditorCursor): void {
if (cursor) {
this.setInnerCursorState(cursor);
}
this.onSetScript.execute({ script, source, cursor });
}
@@ -243,13 +246,10 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
}
setCursor(anchor: number, head = anchor): void {
const scriptLength = this.script.length;
this.innerCursorState = Object.freeze({
anchor: Math.min(anchor, scriptLength),
head: Math.min(head, scriptLength),
this.setInnerCursorState({
anchor,
head,
});
this.onUpdate.execute();
}
@@ -305,4 +305,12 @@ export abstract class BaseSqlDataSource implements ISqlDataSource {
protected abstract setBaseScript(script: string): void;
protected abstract setBaseExecutionContext(executionContext: IConnectionExecutionContextInfo | undefined): void;
protected setInnerCursorState(cursor: ISqlEditorCursor): void {
const scriptLength = this.script.length;
this.innerCursorState = Object.freeze({
anchor: Math.min(cursor.anchor, scriptLength),
head: Math.min(cursor.head, scriptLength),
});
}
}
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* Copyright (C) 2020-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -14,4 +14,5 @@ export interface ILocalStorageSqlDataSourceState {
name?: string;
executionContext?: IConnectionExecutionContextInfo;
history: ISqlDataSourceHistoryState;
showOnlyResults?: boolean;
}
@@ -38,6 +38,9 @@ export class LocalStorageSqlDataSource extends BaseSqlDataSource {
}
override get features(): ESqlDataSourceFeatures[] {
if (this.state.showOnlyResults) {
return [];
}
return [ESqlDataSourceFeatures.script, ESqlDataSourceFeatures.query, ESqlDataSourceFeatures.executable, ESqlDataSourceFeatures.setName];
}
@@ -76,6 +79,11 @@ export class LocalStorageSqlDataSource extends BaseSqlDataSource {
return true;
}
// TODO: should we move it to the BaseSqlDataSource?
setShowOnlyResults(showOnlyResults: boolean): void {
this.state.showOnlyResults = showOnlyResults;
}
override setScript(script: string, source?: string, cursor?: ISqlEditorCursor): void {
this.state.script = script;
super.setScript(script, source, cursor);
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* Copyright (C) 2020-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -82,6 +82,7 @@ export class LocalStorageSqlDataSourceBootstrap extends Bootstrap {
script: options?.script ?? '',
executionContext: options?.executionContext,
history: createSqlDataSourceHistoryInitialState(options?.script),
...options?.dataSourceState,
});
this.dataSourceStateState.set(editorId, state);
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* Copyright (C) 2020-2025 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,6 +19,7 @@ export interface ISqlDataSourceOptions {
name?: string;
script?: string;
executionContext?: IConnectionExecutionContextInfo;
dataSourceState?: Record<string, any>;
}
type ISqlDataSourceFactory = (editorId: string, options?: ISqlDataSourceOptions) => ISqlDataSource;
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* Copyright (C) 2020-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import SqlEditorTab from './shared/SqlEditorTab.module.css';
import SqlEditorTabList from './shared/SqlEditorTabList.module.css';
import { SQLEditorActions } from './SQLEditorActions.js';
import { useSqlEditor } from './useSqlEditor.js';
import { useActiveQuery } from './useActiveQuery.js';
const sqlEditorRegistry: StyleRegistry = [
[TabListStyles, { mode: 'append', styles: [SqlEditorTabList] }],
@@ -33,6 +34,7 @@ export const SqlEditor = observer<ISqlEditorProps>(function SqlEditor({ state, c
const style = useS(styles, SqlEditorTab);
const sqlEditorModeService = useService(SqlEditorModeService);
const data = useSqlEditor(state);
useActiveQuery(data);
const [modesState] = useState(() => new MetadataMap<string, any>());
useMemo(() => {
@@ -0,0 +1,23 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 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 { ISQLEditorData } from './ISQLEditorData.js';
interface ISqlEditorStateContext {
state: ISQLEditorData | null;
setState: (state: ISQLEditorData | null) => void;
}
export function SqlEditorStateContext(): ISqlEditorStateContext {
return {
state: null,
setState(state) {
this.state = state;
},
};
}
@@ -0,0 +1,87 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 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 { useService } from '@cloudbeaver/core-di';
import type { ISQLEditorData } from './ISQLEditorData.js';
import { SqlEditorService, type ISqlEditorActiveQueryUpdateData } from '../SqlEditorService.js';
import { useExecutor } from '@cloudbeaver/core-blocks';
import { useState } from 'react';
import { ExecutorHandlersCollection } from '@cloudbeaver/core-executor';
import { SqlEditorStateContext } from './SqlEditorStateContext.js';
export function useActiveQuery(state: ISQLEditorData): void {
const [collection] = useState(() => new ExecutorHandlersCollection<ISqlEditorActiveQueryUpdateData>());
const sqlEditorService = useService(SqlEditorService);
useExecutor({
executor: collection,
handlers: [
function fillEditorState(data, context) {
const sqlEditorStateContext = context.getContext(SqlEditorStateContext);
sqlEditorStateContext.setState(state);
},
],
});
useExecutor({
executor: sqlEditorService.updateActiveQuery,
before: collection,
handlers: [
async function updateActiveQuery(data, context) {
const sqlEditorStateContext = context.getContext(SqlEditorStateContext);
const sqlEditorData = sqlEditorStateContext.state;
if (!sqlEditorData) {
return;
}
const segment = await sqlEditorData.getResolvedSegment();
let query = data.update.query.trim();
if (segment) {
query = query.trim();
// TODO: getResolvedSegment will return segment without end delimiter
// we need this to avoid duplicated end delimiter
const dialectDelimiter = sqlEditorData.dialect?.scriptDelimiter ?? '';
const endDelimiterLength = dialectDelimiter.length;
const endDelimiter = sqlEditorData.value.slice(segment.end, segment.end + endDelimiterLength);
if (endDelimiter === dialectDelimiter && query.endsWith(endDelimiter)) {
query = query.slice(0, -endDelimiterLength);
}
}
switch (data.update.type) {
case 'replace':
if (segment) {
const firstQueryPart = sqlEditorData.value.slice(0, segment.begin) + query;
sqlEditorData.setScript(firstQueryPart + sqlEditorData.value.slice(segment.end), undefined, {
anchor: firstQueryPart.length,
head: firstQueryPart.length,
});
} else {
sqlEditorData.setScript(query, undefined, sqlEditorData.cursor);
}
break;
case 'append':
{
const newScript = sqlEditorData.value + query;
sqlEditorData.setScript(newScript, undefined, { anchor: newScript.length, head: newScript.length });
}
break;
case 'prepend':
{
const newScript = query + sqlEditorData.value;
sqlEditorData.setScript(newScript, undefined, { anchor: 0, head: 0 });
}
break;
}
},
],
});
}
@@ -404,7 +404,7 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
passEmpty?: boolean,
passDisabled?: boolean,
): Promise<T | undefined> {
if (!segment || (this.isDisabled && !passDisabled) || (!passEmpty && this.isScriptEmpty)) {
if (!segment || segment.end === segment.begin || (this.isDisabled && !passDisabled) || (!passEmpty && this.isScriptEmpty)) {
return;
}
@@ -435,24 +435,35 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
const projectId = this.dataSource?.executionContext?.projectId;
const connectionId = this.dataSource?.executionContext?.connectionId;
await data.updateParserScripts();
while (true) {
const currentScript = this.parser.actualScript;
// TODO: we updating parser scripts
// script may be changed this will lead to temporary wrong segments offsets
await data.updateParserScripts();
if (currentScript !== this.parser.actualScript) {
continue;
}
if (!projectId || !connectionId || this.cursor.anchor !== this.cursor.head) {
return this.getSubQuery();
if (!projectId || !connectionId || this.cursor.anchor !== this.cursor.head) {
return this.getSubQuery();
}
if (this.activeSegmentMode.activeSegmentMode) {
return this.activeSegment;
}
const result = await this.sqlEditorService.parseSQLQuery(projectId, connectionId, currentScript, this.cursor.anchor);
if (currentScript !== this.parser.actualScript) {
continue;
}
if (result.end === 0 && result.start === 0) {
return this.cursorSegment;
}
// TODO: here we use parser that may be outdated and segment will return wrong value
const segment = this.parser.getSegment(result.start, result.end);
return segment;
}
if (this.activeSegmentMode.activeSegmentMode) {
return this.activeSegment;
}
const result = await this.sqlEditorService.parseSQLQuery(projectId, connectionId, this.value, this.cursor.anchor);
if (result.end === 0 && result.start === 0) {
return;
}
const segment = this.parser.getSegment(result.start, result.end);
return segment;
},
getSubQuery(): ISQLScriptSegment | undefined {
@@ -508,8 +519,6 @@ export function useSqlEditor(state: ISqlEditorTabState): ISQLEditorData {
executor: data.dataSource?.onSetScript,
handlers: [
function setScript({ script }) {
// ensure that cursor is in script boundaries
data.setCursor(data.cursor.anchor, data.cursor.head);
data.parser.setScript(script);
data.updateParserScriptsDebounced().catch(() => {});
data.onUpdate.execute();
@@ -30,12 +30,22 @@ import type { ISqlEditorTabState } from './ISqlEditorTabState.js';
import { ESqlDataSourceFeatures } from './SqlDataSource/ESqlDataSourceFeatures.js';
import { SqlDataSourceService } from './SqlDataSource/SqlDataSourceService.js';
import { SqlEditorSettingsService } from './SqlEditorSettingsService.js';
import { Executor, type IExecutor } from '@cloudbeaver/core-executor';
import { SqlQueryService } from './SqlResultTabs/SqlQueryService.js';
export type SQLProposal = SqlCompletionProposal;
export interface ISqlEditorActiveQueryUpdateData {
editorId: string;
update: {
query: string;
type: 'replace' | 'append' | 'prepend';
};
}
@injectable()
export class SqlEditorService {
get autoSave() {
get autoSave(): boolean {
return this.sqlEditorSettingsService.autoSave && !this.serverConfigResource.isFeatureEnabled(FEATURE_GIT_ID, true);
}
@@ -43,6 +53,12 @@ export class SqlEditorService {
return this.sqlEditorSettingsService.insertTableAlias;
}
/**
* This executor implemented in the useActiveQuery hook.
* It will work only when editor is mounted in the dom.
*/
readonly updateActiveQuery: IExecutor<ISqlEditorActiveQueryUpdateData>;
constructor(
private readonly graphQLService: GraphQLService,
private readonly connectionsManagerService: ConnectionsManagerService,
@@ -53,14 +69,20 @@ export class SqlEditorService {
private readonly sqlDataSourceService: SqlDataSourceService,
private readonly sqlEditorSettingsService: SqlEditorSettingsService,
private readonly serverConfigResource: ServerConfigResource,
) {}
private readonly sqlQueryService: SqlQueryService,
) {
this.updateActiveQuery = new Executor();
getState(editorId: string, datasourceKey: string, order: number, source?: string): ISqlEditorTabState {
this.sqlQueryService.onQueryExecution.addHandler(editorState => this.initEditorConnection(editorState));
}
getState(editorId: string, datasourceKey: string, order: number, source?: string, metadata?: Record<string, any>): ISqlEditorTabState {
return observable({
editorId,
datasourceKey,
source,
order,
metadata,
tabs: observable([]),
resultGroups: observable([]),
resultTabs: observable([]),
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
* Copyright (C) 2020-2025 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import type { IResultGroup, ISqlEditorTabState } from '../ISqlEditorTabState.js'
import { QueryDataSource } from '../QueryDataSource.js';
import { SqlDataSourceService } from '../SqlDataSource/SqlDataSourceService.js';
import { SqlQueryResultService } from './SqlQueryResultService.js';
import { Executor, type IExecutor } from '@cloudbeaver/core-executor';
interface IQueryExecutionOptions {
onQueryExecutionStart?: (query: string, index: number) => void;
@@ -44,6 +45,7 @@ export interface IQueryExecutionStatistics {
@injectable()
export class SqlQueryService {
private readonly statisticsMap: Map<string, IQueryExecutionStatistics>;
readonly onQueryExecution: IExecutor<ISqlEditorTabState>;
constructor(
private readonly serviceProvider: IServiceProvider,
@@ -60,6 +62,7 @@ export class SqlQueryService {
private readonly dataViewerSettingsService: DataViewerSettingsService,
) {
this.statisticsMap = new Map();
this.onQueryExecution = new Executor();
makeObservable<this, 'statisticsMap'>(this, {
statisticsMap: observable,
@@ -111,6 +114,7 @@ export class SqlQueryService {
}
async executeEditorQuery(editorState: ISqlEditorTabState, query: string, inNewTab: boolean): Promise<void> {
await this.onQueryExecution.execute(editorState);
const dataSource = this.sqlDataSourceService.get(editorState.editorId);
const contextInfo = dataSource?.executionContext;
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.id);
@@ -179,6 +183,7 @@ export class SqlQueryService {
}
async executeQueries(editorState: ISqlEditorTabState, queries: string[], options?: IQueryExecutionOptions): Promise<void> {
await this.onQueryExecution.execute(editorState);
const dataSource = this.sqlDataSourceService.get(editorState.editorId);
const contextInfo = dataSource?.executionContext;
const executionContext = contextInfo && this.connectionExecutionContextService.get(contextInfo.id);
@@ -33,6 +33,7 @@ export * from './SqlEditor/DATA_CONTEXT_SQL_EDITOR_DATA.js';
export * from './SqlEditor/SQL_EDITOR_ACTIONS_MENU.js';
export * from './SqlEditor/SQL_EDITOR_TOOLS_MENU.js';
export * from './SqlEditor/SQLEditorModeContext.js';
export * from './SqlEditor/SqlEditorStateContext.js';
export * from './SqlResultTabs/DATA_CONTEXT_SQL_EDITOR_RESULT_ID.js';
export * from './SqlResultTabs/SqlResultTabsService.js';
export * from './SqlResultTabs/OutputLogs/OutputLogsEventHandler.js';
+10
View File
@@ -4506,6 +4506,7 @@ __metadata:
dependencies:
"@dbeaver/cli": "workspace:^"
"@dbeaver/tsconfig": "workspace:^"
async-mutex: "npm:^0"
rimraf: "npm:^6"
typescript: "npm:^5"
vitest: "npm:^3"
@@ -8644,6 +8645,15 @@ __metadata:
languageName: node
linkType: hard
"async-mutex@npm:^0":
version: 0.5.0
resolution: "async-mutex@npm:0.5.0"
dependencies:
tslib: "npm:^2.4.0"
checksum: 10c0/9096e6ad6b674c894d8ddd5aa4c512b09bb05931b8746ebd634952b05685608b2b0820ed5c406e6569919ff5fe237ab3c491e6f2887d6da6b6ba906db3ee9c32
languageName: node
linkType: hard
"async@npm:^3.2.3":
version: 3.2.6
resolution: "async@npm:3.2.6"