mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add toggle query history capture command/action (#7427)
* Add toggle query history capture command/action * Add extension updates
This commit is contained in:
committed by
Karl Burtram
parent
3e17618056
commit
0a6779f96e
@@ -10,7 +10,7 @@
|
|||||||
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.30.1",
|
"vscode": "^1.30.1",
|
||||||
"azdata": ">=1.9.0"
|
"azdata": ">=1.12.0"
|
||||||
},
|
},
|
||||||
"activationEvents": [
|
"activationEvents": [
|
||||||
"*"
|
"*"
|
||||||
@@ -28,12 +28,20 @@
|
|||||||
"command": "queryHistory.clear",
|
"command": "queryHistory.clear",
|
||||||
"title": "%queryHistory.clear%",
|
"title": "%queryHistory.clear%",
|
||||||
"category": "%queryHistory.displayName%"
|
"category": "%queryHistory.displayName%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "queryHistory.toggleCapture",
|
||||||
|
"title": "%queryHistory.toggleCapture%",
|
||||||
|
"category": "%queryHistory.displayName%"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"menus": {
|
"menus": {
|
||||||
"commandPalette": [
|
"commandPalette": [
|
||||||
{
|
{
|
||||||
"command": "queryHistory.clear"
|
"command": "queryHistory.clear"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "queryHistory.toggleCapture"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"queryHistory.displayName": "Query History",
|
"queryHistory.displayName": "Query History",
|
||||||
"queryHistory.description": "View and run previously executed queries",
|
"queryHistory.description": "View and run previously executed queries",
|
||||||
"queryHistory.clear": "Clear All History"
|
"queryHistory.clear": "Clear All History",
|
||||||
|
"queryHistory.toggleCapture": "Toggle Query History Capture"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,39 @@ export const IQueryHistoryService = createDecorator<IQueryHistoryService>(SERVIC
|
|||||||
export interface IQueryHistoryService {
|
export interface IQueryHistoryService {
|
||||||
_serviceBrand: any;
|
_serviceBrand: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event fired whenever the collection of stored QueryHistoryInfo's is updated
|
||||||
|
*/
|
||||||
onInfosUpdated: Event<QueryHistoryInfo[]>;
|
onInfosUpdated: Event<QueryHistoryInfo[]>;
|
||||||
|
/**
|
||||||
|
* Event fired whenever the Query History capture state has changed
|
||||||
|
*/
|
||||||
|
onQueryHistoryCaptureChanged: Event<boolean>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Query History capture is currently enabled
|
||||||
|
*/
|
||||||
|
readonly captureEnabled: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current list of Query History Info objects that have been collected
|
||||||
|
*/
|
||||||
getQueryHistoryInfos(): QueryHistoryInfo[];
|
getQueryHistoryInfos(): QueryHistoryInfo[];
|
||||||
|
/**
|
||||||
|
* Deletes all QueryHistoryInfo's from the collection that have the same id as the specified one
|
||||||
|
* @param info The QueryHistoryInfo to delete
|
||||||
|
*/
|
||||||
deleteQueryHistoryInfo(info: QueryHistoryInfo): void;
|
deleteQueryHistoryInfo(info: QueryHistoryInfo): void;
|
||||||
|
/**
|
||||||
|
* Clears all Query History - removing all collected items
|
||||||
|
*/
|
||||||
clearQueryHistory(): void;
|
clearQueryHistory(): void;
|
||||||
|
/**
|
||||||
|
* Toggles whether Query History capture is enabled
|
||||||
|
*/
|
||||||
|
toggleCaptureEnabled(): Promise<void>;
|
||||||
|
/**
|
||||||
|
* Starts the Query History Service
|
||||||
|
*/
|
||||||
start(): void;
|
start(): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { QueryHistoryInfo, QueryStatus } from 'sql/platform/queryHistory/common/
|
|||||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||||
import { Event, Emitter } from 'vs/base/common/event';
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
|
||||||
|
import { IConfigurationChangedEvent } from 'sql/workbench/parts/profiler/browser/profilerFindWidget';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that collects the results of executed queries
|
* Service that collects the results of executed queries
|
||||||
@@ -23,20 +25,30 @@ export class QueryHistoryService extends Disposable implements IQueryHistoryServ
|
|||||||
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
// MEMBER VARIABLES ////////////////////////////////////////////////////
|
||||||
private _infos: QueryHistoryInfo[] = [];
|
private _infos: QueryHistoryInfo[] = [];
|
||||||
private _onInfosUpdated: Emitter<QueryHistoryInfo[]> = new Emitter<QueryHistoryInfo[]>();
|
private _onInfosUpdated: Emitter<QueryHistoryInfo[]> = new Emitter<QueryHistoryInfo[]>();
|
||||||
|
private _onQueryHistoryCaptureChanged: Emitter<boolean> = new Emitter<boolean>();
|
||||||
|
private _captureEnabled;
|
||||||
// EVENTS //////////////////////////////////////////////////////////////
|
// EVENTS //////////////////////////////////////////////////////////////
|
||||||
public get onInfosUpdated(): Event<QueryHistoryInfo[]> { return this._onInfosUpdated.event; }
|
public get onInfosUpdated(): Event<QueryHistoryInfo[]> { return this._onInfosUpdated.event; }
|
||||||
|
public get onQueryHistoryCaptureChanged(): Event<boolean> { return this._onQueryHistoryCaptureChanged.event; }
|
||||||
// CONSTRUCTOR /////////////////////////////////////////////////////////
|
// CONSTRUCTOR /////////////////////////////////////////////////////////
|
||||||
constructor(
|
constructor(
|
||||||
@IQueryModelService _queryModelService: IQueryModelService,
|
@IQueryModelService _queryModelService: IQueryModelService,
|
||||||
@IModelService _modelService: IModelService,
|
@IModelService _modelService: IModelService,
|
||||||
@IConnectionManagementService _connectionManagementService: IConnectionManagementService
|
@IConnectionManagementService _connectionManagementService: IConnectionManagementService,
|
||||||
|
@IConfigurationService private _configurationService: IConfigurationService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this._captureEnabled = !!this._configurationService.getValue<boolean>('queryHistory.captureEnabled');
|
||||||
|
|
||||||
|
this._register(this._configurationService.onDidChangeConfiguration((e: IConfigurationChangeEvent) => {
|
||||||
|
if (e.affectedKeys.includes('queryHistory.captureEnabled')) {
|
||||||
|
this.updateCaptureEnabled();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
this._register(_queryModelService.onQueryEvent((e: IQueryEvent) => {
|
this._register(_queryModelService.onQueryEvent((e: IQueryEvent) => {
|
||||||
if (e.type === 'queryStop') {
|
if (this._captureEnabled && e.type === 'queryStop') {
|
||||||
const uri: URI = URI.parse(e.uri);
|
const uri: URI = URI.parse(e.uri);
|
||||||
// VS Range is 1 based so offset values by 1. The endLine we get back from SqlToolsService is incremented
|
// VS Range is 1 based so offset values by 1. The endLine we get back from SqlToolsService is incremented
|
||||||
// by 1 from the original input range sent in as well so take that into account and don't modify
|
// by 1 from the original input range sent in as well so take that into account and don't modify
|
||||||
@@ -62,6 +74,13 @@ export class QueryHistoryService extends Disposable implements IQueryHistoryServ
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Query History capture is currently enabled
|
||||||
|
*/
|
||||||
|
public get captureEnabled(): boolean {
|
||||||
|
return this._captureEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all the current query history infos
|
* Gets all the current query history infos
|
||||||
*/
|
*/
|
||||||
@@ -73,7 +92,7 @@ export class QueryHistoryService extends Disposable implements IQueryHistoryServ
|
|||||||
* Deletes infos from the cache with the same ID as the given QueryHistoryInfo
|
* Deletes infos from the cache with the same ID as the given QueryHistoryInfo
|
||||||
* @param info The QueryHistoryInfo to delete
|
* @param info The QueryHistoryInfo to delete
|
||||||
*/
|
*/
|
||||||
public deleteQueryHistoryInfo(info: QueryHistoryInfo) {
|
public deleteQueryHistoryInfo(info: QueryHistoryInfo): void {
|
||||||
this._infos = this._infos.filter(i => i.id !== info.id);
|
this._infos = this._infos.filter(i => i.id !== info.id);
|
||||||
this._onInfosUpdated.fire(this._infos);
|
this._onInfosUpdated.fire(this._infos);
|
||||||
}
|
}
|
||||||
@@ -81,11 +100,24 @@ export class QueryHistoryService extends Disposable implements IQueryHistoryServ
|
|||||||
/**
|
/**
|
||||||
* Clears all infos from the cache
|
* Clears all infos from the cache
|
||||||
*/
|
*/
|
||||||
public clearQueryHistory() {
|
public clearQueryHistory(): void {
|
||||||
this._infos = [];
|
this._infos = [];
|
||||||
this._onInfosUpdated.fire(this._infos);
|
this._onInfosUpdated.fire(this._infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async toggleCaptureEnabled(): Promise<void> {
|
||||||
|
const captureEnabled = !!this._configurationService.getValue<boolean>('queryHistory.captureEnabled');
|
||||||
|
await this._configurationService.updateValue('queryHistory.captureEnabled', !captureEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateCaptureEnabled(): void {
|
||||||
|
const currentCaptureEnabled = this._captureEnabled;
|
||||||
|
this._captureEnabled = !!this._configurationService.getValue<boolean>('queryHistory.captureEnabled');
|
||||||
|
if (currentCaptureEnabled !== this._captureEnabled) {
|
||||||
|
this._onQueryHistoryCaptureChanged.fire(this._captureEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to force initialization of the service so that it can start tracking query events
|
* Method to force initialization of the service so that it can start tracking query events
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { DeleteAction, OpenQueryAction, RunQueryAction, ClearHistoryAction } from 'sql/workbench/parts/queryHistory/browser/queryHistoryActions';
|
import { DeleteAction, OpenQueryAction, RunQueryAction, ClearHistoryAction, ToggleQueryHistoryCaptureAction } from 'sql/workbench/parts/queryHistory/browser/queryHistoryActions';
|
||||||
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
import { ITree } from 'vs/base/parts/tree/browser/tree';
|
||||||
import { ContributableActionProvider } from 'vs/workbench/browser/actions';
|
import { ContributableActionProvider } from 'vs/workbench/browser/actions';
|
||||||
import { IAction } from 'vs/base/common/actions';
|
import { IAction } from 'vs/base/common/actions';
|
||||||
@@ -19,7 +19,8 @@ export class QueryHistoryActionProvider extends ContributableActionProvider {
|
|||||||
openQueryAction: IAction,
|
openQueryAction: IAction,
|
||||||
runQueryAction: IAction,
|
runQueryAction: IAction,
|
||||||
deleteAction: IAction,
|
deleteAction: IAction,
|
||||||
clearAction: IAction
|
clearAction: IAction,
|
||||||
|
toggleCaptureAction: IAction
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -30,7 +31,8 @@ export class QueryHistoryActionProvider extends ContributableActionProvider {
|
|||||||
openQueryAction: instantiationService.createInstance(OpenQueryAction, OpenQueryAction.ID, OpenQueryAction.LABEL),
|
openQueryAction: instantiationService.createInstance(OpenQueryAction, OpenQueryAction.ID, OpenQueryAction.LABEL),
|
||||||
runQueryAction: instantiationService.createInstance(RunQueryAction, RunQueryAction.ID, RunQueryAction.LABEL),
|
runQueryAction: instantiationService.createInstance(RunQueryAction, RunQueryAction.ID, RunQueryAction.LABEL),
|
||||||
deleteAction: instantiationService.createInstance(DeleteAction, DeleteAction.ID, DeleteAction.LABEL),
|
deleteAction: instantiationService.createInstance(DeleteAction, DeleteAction.ID, DeleteAction.LABEL),
|
||||||
clearAction: instantiationService.createInstance(ClearHistoryAction, ClearHistoryAction.ID, ClearHistoryAction.LABEL)
|
clearAction: instantiationService.createInstance(ClearHistoryAction, ClearHistoryAction.ID, ClearHistoryAction.LABEL),
|
||||||
|
toggleCaptureAction: instantiationService.createInstance(ToggleQueryHistoryCaptureAction, ToggleQueryHistoryCaptureAction.ID, ToggleQueryHistoryCaptureAction.LABEL)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +45,7 @@ export class QueryHistoryActionProvider extends ContributableActionProvider {
|
|||||||
*/
|
*/
|
||||||
public getActions(element: any): IAction[] {
|
public getActions(element: any): IAction[] {
|
||||||
const actions: IAction[] = [];
|
const actions: IAction[] = [];
|
||||||
|
// Actions we only want to display if we're on a valid QueryHistoryNode
|
||||||
if (element instanceof QueryHistoryNode && element.info) {
|
if (element instanceof QueryHistoryNode && element.info) {
|
||||||
if (element.info && element.info.queryText && element.info.queryText !== '') {
|
if (element.info && element.info.queryText && element.info.queryText !== '') {
|
||||||
actions.push(this._actions.openQueryAction);
|
actions.push(this._actions.openQueryAction);
|
||||||
@@ -50,7 +53,8 @@ export class QueryHistoryActionProvider extends ContributableActionProvider {
|
|||||||
}
|
}
|
||||||
actions.push(this._actions.deleteAction);
|
actions.push(this._actions.deleteAction);
|
||||||
}
|
}
|
||||||
actions.push(this._actions.clearAction);
|
// Common actions we want to always display
|
||||||
|
actions.push(this._actions.clearAction, this._actions.toggleCaptureAction);
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export class ClearHistoryAction extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async run(): Promise<void> {
|
public async run(): Promise<void> {
|
||||||
this._commandService.executeCommand('queryHistory.clear');
|
return this._commandService.executeCommand('queryHistory.clear');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,3 +106,33 @@ export class RunQueryAction extends Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ToggleQueryHistoryCaptureAction extends Action {
|
||||||
|
public static ID = 'queryHistory.toggleCapture';
|
||||||
|
public static LABEL = localize('queryHistory.toggleCaptureLabel', "Toggle Query History capture");
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: string,
|
||||||
|
label: string,
|
||||||
|
@ICommandService private _commandService: ICommandService,
|
||||||
|
@IQueryHistoryService queryHistoryService: IQueryHistoryService
|
||||||
|
) {
|
||||||
|
super(id, label);
|
||||||
|
this.setClassAndLabel(queryHistoryService.captureEnabled);
|
||||||
|
this._register(queryHistoryService.onQueryHistoryCaptureChanged((captureEnabled: boolean) => { this.setClassAndLabel(captureEnabled); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async run(): Promise<void> {
|
||||||
|
return this._commandService.executeCommand('queryHistory.toggleCapture');
|
||||||
|
}
|
||||||
|
|
||||||
|
private setClassAndLabel(enabled: boolean) {
|
||||||
|
if (enabled) {
|
||||||
|
this.class = 'toggle-query-history-capture-action codicon-pause';
|
||||||
|
this.label = localize('queryHistory.disableCapture', "Pause Query History capture");
|
||||||
|
} else {
|
||||||
|
this.class = 'toggle-query-history-capture-action codicon-play';
|
||||||
|
this.label = localize('queryHistory.enableCapture', "Start Query History capture");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'v
|
|||||||
import { QUERY_HISTORY_PANEL_ID } from 'sql/workbench/parts/queryHistory/common/constants';
|
import { QUERY_HISTORY_PANEL_ID } from 'sql/workbench/parts/queryHistory/common/constants';
|
||||||
import { ToggleQueryHistoryAction } from 'sql/workbench/parts/queryHistory/browser/queryHistoryActions';
|
import { ToggleQueryHistoryAction } from 'sql/workbench/parts/queryHistory/browser/queryHistoryActions';
|
||||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||||
|
import { IConfigurationRegistry, ConfigurationScope, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||||
|
|
||||||
export class QueryHistoryWorkbenchContribution implements IWorkbenchContribution {
|
export class QueryHistoryWorkbenchContribution implements IWorkbenchContribution {
|
||||||
|
|
||||||
@@ -34,6 +35,21 @@ export class QueryHistoryWorkbenchContribution implements IWorkbenchContribution
|
|||||||
if (!this.queryHistoryEnabled) {
|
if (!this.queryHistoryEnabled) {
|
||||||
this.queryHistoryEnabled = true;
|
this.queryHistoryEnabled = true;
|
||||||
|
|
||||||
|
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||||
|
configurationRegistry.registerConfiguration({
|
||||||
|
id: 'queryHistory',
|
||||||
|
title: localize('queryHistoryConfigurationTitle', "QueryHistory"),
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
'queryHistory.captureEnabled': {
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
scope: ConfigurationScope.APPLICATION,
|
||||||
|
description: localize('queryHistoryCaptureEnabled', "Whether Query History capture is enabled. If false queries executed will not be captured.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// We need this to be running in the background even if the Panel (which is currently the only thing using it)
|
// We need this to be running in the background even if the Panel (which is currently the only thing using it)
|
||||||
// isn't shown yet. Otherwise the service won't be initialized until the Panel is which means we might miss out
|
// isn't shown yet. Otherwise the service won't be initialized until the Panel is which means we might miss out
|
||||||
// on some events
|
// on some events
|
||||||
@@ -47,6 +63,14 @@ export class QueryHistoryWorkbenchContribution implements IWorkbenchContribution
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CommandsRegistry.registerCommand({
|
||||||
|
id: 'queryHistory.toggleCapture',
|
||||||
|
handler: (accessor) => {
|
||||||
|
const queryHistoryService = accessor.get(IQueryHistoryService);
|
||||||
|
queryHistoryService.toggleCaptureEnabled();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||||
registry.registerWorkbenchAction(
|
registry.registerWorkbenchAction(
|
||||||
new SyncActionDescriptor(
|
new SyncActionDescriptor(
|
||||||
|
|||||||
Reference in New Issue
Block a user