From 76282ed1ef5ea6e294192fc3e63f08e9184be5b3 Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Tue, 16 Oct 2018 18:12:01 -0700 Subject: [PATCH 1/5] Look for showplan colum name (#2919) * change method for finding show plan through column name * formatting --- src/sql/parts/query/execution/queryRunner.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sql/parts/query/execution/queryRunner.ts b/src/sql/parts/query/execution/queryRunner.ts index b0450ce27b..2e7c6f1808 100644 --- a/src/sql/parts/query/execution/queryRunner.ts +++ b/src/sql/parts/query/execution/queryRunner.ts @@ -343,7 +343,11 @@ export default class QueryRunner { } // handle getting queryPlanxml if we need too if (this.isQueryPlan) { - this.getQueryRows(0, 1, 0, 0).then(e => this._planXml.resolve(e.resultSubset.rows[0][0].displayValue)); + // check if this result has show plan, this needs work, it won't work for any other provider + let hasShowPlan = !!result.resultSetSummary.columnInfo.find(e => e.columnName === 'Microsoft SQL Server 2005 XML Showplan'); + if (hasShowPlan) { + this.getQueryRows(0, 1, result.resultSetSummary.batchId, result.resultSetSummary.id).then(e => this._planXml.resolve(e.resultSubset.rows[0][0].displayValue)); + } } if (batchSet) { // Store the result set in the batch and emit that a result set has completed From 6ee3886ecf907f389336863c65115aeaab2337b4 Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Tue, 16 Oct 2018 18:31:19 -0700 Subject: [PATCH 2/5] clear out plan xml on executes (#2921) --- src/sql/parts/query/execution/queryRunner.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sql/parts/query/execution/queryRunner.ts b/src/sql/parts/query/execution/queryRunner.ts index 2e7c6f1808..03cdfd3ea6 100644 --- a/src/sql/parts/query/execution/queryRunner.ts +++ b/src/sql/parts/query/execution/queryRunner.ts @@ -184,6 +184,7 @@ export default class QueryRunner { this._echoedResultSet.clear(); this._debouncedMessage.clear(); this._debouncedResultSet.clear(); + this._planXml = new Deferred(); let ownerUri = this.uri; this._batchSets = []; this._hasCompleted = false; From 67514ccc5f4ff52f3363cae0908890b1557aaa6a Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Tue, 16 Oct 2018 21:55:21 -0700 Subject: [PATCH 3/5] change scroll container to fix ui glitch (#2924) --- src/sql/parts/queryPlan/queryPlan.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/parts/queryPlan/queryPlan.ts b/src/sql/parts/queryPlan/queryPlan.ts index 420ee11bce..f4e56a1207 100644 --- a/src/sql/parts/queryPlan/queryPlan.ts +++ b/src/sql/parts/queryPlan/queryPlan.ts @@ -41,7 +41,7 @@ export class QueryPlanView implements IPanelView { } } container.appendChild(this.container); - container.style.overflow = 'scroll'; + this.container.style.overflow = 'scroll'; } public layout(dimension: Dimension): void { From 7ba14a3925b91c9e91363a41bf9266deac2a371b Mon Sep 17 00:00:00 2001 From: Aditya Bist Date: Tue, 16 Oct 2018 22:51:54 -0700 Subject: [PATCH 4/5] schedules now get added in edit job (#2915) --- extensions/agent/package.json | 6 ------ extensions/agent/src/data/jobData.ts | 9 +++++++-- extensions/agent/src/data/pickScheduleData.ts | 7 ++++++- extensions/agent/src/dialogs/jobDialog.ts | 6 ++++-- extensions/agent/src/dialogs/pickScheduleDialog.ts | 4 ++-- extensions/agent/src/mainController.ts | 8 ++++---- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/extensions/agent/package.json b/extensions/agent/package.json index fbbb9541d7..dd2d7effe1 100644 --- a/extensions/agent/package.json +++ b/extensions/agent/package.json @@ -26,12 +26,6 @@ "outputChannels": [ "sqlagent" ], - "commands": [ - { - "command": "agent.openNewStepDialog", - "title": "agent.openNewStepDialog" - } - ], "dashboard.tabs": [ { "id": "data-management-agent", diff --git a/extensions/agent/src/data/jobData.ts b/extensions/agent/src/data/jobData.ts index ca16a07208..9f6f24cc87 100644 --- a/extensions/agent/src/data/jobData.ts +++ b/extensions/agent/src/data/jobData.ts @@ -136,8 +136,13 @@ export class JobData implements IAgentDialogData { } public addJobSchedule(schedule: sqlops.AgentJobScheduleInfo) { - let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name); - if (!existingSchedule) { + if (this.jobSchedules) { + let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name); + if (!existingSchedule) { + this.jobSchedules.push(schedule); + } + } else { + this.jobSchedules = []; this.jobSchedules.push(schedule); } } diff --git a/extensions/agent/src/data/pickScheduleData.ts b/extensions/agent/src/data/pickScheduleData.ts index 0192aa3176..15ad4c0f34 100644 --- a/extensions/agent/src/data/pickScheduleData.ts +++ b/extensions/agent/src/data/pickScheduleData.ts @@ -13,9 +13,11 @@ export class PickScheduleData implements IAgentDialogData { public ownerUri: string; public schedules: sqlops.AgentJobScheduleInfo[]; public selectedSchedule: sqlops.AgentJobScheduleInfo; + private jobName: string; - constructor(ownerUri:string) { + constructor(ownerUri:string, jobName: string) { this.ownerUri = ownerUri; + this.jobName = jobName; } public async initialize() { @@ -27,5 +29,8 @@ export class PickScheduleData implements IAgentDialogData { } public async save() { + let agentService = await AgentUtils.getAgentService(); + this.selectedSchedule.jobName = this.jobName; + let result = await agentService.createJobSchedule(this.ownerUri, this.selectedSchedule); } } diff --git a/extensions/agent/src/dialogs/jobDialog.ts b/extensions/agent/src/dialogs/jobDialog.ts index e77baa2261..bf3523daf1 100644 --- a/extensions/agent/src/dialogs/jobDialog.ts +++ b/extensions/agent/src/dialogs/jobDialog.ts @@ -108,12 +108,14 @@ export class JobDialog extends AgentDialog { // Alert tab controls private alertsTable: sqlops.TableComponent; private newAlertButton: sqlops.ButtonComponent; + private isEdit: boolean = false; constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) { super( ownerUri, new JobData(ownerUri, jobInfo), jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle); + this.isEdit = jobInfo ? true : false; } protected async initializeDialog() { @@ -373,12 +375,12 @@ export class JobDialog extends AgentDialog { label: this.PickScheduleButtonString, width: 80 }).component(); - this.pickScheduleButton.onDidClick((e)=>{ - let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri); + let pickScheduleDialog = new PickScheduleDialog(this.model.ownerUri, this.model.name); pickScheduleDialog.onSuccess((dialogModel) => { let selectedSchedule = dialogModel.selectedSchedule; if (selectedSchedule) { + selectedSchedule.jobName = this.model.name; this.model.addJobSchedule(selectedSchedule); this.populateScheduleTable(); } diff --git a/extensions/agent/src/dialogs/pickScheduleDialog.ts b/extensions/agent/src/dialogs/pickScheduleDialog.ts index 5fcd1ac1d1..91c5e23e98 100644 --- a/extensions/agent/src/dialogs/pickScheduleDialog.ts +++ b/extensions/agent/src/dialogs/pickScheduleDialog.ts @@ -33,8 +33,8 @@ export class PickScheduleDialog { private _onSuccess: vscode.EventEmitter = new vscode.EventEmitter(); public readonly onSuccess: vscode.Event = this._onSuccess.event; - constructor(ownerUri: string) { - this.model = new PickScheduleData(ownerUri); + constructor(ownerUri: string, jobName: string) { + this.model = new PickScheduleData(ownerUri, jobName); } public async showDialog() { diff --git a/extensions/agent/src/mainController.ts b/extensions/agent/src/mainController.ts index d7f6b3fde4..af10fa01be 100644 --- a/extensions/agent/src/mainController.ts +++ b/extensions/agent/src/mainController.ts @@ -41,12 +41,12 @@ export class MainController { let dialog = new JobDialog(ownerUri, jobInfo); dialog.openDialog(); }); - vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobData: JobData) => { - let dialog = new JobStepDialog(ownerUri, server, jobData); + vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobData: JobData, jobStepInfo: sqlops.AgentJobStepInfo) => { + let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo); dialog.openDialog(); }); - vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string) => { - let dialog = new PickScheduleDialog(ownerUri); + vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string, jobName: string) => { + let dialog = new PickScheduleDialog(ownerUri, jobName); dialog.showDialog(); }); vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, alertInfo: sqlops.AgentAlertInfo, jobs: string[]) => { From ac47fb84a84974f575822d14af61b8516b9529aa Mon Sep 17 00:00:00 2001 From: Chris LaFreniere <40371649+chlafreniere@users.noreply.github.com> Date: Wed, 17 Oct 2018 10:18:04 -0700 Subject: [PATCH 5/5] Fix Default Height for Editor Component (#2920) Editor component didn't have a minimum height set, so fixing this by passing through a minimum height to EditorComponent. Now, if the scrollable height of the editor is less than the minimum height, we use the minimum height as the height of the component. Also fixed an issue where the markdown code editor's height was far too high. Now we're calculating the height on the layout() call, which gets called every time we display the markdown editor. --- .../parts/modelComponents/editor.component.ts | 16 +++++++++++++++- src/sql/parts/modelComponents/queryTextEditor.ts | 8 +++++++- src/sql/sqlops.proposed.d.ts | 9 +++++++++ src/sql/workbench/api/node/extHostModelView.ts | 8 ++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/sql/parts/modelComponents/editor.component.ts b/src/sql/parts/modelComponents/editor.component.ts index cf1dc2c852..d42a8a8929 100644 --- a/src/sql/parts/modelComponents/editor.component.ts +++ b/src/sql/parts/modelComponents/editor.component.ts @@ -39,6 +39,7 @@ export default class EditorComponent extends ComponentBase implements IComponent private _languageMode: string; private _uri: string; private _isAutoResizable: boolean; + private _minimumHeight: number; constructor( @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef, @@ -79,6 +80,9 @@ export default class EditorComponent extends ComponentBase implements IComponent this._register(this._editorModel.onDidChangeContent(e => { this.content = this._editorModel.getValue(); if (this._isAutoResizable) { + if (this._minimumHeight) { + this._editor.setMinimumHeight(this._minimumHeight); + } this._editor.setHeightToScrollHeight(); } @@ -109,7 +113,8 @@ export default class EditorComponent extends ComponentBase implements IComponent let height: number = this.convertSizeToNumber(this.height); if (this._isAutoResizable) { - height = this._editor.scrollHeight; + this._editor.setHeightToScrollHeight(); + height = Math.max(this._editor.scrollHeight, this._minimumHeight ? this._minimumHeight : 0); } this._editor.layout(new DOM.Dimension( width && width > 0 ? width : DOM.getContentWidth(this._el.nativeElement), @@ -152,6 +157,7 @@ export default class EditorComponent extends ComponentBase implements IComponent // Intentionally always updating editorUri as it's wiped out by parent setProperties call. this.editorUri = this._uri; this._isAutoResizable = this.isAutoResizable; + this._minimumHeight = this.minimumHeight; } // CSS-bound properties @@ -179,6 +185,14 @@ export default class EditorComponent extends ComponentBase implements IComponent this.setPropertyFromUI((properties, isAutoResizable) => { properties.isAutoResizable = isAutoResizable; }, newValue); } + public get minimumHeight(): number { + return this.getPropertyOrDefault((props) => props.minimumHeight, this._editor.minimumHeight); + } + + public set minimumHeight(newValue: number) { + this.setPropertyFromUI((properties, minimumHeight) => { properties.minimumHeight = minimumHeight; }, newValue); + } + public get editorUri(): string { return this.getPropertyOrDefault((props) => props.editorUri, ''); } diff --git a/src/sql/parts/modelComponents/queryTextEditor.ts b/src/sql/parts/modelComponents/queryTextEditor.ts index 15017de2cb..f18e2ed6b6 100644 --- a/src/sql/parts/modelComponents/queryTextEditor.ts +++ b/src/sql/parts/modelComponents/queryTextEditor.ts @@ -34,6 +34,7 @@ export class QueryTextEditor extends BaseTextEditor { public static ID = 'modelview.editors.textEditor'; private _dimension: DOM.Dimension; private _config: editorCommon.IConfiguration; + private _minHeight: number; constructor( @ITelemetryService telemetryService: ITelemetryService, @IInstantiationService instantiationService: IInstantiationService, @@ -116,6 +117,11 @@ export class QueryTextEditor extends BaseTextEditor { this._config = new Configuration(undefined, editorWidget.getDomNode()); } let editorHeightUsingLines = this._config.editor.lineHeight * editorWidget.getModel().getLineCount(); - this.setHeight(editorHeightUsingLines); + let editorHeightUsingMinHeight = Math.max(editorHeightUsingLines, this._minHeight); + this.setHeight(editorHeightUsingMinHeight); + } + + public setMinimumHeight(height: number) : void { + this._minHeight = height; } } diff --git a/src/sql/sqlops.proposed.d.ts b/src/sql/sqlops.proposed.d.ts index 3e830bd80d..0989c95ee9 100644 --- a/src/sql/sqlops.proposed.d.ts +++ b/src/sql/sqlops.proposed.d.ts @@ -595,6 +595,10 @@ declare module 'sqlops' { * The languge mode for this text editor. The language mode is SQL by default. */ languageMode?: string; + /** + * Minimum height for editor component + */ + minimumHeight?: number; } export interface ButtonProperties extends ComponentProperties, ComponentWithIcon { @@ -722,6 +726,11 @@ declare module 'sqlops' { */ isAutoResizable: boolean; + /** + * Minimum height for editor component + */ + minimumHeight: number; + } export interface ButtonComponent extends Component, ButtonProperties { diff --git a/src/sql/workbench/api/node/extHostModelView.ts b/src/sql/workbench/api/node/extHostModelView.ts index fd4bbfbee0..314110c367 100644 --- a/src/sql/workbench/api/node/extHostModelView.ts +++ b/src/sql/workbench/api/node/extHostModelView.ts @@ -913,6 +913,14 @@ class EditorWrapper extends ComponentWrapper implements sqlops.EditorComponent { this.setProperty('isAutoResizable', v); } + public get minimumHeight(): number { + return this.properties['minimumHeight']; + } + + public set minimumHeight(v: number) { + this.setProperty('minimumHeight', v); + } + public get onContentChanged(): vscode.Event { let emitter = this._emitterMap.get(ComponentEventType.onDidChange); return emitter && emitter.event;