From 8c090dc2dae7d6d50f9a09861f42a960e60eed5d Mon Sep 17 00:00:00 2001 From: ssreerama Date: Fri, 14 Jul 2023 16:29:24 -0700 Subject: [PATCH 01/80] initial changes for loadin dsc table with real values from smo --- .../mssql/src/objectManagement/constants.ts | 1 + .../mssql/src/objectManagement/interfaces.ts | 8 +++ .../objectManagement/localizedConstants.ts | 6 +- .../objectManagementService.ts | 19 +++++- .../src/objectManagement/ui/databaseDialog.ts | 59 ++++++++++++++++++- 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/extensions/mssql/src/objectManagement/constants.ts b/extensions/mssql/src/objectManagement/constants.ts index 2e8c5f641732..0f66a13fe8c0 100644 --- a/extensions/mssql/src/objectManagement/constants.ts +++ b/extensions/mssql/src/objectManagement/constants.ts @@ -33,6 +33,7 @@ export const ViewMemoryServerPropertiesDocUrl = 'https://learn.microsoft.com/sql export const DetachDatabaseDocUrl = 'https://go.microsoft.com/fwlink/?linkid=2240322'; export const DatabaseGeneralPropertiesDocUrl = 'https://learn.microsoft.com/sql/relational-databases/databases/database-properties-general-page'; export const DatabaseOptionsPropertiesDocUrl = 'https://learn.microsoft.com/sql/relational-databases/databases/database-properties-options-page' +export const DatabaseScopedConfigurationPropertiesDocUrl = 'https://learn.microsoft.com/sql/t-sql/statements/alter-database-scoped-configuration-transact-sql' export const enum TelemetryActions { CreateObject = 'CreateObject', diff --git a/extensions/mssql/src/objectManagement/interfaces.ts b/extensions/mssql/src/objectManagement/interfaces.ts index d9b40ea05b9f..519d6f8f6813 100644 --- a/extensions/mssql/src/objectManagement/interfaces.ts +++ b/extensions/mssql/src/objectManagement/interfaces.ts @@ -454,6 +454,7 @@ export interface Database extends ObjectManagement.SqlObject { databaseReadOnly?: boolean; encryptionEnabled: boolean; restrictAccess?: string; + databaseScopedConfigurations: DatabaseScopedConfigurationsInfo[]; } export interface DatabaseViewInfo extends ObjectManagement.ObjectViewInfo { @@ -472,6 +473,13 @@ export interface DatabaseViewInfo extends ObjectManagement.ObjectViewInfo{ + collationNames: ['Latin1_General_100_CI_AS_KS_WS', 'Latin1_General_100_CI_AS_KS_WS_SC'], + compatibilityLevels: ['SQL Server 2008', 'SQL Server 2012', 'SQL Server 2014', 'SQL Server 2016', 'SQL Server 2017', 'SQL Server 2019'], + containmentTypes: ['NONE', 'PARTIAL'], + restrictAccessOptions: ['MULTI_USER', 'RESTRICTED_USER', 'SINGLE_USER'], + pageVerifyOptions: ['CHECKSUM', 'NONE', 'TORN_PAGE_DETECTION'], + recoveryModels: ['FULL', 'SIMPLE', 'BULK_LOGGED'], objectInfo: { name: 'Database Properties1', collationName: 'Latin1_General_100_CI_AS_KS_WS', @@ -482,8 +488,19 @@ export class TestObjectManagementService implements IObjectManagementService { databaseReadOnly: true, encryptionEnabled: false, restrictAccess: 'SINGLE_USER', + databaseScopedConfigurations: [ + { name: 'MAXDOP', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, + { name: 'legacy_cardinality_estimation', isDefaultValue: false, valueForPrimary: '', valueForSecondary: '' }, + { name: 'parameter_sniffing', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, + { name: 'query_optimizer_hotfixes', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, + { name: 'identity_cache', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, + { name: 'interleaved_execution_tvf', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, + { name: 'batch_mode_memory_grant_feedback', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, + { name: 'batch_mode_adaptive_joins', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, + { name: 'tsql_scalar_udf_inlining', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' } + ] } - }; + } } private delayAndResolve(obj?: any): Promise { diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index 700de130a980..77939b9faef2 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -5,10 +5,10 @@ import * as azdata from 'azdata'; import { ObjectManagementDialogBase, ObjectManagementDialogOptions } from './objectManagementDialogBase'; -import { DefaultInputWidth } from '../../ui/dialogBase'; +import { DefaultInputWidth, DefaultTableWidth, getTableHeight } from '../../ui/dialogBase'; import { IObjectManagementService } from 'mssql'; import * as localizedConstants from '../localizedConstants'; -import { CreateDatabaseDocUrl, DatabaseGeneralPropertiesDocUrl, DatabaseOptionsPropertiesDocUrl } from '../constants'; +import { CreateDatabaseDocUrl, DatabaseGeneralPropertiesDocUrl, DatabaseOptionsPropertiesDocUrl, DatabaseScopedConfigurationPropertiesDocUrl } from '../constants'; import { Database, DatabaseViewInfo } from '../interfaces'; import { convertNumToTwoDecimalStringInMB } from '../utils'; import { isUndefinedOrNull } from '../../types'; @@ -17,6 +17,7 @@ export class DatabaseDialog extends ObjectManagementDialogBase { + return [ + metaData.name, + metaData.isDefaultValue, + metaData.valueForPrimary, + metaData.valueForSecondary] + }), + height: getTableHeight(this.objectInfo.databaseScopedConfigurations.length, 1, 15), + width: DefaultTableWidth + }).component(); + + this.dscTabSectionsContainer.push(this.createGroup('', [this.dscTable], true)); + } + private initializeConfigureSLOSection(): azdata.GroupContainer { let containers: azdata.Component[] = []; if (this.viewInfo.azureEditions?.length > 0) { From d599463a735f2502ccba5fe3413447d3d85efe1d Mon Sep 17 00:00:00 2001 From: ssreerama Date: Mon, 17 Jul 2023 13:23:32 -0700 Subject: [PATCH 02/80] Displaying diff columns for DSC for diff sql server --- .../mssql/src/objectManagement/interfaces.ts | 2 +- .../src/objectManagement/ui/databaseDialog.ts | 56 ++++++++++++------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/extensions/mssql/src/objectManagement/interfaces.ts b/extensions/mssql/src/objectManagement/interfaces.ts index 519d6f8f6813..827676680a3e 100644 --- a/extensions/mssql/src/objectManagement/interfaces.ts +++ b/extensions/mssql/src/objectManagement/interfaces.ts @@ -475,7 +475,7 @@ export interface DatabaseViewInfo extends ObjectManagement.ObjectViewInfo 0 && this.objectInfo.databaseScopedConfigurations[0].isDefaultValue !== null; + const dscNameColumn: azdata.TableColumn = { + type: azdata.ColumnType.text, + value: localizedConstants.DatabaseScopedOptionsColumnHeader, + width: isValueDefaultAvailable ? 169 : 200 + }; + const isValueDefaultColumn: azdata.TableColumn = { + type: azdata.ColumnType.checkBox, + value: localizedConstants.IsDefaultValueColumnHeader, + width: 84 + }; + const primaryValueColumn: azdata.TableColumn = { + type: azdata.ColumnType.text, + value: localizedConstants.ValueForPrimaryColumnHeader, + width: isValueDefaultAvailable ? 92 : 125 + }; + const secondaryValueColumn: azdata.TableColumn = { + type: azdata.ColumnType.text, + value: localizedConstants.ValueForSecondaryColumnHeader, + width: isValueDefaultAvailable ? 106 : 125 + }; + let dscTableColumns: azdata.TableColumn[] = [dscNameColumn, isValueDefaultColumn, primaryValueColumn, secondaryValueColumn]; + + // isDefaultValue property is not supported for all the database scoped configurations in case of SQL Server 2016 and below + if (!isValueDefaultAvailable) { + dscTableColumns = [dscNameColumn, primaryValueColumn, secondaryValueColumn] + } this.dscTable = this.modelView.modelBuilder.table().withProps({ - columns: - [{ - type: azdata.ColumnType.text, - value: localizedConstants.DatabaseScopedOptionsColumnHeader - }, { - type: azdata.ColumnType.checkBox, - value: localizedConstants.IsDefaultValueColumnHeader, - width: 84 - }, { - type: azdata.ColumnType.text, - value: localizedConstants.ValueForPrimaryColumnHeader, - width: 92 - }, { - type: azdata.ColumnType.text, - value: localizedConstants.ValueForSecondaryColumnHeader, - width: 106 - }], + columns: dscTableColumns, data: this.objectInfo.databaseScopedConfigurations.map(metaData => { - return [ + return isValueDefaultAvailable ? [ metaData.name, metaData.isDefaultValue, metaData.valueForPrimary, - metaData.valueForSecondary] + metaData.valueForSecondary] : [ + metaData.name, + metaData.valueForPrimary, + metaData.valueForSecondary + ] }), height: getTableHeight(this.objectInfo.databaseScopedConfigurations.length, 1, 15), - width: DefaultTableWidth + width: DefaultTableWidth + 10 }).component(); this.dscTabSectionsContainer.push(this.createGroup('', [this.dscTable], true)); From 874c8e296dea1432bb3a1c6e22a90b02708d286a Mon Sep 17 00:00:00 2001 From: ssreerama Date: Wed, 19 Jul 2023 10:03:43 -0700 Subject: [PATCH 03/80] checkbox maiants the selection --- .../mssql/src/objectManagement/interfaces.ts | 4 ++ .../objectManagement/localizedConstants.ts | 13 ++-- .../src/objectManagement/ui/databaseDialog.ts | 63 +++++++++++++++++-- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/extensions/mssql/src/objectManagement/interfaces.ts b/extensions/mssql/src/objectManagement/interfaces.ts index 827676680a3e..9936f133fb55 100644 --- a/extensions/mssql/src/objectManagement/interfaces.ts +++ b/extensions/mssql/src/objectManagement/interfaces.ts @@ -471,6 +471,9 @@ export interface DatabaseViewInfo extends ObjectManagement.ObjectViewInfo { const isValueDefaultAvailable = this.objectInfo.databaseScopedConfigurations.length > 0 && this.objectInfo.databaseScopedConfigurations[0].isDefaultValue !== null; const dscNameColumn: azdata.TableColumn = { type: azdata.ColumnType.text, @@ -471,8 +476,58 @@ export class DatabaseDialog extends ObjectManagementDialogBase { + await this.valuesContainerGroup.updateCssStyles({ 'visibility': 'visible' }); + const row = this.dscTable.data[this.dscTable.selectedRows[0]]; + + // Update the primary and secondary dropdown options based on the selected database scoped configuration + if (row[0] === localizedConstants.ELEVATE_ONLINE_DSC_OptionText || row[0] === localizedConstants.ELEVATE_RESUMABLE_DSC_OptionText) { + this.valueForPrimaryInput.values = this.viewInfo.dscElevateOptions; + this.valueForSecondaryInput.values = []; + } else { + this.valueForPrimaryInput.values = this.viewInfo.dscOnOffOptions; + this.valueForSecondaryInput.values = this.viewInfo.dscOnOffPrimaryOptions; + } + + // Update the values of primary and secondary dropdowns based on the selected database scoped configuration + this.valueForPrimaryInput.value = isValueDefaultAvailable ? row[2] : row[1]; + this.valueForSecondaryInput.value = isValueDefaultAvailable ? row[3] : row[2]; + this.currentRowId = this.dscTable.selectedRows[0]; + this.setSecondaryCheckbox.checked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary; + } + ) + ); + } + + private async updateValuesSectionGroup(): Promise { + let containers: azdata.Component[] = []; + this.valueForPrimaryInput = this.createDropdown(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { + // this.objectInfo = newValue; + }, this.viewInfo.dscOnOffOptions, '', true, 150) + containers.push(this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForPrimaryInput)); + + this.setSecondaryCheckbox = this.createCheckbox(localizedConstants.SetSecondaryText, async (checked) => { + // Disable secondary dropdown and apply PRIMARY value as selected value + this.valueForSecondaryInput.enabled = !checked; + this.valueForSecondaryInput.value = this.viewInfo.dscOnOffPrimaryOptions[2]; + this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary = checked; + }, false); + containers.push(this.createLabelInputContainer(localizedConstants.SetSecondaryText, this.setSecondaryCheckbox)); + + this.valueForSecondaryInput = this.createDropdown(localizedConstants.ValueForSecondaryColumnHeader, async (newValue) => { + // this.objectInfo.restrictAccess = newValue; + }, this.viewInfo.dscOnOffPrimaryOptions, '', true, 150); + containers.push(this.createLabelInputContainer(localizedConstants.ValueForSecondaryColumnHeader, this.valueForSecondaryInput)); + + this.valuesContainerGroup = this.createGroup('', containers, true, true); + await this.valuesContainerGroup.updateCssStyles({ 'visibility': 'hidden' }); + + return this.valuesContainerGroup; } + // #endregion private initializeConfigureSLOSection(): azdata.GroupContainer { let containers: azdata.Component[] = []; From 57637907c2c1aff6ccba8f0e35f0c6a73a087f57 Mon Sep 17 00:00:00 2001 From: ssreerama Date: Wed, 19 Jul 2023 20:37:54 -0700 Subject: [PATCH 04/80] elevate option fails to load correct value when set to when_supported option --- .../objectManagement/localizedConstants.ts | 2 + .../src/objectManagement/ui/databaseDialog.ts | 82 +++++++++++-------- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/extensions/mssql/src/objectManagement/localizedConstants.ts b/extensions/mssql/src/objectManagement/localizedConstants.ts index b502f6bf40df..fd79a9b46379 100644 --- a/extensions/mssql/src/objectManagement/localizedConstants.ts +++ b/extensions/mssql/src/objectManagement/localizedConstants.ts @@ -302,6 +302,8 @@ export const ValueForSecondaryColumnHeader = localize('objectManagement.database export const SetSecondaryText = localize('objectManagement.databaseProperties.setSecondaryText', "Set Secondary same as Primary"); export const ELEVATE_ONLINE_DSC_OptionText = localize('objectManagement.databaseProperties.elevate_online_dsc_option', "ELEVATE_ONLINE"); export const ELEVATE_RESUMABLE_DSC_OptionText = localize('objectManagement.databaseProperties.elevate_resumable_dsc_option', "ELEVATE_RESUMABLE"); +export const MAXDOP = localize('objectManagement.databaseProperties.maxdop', "MAXDOP"); +export const IDENTITY_CACHE = localize('objectManagement.databaseProperties.identity_cache', "IDENTITY_CACHE"); // Util functions export function getNodeTypeDisplayName(type: string, inTitle: boolean = false): string { diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index ad02ba3cc41f..06b37c3d8d42 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -9,7 +9,7 @@ import { DefaultInputWidth, DefaultTableWidth, getTableHeight } from '../../ui/d import { IObjectManagementService } from 'mssql'; import * as localizedConstants from '../localizedConstants'; import { CreateDatabaseDocUrl, DatabaseGeneralPropertiesDocUrl, DatabaseOptionsPropertiesDocUrl, DatabaseScopedConfigurationPropertiesDocUrl } from '../constants'; -import { Database, DatabaseViewInfo, DatabaseScopedConfigurationsInfo } from '../interfaces'; +import { Database, DatabaseViewInfo } from '../interfaces'; import { convertNumToTwoDecimalStringInMB } from '../utils'; import { isUndefinedOrNull } from '../../types'; @@ -59,6 +59,7 @@ export class DatabaseDialog extends ObjectManagementDialogBase { - const isValueDefaultAvailable = this.objectInfo.databaseScopedConfigurations.length > 0 && this.objectInfo.databaseScopedConfigurations[0].isDefaultValue !== null; + this.isValueDefaultAvailable = this.objectInfo.databaseScopedConfigurations.length > 0 && !isUndefinedOrNull(this.objectInfo.databaseScopedConfigurations[0].isDefaultValue) const dscNameColumn: azdata.TableColumn = { type: azdata.ColumnType.text, value: localizedConstants.DatabaseScopedOptionsColumnHeader, - width: isValueDefaultAvailable ? 169 : 200 + width: this.isValueDefaultAvailable ? 169 : 200 }; const isValueDefaultColumn: azdata.TableColumn = { type: azdata.ColumnType.checkBox, @@ -446,31 +447,25 @@ export class DatabaseDialog extends ObjectManagementDialogBase { - return isValueDefaultAvailable ? [ - metaData.name, - metaData.isDefaultValue, - metaData.valueForPrimary, - metaData.valueForSecondary] : [ - metaData.name, - metaData.valueForPrimary, - metaData.valueForSecondary - ] + return this.isValueDefaultAvailable + ? [metaData.name, metaData.isDefaultValue, metaData.valueForPrimary, metaData.valueForSecondary] + : [metaData.name, metaData.valueForPrimary, metaData.valueForSecondary] }), height: getTableHeight(this.objectInfo.databaseScopedConfigurations.length, 1, 15), width: DefaultTableWidth + 10 @@ -481,52 +476,73 @@ export class DatabaseDialog extends ObjectManagementDialogBase { await this.valuesContainerGroup.updateCssStyles({ 'visibility': 'visible' }); + this.currentRowId = this.dscTable.selectedRows[0]; const row = this.dscTable.data[this.dscTable.selectedRows[0]]; + // Update the values of primary and secondary dropdown based on the selected database scoped configuration + this.valueForPrimaryInput.value = this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary; + this.valueForSecondaryInput.value = this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary; + this.setSecondaryCheckbox.checked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary; + // Update the primary and secondary dropdown options based on the selected database scoped configuration if (row[0] === localizedConstants.ELEVATE_ONLINE_DSC_OptionText || row[0] === localizedConstants.ELEVATE_RESUMABLE_DSC_OptionText) { this.valueForPrimaryInput.values = this.viewInfo.dscElevateOptions; this.valueForSecondaryInput.values = []; + } else if (row[0] === localizedConstants.MAXDOP) { + this.valueForSecondaryInput.values = [this.viewInfo.dscOnOffPrimaryOptions[2]]; + } else if (row[0] === localizedConstants.IDENTITY_CACHE) { + this.valueForPrimaryInput.values = this.viewInfo.dscOnOffOptions; + this.valueForSecondaryInput.values = []; } else { this.valueForPrimaryInput.values = this.viewInfo.dscOnOffOptions; this.valueForSecondaryInput.values = this.viewInfo.dscOnOffPrimaryOptions; } - - // Update the values of primary and secondary dropdowns based on the selected database scoped configuration - this.valueForPrimaryInput.value = isValueDefaultAvailable ? row[2] : row[1]; - this.valueForSecondaryInput.value = isValueDefaultAvailable ? row[3] : row[2]; - this.currentRowId = this.dscTable.selectedRows[0]; - this.setSecondaryCheckbox.checked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary; } ) ); } private async updateValuesSectionGroup(): Promise { - let containers: azdata.Component[] = []; + // Value for Primary this.valueForPrimaryInput = this.createDropdown(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { - // this.objectInfo = newValue; - }, this.viewInfo.dscOnOffOptions, '', true, 150) - containers.push(this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForPrimaryInput)); + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue as string; + this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 2 : 1] = newValue; + await this.updateDscTable(this.dscTable.data); + }, [], '', true, 150) + const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForPrimaryInput); + // Apply Primary To Secondary checkbox this.setSecondaryCheckbox = this.createCheckbox(localizedConstants.SetSecondaryText, async (checked) => { // Disable secondary dropdown and apply PRIMARY value as selected value this.valueForSecondaryInput.enabled = !checked; this.valueForSecondaryInput.value = this.viewInfo.dscOnOffPrimaryOptions[2]; + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = this.viewInfo.dscOnOffPrimaryOptions[2]; this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary = checked; + await this.updateDscTable(this.dscTable.data); }, false); - containers.push(this.createLabelInputContainer(localizedConstants.SetSecondaryText, this.setSecondaryCheckbox)); + const applyPrimaryToSecondaryContainer = this.createLabelInputContainer(localizedConstants.SetSecondaryText, this.setSecondaryCheckbox); + // Value for Secondary this.valueForSecondaryInput = this.createDropdown(localizedConstants.ValueForSecondaryColumnHeader, async (newValue) => { - // this.objectInfo.restrictAccess = newValue; - }, this.viewInfo.dscOnOffPrimaryOptions, '', true, 150); - containers.push(this.createLabelInputContainer(localizedConstants.ValueForSecondaryColumnHeader, this.valueForSecondaryInput)); + if (!isUndefinedOrNull(newValue)) { + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = newValue as string; + this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 3 : 2] = newValue; + await this.updateDscTable(this.dscTable.data); + } + }, [], '', true, 150); + const secondaryContainer = this.createLabelInputContainer(localizedConstants.ValueForSecondaryColumnHeader, this.valueForSecondaryInput); - this.valuesContainerGroup = this.createGroup('', containers, true, true); + this.valuesContainerGroup = this.createGroup('', [primaryContainer, applyPrimaryToSecondaryContainer, secondaryContainer], true, true); await this.valuesContainerGroup.updateCssStyles({ 'visibility': 'hidden' }); return this.valuesContainerGroup; } + + private async updateDscTable(data: any[][]): Promise { + await this.dscTable.updateProperties({ + 'data': data + }); + } // #endregion private initializeConfigureSLOSection(): azdata.GroupContainer { From cd2ca3f5c31580cfea448d6d46de629415d3c95d Mon Sep 17 00:00:00 2001 From: ssreerama Date: Thu, 20 Jul 2023 14:12:33 -0700 Subject: [PATCH 05/80] all working till maxdop, todo pause option, save --- .../mssql/src/objectManagement/interfaces.ts | 1 + .../objectManagement/localizedConstants.ts | 3 + .../src/objectManagement/ui/databaseDialog.ts | 128 ++++++++++++++---- 3 files changed, 108 insertions(+), 24 deletions(-) diff --git a/extensions/mssql/src/objectManagement/interfaces.ts b/extensions/mssql/src/objectManagement/interfaces.ts index 9936f133fb55..817611f24def 100644 --- a/extensions/mssql/src/objectManagement/interfaces.ts +++ b/extensions/mssql/src/objectManagement/interfaces.ts @@ -474,6 +474,7 @@ export interface DatabaseViewInfo extends ObjectManagement.ObjectViewInfo { - await this.valuesContainerGroup.updateCssStyles({ 'visibility': 'visible' }); this.currentRowId = this.dscTable.selectedRows[0]; const row = this.dscTable.data[this.dscTable.selectedRows[0]]; // Update the values of primary and secondary dropdown based on the selected database scoped configuration - this.valueForPrimaryInput.value = this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary; - this.valueForSecondaryInput.value = this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary; this.setSecondaryCheckbox.checked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary; - - // Update the primary and secondary dropdown options based on the selected database scoped configuration - if (row[0] === localizedConstants.ELEVATE_ONLINE_DSC_OptionText || row[0] === localizedConstants.ELEVATE_RESUMABLE_DSC_OptionText) { - this.valueForPrimaryInput.values = this.viewInfo.dscElevateOptions; - this.valueForSecondaryInput.values = []; - } else if (row[0] === localizedConstants.MAXDOP) { - this.valueForSecondaryInput.values = [this.viewInfo.dscOnOffPrimaryOptions[2]]; - } else if (row[0] === localizedConstants.IDENTITY_CACHE) { - this.valueForPrimaryInput.values = this.viewInfo.dscOnOffOptions; - this.valueForSecondaryInput.values = []; - } else { - this.valueForPrimaryInput.values = this.viewInfo.dscOnOffOptions; - this.valueForSecondaryInput.values = this.viewInfo.dscOnOffPrimaryOptions; - } + await this.validateUpdateToggleDscPrimaryAndSecondaryOptions(row); } ) ); } - private async updateValuesSectionGroup(): Promise { + /** + * Validating the selected database scoped configuration and updating the primary and secondary dropdown options and their selected values + * @param row selected row in the database scoped configuration table + */ + private async validateUpdateToggleDscPrimaryAndSecondaryOptions(row: any[]): Promise { + // Update the primary and secondary dropdown options based on the selected database scoped configuration + // + // Elevate online and Elevate resumable options have diff set of drodpdown options and do not support secondary value update + if (row[0] === localizedConstants.ELEVATE_ONLINE_DSC_OptionText || row[0] === localizedConstants.ELEVATE_RESUMABLE_DSC_OptionText) { + await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.valueForPrimaryInput.updateProperties({ + values: this.viewInfo.dscElevateOptions + , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary + }); + await this.valueForSecondaryInput.updateProperties({ values: [], value: undefined }); + } + // MAXDOP option accepts both number and 'OFF' as primary values, and secondary value accepts only PRIMARY as value + else if (row[0] === localizedConstants.MAXDOP) { + await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.valueForSecondaryInput.updateProperties({ + values: this.viewInfo.dscOnOffPrimaryOptions[2] + , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary + }); + } + // Identity cache option accepts only primary value updates, and do not support secondary value update + else if (row[0] === localizedConstants.IDENTITY_CACHE) { + await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.valueForPrimaryInput.updateProperties({ + values: this.viewInfo.dscOnOffOptions + , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary + }); + await this.valueForSecondaryInput.updateProperties({ values: [], value: undefined }); + } + // DW compatibily level options accepts 1(Enabled) or 0(Disabled) values as primary and secondary values + else if (row[0] === localizedConstants.DW_COMPATIBILITY_LEVEL) { + await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); + await this.valueForPrimaryInput.updateProperties({ + values: this.viewInfo.dscEnableDisableOptions + , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary + }); + await this.valueForSecondaryInput.updateProperties({ + values: [this.viewInfo.dscEnableDisableOptions[0], this.viewInfo.dscEnableDisableOptions[1], this.viewInfo.dscOnOffPrimaryOptions[2]] + , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary + }); + } + // All other options accepts primary and seconday values as ON/OFF/PRIMARY(only secondary) + else { + await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); + await this.valueForPrimaryInput.updateProperties({ + values: this.viewInfo.dscOnOffOptions + , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary + }); + await this.valueForSecondaryInput.updateProperties({ + values: this.viewInfo.dscOnOffPrimaryOptions + , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary + }); + } + } + + /** + * Max limt for the MAXDOP primary value is a 16bit signed integer - 32767 + * @returns GroupContainer for MAXDOP primary value + */ + private async InitilaizeDscMaxDopPrimarySection(): Promise { + this.valueForMaxDopPrimaryInput = this.createInputBox(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue as string; + this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 2 : 1] = newValue; + await this.updateDscTable(this.dscTable.data); + }, '', true, 'number', DefaultInputWidth - 17, true, 0, 32767); + const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForMaxDopPrimaryInput); + + this.dscMaxDopPrimaryValueGroup = this.createGroup('', [primaryContainer], true, true); + await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'margin': '-160px 0px 0px -8px' }); + + return this.dscMaxDopPrimaryValueGroup; + } + + private async InitializeDscPrimaryValueGroup(): Promise { // Value for Primary this.valueForPrimaryInput = this.createDropdown(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue as string; @@ -511,6 +584,13 @@ export class DatabaseDialog extends ObjectManagementDialogBase { // Apply Primary To Secondary checkbox this.setSecondaryCheckbox = this.createCheckbox(localizedConstants.SetSecondaryText, async (checked) => { // Disable secondary dropdown and apply PRIMARY value as selected value @@ -532,10 +612,10 @@ export class DatabaseDialog extends ObjectManagementDialogBase { From 0cedabf64abcb4bf36d2b738ca8f55a94e1b20ca Mon Sep 17 00:00:00 2001 From: ssreerama Date: Fri, 21 Jul 2023 15:20:12 -0700 Subject: [PATCH 06/80] commented MAXDOP changes, as it is causing issues --- .../src/objectManagement/ui/databaseDialog.ts | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index 9e1ba1685b2a..b0a4463c9e48 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -473,15 +473,16 @@ export class DatabaseDialog extends ObjectManagementDialogBase { this.currentRowId = this.dscTable.selectedRows[0]; const row = this.dscTable.data[this.dscTable.selectedRows[0]]; - // Update the values of primary and secondary dropdown based on the selected database scoped configuration - this.setSecondaryCheckbox.checked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary; await this.validateUpdateToggleDscPrimaryAndSecondaryOptions(row); } ) @@ -494,12 +495,13 @@ export class DatabaseDialog extends ObjectManagementDialogBase { // Update the primary and secondary dropdown options based on the selected database scoped configuration - // + this.setSecondaryCheckbox.checked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary; + // TODO:await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'inline !important' }); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important' }); // Elevate online and Elevate resumable options have diff set of drodpdown options and do not support secondary value update if (row[0] === localizedConstants.ELEVATE_ONLINE_DSC_OptionText || row[0] === localizedConstants.ELEVATE_RESUMABLE_DSC_OptionText) { - await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); - await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); - await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible', 'display': 'inline !important' }); await this.valueForPrimaryInput.updateProperties({ values: this.viewInfo.dscElevateOptions , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary @@ -507,20 +509,17 @@ export class DatabaseDialog extends ObjectManagementDialogBase { - this.valueForMaxDopPrimaryInput = this.createInputBox(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { - this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue as string; - this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 2 : 1] = newValue; - await this.updateDscTable(this.dscTable.data); - }, '', true, 'number', DefaultInputWidth - 17, true, 0, 32767); - const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForMaxDopPrimaryInput); - - this.dscMaxDopPrimaryValueGroup = this.createGroup('', [primaryContainer], true, true); - await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'margin': '-160px 0px 0px -8px' }); - - return this.dscMaxDopPrimaryValueGroup; - } + // private async InitilaizeDscMaxDopPrimarySection(): Promise { + // this.valueForMaxDopPrimaryInput = this.createInputBox(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { + // if (this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary !== newValue) { + // this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue; + // this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 2 : 1] = newValue; + // await this.updateDscTable(this.dscTable.data); + // } + // }, '', true, 'number', DefaultInputWidth - 17, true, 0, 32767); + // const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForMaxDopPrimaryInput); + + // this.dscMaxDopPrimaryValueGroup = this.createGroup('', [primaryContainer], true, true); + // await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important', 'margin-top': '-132px' }); + + // return this.dscMaxDopPrimaryValueGroup; + // } private async InitializeDscPrimaryValueGroup(): Promise { // Value for Primary @@ -585,7 +584,7 @@ export class DatabaseDialog extends ObjectManagementDialogBase { @@ -613,7 +612,7 @@ export class DatabaseDialog extends ObjectManagementDialogBase Date: Mon, 24 Jul 2023 13:26:17 -0700 Subject: [PATCH 07/80] primary,sec,checkbox working as expected, TODO:MaxDop etc options,saving,tests --- .../mssql/src/objectManagement/interfaces.ts | 3 - .../objectManagement/localizedConstants.ts | 2 +- .../src/objectManagement/ui/databaseDialog.ts | 122 ++++++++++-------- 3 files changed, 69 insertions(+), 58 deletions(-) diff --git a/extensions/mssql/src/objectManagement/interfaces.ts b/extensions/mssql/src/objectManagement/interfaces.ts index 817611f24def..ff61654b7410 100644 --- a/extensions/mssql/src/objectManagement/interfaces.ts +++ b/extensions/mssql/src/objectManagement/interfaces.ts @@ -471,7 +471,6 @@ export interface DatabaseViewInfo extends ObjectManagement.ObjectViewInfo { // Database Properties tabs @@ -54,15 +55,17 @@ export class DatabaseDialog extends ObjectManagementDialogBase { - this.isValueDefaultAvailable = this.objectInfo.databaseScopedConfigurations.length > 0 && !isUndefinedOrNull(this.objectInfo.databaseScopedConfigurations[0].isDefaultValue) + this.dscOriginalData = deepClone(this.objectInfo.databaseScopedConfigurations); const dscNameColumn: azdata.TableColumn = { type: azdata.ColumnType.text, value: localizedConstants.DatabaseScopedOptionsColumnHeader, - width: this.isValueDefaultAvailable ? 169 : 200 - }; - const isValueDefaultColumn: azdata.TableColumn = { - type: azdata.ColumnType.checkBox, - value: localizedConstants.IsDefaultValueColumnHeader, - width: 84 + width: 215 }; const primaryValueColumn: azdata.TableColumn = { type: azdata.ColumnType.text, - value: localizedConstants.ValueForPrimaryColumnHeader, - width: this.isValueDefaultAvailable ? 92 : 125 + value: localizedConstants.ValueForPrimaryColumnHeader }; const secondaryValueColumn: azdata.TableColumn = { type: azdata.ColumnType.text, - value: localizedConstants.ValueForSecondaryColumnHeader, - width: this.isValueDefaultAvailable ? 106 : 125 + value: localizedConstants.ValueForSecondaryColumnHeader }; - // isDefaultValue property is not supported for all the database scoped configurations in case of SQL Server 2016 and below - const dscTableColumns: azdata.TableColumn[] = this.isValueDefaultAvailable - ? [dscNameColumn, isValueDefaultColumn, primaryValueColumn, secondaryValueColumn] - : [dscNameColumn, primaryValueColumn, secondaryValueColumn]; - this.dscTable = this.modelView.modelBuilder.table().withProps({ - columns: dscTableColumns, + columns: [dscNameColumn, primaryValueColumn, secondaryValueColumn], data: this.objectInfo.databaseScopedConfigurations.map(metaData => { - return this.isValueDefaultAvailable - ? [metaData.name, metaData.isDefaultValue, metaData.valueForPrimary, metaData.valueForSecondary] - : [metaData.name, metaData.valueForPrimary, metaData.valueForSecondary] + return [metaData.name, + metaData.valueForPrimary, + metaData.valueForSecondary] }), height: getTableHeight(this.objectInfo.databaseScopedConfigurations.length, 1, 15), - width: DefaultTableWidth + 10 + width: DefaultTableWidth }).component(); const dscPrimaryValueGroup = await this.InitializeDscPrimaryValueGroup(); const dscSecondaryValueGroup = await this.InitializeDscSecondaryValueGroup(); + const dscSecondaryCheckboxValueGroup = await this.InitializeDscSecondaryCheckboxValueGroup(); // const dscMaxDopPrimaryValueGroup = await this.InitilaizeDscMaxDopPrimarySection(); - this.dscTabSectionsContainer.push(this.createGroup('', [this.dscTable, dscPrimaryValueGroup, dscSecondaryValueGroup/*, dscMaxDopPrimaryValueGroup*/], true)); + this.dscTabSectionsContainer.push(this.createGroup('', [this.dscTable, dscPrimaryValueGroup, dscSecondaryCheckboxValueGroup, dscSecondaryValueGroup/*, dscMaxDopPrimaryValueGroup*/], true)); this.disposables.push( this.dscTable.onRowSelected( async (selectedRow) => { this.currentRowId = this.dscTable.selectedRows[0]; - const row = this.dscTable.data[this.dscTable.selectedRows[0]]; + const row = this.dscTable.data[this.currentRowId]; await this.validateUpdateToggleDscPrimaryAndSecondaryOptions(row); } @@ -495,13 +487,16 @@ export class DatabaseDialog extends ObjectManagementDialogBase { // Update the primary and secondary dropdown options based on the selected database scoped configuration - this.setSecondaryCheckbox.checked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary; + const isSecondaryCheckboxChecked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary === this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary; + // TODO:await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important' }); - await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'inline !important' }); - await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important' }); - // Elevate online and Elevate resumable options have diff set of drodpdown options and do not support secondary value update + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscSecondaryCheckboxValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + + // Cannot set the 'ELEVATE_RESUMABLE' option for the secondaries replica while this option is only allowed to be set for the primary if (row[0] === localizedConstants.ELEVATE_ONLINE_DSC_OptionText || row[0] === localizedConstants.ELEVATE_RESUMABLE_DSC_OptionText) { - await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible', 'display': 'inline !important' }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'visible' }); await this.valueForPrimaryInput.updateProperties({ values: this.viewInfo.dscElevateOptions , value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary @@ -517,9 +512,9 @@ export class DatabaseDialog extends ObjectManagementDialogBase { // Value for Primary this.valueForPrimaryInput = this.createDropdown(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { - this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue as string; - this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 2 : 1] = newValue; + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue; + this.dscTable.data[this.currentRowId][1] = newValue; + // Update the secondary value with the primary, when the set seconadry checkbox is checked + if (this.setSecondaryCheckbox.checked + && this.objectInfo.databaseScopedConfigurations[this.currentRowId].name !== localizedConstants.IDENTITY_CACHE + && this.objectInfo.databaseScopedConfigurations[this.currentRowId].name !== localizedConstants.ELEVATE_ONLINE_DSC_OptionText + && this.objectInfo.databaseScopedConfigurations[this.currentRowId].name !== localizedConstants.ELEVATE_RESUMABLE_DSC_OptionText) { + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = newValue; + this.dscTable.data[this.currentRowId][2] = newValue; + } await this.updateDscTable(this.dscTable.data); }, [], '', true, 150) const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForPrimaryInput); this.dscPrimaryValueGroup = this.createGroup('', [primaryContainer], true, true); - await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important', }); + await this.dscPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); return this.dscPrimaryValueGroup; } - private async InitializeDscSecondaryValueGroup(): Promise { + private async InitializeDscSecondaryCheckboxValueGroup(): Promise { // Apply Primary To Secondary checkbox this.setSecondaryCheckbox = this.createCheckbox(localizedConstants.SetSecondaryText, async (checked) => { - // Disable secondary dropdown and apply PRIMARY value as selected value - this.valueForSecondaryInput.enabled = !checked; - this.valueForSecondaryInput.value = this.viewInfo.dscOnOffPrimaryOptions[2]; - this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = this.viewInfo.dscOnOffPrimaryOptions[2]; - this.objectInfo.databaseScopedConfigurations[this.currentRowId].applyPrimaryToSecondary = checked; - await this.updateDscTable(this.dscTable.data); - }, false); - const applyPrimaryToSecondaryContainer = this.createLabelInputContainer('', this.setSecondaryCheckbox); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': checked ? 'hidden' : 'visible' }); + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = checked + ? this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary + : this.dscOriginalData[this.currentRowId].valueForSecondary; + await this.valueForSecondaryInput.updateProperties({ value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary }); + }, true); + + this.dscSecondaryCheckboxValueGroup = this.createGroup('', [this.setSecondaryCheckbox], true, true); + await this.dscSecondaryCheckboxValueGroup.updateCssStyles({ 'visibility': 'hidden', 'margin-top': '-13px' }); + return this.dscSecondaryCheckboxValueGroup; + } + + private async InitializeDscSecondaryValueGroup(): Promise { // Value for Secondary this.valueForSecondaryInput = this.createDropdown(localizedConstants.ValueForSecondaryColumnHeader, async (newValue) => { if (!isUndefinedOrNull(newValue)) { this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = newValue as string; - this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 3 : 2] = newValue; + this.dscTable.data[this.currentRowId][2] = newValue; await this.updateDscTable(this.dscTable.data); } }, [], '', true, 150); const secondaryContainer = this.createLabelInputContainer(localizedConstants.ValueForSecondaryColumnHeader, this.valueForSecondaryInput); - this.dscSecondaryValueGroup = this.createGroup('', [applyPrimaryToSecondaryContainer, secondaryContainer], true, true); - await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important', 'margin-top': '-13px' }); + this.dscSecondaryValueGroup = this.createGroup('', [secondaryContainer], true, true); + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'margin-top': '-13px' }); return this.dscSecondaryValueGroup; } From 8aca6ad0acab51e2490e682196e538fb6e002bbf Mon Sep 17 00:00:00 2001 From: ssreerama Date: Mon, 24 Jul 2023 13:27:26 -0700 Subject: [PATCH 08/80] Undo MAXDOP commented code --- .../src/objectManagement/ui/databaseDialog.ts | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index 523d6d890ef1..35ac22cd177e 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -467,7 +467,6 @@ export class DatabaseDialog extends ObjectManagementDialogBase { - // this.valueForMaxDopPrimaryInput = this.createInputBox(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { - // if (this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary !== newValue) { - // this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue; - // this.dscTable.data[this.currentRowId][this.isValueDefaultAvailable ? 2 : 1] = newValue; - // await this.updateDscTable(this.dscTable.data); - // } - // }, '', true, 'number', DefaultInputWidth - 17, true, 0, 32767); - // const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForMaxDopPrimaryInput); - - // this.dscMaxDopPrimaryValueGroup = this.createGroup('', [primaryContainer], true, true); - // await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden', 'display': 'none !important', 'margin-top': '-132px' }); - - // return this.dscMaxDopPrimaryValueGroup; - // } - private async InitializeDscPrimaryValueGroup(): Promise { // Value for Primary this.valueForPrimaryInput = this.createDropdown(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { From 63d140bb03a74813c4aaa6c48d188719793f1663 Mon Sep 17 00:00:00 2001 From: ssreerama Date: Mon, 24 Jul 2023 13:33:57 -0700 Subject: [PATCH 09/80] refactored with service data --- .../objectManagementService.ts | 21 +++++++++++-------- .../src/objectManagement/ui/databaseDialog.ts | 3 --- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/extensions/mssql/src/objectManagement/objectManagementService.ts b/extensions/mssql/src/objectManagement/objectManagementService.ts index c2b7829bfdb3..44fbf2c28648 100644 --- a/extensions/mssql/src/objectManagement/objectManagementService.ts +++ b/extensions/mssql/src/objectManagement/objectManagementService.ts @@ -464,6 +464,9 @@ export class TestObjectManagementService implements IObjectManagementService { restrictAccessOptions: ['MULTI_USER', 'RESTRICTED_USER', 'SINGLE_USER'], pageVerifyOptions: ['CHECKSUM', 'NONE', 'TORN_PAGE_DETECTION'], recoveryModels: ['FULL', 'SIMPLE', 'BULK_LOGGED'], + dscElevateOptions: ['OFF', 'WHEN_SUPPORTED', 'FAIL_UNSUPPORTED'], + dscEnableDisableOptions: ['ENABLED', 'DISABLED'], + dscOnOffOptions: ['ON', 'OFF'], objectInfo: { name: 'Database Properties1', collationName: 'Latin1_General_100_CI_AS_KS_WS', @@ -489,15 +492,15 @@ export class TestObjectManagementService implements IObjectManagementService { encryptionEnabled: false, restrictAccess: 'SINGLE_USER', databaseScopedConfigurations: [ - { name: 'MAXDOP', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, - { name: 'legacy_cardinality_estimation', isDefaultValue: false, valueForPrimary: '', valueForSecondary: '' }, - { name: 'parameter_sniffing', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, - { name: 'query_optimizer_hotfixes', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, - { name: 'identity_cache', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, - { name: 'interleaved_execution_tvf', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, - { name: 'batch_mode_memory_grant_feedback', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, - { name: 'batch_mode_adaptive_joins', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' }, - { name: 'tsql_scalar_udf_inlining', isDefaultValue: true, valueForPrimary: '', valueForSecondary: '' } + { name: 'MAXDOP', valueForPrimary: '', valueForSecondary: '' }, + { name: 'legacy_cardinality_estimation', valueForPrimary: 'ON', valueForSecondary: 'ON' }, + { name: 'parameter_sniffing', valueForPrimary: 'ON', valueForSecondary: 'OFF' }, + { name: 'query_optimizer_hotfixes', valueForPrimary: 'ON', valueForSecondary: 'OFF' }, + { name: 'identity_cache', valueForPrimary: 'ON', valueForSecondary: 'ON' }, + { name: 'interleaved_execution_tvf', valueForPrimary: 'ON', valueForSecondary: 'ON' }, + { name: 'batch_mode_memory_grant_feedback', valueForPrimary: 'OFF', valueForSecondary: 'OFF' }, + { name: 'batch_mode_adaptive_joins', valueForPrimary: 'OFF', valueForSecondary: 'ON' }, + { name: 'tsql_scalar_udf_inlining', valueForPrimary: 'ON', valueForSecondary: 'ON' } ] } } diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index 35ac22cd177e..3a5816708073 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -59,10 +59,7 @@ export class DatabaseDialog extends ObjectManagementDialogBase Date: Tue, 25 Jul 2023 08:29:33 -0700 Subject: [PATCH 10/80] column header width adjustments --- .../mssql/src/objectManagement/ui/databaseDialog.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index 3a5816708073..204c4f869c65 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -439,15 +439,17 @@ export class DatabaseDialog extends ObjectManagementDialogBase Date: Tue, 25 Jul 2023 19:18:15 -0700 Subject: [PATCH 11/80] Maxdop and pause resume options completed, apply button is failing now --- .../objectManagement/localizedConstants.ts | 3 +- .../src/objectManagement/ui/databaseDialog.ts | 130 +++++++++++++++--- 2 files changed, 110 insertions(+), 23 deletions(-) diff --git a/extensions/mssql/src/objectManagement/localizedConstants.ts b/extensions/mssql/src/objectManagement/localizedConstants.ts index 68d848d3da5a..4c7922968063 100644 --- a/extensions/mssql/src/objectManagement/localizedConstants.ts +++ b/extensions/mssql/src/objectManagement/localizedConstants.ts @@ -308,8 +308,7 @@ export const ELEVATE_RESUMABLE_DSC_OptionText = localize('objectManagement.datab export const MAXDOP = localize('objectManagement.databaseProperties.maxdop', "MAXDOP"); export const IDENTITY_CACHE = localize('objectManagement.databaseProperties.identity_cache', "IDENTITY_CACHE"); export const DW_COMPATIBILITY_LEVEL = localize('objectManagement.databaseProperties.dw_compatibility_level', "DW_COMPATIBILITY_LEVEL"); -export const DSCOptionEnabled = localize('objectManagement.databaseProperties.dSCOptionEnabled', "ENABLED"); -export const DSCOptionDisabled = localize('objectManagement.databaseProperties.dSCOptionDisabled', "DISABLED"); +export const PAUSED_RESUMABLE_INDEX_ABORT_DURATION_MINUTES = localize('objectManagement.databaseProperties.paused_resumable_index_abort_duration_minutes', "PAUSED_RESUMABLE_INDEX_ABORT_DURATION_MINUTES"); // Util functions export function getNodeTypeDisplayName(type: string, inTitle: boolean = false): string { diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index 204c4f869c65..a67b482876ae 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -20,6 +20,7 @@ export class DatabaseDialog extends ObjectManagementDialogBase { @@ -488,6 +501,9 @@ export class DatabaseDialog extends ObjectManagementDialogBase { + /** + * Max limt for the MAXDOP primary value is a 16bit signed integer - 32767 + * @returns GroupContainer for MAXDOP primary value + */ + private async InitilaizeDscMaxDopValueSection(): Promise { + // Primary value + this.maxDopPrimaryInput = this.createInputBox(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue; + if (this.dscTable.data[this.currentRowId][1] !== newValue) { + this.dscTable.data[this.currentRowId][1] = newValue; + await this.updateDscTable(this.dscTable.data); + } + }, '', true, 'number', 150, true, 0, 32767); + const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.maxDopPrimaryInput); + this.dscMaxDopPrimaryValueGroup = this.createGroup('', [primaryContainer], true, true); + await this.dscMaxDopPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + + // Apply Primary To Secondary checkbox + this.setMaxDopSecondaryCheckbox = this.createCheckbox(localizedConstants.SetSecondaryText, async (checked) => { + await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': checked ? 'hidden' : 'visible' }); + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = checked + ? this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary + : this.dscOriginalData[this.currentRowId].valueForSecondary; + await this.maxDopSecondaryInput.updateProperties({ value: this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary }); + }, true); + this.dscMaxDopSecondaryCheckboxValueGroup = this.createGroup('', [this.setMaxDopSecondaryCheckbox], true, true); + await this.dscMaxDopSecondaryCheckboxValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + + // Value for Secondary + this.maxDopSecondaryInput = this.createInputBox(localizedConstants.ValueForSecondaryColumnHeader, async (newValue) => { + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary = newValue; + if (this.dscTable.data[this.currentRowId][2] !== newValue) { + this.dscTable.data[this.currentRowId][2] = newValue; + await this.updateDscTable(this.dscTable.data); + } + }, '', true, 'number', 150, true, 0, 32767); + const secondaryContainer = this.createLabelInputContainer(localizedConstants.ValueForSecondaryColumnHeader, this.maxDopSecondaryInput); + this.dscMaxDopSecondaryValueGroup = this.createGroup('', [secondaryContainer], true, true); + await this.dscMaxDopSecondaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + + const maxDopGroup = this.createGroup('', [this.dscMaxDopPrimaryValueGroup, this.dscMaxDopSecondaryCheckboxValueGroup, this.dscMaxDopSecondaryValueGroup], true, true); + await maxDopGroup.updateCssStyles({ 'margin-left': '-10px' }); + return maxDopGroup; + } + + /** + * PAUSED_RESUMABLE_INDEX_ABORT_DURATION_MINUTES wait time must be greater or equal to 0 and less or equal to 71582 + * @returns GroupContainer for Paused resumable index abort duration minutes primary value + */ + private async InitilaizeDscPausedResumableIndexPrimarySection(): Promise { + this.valueForPausedResumableIndexPrimaryInput = this.createInputBox(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { + this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue; + if (this.dscTable.data[this.currentRowId][1] !== newValue) { + this.dscTable.data[this.currentRowId][1] = newValue; + await this.updateDscTable(this.dscTable.data); + } + }, '', true, 'number', 150, true, 0, 71582); + const primaryContainer = this.createLabelInputContainer(localizedConstants.ValueForPrimaryColumnHeader, this.valueForPausedResumableIndexPrimaryInput); + this.dscPausedResumableIndexPrimaryValueGroup = this.createGroup('', [primaryContainer], true, true); + await this.dscPausedResumableIndexPrimaryValueGroup.updateCssStyles({ 'visibility': 'hidden' }); + return this.dscPausedResumableIndexPrimaryValueGroup; + } + + /** + * This method returns the primary and secondary values for all other database scoped configurations except the MAXDOP and Pause resumable index options + * @returns GroupContainer + */ + private async InitializeDscValueSection(): Promise { // Value for Primary this.valueForPrimaryInput = this.createDropdown(localizedConstants.ValueForPrimaryColumnHeader, async (newValue) => { this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary = newValue; @@ -560,14 +657,9 @@ export class DatabaseDialog extends ObjectManagementDialogBase { // Apply Primary To Secondary checkbox this.setSecondaryCheckbox = this.createCheckbox(localizedConstants.SetSecondaryText, async (checked) => { await this.dscSecondaryValueGroup.updateCssStyles({ 'visibility': checked ? 'hidden' : 'visible' }); @@ -576,14 +668,9 @@ export class DatabaseDialog extends ObjectManagementDialogBase { // Value for Secondary this.valueForSecondaryInput = this.createDropdown(localizedConstants.ValueForSecondaryColumnHeader, async (newValue) => { if (!isUndefinedOrNull(newValue)) { @@ -593,11 +680,12 @@ export class DatabaseDialog extends ObjectManagementDialogBase { From 945449291aa7aada9572e0eb2ef33daa6977155d Mon Sep 17 00:00:00 2001 From: ssreerama Date: Tue, 25 Jul 2023 19:32:00 -0700 Subject: [PATCH 12/80] Removed option names from loc and using Id instead as names may change in future like in doc --- .../mssql/src/objectManagement/interfaces.ts | 1 + .../objectManagement/localizedConstants.ts | 7 --- .../src/objectManagement/ui/databaseDialog.ts | 43 ++++++++----------- 3 files changed, 19 insertions(+), 32 deletions(-) diff --git a/extensions/mssql/src/objectManagement/interfaces.ts b/extensions/mssql/src/objectManagement/interfaces.ts index ff61654b7410..89cedfed27a9 100644 --- a/extensions/mssql/src/objectManagement/interfaces.ts +++ b/extensions/mssql/src/objectManagement/interfaces.ts @@ -477,6 +477,7 @@ export interface DatabaseViewInfo extends ObjectManagement.ObjectViewInfo { // Database Properties tabs @@ -474,19 +475,12 @@ export class DatabaseDialog extends ObjectManagementDialogBase { this.currentRowId = this.dscTable.selectedRows[0]; - const row = this.dscTable.data[this.currentRowId]; - - await this.validateUpdateToggleDscPrimaryAndSecondaryOptions(row); + await this.validateUpdateToggleDscPrimaryAndSecondaryOptions(); } ) ); @@ -494,9 +488,8 @@ export class DatabaseDialog extends ObjectManagementDialogBase { + private async validateUpdateToggleDscPrimaryAndSecondaryOptions(): Promise { // Update the primary and secondary dropdown options based on the selected database scoped configuration const isSecondaryCheckboxChecked = this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForPrimary === this.objectInfo.databaseScopedConfigurations[this.currentRowId].valueForSecondary; @@ -508,8 +501,8 @@ export class DatabaseDialog extends ObjectManagementDialogBase Date: Wed, 26 Jul 2023 08:52:49 -0700 Subject: [PATCH 13/80] Apply button fixed --- .../src/objectManagement/ui/databaseDialog.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index c166d4b04981..b958250d0a19 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -521,7 +521,7 @@ export class DatabaseDialog extends ObjectManagementDialogBase Date: Wed, 26 Jul 2023 11:26:01 -0700 Subject: [PATCH 14/80] refactored to reduce table reload --- .../src/objectManagement/ui/databaseDialog.ts | 71 ++++++++++++------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts index b958250d0a19..25d1d6883bcd 100644 --- a/extensions/mssql/src/objectManagement/ui/databaseDialog.ts +++ b/extensions/mssql/src/objectManagement/ui/databaseDialog.ts @@ -493,10 +493,11 @@ export class DatabaseDialog extends ObjectManagementDialogBase