mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
SQL DB Project Extension - Providing publish deploy options (#17993)
* initilaizing the sqlproj display options work * added more code to the options dialog, need default option values * Except REset Button, all works and need to refactor and test * DisplayOptions for SQL DB Proj completed, refactor needed * Tests for display options * refactor code and removed unnecessary await calls * Description values getting from STS API and code refactor * DacpacExtesnion test model error fix * updates related to STS model updates * Dac Deployement options model updates according to STS changes * Undoing file updates and moving as separate PR * Undoing vscode whitespace changes which were added accidentally * Options display name coming from API * Updated model with dac deploy options display names coming from the STS API * errors fixed after merge to main * separating model related changes after merge, separate PR exists * wrong Comment for the test case removed * code refactor updates * Hyperlink changes to secondary button and style updates * refactoring code and comments * importing type only instead of whole azdata and comment updates * projectcontroller test fix * removed duplicate file updates from other PR * code refactor according to comments * Added dispose to the onclick handler * Added test case * parameter change results error and fixed * Addressing all comments with updates * Unused variable removed and missed with previous commit * Updated the ppublish button and width * Adjusted the database dropdown and options margins to make all input align in same line * Updated the database width and moved stylings to uiconstants file
This commit is contained in:
committed by
GitHub
parent
0b89272739
commit
e08a87d035
@@ -76,7 +76,6 @@ export const vscodeOpenCommand = 'vscode.open';
|
||||
export const refreshDataWorkspaceCommand = 'dataworkspace.refresh';
|
||||
|
||||
// UI Strings
|
||||
|
||||
export const dataSourcesNodeName = localize('dataSourcesNodeName', "Data Sources");
|
||||
export const databaseReferencesNodeName = localize('databaseReferencesNodeName', "Database References");
|
||||
export const sqlConnectionStringFriendly = localize('sqlConnectionStringFriendly', "SQL connection string");
|
||||
@@ -111,7 +110,6 @@ export function convertToSdkStyleConfirmation(projectName: string) { return loca
|
||||
export function updatedToSdkStyleError(projectName: string) { return localize('updatedToSdkStyleError', "Converting the project {0} to SDK-style was unsuccessful. Changes to the .sqlproj have been rolled back.", projectName); }
|
||||
|
||||
// Publish dialog strings
|
||||
|
||||
export const publishDialogName = localize('publishDialogName', "Publish project");
|
||||
export const publish = localize('publish', "Publish");
|
||||
export const cancelButtonText = localize('cancelButtonText', "Cancel");
|
||||
@@ -147,6 +145,16 @@ export const selectDatabase = localize('selectDatabase', "Select database");
|
||||
export const done = localize('done', "Done");
|
||||
export const nameMustNotBeEmpty = localize('nameMustNotBeEmpty', "Name must not be empty");
|
||||
|
||||
// Publish Dialog options
|
||||
export const publishOptions = localize('publishOptions', 'Publish Options');
|
||||
export const publishingOptions = localize('publishingOptions', 'Publishing Options');
|
||||
export const GeneralOptions: string = localize('generalOptions', "General Options");
|
||||
export const ResetButton: string = localize('reset', "Reset");
|
||||
export const OptionDescription: string = localize('optionDescription', "Option Description");
|
||||
export const OptionName: string = localize('optionName', "Option Name");
|
||||
export const OptionInclude: string = localize('Include', "Include");
|
||||
|
||||
|
||||
// Deploy
|
||||
export const SqlServerName = 'SQL server';
|
||||
export const AzureSqlServerName = 'Azure SQL server';
|
||||
@@ -273,7 +281,6 @@ export const dacpacNotOnSameDrive = (projectLocation: string): string => { retur
|
||||
export const referenceType = localize('referenceType', "Reference type");
|
||||
|
||||
// Create Project From Database dialog strings
|
||||
|
||||
export const createProjectFromDatabaseDialogName = localize('createProjectFromDatabaseDialogName', "Create project from database");
|
||||
export const createProjectDialogOkButtonText = localize('createProjectDialogOkButtonText', "Create");
|
||||
export const sourceDatabase = localize('sourceDatabase', "Source database");
|
||||
|
||||
@@ -40,5 +40,6 @@ export enum TelemetryActions {
|
||||
updateProjectFromDatabase = 'updateProjectFromDatabase',
|
||||
publishToContainer = 'publishToContainer',
|
||||
publishToNewAzureServer = 'publishToNewAzureServer',
|
||||
generateProjectFromOpenApiSpec = 'generateProjectFromOpenApiSpec'
|
||||
generateProjectFromOpenApiSpec = 'generateProjectFromOpenApiSpec',
|
||||
publishConfigureOptionsClicked = 'PublishConfigureOptionsClicked'
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ export namespace cssStyles {
|
||||
|
||||
export const publishDialogLabelWidth = '205px';
|
||||
export const publishDialogTextboxWidth = '190px';
|
||||
export const publishDialogDropdownWidth = '192px';
|
||||
export const PublishingOptionsButtonWidth = '120px';
|
||||
|
||||
export const addDatabaseReferenceDialogLabelWidth = '215px';
|
||||
export const addDatabaseReferenceInputboxWidth = '220px';
|
||||
|
||||
@@ -18,6 +18,7 @@ import { getAgreementDisplayText, getConnectionName, getDockerBaseImages, getPub
|
||||
import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry';
|
||||
import { ILocalDbDeployProfile } from '../models/deploy/deployProfile';
|
||||
import { Deferred } from '../common/promise';
|
||||
import { PublishOptionsDialog } from './publishOptionsDialog';
|
||||
|
||||
interface DataSourceDropdownValue extends azdataType.CategoryValue {
|
||||
dataSource: SqlConnectionDataSource;
|
||||
@@ -56,6 +57,8 @@ export class PublishDatabaseDialog {
|
||||
private deploymentOptions: DeploymentOptions | undefined;
|
||||
private profileUsed: boolean = false;
|
||||
private serverName: string | undefined;
|
||||
protected optionsButton: azdataType.ButtonComponent | undefined;
|
||||
private publishOptionsDialog: PublishOptionsDialog | undefined;
|
||||
|
||||
private completionPromise: Deferred = new Deferred();
|
||||
|
||||
@@ -134,13 +137,17 @@ export class PublishDatabaseDialog {
|
||||
title: constants.sqlCmdVariables
|
||||
};
|
||||
|
||||
// Get the default deployment option and set
|
||||
const options = await this.getDefaultDeploymentOptions();
|
||||
this.setDeploymentOptions(options);
|
||||
|
||||
const profileRow = this.createProfileRow(view);
|
||||
this.connectionRow = this.createConnectionRow(view);
|
||||
this.databaseRow = this.createDatabaseRow(view);
|
||||
const displayOptionsButton = this.createOptionsButton(view);
|
||||
|
||||
const horizontalFormSection = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column' }).component();
|
||||
horizontalFormSection.addItems([profileRow, this.databaseRow]);
|
||||
|
||||
horizontalFormSection.addItems([profileRow, this.databaseRow, displayOptionsButton]);
|
||||
|
||||
this.formBuilder = <azdataType.FormBuilder>view.modelBuilder.formContainer()
|
||||
.withFormItems([
|
||||
@@ -281,8 +288,6 @@ export class PublishDatabaseDialog {
|
||||
}
|
||||
|
||||
public async getDeploymentOptions(): Promise<DeploymentOptions> {
|
||||
// eventually, database options will be configurable in this dialog
|
||||
// but for now, just send the default DacFx deployment options if no options were loaded from a publish profile
|
||||
if (!this.deploymentOptions) {
|
||||
// We only use the dialog in ADS context currently so safe to cast to the mssql DeploymentOptions here
|
||||
this.deploymentOptions = await utils.getDefaultPublishDeploymentOptions(this.project) as DeploymentOptions;
|
||||
@@ -534,7 +539,7 @@ export class PublishDatabaseDialog {
|
||||
width: cssStyles.publishDialogLabelWidth
|
||||
}).component();
|
||||
|
||||
const connectionRow = view.modelBuilder.flexContainer().withItems([serverLabel, this.targetConnectionTextBox], { flex: '0 0 auto', CSSStyles: { 'margin-right': '10px' } }).withLayout({ flexFlow: 'row', alignItems: 'center' }).component();
|
||||
const connectionRow = view.modelBuilder.flexContainer().withItems([serverLabel, this.targetConnectionTextBox], { flex: '0 0 auto', CSSStyles: { 'margin': '-8px 10px -15px 0' } }).withLayout({ flexFlow: 'row', alignItems: 'center' }).component();
|
||||
connectionRow.insertItem(selectConnectionButton, 2, { CSSStyles: { 'margin-right': '0px' } });
|
||||
|
||||
return connectionRow;
|
||||
@@ -650,7 +655,7 @@ export class PublishDatabaseDialog {
|
||||
this.targetDatabaseTextBox = view.modelBuilder.inputBox().withProps({
|
||||
ariaLabel: constants.databaseNameLabel,
|
||||
required: true,
|
||||
width: cssStyles.publishDialogTextboxWidth,
|
||||
width: cssStyles.publishDialogDropdownWidth,
|
||||
value: this.getDefaultDatabaseName()
|
||||
}).component();
|
||||
}
|
||||
@@ -662,7 +667,7 @@ export class PublishDatabaseDialog {
|
||||
value: this.getDefaultDatabaseName(),
|
||||
ariaLabel: constants.databaseNameLabel,
|
||||
required: true,
|
||||
width: cssStyles.publishDialogTextboxWidth,
|
||||
width: cssStyles.publishDialogDropdownWidth,
|
||||
editable: true,
|
||||
fireOnTextChange: true
|
||||
}).component();
|
||||
@@ -896,6 +901,42 @@ export class PublishDatabaseDialog {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates Display options container with a 'configure options' button
|
||||
*/
|
||||
private createOptionsButton(view: azdataType.ModelView): azdataType.FlexContainer {
|
||||
this.optionsButton = view.modelBuilder.button().withProps({
|
||||
label: constants.publishingOptions,
|
||||
secondary: true,
|
||||
width: cssStyles.PublishingOptionsButtonWidth
|
||||
}).component();
|
||||
|
||||
const optionsRow = view.modelBuilder.flexContainer().withItems([this.optionsButton], { CSSStyles: { flex: '0 0 auto', 'margin': '6px 0 0 287px' } }).withLayout({ flexFlow: 'row', alignItems: 'center' }).component();
|
||||
|
||||
this.toDispose.push(this.optionsButton.onDidClick(async () => {
|
||||
TelemetryReporter.sendActionEvent(TelemetryViews.SqlProjectPublishDialog, TelemetryActions.publishConfigureOptionsClicked);
|
||||
// Create fresh options dialog with default selections each time when creating the 'configure options' button
|
||||
this.publishOptionsDialog = new PublishOptionsDialog(this.deploymentOptions!, this);
|
||||
this.publishOptionsDialog.openDialog();
|
||||
}));
|
||||
|
||||
return optionsRow;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the default deployment options from the dacfx service
|
||||
*/
|
||||
public async getDefaultDeploymentOptions(): Promise<DeploymentOptions> {
|
||||
return await utils.getDefaultPublishDeploymentOptions(this.project) as DeploymentOptions;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the default deployment options to deployment options model object
|
||||
*/
|
||||
public setDeploymentOptions(deploymentOptions: DeploymentOptions): void {
|
||||
this.deploymentOptions = deploymentOptions;
|
||||
}
|
||||
}
|
||||
|
||||
export function promptForPublishProfile(defaultPath: string): Thenable<vscode.Uri[] | undefined> {
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as constants from '../common/constants';
|
||||
import * as vscode from 'vscode';
|
||||
import * as mssql from 'mssql';
|
||||
import * as utils from '../common/utils';
|
||||
import type * as azdataType from 'azdata';
|
||||
import { PublishDatabaseDialog } from './publishDatabaseDialog';
|
||||
import { DeployOptionsModel } from '../models/options/deployOptionsModel';
|
||||
|
||||
export class PublishOptionsDialog {
|
||||
|
||||
public dialog!: azdataType.window.Dialog;
|
||||
private optionsTab: azdataType.window.DialogTab | undefined;
|
||||
private disposableListeners: vscode.Disposable[] = [];
|
||||
private descriptionHeading: azdataType.TableComponent | undefined;
|
||||
private descriptionText: azdataType.TextComponent | undefined;
|
||||
private optionsTable: azdataType.TableComponent | undefined;
|
||||
public optionsModel: DeployOptionsModel;
|
||||
private optionsFlexBuilder: azdataType.FlexContainer | undefined;
|
||||
|
||||
constructor(defaultOptions: mssql.DeploymentOptions, private publish: PublishDatabaseDialog) {
|
||||
this.optionsModel = new DeployOptionsModel(defaultOptions);
|
||||
}
|
||||
|
||||
protected initializeDialog(): void {
|
||||
this.optionsTab = utils.getAzdataApi()!.window.createTab(constants.publishOptions);
|
||||
this.intializeDeploymentOptionsDialogTab();
|
||||
this.dialog.content = [this.optionsTab];
|
||||
}
|
||||
|
||||
public openDialog(): void {
|
||||
this.dialog = utils.getAzdataApi()!.window.createModelViewDialog(constants.publishOptions);
|
||||
|
||||
this.initializeDialog();
|
||||
|
||||
this.dialog.okButton.label = constants.okString;
|
||||
this.dialog.okButton.onClick(() => this.execute());
|
||||
|
||||
this.dialog.cancelButton.label = constants.cancelButtonText;
|
||||
this.dialog.cancelButton.onClick(() => this.cancel());
|
||||
|
||||
let resetButton = utils.getAzdataApi()!.window.createButton(constants.ResetButton);
|
||||
resetButton.onClick(async () => await this.reset());
|
||||
this.dialog.customButtons = [resetButton];
|
||||
|
||||
utils.getAzdataApi()!.window.openDialog(this.dialog);
|
||||
}
|
||||
|
||||
private intializeDeploymentOptionsDialogTab(): void {
|
||||
this.optionsTab?.registerContent(async view => {
|
||||
this.descriptionHeading = view.modelBuilder.table().withProps({
|
||||
data: [],
|
||||
columns: [
|
||||
{
|
||||
value: constants.OptionDescription,
|
||||
headerCssClass: 'no-borders',
|
||||
toolTip: constants.OptionDescription
|
||||
}
|
||||
]
|
||||
}).component();
|
||||
|
||||
this.descriptionText = view.modelBuilder.text().withProps({
|
||||
value: ' '
|
||||
}).component();
|
||||
|
||||
this.optionsTable = view.modelBuilder.table().component();
|
||||
await this.updateOptionsTable();
|
||||
|
||||
// Get the description of the selected option
|
||||
this.disposableListeners.push(this.optionsTable.onRowSelected(async () => {
|
||||
const row = this.optionsTable?.selectedRows![0];
|
||||
const label = this.optionsModel.optionsLabels[row!];
|
||||
await this.descriptionText?.updateProperties({
|
||||
value: this.optionsModel.getDescription(label)
|
||||
});
|
||||
}));
|
||||
|
||||
// Update deploy options value on checkbox onchange
|
||||
this.disposableListeners.push(this.optionsTable.onCellAction!((rowState) => {
|
||||
const checkboxState = <azdataType.ICheckboxCellActionEventArgs>rowState;
|
||||
if (checkboxState && checkboxState.row !== undefined) {
|
||||
const label = this.optionsModel.optionsLabels[checkboxState.row];
|
||||
this.optionsModel.optionsLookup[label] = checkboxState.checked;
|
||||
}
|
||||
}));
|
||||
|
||||
this.optionsFlexBuilder = view.modelBuilder.flexContainer()
|
||||
.withLayout({
|
||||
flexFlow: 'column'
|
||||
}).component();
|
||||
|
||||
this.optionsFlexBuilder.addItem(this.optionsTable, { CSSStyles: { 'overflow': 'scroll', 'height': '65vh' } });
|
||||
this.optionsFlexBuilder.addItem(this.descriptionHeading, { CSSStyles: { 'font-weight': 'bold', 'height': '30px' } });
|
||||
this.optionsFlexBuilder.addItem(this.descriptionText, { CSSStyles: { 'padding': '4px', 'margin-right': '10px', 'overflow': 'scroll', 'height': '10vh' } });
|
||||
await view.initializeModel(this.optionsFlexBuilder);
|
||||
// focus the first option
|
||||
await this.optionsTable.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the default options to the options table area
|
||||
*/
|
||||
private async updateOptionsTable(): Promise<void> {
|
||||
const data = this.optionsModel.getOptionsData();
|
||||
await this.optionsTable?.updateProperties({
|
||||
data: data,
|
||||
columns: [
|
||||
<azdataType.CheckboxColumn>
|
||||
{
|
||||
value: constants.OptionInclude,
|
||||
type: utils.getAzdataApi()!.ColumnType.checkBox,
|
||||
action: utils.getAzdataApi()!.ActionOnCellCheckboxCheck.customAction,
|
||||
headerCssClass: 'display-none',
|
||||
cssClass: 'no-borders align-with-header',
|
||||
width: 50
|
||||
},
|
||||
{
|
||||
value: constants.OptionName,
|
||||
headerCssClass: 'display-none',
|
||||
cssClass: 'no-borders align-with-header',
|
||||
width: 50
|
||||
}
|
||||
],
|
||||
ariaRowCount: data.length
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok button click, will update the deployment options with selections
|
||||
*/
|
||||
protected execute(): void {
|
||||
this.optionsModel.setDeploymentOptions();
|
||||
this.publish.setDeploymentOptions(this.optionsModel.deploymentOptions);
|
||||
this.disposeListeners();
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancels the deploy options table dialog and its changes will be disposed
|
||||
*/
|
||||
protected cancel(): void {
|
||||
this.disposeListeners();
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset button click, resets all the options selection
|
||||
*/
|
||||
private async reset(): Promise<void> {
|
||||
const result = await this.publish.getDefaultDeploymentOptions();
|
||||
this.optionsModel.deploymentOptions = result;
|
||||
|
||||
// This will update the Map table with default values
|
||||
this.optionsModel.InitializeUpdateOptionsMapTable();
|
||||
|
||||
await this.updateOptionsTable();
|
||||
this.optionsFlexBuilder?.removeItem(this.optionsTable!);
|
||||
this.optionsFlexBuilder?.insertItem(this.optionsTable!, 0, { CSSStyles: { 'overflow': 'scroll', 'height': '65vh' } });
|
||||
}
|
||||
|
||||
private disposeListeners(): void {
|
||||
this.disposableListeners.forEach(x => x.dispose());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as mssql from 'mssql';
|
||||
|
||||
export class DeployOptionsModel {
|
||||
public deploymentOptions: mssql.DeploymentOptions;
|
||||
|
||||
public optionsLookup: Record<string, boolean> = {};
|
||||
public optionsMapTable: Record<string, mssql.DacDeployOptionPropertyBoolean> = {};
|
||||
|
||||
constructor(defaultOptions: mssql.DeploymentOptions) {
|
||||
this.deploymentOptions = defaultOptions;
|
||||
this.InitializeUpdateOptionsMapTable();
|
||||
this.InitializeOptionsLabels();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the options mapping table
|
||||
* This will map the key:Option_DisplayName to the value:DacFx_OptionsValue
|
||||
*/
|
||||
public InitializeUpdateOptionsMapTable() {
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreTableOptions.displayName] = this.deploymentOptions.ignoreTableOptions;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreSemicolonBetweenStatements.displayName] = this.deploymentOptions.ignoreSemicolonBetweenStatements;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreRouteLifetime.displayName] = this.deploymentOptions.ignoreRouteLifetime;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreRoleMembership.displayName] = this.deploymentOptions.ignoreRoleMembership;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreQuotedIdentifiers.displayName] = this.deploymentOptions.ignoreQuotedIdentifiers;
|
||||
this.optionsMapTable[this.deploymentOptions.ignorePermissions.displayName] = this.deploymentOptions.ignorePermissions;
|
||||
this.optionsMapTable[this.deploymentOptions.ignorePartitionSchemes.displayName] = this.deploymentOptions.ignorePartitionSchemes;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreObjectPlacementOnPartitionScheme.displayName] = this.deploymentOptions.ignoreObjectPlacementOnPartitionScheme;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreNotForReplication.displayName] = this.deploymentOptions.ignoreNotForReplication;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreLoginSids.displayName] = this.deploymentOptions.ignoreLoginSids;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreLockHintsOnIndexes.displayName] = this.deploymentOptions.ignoreLockHintsOnIndexes;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreKeywordCasing.displayName] = this.deploymentOptions.ignoreKeywordCasing;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreIndexPadding.displayName] = this.deploymentOptions.ignoreIndexPadding;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreIndexOptions.displayName] = this.deploymentOptions.ignoreIndexOptions;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreIncrement.displayName] = this.deploymentOptions.ignoreIncrement;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreIdentitySeed.displayName] = this.deploymentOptions.ignoreIdentitySeed;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreUserSettingsObjects.displayName] = this.deploymentOptions.ignoreUserSettingsObjects;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreFullTextCatalogFilePath.displayName] = this.deploymentOptions.ignoreFullTextCatalogFilePath;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreWhitespace.displayName] = this.deploymentOptions.ignoreWhitespace;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreWithNocheckOnForeignKeys.displayName] = this.deploymentOptions.ignoreWithNocheckOnForeignKeys;
|
||||
this.optionsMapTable[this.deploymentOptions.verifyCollationCompatibility.displayName] = this.deploymentOptions.verifyCollationCompatibility;
|
||||
this.optionsMapTable[this.deploymentOptions.unmodifiableObjectWarnings.displayName] = this.deploymentOptions.unmodifiableObjectWarnings;
|
||||
this.optionsMapTable[this.deploymentOptions.treatVerificationErrorsAsWarnings.displayName] = this.deploymentOptions.treatVerificationErrorsAsWarnings;
|
||||
this.optionsMapTable[this.deploymentOptions.scriptRefreshModule.displayName] = this.deploymentOptions.scriptRefreshModule;
|
||||
this.optionsMapTable[this.deploymentOptions.scriptNewConstraintValidation.displayName] = this.deploymentOptions.scriptNewConstraintValidation;
|
||||
this.optionsMapTable[this.deploymentOptions.scriptFileSize.displayName] = this.deploymentOptions.scriptFileSize;
|
||||
this.optionsMapTable[this.deploymentOptions.scriptDeployStateChecks.displayName] = this.deploymentOptions.scriptDeployStateChecks;
|
||||
this.optionsMapTable[this.deploymentOptions.scriptDatabaseOptions.displayName] = this.deploymentOptions.scriptDatabaseOptions;
|
||||
this.optionsMapTable[this.deploymentOptions.scriptDatabaseCompatibility.displayName] = this.deploymentOptions.scriptDatabaseCompatibility;
|
||||
this.optionsMapTable[this.deploymentOptions.scriptDatabaseCollation.displayName] = this.deploymentOptions.scriptDatabaseCollation;
|
||||
this.optionsMapTable[this.deploymentOptions.runDeploymentPlanExecutors.displayName] = this.deploymentOptions.runDeploymentPlanExecutors;
|
||||
this.optionsMapTable[this.deploymentOptions.registerDataTierApplication.displayName] = this.deploymentOptions.registerDataTierApplication;
|
||||
this.optionsMapTable[this.deploymentOptions.populateFilesOnFileGroups.displayName] = this.deploymentOptions.populateFilesOnFileGroups;
|
||||
this.optionsMapTable[this.deploymentOptions.noAlterStatementsToChangeClrTypes.displayName] = this.deploymentOptions.noAlterStatementsToChangeClrTypes;
|
||||
this.optionsMapTable[this.deploymentOptions.includeTransactionalScripts.displayName] = this.deploymentOptions.includeTransactionalScripts;
|
||||
this.optionsMapTable[this.deploymentOptions.includeCompositeObjects.displayName] = this.deploymentOptions.includeCompositeObjects;
|
||||
this.optionsMapTable[this.deploymentOptions.allowUnsafeRowLevelSecurityDataMovement.displayName] = this.deploymentOptions.allowUnsafeRowLevelSecurityDataMovement;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreWithNocheckOnCheckConstraints.displayName] = this.deploymentOptions.ignoreWithNocheckOnCheckConstraints;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreFillFactor.displayName] = this.deploymentOptions.ignoreFillFactor;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreFileSize.displayName] = this.deploymentOptions.ignoreFileSize;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreFilegroupPlacement.displayName] = this.deploymentOptions.ignoreFilegroupPlacement;
|
||||
this.optionsMapTable[this.deploymentOptions.doNotAlterReplicatedObjects.displayName] = this.deploymentOptions.doNotAlterReplicatedObjects;
|
||||
this.optionsMapTable[this.deploymentOptions.doNotAlterChangeDataCaptureObjects.displayName] = this.deploymentOptions.doNotAlterChangeDataCaptureObjects;
|
||||
this.optionsMapTable[this.deploymentOptions.disableAndReenableDdlTriggers.displayName] = this.deploymentOptions.disableAndReenableDdlTriggers;
|
||||
this.optionsMapTable[this.deploymentOptions.deployDatabaseInSingleUserMode.displayName] = this.deploymentOptions.deployDatabaseInSingleUserMode;
|
||||
this.optionsMapTable[this.deploymentOptions.createNewDatabase.displayName] = this.deploymentOptions.createNewDatabase;
|
||||
this.optionsMapTable[this.deploymentOptions.compareUsingTargetCollation.displayName] = this.deploymentOptions.compareUsingTargetCollation;
|
||||
this.optionsMapTable[this.deploymentOptions.commentOutSetVarDeclarations.displayName] = this.deploymentOptions.commentOutSetVarDeclarations;
|
||||
this.optionsMapTable[this.deploymentOptions.blockWhenDriftDetected.displayName] = this.deploymentOptions.blockWhenDriftDetected;
|
||||
this.optionsMapTable[this.deploymentOptions.blockOnPossibleDataLoss.displayName] = this.deploymentOptions.blockOnPossibleDataLoss;
|
||||
this.optionsMapTable[this.deploymentOptions.backupDatabaseBeforeChanges.displayName] = this.deploymentOptions.backupDatabaseBeforeChanges;
|
||||
this.optionsMapTable[this.deploymentOptions.allowIncompatiblePlatform.displayName] = this.deploymentOptions.allowIncompatiblePlatform;
|
||||
this.optionsMapTable[this.deploymentOptions.allowDropBlockingAssemblies.displayName] = this.deploymentOptions.allowDropBlockingAssemblies;
|
||||
this.optionsMapTable[this.deploymentOptions.dropConstraintsNotInSource.displayName] = this.deploymentOptions.dropConstraintsNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.dropDmlTriggersNotInSource.displayName] = this.deploymentOptions.dropDmlTriggersNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.dropExtendedPropertiesNotInSource.displayName] = this.deploymentOptions.dropExtendedPropertiesNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.dropIndexesNotInSource.displayName] = this.deploymentOptions.dropIndexesNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreFileAndLogFilePath.displayName] = this.deploymentOptions.ignoreFileAndLogFilePath;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreExtendedProperties.displayName] = this.deploymentOptions.ignoreExtendedProperties;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreDmlTriggerState.displayName] = this.deploymentOptions.ignoreDmlTriggerState;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreDmlTriggerOrder.displayName] = this.deploymentOptions.ignoreDmlTriggerOrder;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreDefaultSchema.displayName] = this.deploymentOptions.ignoreDefaultSchema;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreDdlTriggerState.displayName] = this.deploymentOptions.ignoreDdlTriggerState;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreDdlTriggerOrder.displayName] = this.deploymentOptions.ignoreDdlTriggerOrder;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreCryptographicProviderFilePath.displayName] = this.deploymentOptions.ignoreCryptographicProviderFilePath;
|
||||
this.optionsMapTable[this.deploymentOptions.verifyDeployment.displayName] = this.deploymentOptions.verifyDeployment;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreComments.displayName] = this.deploymentOptions.ignoreComments;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreColumnCollation.displayName] = this.deploymentOptions.ignoreColumnCollation;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreAuthorizer.displayName] = this.deploymentOptions.ignoreAuthorizer;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreAnsiNulls.displayName] = this.deploymentOptions.ignoreAnsiNulls;
|
||||
this.optionsMapTable[this.deploymentOptions.generateSmartDefaults.displayName] = this.deploymentOptions.generateSmartDefaults;
|
||||
this.optionsMapTable[this.deploymentOptions.dropStatisticsNotInSource.displayName] = this.deploymentOptions.dropStatisticsNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.dropRoleMembersNotInSource.displayName] = this.deploymentOptions.dropRoleMembersNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.dropPermissionsNotInSource.displayName] = this.deploymentOptions.dropPermissionsNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.dropObjectsNotInSource.displayName] = this.deploymentOptions.dropObjectsNotInSource;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreColumnOrder.displayName] = this.deploymentOptions.ignoreColumnOrder;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreTablePartitionOptions.displayName] = this.deploymentOptions.ignoreTablePartitionOptions;
|
||||
this.optionsMapTable[this.deploymentOptions.doNotEvaluateSqlCmdVariables.displayName] = this.deploymentOptions.doNotEvaluateSqlCmdVariables;
|
||||
this.optionsMapTable[this.deploymentOptions.disableParallelismForEnablingIndexes.displayName] = this.deploymentOptions.disableParallelismForEnablingIndexes;
|
||||
this.optionsMapTable[this.deploymentOptions.disableIndexesForDataPhase.displayName] = this.deploymentOptions.disableIndexesForDataPhase;
|
||||
this.optionsMapTable[this.deploymentOptions.restoreSequenceCurrentValue.displayName] = this.deploymentOptions.restoreSequenceCurrentValue;
|
||||
this.optionsMapTable[this.deploymentOptions.rebuildIndexesOfflineForDataPhase.displayName] = this.deploymentOptions.rebuildIndexesOfflineForDataPhase;
|
||||
this.optionsMapTable[this.deploymentOptions.preserveIdentityLastValues.displayName] = this.deploymentOptions.preserveIdentityLastValues;
|
||||
this.optionsMapTable[this.deploymentOptions.isAlwaysEncryptedParameterizationEnabled.displayName] = this.deploymentOptions.isAlwaysEncryptedParameterizationEnabled;
|
||||
this.optionsMapTable[this.deploymentOptions.allowExternalLibraryPaths.displayName] = this.deploymentOptions.allowExternalLibraryPaths;
|
||||
this.optionsMapTable[this.deploymentOptions.allowExternalLanguagePaths.displayName] = this.deploymentOptions.allowExternalLanguagePaths;
|
||||
this.optionsMapTable[this.deploymentOptions.hashObjectNamesInLogs.displayName] = this.deploymentOptions.hashObjectNamesInLogs;
|
||||
this.optionsMapTable[this.deploymentOptions.doNotDropWorkloadClassifiers.displayName] = this.deploymentOptions.doNotDropWorkloadClassifiers;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreWorkloadClassifiers.displayName] = this.deploymentOptions.ignoreWorkloadClassifiers;
|
||||
this.optionsMapTable[this.deploymentOptions.ignoreDatabaseWorkloadGroups.displayName] = this.deploymentOptions.ignoreDatabaseWorkloadGroups;
|
||||
this.optionsMapTable[this.deploymentOptions.doNotDropDatabaseWorkloadGroups.displayName] = this.deploymentOptions.doNotDropDatabaseWorkloadGroups;
|
||||
}
|
||||
|
||||
/*
|
||||
* List of Dac Deploy options to display
|
||||
*/
|
||||
public optionsLabels: string[] = [];
|
||||
public InitializeOptionsLabels() {
|
||||
this.optionsLabels = [this.deploymentOptions.ignoreTableOptions.displayName
|
||||
, this.deploymentOptions.ignoreSemicolonBetweenStatements.displayName
|
||||
, this.deploymentOptions.ignoreRouteLifetime.displayName
|
||||
, this.deploymentOptions.ignoreRoleMembership.displayName
|
||||
, this.deploymentOptions.ignoreQuotedIdentifiers.displayName
|
||||
, this.deploymentOptions.ignorePermissions.displayName
|
||||
, this.deploymentOptions.ignorePartitionSchemes.displayName
|
||||
, this.deploymentOptions.ignoreObjectPlacementOnPartitionScheme.displayName
|
||||
, this.deploymentOptions.ignoreNotForReplication.displayName
|
||||
, this.deploymentOptions.ignoreLoginSids.displayName
|
||||
, this.deploymentOptions.ignoreLockHintsOnIndexes.displayName
|
||||
, this.deploymentOptions.ignoreKeywordCasing.displayName
|
||||
, this.deploymentOptions.ignoreIndexPadding.displayName
|
||||
, this.deploymentOptions.ignoreIndexOptions.displayName
|
||||
, this.deploymentOptions.ignoreIncrement.displayName
|
||||
, this.deploymentOptions.ignoreIdentitySeed.displayName
|
||||
, this.deploymentOptions.ignoreUserSettingsObjects.displayName
|
||||
, this.deploymentOptions.ignoreFullTextCatalogFilePath.displayName
|
||||
, this.deploymentOptions.ignoreWhitespace.displayName
|
||||
, this.deploymentOptions.ignoreWithNocheckOnForeignKeys.displayName
|
||||
, this.deploymentOptions.verifyCollationCompatibility.displayName
|
||||
, this.deploymentOptions.unmodifiableObjectWarnings.displayName
|
||||
, this.deploymentOptions.treatVerificationErrorsAsWarnings.displayName
|
||||
, this.deploymentOptions.scriptRefreshModule.displayName
|
||||
, this.deploymentOptions.scriptNewConstraintValidation.displayName
|
||||
, this.deploymentOptions.scriptFileSize.displayName
|
||||
, this.deploymentOptions.scriptDeployStateChecks.displayName
|
||||
, this.deploymentOptions.scriptDatabaseOptions.displayName
|
||||
, this.deploymentOptions.scriptDatabaseCompatibility.displayName
|
||||
, this.deploymentOptions.scriptDatabaseCollation.displayName
|
||||
, this.deploymentOptions.runDeploymentPlanExecutors.displayName
|
||||
, this.deploymentOptions.registerDataTierApplication.displayName
|
||||
, this.deploymentOptions.populateFilesOnFileGroups.displayName
|
||||
, this.deploymentOptions.noAlterStatementsToChangeClrTypes.displayName
|
||||
, this.deploymentOptions.includeTransactionalScripts.displayName
|
||||
, this.deploymentOptions.includeCompositeObjects.displayName
|
||||
, this.deploymentOptions.allowUnsafeRowLevelSecurityDataMovement.displayName
|
||||
, this.deploymentOptions.ignoreWithNocheckOnCheckConstraints.displayName
|
||||
, this.deploymentOptions.ignoreFillFactor.displayName
|
||||
, this.deploymentOptions.ignoreFileSize.displayName
|
||||
, this.deploymentOptions.ignoreFilegroupPlacement.displayName
|
||||
, this.deploymentOptions.doNotAlterReplicatedObjects.displayName
|
||||
, this.deploymentOptions.doNotAlterChangeDataCaptureObjects.displayName
|
||||
, this.deploymentOptions.disableAndReenableDdlTriggers.displayName
|
||||
, this.deploymentOptions.deployDatabaseInSingleUserMode.displayName
|
||||
, this.deploymentOptions.createNewDatabase.displayName
|
||||
, this.deploymentOptions.compareUsingTargetCollation.displayName
|
||||
, this.deploymentOptions.commentOutSetVarDeclarations.displayName
|
||||
, this.deploymentOptions.blockWhenDriftDetected.displayName
|
||||
, this.deploymentOptions.blockOnPossibleDataLoss.displayName
|
||||
, this.deploymentOptions.backupDatabaseBeforeChanges.displayName
|
||||
, this.deploymentOptions.allowIncompatiblePlatform.displayName
|
||||
, this.deploymentOptions.allowDropBlockingAssemblies.displayName
|
||||
, this.deploymentOptions.dropConstraintsNotInSource.displayName
|
||||
, this.deploymentOptions.dropDmlTriggersNotInSource.displayName
|
||||
, this.deploymentOptions.dropExtendedPropertiesNotInSource.displayName
|
||||
, this.deploymentOptions.dropIndexesNotInSource.displayName
|
||||
, this.deploymentOptions.ignoreFileAndLogFilePath.displayName
|
||||
, this.deploymentOptions.ignoreExtendedProperties.displayName
|
||||
, this.deploymentOptions.ignoreDmlTriggerState.displayName
|
||||
, this.deploymentOptions.ignoreDmlTriggerOrder.displayName
|
||||
, this.deploymentOptions.ignoreDefaultSchema.displayName
|
||||
, this.deploymentOptions.ignoreDdlTriggerState.displayName
|
||||
, this.deploymentOptions.ignoreDdlTriggerOrder.displayName
|
||||
, this.deploymentOptions.ignoreCryptographicProviderFilePath.displayName
|
||||
, this.deploymentOptions.verifyDeployment.displayName
|
||||
, this.deploymentOptions.ignoreComments.displayName
|
||||
, this.deploymentOptions.ignoreColumnCollation.displayName
|
||||
, this.deploymentOptions.ignoreAuthorizer.displayName
|
||||
, this.deploymentOptions.ignoreAnsiNulls.displayName
|
||||
, this.deploymentOptions.generateSmartDefaults.displayName
|
||||
, this.deploymentOptions.dropStatisticsNotInSource.displayName
|
||||
, this.deploymentOptions.dropRoleMembersNotInSource.displayName
|
||||
, this.deploymentOptions.dropPermissionsNotInSource.displayName
|
||||
, this.deploymentOptions.dropObjectsNotInSource.displayName
|
||||
, this.deploymentOptions.ignoreColumnOrder.displayName
|
||||
, this.deploymentOptions.ignoreTablePartitionOptions.displayName
|
||||
, this.deploymentOptions.doNotEvaluateSqlCmdVariables.displayName
|
||||
, this.deploymentOptions.disableParallelismForEnablingIndexes.displayName
|
||||
, this.deploymentOptions.disableIndexesForDataPhase.displayName
|
||||
, this.deploymentOptions.restoreSequenceCurrentValue.displayName
|
||||
, this.deploymentOptions.rebuildIndexesOfflineForDataPhase.displayName
|
||||
, this.deploymentOptions.preserveIdentityLastValues.displayName
|
||||
, this.deploymentOptions.isAlwaysEncryptedParameterizationEnabled.displayName
|
||||
, this.deploymentOptions.allowExternalLibraryPaths.displayName
|
||||
, this.deploymentOptions.allowExternalLanguagePaths.displayName
|
||||
, this.deploymentOptions.hashObjectNamesInLogs.displayName
|
||||
, this.deploymentOptions.doNotDropWorkloadClassifiers.displayName
|
||||
, this.deploymentOptions.ignoreWorkloadClassifiers.displayName
|
||||
, this.deploymentOptions.ignoreDatabaseWorkloadGroups.displayName
|
||||
, this.deploymentOptions.doNotDropDatabaseWorkloadGroups.displayName].sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the options checkbox check value
|
||||
* @returns string[][]
|
||||
*/
|
||||
public getOptionsData(): string[][] {
|
||||
let data: any = [];
|
||||
this.optionsLookup = {};
|
||||
this.optionsLabels.forEach(l => {
|
||||
let checked: boolean = this.getDeployOptionUtil(l);
|
||||
data.push([checked, l]);
|
||||
this.optionsLookup[l] = checked;
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
public setDeploymentOptions() {
|
||||
for (let option in this.optionsLookup) {
|
||||
this.setDeployOptionUtil(option, this.optionsLookup[option]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the selected/changed value of the option
|
||||
*/
|
||||
public setDeployOptionUtil(label: string, value: boolean) {
|
||||
this.optionsMapTable[label].value = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the selected/default value of the option
|
||||
*/
|
||||
public getDeployOptionUtil(label: string): boolean {
|
||||
return this.optionsMapTable[label]?.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the description of the option selected
|
||||
*/
|
||||
public getDescription(label: string): string {
|
||||
return this.optionsMapTable[label]?.description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as should from 'should';
|
||||
import * as testUtils from '../testUtils';
|
||||
import * as testData from '../testContext';
|
||||
import * as baselines from '../baselines/baselines';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
|
||||
import { PublishOptionsDialog } from '../../dialogs/publishOptionsDialog';
|
||||
import { PublishDatabaseDialog } from '../../dialogs/publishDatabaseDialog';
|
||||
import { Project } from '../../models/project';
|
||||
|
||||
describe('Publish Database Options Dialog', () => {
|
||||
before(async function (): Promise<void> {
|
||||
await baselines.loadBaselines();
|
||||
});
|
||||
|
||||
it('Should open dialog successfully ', async function (): Promise<void> {
|
||||
const publishDatabaseDialog = new PublishDatabaseDialog(new Project(''));
|
||||
const optionsDialog = new PublishOptionsDialog(testData.getDeploymentOptions(), publishDatabaseDialog);
|
||||
optionsDialog.openDialog();
|
||||
|
||||
// Verify the dialog should exists
|
||||
should.notEqual(optionsDialog.dialog, undefined);
|
||||
});
|
||||
|
||||
it('Should deployment options gets initialized correctly with sample test project', async function (): Promise<void> {
|
||||
// Create new sample test project
|
||||
const project = await testUtils.createTestProject(baselines.openProjectFileBaseline);
|
||||
const dialog = TypeMoq.Mock.ofType(PublishDatabaseDialog, undefined, undefined, project);
|
||||
|
||||
dialog.setup(x => x.getDeploymentOptions()).returns(() => { return Promise.resolve(testData.mockDacFxOptionsResult.deploymentOptions); });
|
||||
|
||||
const options = await dialog.object.getDeploymentOptions();
|
||||
const optionsDialog = new PublishOptionsDialog(options, new PublishDatabaseDialog(project));
|
||||
|
||||
// Verify the options model should exists
|
||||
should.notEqual(optionsDialog.optionsModel, undefined);
|
||||
|
||||
// Verify the deployment options should exists
|
||||
should.notEqual(optionsDialog.optionsModel.deploymentOptions, undefined);
|
||||
|
||||
Object.entries(optionsDialog.optionsModel.deploymentOptions).forEach(option => {
|
||||
// Validate the value and description as expected
|
||||
should.equal(option[1].value, false);
|
||||
should.equal(option[1].description, 'Sample Description text');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as should from 'should';
|
||||
import * as testUtils from '../../test/testContext';
|
||||
import { DeployOptionsModel } from '../../models/options/deployOptionsModel';
|
||||
|
||||
describe('Publish Dialog Deploy Options Model', () => {
|
||||
it('Should create model and set options successfully', function (): void {
|
||||
const model = new DeployOptionsModel(testUtils.getDeploymentOptions());
|
||||
should.notEqual(model.getOptionsData(), undefined, 'Options shouldn\'t be undefined');
|
||||
|
||||
should.doesNotThrow(() => model.setDeploymentOptions());
|
||||
|
||||
should(model.getDeployOptionUtil('')).equal(undefined);
|
||||
});
|
||||
|
||||
it('Should get description', function (): void {
|
||||
const model = new DeployOptionsModel(testUtils.getDeploymentOptions());
|
||||
model.optionsLabels.forEach(l => {
|
||||
should(model.getDescription(l)).not.equal(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
it('Should be undefined for null description', function (): void {
|
||||
const model = new DeployOptionsModel(testUtils.getDeploymentOptions());
|
||||
should(model.getDescription('')).equal(undefined);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user