OptionsMapTable preparing from DacFx description,value,displayname at… (#1550)

* OptionsMapTable preparing from DacFx description,value,displayname attributes

* Review Comments addressed for options map table changes

* OptionsMapTable final changes

* Code review comments updated code changes

* Test fix: Adding missing change while splitting the PR

* DacFx vBump

* Reverted to displayName and code updates

* final:prop name changed, references updated, tests fixed, comments addressed

* Code review comments updated for name,exception etc

* updates method names

* property name changes to BooleanOptionsDictionary and comment updates

* Removed the unused properties, null cases handeled, hardcoded values are replaced
This commit is contained in:
Sai Avishkar Sreerama
2022-07-07 16:56:16 -05:00
committed by GitHub
parent 6558f2036d
commit 5663ddba68
6 changed files with 238 additions and 442 deletions

View File

@@ -14,8 +14,9 @@ using System.Collections.Generic;
namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
{
/// <summary>
/// Class to define deployment option default value and the description
/// DeploymentOptionProperty class to define deployment options default value, description, and displayNames
/// </summary>
/// <typeparam name="T"></typeparam>
public class DeploymentOptionProperty<T>
{
public DeploymentOptionProperty(T value, string description = "", string displayName = "")
@@ -25,197 +26,30 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
this.DisplayName = displayName;
}
// Default and selected value of the deployment options
/// <summary>
/// Default and selected value of the deployment option
/// </summary>
public T Value { get; set; }
// Description of the deployment options
/// <summary>
/// Description of the deployment option
/// </summary>
public string Description { get; set; }
// To display the options in ADS extensions UI in SchemaCompare/SQL-DB-Project/Dacpac extensions
/// <summary>
/// Display name of the deployment option
/// </summary>
public string DisplayName { get; set; }
}
/// <summary>
/// Class to define deployment options.
/// Keeping the order and defaults same as DacFx
/// The default values here should also match the default values in ADS UX
/// NOTE: When new deployment options are added in DacFx, they need to be added here too
/// These property names will be given to the DeploymentOptions interface defined in ADS 'azuredatastudio\extensions\mssql\src\mssql.d.ts' and 'azuredatastudio\extensions\types\vscode-mssql.d.ts'
/// BooleanOptionsDictionary will automatically gets the newly added boolean properties from DacFx, All other types should be added here and ADS
/// </summary>
public class DeploymentOptions
{
#region Properties
public DeploymentOptionProperty<bool> IgnoreTableOptions { get; set; }
public DeploymentOptionProperty<bool> IgnoreSemicolonBetweenStatements { get; set; }
public DeploymentOptionProperty<bool> IgnoreRouteLifetime { get; set; }
public DeploymentOptionProperty<bool> IgnoreRoleMembership { get; set; }
public DeploymentOptionProperty<bool> IgnoreQuotedIdentifiers { get; set; }
public DeploymentOptionProperty<bool> IgnorePermissions { get; set; }
public DeploymentOptionProperty<bool> IgnorePartitionSchemes { get; set; }
public DeploymentOptionProperty<bool> IgnoreObjectPlacementOnPartitionScheme { get; set; }
public DeploymentOptionProperty<bool> IgnoreNotForReplication { get; set; }
public DeploymentOptionProperty<bool> IgnoreLoginSids { get; set; }
public DeploymentOptionProperty<bool> IgnoreLockHintsOnIndexes { get; set; }
public DeploymentOptionProperty<bool> IgnoreKeywordCasing { get; set; }
public DeploymentOptionProperty<bool> IgnoreIndexPadding { get; set; }
public DeploymentOptionProperty<bool> IgnoreIndexOptions { get; set; }
public DeploymentOptionProperty<bool> IgnoreIncrement { get; set; }
public DeploymentOptionProperty<bool> IgnoreIdentitySeed { get; set; }
public DeploymentOptionProperty<bool> IgnoreUserSettingsObjects { get; set; }
public DeploymentOptionProperty<bool> IgnoreFullTextCatalogFilePath { get; set; }
public DeploymentOptionProperty<bool> IgnoreWhitespace { get; set; }
public DeploymentOptionProperty<bool> IgnoreWithNocheckOnForeignKeys { get; set; }
public DeploymentOptionProperty<bool> VerifyCollationCompatibility { get; set; }
public DeploymentOptionProperty<bool> UnmodifiableObjectWarnings { get; set; }
public DeploymentOptionProperty<bool> TreatVerificationErrorsAsWarnings { get; set; }
public DeploymentOptionProperty<bool> ScriptRefreshModule { get; set; }
public DeploymentOptionProperty<bool> ScriptNewConstraintValidation { get; set; }
public DeploymentOptionProperty<bool> ScriptFileSize { get; set; }
public DeploymentOptionProperty<bool> ScriptDeployStateChecks { get; set; }
public DeploymentOptionProperty<bool> ScriptDatabaseOptions { get; set; }
public DeploymentOptionProperty<bool> ScriptDatabaseCompatibility { get; set; }
public DeploymentOptionProperty<bool> ScriptDatabaseCollation { get; set; }
public DeploymentOptionProperty<bool> RunDeploymentPlanExecutors { get; set; }
public DeploymentOptionProperty<bool> RegisterDataTierApplication { get; set; }
public DeploymentOptionProperty<bool> PopulateFilesOnFileGroups { get; set; }
public DeploymentOptionProperty<bool> NoAlterStatementsToChangeClrTypes { get; set; }
public DeploymentOptionProperty<bool> IncludeTransactionalScripts { get; set; }
public DeploymentOptionProperty<bool> IncludeCompositeObjects { get; set; }
public DeploymentOptionProperty<bool> AllowUnsafeRowLevelSecurityDataMovement { get; set; }
public DeploymentOptionProperty<bool> IgnoreWithNocheckOnCheckConstraints { get; set; }
public DeploymentOptionProperty<bool> IgnoreFillFactor { get; set; }
public DeploymentOptionProperty<bool> IgnoreFileSize { get; set; }
public DeploymentOptionProperty<bool> IgnoreFilegroupPlacement { get; set; }
public DeploymentOptionProperty<bool> DoNotAlterReplicatedObjects { get; set; }
public DeploymentOptionProperty<bool> DoNotAlterChangeDataCaptureObjects { get; set; }
public DeploymentOptionProperty<bool> DisableAndReenableDdlTriggers { get; set; }
public DeploymentOptionProperty<bool> DeployDatabaseInSingleUserMode { get; set; }
public DeploymentOptionProperty<bool> CreateNewDatabase { get; set; }
public DeploymentOptionProperty<bool> CompareUsingTargetCollation { get; set; }
public DeploymentOptionProperty<bool> CommentOutSetVarDeclarations { get; set; }
// Command timeout to 120 seconds when executing queries against SQL Server.
public DeploymentOptionProperty<int> CommandTimeout { get; set; } = new DeploymentOptionProperty<int>(120);
// LongRunningCommandTimeout 0 seconds to wait indefinitely.
public DeploymentOptionProperty<int> LongRunningCommandTimeout { get; set; } = new DeploymentOptionProperty<int>(0);
// Wait 60 seconds to lock database when executing queries against SQL Server.
public DeploymentOptionProperty<int> DatabaseLockTimeout { get; set; } = new DeploymentOptionProperty<int>(60);
public DeploymentOptionProperty<bool> BlockWhenDriftDetected { get; set; }
public DeploymentOptionProperty<bool> BlockOnPossibleDataLoss { get; set; }
public DeploymentOptionProperty<bool> BackupDatabaseBeforeChanges { get; set; }
public DeploymentOptionProperty<bool> AllowIncompatiblePlatform { get; set; }
public DeploymentOptionProperty<bool> AllowDropBlockingAssemblies { get; set; }
public DeploymentOptionProperty<string> AdditionalDeploymentContributorArguments { get; set; }
public DeploymentOptionProperty<string> AdditionalDeploymentContributors { get; set; }
public DeploymentOptionProperty<bool> DropConstraintsNotInSource { get; set; }
public DeploymentOptionProperty<bool> DropDmlTriggersNotInSource { get; set; }
public DeploymentOptionProperty<bool> DropExtendedPropertiesNotInSource { get; set; }
public DeploymentOptionProperty<bool> DropIndexesNotInSource { get; set; }
public DeploymentOptionProperty<bool> IgnoreFileAndLogFilePath { get; set; }
public DeploymentOptionProperty<bool> IgnoreExtendedProperties { get; set; }
public DeploymentOptionProperty<bool> IgnoreDmlTriggerState { get; set; }
public DeploymentOptionProperty<bool> IgnoreDmlTriggerOrder { get; set; }
public DeploymentOptionProperty<bool> IgnoreDefaultSchema { get; set; }
public DeploymentOptionProperty<bool> IgnoreDdlTriggerState { get; set; }
public DeploymentOptionProperty<bool> IgnoreDdlTriggerOrder { get; set; }
public DeploymentOptionProperty<bool> IgnoreCryptographicProviderFilePath { get; set; }
public DeploymentOptionProperty<bool> VerifyDeployment { get; set; }
public DeploymentOptionProperty<bool> IgnoreComments { get; set; }
public DeploymentOptionProperty<bool> IgnoreColumnCollation { get; set; }
public DeploymentOptionProperty<bool> IgnoreAuthorizer { get; set; }
public DeploymentOptionProperty<bool> IgnoreAnsiNulls { get; set; }
public DeploymentOptionProperty<bool> GenerateSmartDefaults { get; set; }
public DeploymentOptionProperty<bool> DropStatisticsNotInSource { get; set; }
public DeploymentOptionProperty<bool> DropRoleMembersNotInSource { get; set; }
public DeploymentOptionProperty<bool> DropPermissionsNotInSource { get; set; }
public DeploymentOptionProperty<bool> DropObjectsNotInSource { get; set; }
public DeploymentOptionProperty<bool> IgnoreColumnOrder { get; set; }
public DeploymentOptionProperty<bool> IgnoreTablePartitionOptions { get; set; } // DW Specific
public DeploymentOptionProperty<string> AdditionalDeploymentContributorPaths { get; set; }
public DeploymentOptionProperty<ObjectType[]> DoNotDropObjectTypes { get; set; }
public DeploymentOptionProperty<ObjectType[]> ExcludeObjectTypes { get; set; } = new DeploymentOptionProperty<ObjectType[]>
(
new ObjectType[] {
@@ -244,168 +78,17 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
}
);
public DeploymentOptionProperty<bool> AllowExternalLibraryPaths { get; set; }
public DeploymentOptionProperty<bool> AllowExternalLanguagePaths { get; set; }
public DeploymentOptionProperty<bool> DoNotEvaluateSqlCmdVariables { get; set; }
public DeploymentOptionProperty<bool> DisableParallelismForEnablingIndexes { get; set; }
public DeploymentOptionProperty<bool> DoNotDropWorkloadClassifiers { get; set; }
public DeploymentOptionProperty<bool> DisableIndexesForDataPhase { get; set; }
public DeploymentOptionProperty<bool> DoNotDropDatabaseWorkloadGroups { get; set; }
public DeploymentOptionProperty<bool> HashObjectNamesInLogs { get; set; }
public DeploymentOptionProperty<bool> IgnoreWorkloadClassifiers { get; set; }
public DeploymentOptionProperty<bool> IgnoreDatabaseWorkloadGroups { get; set; }
public DeploymentOptionProperty<bool> IsAlwaysEncryptedParameterizationEnabled { get; set; }
public DeploymentOptionProperty<bool> PreserveIdentityLastValues { get; set; }
public DeploymentOptionProperty<bool> RestoreSequenceCurrentValue { get; set; }
public DeploymentOptionProperty<bool> RebuildIndexesOfflineForDataPhase { get; set; }
private Dictionary<string, string> _displayNameMapDict;
/// <summary>
/// BooleanOptionsDictionary contains all boolean type deployment options
/// </summary>
public Dictionary<string, DeploymentOptionProperty<bool>> BooleanOptionsDictionary { get; set; } = new Dictionary<string, DeploymentOptionProperty<bool>>(StringComparer.InvariantCultureIgnoreCase);
#endregion
/// <summary>
/// Mapping the DisplayName to the dac deploy option
/// Adding new properties here would give easy handling of new option to all extensions
/// </summary>
private void SetDisplayNameForOption()
{
#region Display Name and Dac Options Mapping
DacDeployOptions d = new DacDeployOptions();
_displayNameMapDict = new Dictionary<string, string>();
// Ex: displayNameMapDict["DacFx Option Name"] = "ADS UI Display Name"
_displayNameMapDict[nameof(d.AdditionalDeploymentContributorArguments)] = "Additional Deployment Contributor Arguments";
_displayNameMapDict[nameof(d.AdditionalDeploymentContributorPaths)] = "Additional Deployment Contributor Paths";
_displayNameMapDict[nameof(d.AdditionalDeploymentContributors)] = "Additional Deployment Contributors";
_displayNameMapDict[nameof(d.AllowDropBlockingAssemblies)] = "Allow Drop Blocking Assemblies";
_displayNameMapDict[nameof(d.AllowExternalLanguagePaths)] = "Allow External Language Paths";
_displayNameMapDict[nameof(d.AllowExternalLibraryPaths)] = "Allow External Library Paths";
_displayNameMapDict[nameof(d.AllowIncompatiblePlatform)] = "Allow Incompatible Platform";
_displayNameMapDict[nameof(d.AllowUnsafeRowLevelSecurityDataMovement)] = "Allow Unsafe RowLevel Security Data Movement";
_displayNameMapDict[nameof(d.AzureSharedAccessSignatureToken)] = "Azure Shared Access Signature Token";
_displayNameMapDict[nameof(d.AzureStorageBlobEndpoint)] = "Azure Storage Blob Endpoint";
_displayNameMapDict[nameof(d.AzureStorageContainer)] = "Azure Storage Container";
_displayNameMapDict[nameof(d.AzureStorageKey)] = "Azure Storage Key";
_displayNameMapDict[nameof(d.AzureStorageRootPath)] = "Azure Storage Root Path";
_displayNameMapDict[nameof(d.BackupDatabaseBeforeChanges)] = "Backup Database Before Changes";
_displayNameMapDict[nameof(d.BlockOnPossibleDataLoss)] = "Block On Possible Data Loss";
_displayNameMapDict[nameof(d.BlockWhenDriftDetected)] = "Block When Drift Detected";
_displayNameMapDict[nameof(d.CommandTimeout)] = "Command Timeout";
_displayNameMapDict[nameof(d.CommentOutSetVarDeclarations)] = "Comment Out SetVar Declarations";
_displayNameMapDict[nameof(d.CompareUsingTargetCollation)] = "Compare Using Target Collation";
_displayNameMapDict[nameof(d.CreateNewDatabase)] = "Create New Database";
_displayNameMapDict[nameof(d.DatabaseLockTimeout)] = "Database Lock Timeout";
_displayNameMapDict[nameof(d.DatabaseSpecification)] = "Database Specification";
_displayNameMapDict[nameof(d.DataOperationStateProvider)] = "Data Operation State Provider";
_displayNameMapDict[nameof(d.DeployDatabaseInSingleUserMode)] = "Deploy Database In Single User Mode";
_displayNameMapDict[nameof(d.DisableAndReenableDdlTriggers)] = "Disable And Reenable Ddl Triggers";
_displayNameMapDict[nameof(d.DisableIndexesForDataPhase)] = "Disable Indexes For Data Phase";
_displayNameMapDict[nameof(d.DisableParallelismForEnablingIndexes)] = "Disable Parallelism For Enabling Indexes";
_displayNameMapDict[nameof(d.DoNotAlterChangeDataCaptureObjects)] = "Do Not Alter Change Data Capture Objects";
_displayNameMapDict[nameof(d.DoNotAlterReplicatedObjects)] = "Do Not Alter Replicated Objects";
_displayNameMapDict[nameof(d.DoNotDropDatabaseWorkloadGroups)] = "Do Not Drop Database Workload Groups";
_displayNameMapDict[nameof(d.DoNotDropObjectTypes)] = "Do Not Drop Object Types";
_displayNameMapDict[nameof(d.DoNotDropWorkloadClassifiers)] = "Do Not Drop Workload Classifiers";
_displayNameMapDict[nameof(d.DoNotEvaluateSqlCmdVariables)] = "Do Not Evaluate Sql Cmd Variables";
_displayNameMapDict[nameof(d.DropConstraintsNotInSource)] = "Drop Constraints Not In Source";
_displayNameMapDict[nameof(d.DropDmlTriggersNotInSource)] = "Drop Dml Triggers Not In Source";
_displayNameMapDict[nameof(d.DropExtendedPropertiesNotInSource)] = "Drop Extended Properties Not In Source";
_displayNameMapDict[nameof(d.DropIndexesNotInSource)] = "Drop Indexes Not In Source";
_displayNameMapDict[nameof(d.DropObjectsNotInSource)] = "Drop Objects Not In Source";
_displayNameMapDict[nameof(d.DropPermissionsNotInSource)] = "Drop Permissions Not In Source";
_displayNameMapDict[nameof(d.DropRoleMembersNotInSource)] = "Drop Role Members Not In Source";
_displayNameMapDict[nameof(d.DropStatisticsNotInSource)] = "Drop Statistics Not In Source";
_displayNameMapDict[nameof(d.EnclaveAttestationProtocol)] = "Enclave Attestation Protocol";
_displayNameMapDict[nameof(d.EnclaveAttestationUrl)] = "Enclave Attestation Url";
_displayNameMapDict[nameof(d.ExcludeObjectTypes)] = "Exclude Object Types";
_displayNameMapDict[nameof(d.GenerateSmartDefaults)] = "Generate Smart Defaults";
_displayNameMapDict[nameof(d.HashObjectNamesInLogs)] = "Hash Object Names In Logs";
_displayNameMapDict[nameof(d.IgnoreAnsiNulls)] = "Ignore Ansi Nulls";
_displayNameMapDict[nameof(d.IgnoreAuthorizer)] = "Ignore Authorizer";
_displayNameMapDict[nameof(d.IgnoreColumnCollation)] = "Ignore Column Collation";
_displayNameMapDict[nameof(d.IgnoreColumnOrder)] = "Ignore Column Order";
_displayNameMapDict[nameof(d.IgnoreComments)] = "Ignore Comments";
_displayNameMapDict[nameof(d.IgnoreCryptographicProviderFilePath)] = "Ignore Cryptographic Provider File Path";
_displayNameMapDict[nameof(d.IgnoreDatabaseWorkloadGroups)] = "Ignore Database Workload Groups";
_displayNameMapDict[nameof(d.IgnoreDdlTriggerOrder)] = "Ignore Ddl Trigger Order";
_displayNameMapDict[nameof(d.IgnoreDdlTriggerState)] = "Ignore Ddl Trigger State";
_displayNameMapDict[nameof(d.IgnoreDefaultSchema)] = "Ignore Default Schema";
_displayNameMapDict[nameof(d.IgnoreDmlTriggerOrder)] = "Ignore Dml Trigger Order";
_displayNameMapDict[nameof(d.IgnoreDmlTriggerState)] = "Ignore Dml Trigger State";
_displayNameMapDict[nameof(d.IgnoreExtendedProperties)] = "Ignore Extended Properties";
_displayNameMapDict[nameof(d.IgnoreFileAndLogFilePath)] = "Ignore File And Log File Path";
_displayNameMapDict[nameof(d.IgnoreFileSize)] = "Ignore File Size";
_displayNameMapDict[nameof(d.IgnoreFilegroupPlacement)] = "Ignore File Group Placement";
_displayNameMapDict[nameof(d.IgnoreFillFactor)] = "Ignore Fill Factor";
_displayNameMapDict[nameof(d.IgnoreFullTextCatalogFilePath)] = "Ignore Full Text Catalog File Path";
_displayNameMapDict[nameof(d.IgnoreIdentitySeed)] = "Ignore Identity Seed";
_displayNameMapDict[nameof(d.IgnoreIncrement)] = "Ignore Increment";
_displayNameMapDict[nameof(d.IgnoreIndexOptions)] = "Ignore Index Options";
_displayNameMapDict[nameof(d.IgnoreIndexPadding)] = "Ignore Index Padding";
_displayNameMapDict[nameof(d.IgnoreKeywordCasing)] = "Ignore Keyword Casing";
_displayNameMapDict[nameof(d.IgnoreLockHintsOnIndexes)] = "IgnoreLock Hints On Indexes";
_displayNameMapDict[nameof(d.IgnoreLoginSids)] = "IgnoreLogin Sids";
_displayNameMapDict[nameof(d.IgnoreNotForReplication)] = "IgnoreNotForReplication";
_displayNameMapDict[nameof(d.IgnoreObjectPlacementOnPartitionScheme)] = "Ignore Object Placement On Partition Scheme";
_displayNameMapDict[nameof(d.IgnorePartitionSchemes)] = "Ignore Partition Schemes";
_displayNameMapDict[nameof(d.IgnorePermissions)] = "Ignore Permissions";
_displayNameMapDict[nameof(d.IgnoreQuotedIdentifiers)] = "Ignore Quoted Identifiers";
_displayNameMapDict[nameof(d.IgnoreRoleMembership)] = "Ignore Role Membership";
_displayNameMapDict[nameof(d.IgnoreRouteLifetime)] = "Ignore Route Lifetime";
_displayNameMapDict[nameof(d.IgnoreSemicolonBetweenStatements)] = "Ignore Semicolon Between Statements";
_displayNameMapDict[nameof(d.IgnoreTableOptions)] = "Ignore Table Options";
_displayNameMapDict[nameof(d.IgnoreTablePartitionOptions)] = "Ignore Table Partition Options";
_displayNameMapDict[nameof(d.IgnoreUserSettingsObjects)] = "Ignore User Settings Objects";
_displayNameMapDict[nameof(d.IgnoreWhitespace)] = "Ignore Whitespace";
_displayNameMapDict[nameof(d.IgnoreWithNocheckOnCheckConstraints)] = "Ignore With Nocheck On Check Constraints";
_displayNameMapDict[nameof(d.IgnoreWithNocheckOnForeignKeys)] = "Ignore With Nocheck On Foreign Keys";
_displayNameMapDict[nameof(d.IgnoreWorkloadClassifiers)] = "Ignore Workload Classifiers";
_displayNameMapDict[nameof(d.IncludeCompositeObjects)] = "Include Composite Objects";
_displayNameMapDict[nameof(d.IncludeTransactionalScripts)] = "Include Transactional Scripts";
_displayNameMapDict[nameof(d.IsAlwaysEncryptedParameterizationEnabled)] = "Is Always Encrypted Parameterization Enabled";
_displayNameMapDict[nameof(d.LongRunningCommandTimeout)] = "Long Running Command Timeout";
_displayNameMapDict[nameof(d.NoAlterStatementsToChangeClrTypes)] = "No Alter Statements To Change Clr Types";
_displayNameMapDict[nameof(d.PopulateFilesOnFileGroups)] = "Populate Files On File Groups";
_displayNameMapDict[nameof(d.PreserveIdentityLastValues)] = "Preserve Identity Last Values";
_displayNameMapDict[nameof(d.RebuildIndexesOfflineForDataPhase)] = "Rebuild Indexes Offline For Data Phase";
_displayNameMapDict[nameof(d.RegisterDataTierApplication)] = "Register Data Tier Application";
_displayNameMapDict[nameof(d.RestoreSequenceCurrentValue)] = "Restore Sequence Current Value";
_displayNameMapDict[nameof(d.RunDeploymentPlanExecutors)] = "Run Deployment Plan Executors";
_displayNameMapDict[nameof(d.ScriptDatabaseCollation)] = "Script Database Collation";
_displayNameMapDict[nameof(d.ScriptDatabaseCompatibility)] = "Script Database Compatibility";
_displayNameMapDict[nameof(d.ScriptDatabaseOptions)] = "Script Database Options";
_displayNameMapDict[nameof(d.ScriptDeployStateChecks)] = "Script Deploy State Checks";
_displayNameMapDict[nameof(d.ScriptFileSize)] = "Script File Size";
_displayNameMapDict[nameof(d.ScriptNewConstraintValidation)] = "Script New Constraint Validation";
_displayNameMapDict[nameof(d.ScriptRefreshModule)] = "Script Refresh Module";
_displayNameMapDict[nameof(d.SqlCommandVariableValues)] = "Sql Command Variable Values";
_displayNameMapDict[nameof(d.TreatVerificationErrorsAsWarnings)] = "Treat Verification Errors As Warnings";
_displayNameMapDict[nameof(d.UnmodifiableObjectWarnings)] = "Unmodifiable Object Warnings";
_displayNameMapDict[nameof(d.VerifyCollationCompatibility)] = "Verify Collation Compatibility";
_displayNameMapDict[nameof(d.VerifyDeployment)] = "Verify Deployment";
#endregion
}
public DeploymentOptions()
{
DacDeployOptions options = new DacDeployOptions();
// Setting Display names for all dacDeploy options
SetDisplayNameForOption();
// Adding these defaults to ensure behavior similarity with other tools. Dacfx and SSMS import/export wizards use these defaults.
// Tracking the full fix : https://github.com/microsoft/azuredatastudio/issues/5599
options.AllowDropBlockingAssemblies = true;
@@ -416,26 +99,13 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
options.IgnoreKeywordCasing = false;
options.IgnoreSemicolonBetweenStatements = false;
PropertyInfo[] deploymentOptionsProperties = this.GetType().GetProperties();
foreach (var deployOptionsProp in deploymentOptionsProperties)
{
var prop = options.GetType().GetProperty(deployOptionsProp.Name);
// Note that we set excluded object types here since dacfx has this value as null;
if (prop != null && deployOptionsProp.Name != "ExcludeObjectTypes")
{
// Setting DacFx default values to the generic deployment options properties.
SetGenericDeployOptionProps(prop, options, deployOptionsProp);
}
}
// Initializing the default boolean type options to the BooleanOptionsDictionary
// Not considering DacFx default ExcludeObjectTypes, as it has some STS defaults which needs to be considered here, DacFx defaults are only considered for InitializeFromProfile(), where options are loading from profile
InitializeBooleanTypeOptions(options);
}
public DeploymentOptions(DacDeployOptions options)
{
// Setting Display names for all dacDeploy options
SetDisplayNameForOption();
SetOptions(options);
}
@@ -480,35 +150,66 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
SetOptions(options);
}
/// <summary>
/// Populates BooleanOptionsDictionary with the boolean type properties
/// </summary>
/// <param name="options"></param>
public void InitializeBooleanTypeOptions(DacDeployOptions options)
{
PropertyInfo[] dacDeploymentOptionsProperties = options.GetType().GetProperties();
foreach (PropertyInfo prop in dacDeploymentOptionsProperties)
{
if (prop != null && prop.PropertyType == typeof(System.Boolean))
{
object setProp = GetDeploymentOptionProp(prop, options);
this.BooleanOptionsDictionary[prop.Name] = (DeploymentOptionProperty<bool>)setProp;
}
}
}
public void SetOptions(DacDeployOptions options)
{
System.Reflection.PropertyInfo[] deploymentOptionsProperties = this.GetType().GetProperties();
// Set the default options properties
InitializeBooleanTypeOptions(options);
InitializeNonBooleanTypeOptions(options);
}
foreach (var deployOptionsProp in deploymentOptionsProperties)
/// <summary>
/// Preparing all non boolean properties (except BooleanOptionsDictionary)
/// </summary>
/// <param name="options"></param>
public void InitializeNonBooleanTypeOptions(DacDeployOptions options)
{
// preparing remaining properties
PropertyInfo[] deploymentOptionsProperties = this.GetType().GetProperties();
foreach (PropertyInfo deployOptionsProp in deploymentOptionsProperties)
{
var prop = options.GetType().GetProperty(deployOptionsProp.Name);
// Note that we set excluded object types here since dacfx has this value as null;
if (prop != null)
if (deployOptionsProp.Name != nameof(DeploymentOptions.BooleanOptionsDictionary))
{
SetGenericDeployOptionProps(prop, options, deployOptionsProp);
PropertyInfo prop = options.GetType().GetProperty(deployOptionsProp.Name);
object setProp = GetDeploymentOptionProp(prop, options);
deployOptionsProp.SetValue(this, setProp);
}
}
}
/// <summary>
/// Sets the Value and Description to all properties
/// Prepares and returns the value and description of a property
/// </summary>
/// <param name="prop"></param>
/// <param name="val"></param>
/// <param name="deployOptionsProp"></param>
public void SetGenericDeployOptionProps(PropertyInfo prop, DacDeployOptions options, PropertyInfo deployOptionsProp)
/// <param name="options"></param>
public object GetDeploymentOptionProp(PropertyInfo prop, DacDeployOptions options)
{
var val = prop.GetValue(options);
var attribute = prop.GetCustomAttributes<DescriptionAttribute>(true).FirstOrDefault();
Type type = val != null ? typeof(DeploymentOptionProperty<>).MakeGenericType(val.GetType())
DescriptionAttribute descriptionAttribute = prop.GetCustomAttributes<DescriptionAttribute>().FirstOrDefault();
DisplayNameAttribute displayNameAttribute = prop.GetCustomAttributes<DisplayNameAttribute>().FirstOrDefault();
Type type = val != null ? typeof(DeploymentOptionProperty<>).MakeGenericType(val.GetType())
: typeof(DeploymentOptionProperty<>).MakeGenericType(prop.PropertyType);
object setProp = Activator.CreateInstance(type, val, attribute.Description,_displayNameMapDict[deployOptionsProp.Name]);
deployOptionsProp.SetValue(this, setProp);
object setProp = Activator.CreateInstance(type, val,
(descriptionAttribute != null ? descriptionAttribute.Description : ""),
(displayNameAttribute != null ? displayNameAttribute.DisplayName : ""));
return setProp;
}
public static DeploymentOptions GetDefaultSchemaCompareOptions()

View File

@@ -4,6 +4,7 @@
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
@@ -14,6 +15,7 @@ using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
{
@@ -23,31 +25,60 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
/// </summary>
internal static class SchemaCompareUtils
{
/// <summary>
/// Converts DeploymentOptions used in STS and ADS to DacDeployOptions which can be passed to the DacFx apis
/// </summary>
/// <param name="deploymentOptions"></param>
/// <returns>DacDeployOptions</returns
internal static DacDeployOptions CreateSchemaCompareOptions(DeploymentOptions deploymentOptions)
{
PropertyInfo[] deploymentOptionsProperties = deploymentOptions.GetType().GetProperties();
DacDeployOptions dacOptions = new DacDeployOptions();
foreach (var deployOptionsProp in deploymentOptionsProperties)
try
{
var prop = dacOptions.GetType().GetProperty(deployOptionsProp.Name);
if (prop != null)
{
var val = deployOptionsProp.GetValue(deploymentOptions);
var selectedVal = val.GetType().GetProperty("Value").GetValue(val);
PropertyInfo[] deploymentOptionsProperties = deploymentOptions.GetType().GetProperties();
// JSON.NET by default reads Number type as Int64, deserializing an object type to dacOptions of Int32 type required to convert into Int32 from Int64.
// If not converted setting value(Int64) to dacOption(Int32) will throw {"Object of type 'System.Int64' cannot be converted to type 'System.Int32'."}.
// As these integer type options are non-editable and are not availbale in ADS to update, integer overflow exception will not be happening here.
if (selectedVal != null && selectedVal.GetType() == typeof(System.Int64))
DacDeployOptions dacOptions = new DacDeployOptions();
Type propType = dacOptions.GetType();
Dictionary<string, DeploymentOptionProperty<bool>> booleanOptionsDictionary = new Dictionary<string, DeploymentOptionProperty<bool>>();
foreach (PropertyInfo deployOptionsProp in deploymentOptionsProperties)
{
var prop = propType.GetProperty(deployOptionsProp.Name);
if (prop != null)
{
selectedVal = Convert.ToInt32(selectedVal);
var val = deployOptionsProp.GetValue(deploymentOptions);
var selectedVal = val.GetType().GetProperty("Value").GetValue(val);
// Set the excludeObjectTypes values to the DacDeployOptions
if (selectedVal != null && deployOptionsProp.Name == nameof(deploymentOptions.ExcludeObjectTypes))
{
prop.SetValue(dacOptions, selectedVal);
}
}
prop.SetValue(dacOptions, selectedVal);
// BooleanOptionsDictionary has all the deployment options and is being processed separately in the second iteration by collecting here
if (deployOptionsProp.Name == nameof(deploymentOptions.BooleanOptionsDictionary))
{
booleanOptionsDictionary = deploymentOptions.BooleanOptionsDictionary as Dictionary<string, DeploymentOptionProperty<bool>>;
}
}
// Iterating through the updated boolean options coming from the booleanOptionsDictionary and assigning them to DacDeployOptions
foreach (KeyValuePair<string, DeploymentOptionProperty<bool>> deployOptionsProp in booleanOptionsDictionary)
{
var prop = propType.GetProperty(deployOptionsProp.Key);
if (prop != null)
{
var selectedVal = deployOptionsProp.Value.Value;
prop.SetValue(dacOptions, selectedVal);
}
}
return dacOptions;
}
catch (Exception e)
{
Logger.Write(TraceEventType.Error, string.Format("Schema compare create options model failed: {0}", e.Message));
throw;
}
return dacOptions;
}
internal static DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent)

View File

@@ -18,6 +18,7 @@ using Microsoft.SqlTools.ServiceLayer.TaskServices;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using NUnit.Framework;
using Moq;
using System.Reflection;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.DacFx
{
@@ -586,11 +587,13 @@ FROM MissingEdgeHubInputStream'";
UpgradeExisting = true,
DeploymentOptions = new DeploymentOptions()
{
DropObjectsNotInSource = new DeploymentOptionProperty<bool>(false),
ExcludeObjectTypes = new DeploymentOptionProperty<ObjectType[]>(new[] { ObjectType.Views })
}
};
// Updating the BooleanOptionsDictionary since it has all the boolean type options
deployParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.DropObjectsNotInSource)].Value = false;
// expect table3 to not have been dropped and view1 to not have been created
await VerifyDeployWithOptions(deployParams, targetDb, service, result.ConnectionInfo, expectedTableResult: "table3", expectedViewResult: null);
@@ -664,11 +667,13 @@ FROM MissingEdgeHubInputStream'";
DatabaseName = targetDb.DatabaseName,
DeploymentOptions = new DeploymentOptions()
{
DropObjectsNotInSource = new DeploymentOptionProperty<bool>(false),
ExcludeObjectTypes = new DeploymentOptionProperty<ObjectType[]>(new[] { ObjectType.Views })
}
};
// Updating the BooleanOptionsDictionary since it has all the boolean type properties
generateScriptFalseOptionParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.DropObjectsNotInSource)].Value = false;
var generateScriptFalseOptionOperation = new GenerateDeployScriptOperation(generateScriptFalseOptionParams, result.ConnectionInfo);
service.PerformOperation(generateScriptFalseOptionOperation, TaskExecutionMode.Execute);
@@ -682,7 +687,6 @@ FROM MissingEdgeHubInputStream'";
DatabaseName = targetDb.DatabaseName,
DeploymentOptions = new DeploymentOptions()
{
DropObjectsNotInSource = new DeploymentOptionProperty<bool>(true),
ExcludeObjectTypes = new DeploymentOptionProperty<ObjectType[]>( new[] { ObjectType.Views })
}
};
@@ -727,10 +731,10 @@ FROM MissingEdgeHubInputStream'";
DeploymentOptions expectedResults = DeploymentOptions.GetDefaultPublishOptions();
expectedResults.ExcludeObjectTypes = null;
expectedResults.IncludeCompositeObjects = new DeploymentOptionProperty<bool>(true);
expectedResults.BlockOnPossibleDataLoss = new DeploymentOptionProperty<bool>(true);
expectedResults.AllowIncompatiblePlatform = new DeploymentOptionProperty<bool>(true);
expectedResults.DisableIndexesForDataPhase = new DeploymentOptionProperty<bool>(false);
expectedResults.BooleanOptionsDictionary[nameof(DacDeployOptions.IncludeCompositeObjects)].Value = true;
expectedResults.BooleanOptionsDictionary[nameof(DacDeployOptions.BlockOnPossibleDataLoss)].Value = true;
expectedResults.BooleanOptionsDictionary[nameof(DacDeployOptions.AllowIncompatiblePlatform)].Value = true;
expectedResults.BooleanOptionsDictionary[nameof(DacDeployOptions.DisableIndexesForDataPhase)].Value = false;
var dacfxRequestContext = new Mock<RequestContext<DacFxOptionsResult>>();
dacfxRequestContext.Setup((RequestContext<DacFxOptionsResult> x) => x.SendResult(It.Is<DacFxOptionsResult>((result) => ValidateOptions(expectedResults, result.DeploymentOptions) == true))).Returns(Task.FromResult(new object()));
@@ -755,7 +759,7 @@ FROM MissingEdgeHubInputStream'";
{
DeploymentOptions expectedResults = DeploymentOptions.GetDefaultPublishOptions();
expectedResults.ExcludeObjectTypes = null;
expectedResults.DisableIndexesForDataPhase = new DeploymentOptionProperty<bool>(false);
expectedResults.BooleanOptionsDictionary["DisableIndexesForDataPhase"].Value = false;
var dacfxRequestContext = new Mock<RequestContext<DacFxOptionsResult>>();
dacfxRequestContext.Setup((RequestContext<DacFxOptionsResult> x) => x.SendResult(It.Is<DacFxOptionsResult>((result) => ValidateOptions(expectedResults, result.DeploymentOptions) == true))).Returns(Task.FromResult(new object()));
@@ -842,26 +846,37 @@ Streaming query statement contains a reference to missing output stream 'Missing
private bool ValidateOptions(DeploymentOptions expected, DeploymentOptions actual)
{
System.Reflection.PropertyInfo[] deploymentOptionsProperties = expected.GetType().GetProperties();
foreach (var v in deploymentOptionsProperties)
var booleanOptionsDictionary = new Dictionary<string, DeploymentOptionProperty<bool>>();
foreach (PropertyInfo v in deploymentOptionsProperties)
{
var defaultP = v.GetValue(expected);
var defaultPValue = defaultP != null ? defaultP.GetType().GetProperty("Value").GetValue(defaultP): defaultP;
var actualP = v.GetValue(actual);
var actualPValue = actualP.GetType().GetProperty("Value").GetValue(actualP);
if (v.Name == "ExcludeObjectTypes")
if (v.Name != nameof(DeploymentOptions.BooleanOptionsDictionary))
{
Assert.True((defaultP as ObjectType[])?.Length == (actualP as ObjectType[])?.Length, "Number of excluded objects is different not equal");
var defaultP = v.GetValue(expected);
var defaultPValue = defaultP != null ? defaultP.GetType().GetProperty("Value").GetValue(defaultP) : defaultP;
var actualP = v.GetValue(actual);
var actualPValue = actualP.GetType().GetProperty("Value").GetValue(actualP);
if (v.Name == nameof(DeploymentOptions.ExcludeObjectTypes))
{
Assert.True((defaultP as ObjectType[])?.Length == (actualP as ObjectType[])?.Length, "Number of excluded objects is different not equal");
}
else
{
//Verifying expected and actual deployment options properties are equal
Assert.True((defaultPValue == null && String.IsNullOrEmpty(actualPValue as string))
|| (defaultPValue).Equals(actualPValue)
, $"Actual Property from Service is not equal to default property for {v.Name}, Actual value: {actualPValue} and Default value: {defaultPValue}");
}
}
else
{
//Verifying expected and actual deployment options properties are equal
Assert.True((defaultPValue == null && String.IsNullOrEmpty(actualPValue as string))
|| (defaultPValue).Equals(actualPValue)
, $"Actual Property from Service is not equal to default property for {v.Name}, Actual value: {actualPValue} and Default value: {defaultPValue}");
booleanOptionsDictionary = v.GetValue(expected) as Dictionary<string, DeploymentOptionProperty<bool>>;
}
}
// Verify expected and actual DeploymentOptions BooleanOptionsDictionary
VerifyExpectedAndActualBooleanOptionsDictionary(booleanOptionsDictionary, actual.BooleanOptionsDictionary);
return true;
}
@@ -895,5 +910,21 @@ Streaming query statement contains a reference to missing output stream 'Missing
File.Delete(filePath);
}
}
/// <summary>
/// Verify expected and actual DeploymentOptions BooleanOptionsDictionary values
/// </summary>
/// <param name="expectedBooleanOptionsDictionary"></param>
/// <param name="actualBooleanOptionsDictionary"></param>
public void VerifyExpectedAndActualBooleanOptionsDictionary(Dictionary<string, DeploymentOptionProperty<bool>> expectedBooleanOptionsDictionary, Dictionary<string, DeploymentOptionProperty<bool>> actualBooleanOptionsDictionary)
{
foreach (KeyValuePair<string, DeploymentOptionProperty<bool>> optionRow in expectedBooleanOptionsDictionary)
{
var expectedValue = optionRow.Value.Value;
var actualValue = actualBooleanOptionsDictionary[optionRow.Key].Value;
Assert.That(actualValue, Is.EqualTo(expectedValue), $"Actual Property from Service is not equal to default property for {optionRow.Key}");
}
}
}
}

View File

@@ -72,7 +72,7 @@ END
private DeploymentOptions GetIgnoreColumnOptions()
{
var options = new DeploymentOptions();
options.IgnoreColumnOrder = new DeploymentOptionProperty<bool>(true);
options.BooleanOptionsDictionary[nameof(DacDeployOptions.IgnoreColumnOrder)].Value = true;
return options;
}

View File

@@ -20,6 +20,7 @@ using System.Threading.Tasks;
using NUnit.Framework;
using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper;
using System.Collections.Generic;
using Microsoft.SqlServer.Dac;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
{
@@ -1823,22 +1824,21 @@ WITH VALUES
{
SourceEndpointInfo = sourceInfo,
TargetEndpointInfo = targetInfo,
DeploymentOptions = new DeploymentOptions()
{
// change some random ones explicitly
AllowDropBlockingAssemblies = new DeploymentOptionProperty<bool>(true),
DropConstraintsNotInSource = new DeploymentOptionProperty<bool>(true),
IgnoreAnsiNulls = new DeploymentOptionProperty<bool>(true),
NoAlterStatementsToChangeClrTypes = new DeploymentOptionProperty<bool>(false),
PopulateFilesOnFileGroups = new DeploymentOptionProperty<bool>(false),
VerifyDeployment = new DeploymentOptionProperty<bool>(false),
DisableIndexesForDataPhase = new DeploymentOptionProperty<bool>(false)
},
DeploymentOptions = new DeploymentOptions(),
ScmpFilePath = filePath,
ExcludedSourceObjects = schemaCompareObjectIds,
ExcludedTargetObjects = null,
};
// change some random ones explicitly
schemaCompareParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.AllowDropBlockingAssemblies)].Value = true;
schemaCompareParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.DropConstraintsNotInSource)].Value = true;
schemaCompareParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.IgnoreAnsiNulls)].Value = true;
schemaCompareParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.NoAlterStatementsToChangeClrTypes)].Value = false;
schemaCompareParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.PopulateFilesOnFileGroups)].Value = false;
schemaCompareParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.VerifyDeployment)].Value = false;
schemaCompareParams.DeploymentOptions.BooleanOptionsDictionary[nameof(DacDeployOptions.DisableIndexesForDataPhase)].Value = false;
SchemaCompareSaveScmpOperation schemaCompareOperation = new SchemaCompareSaveScmpOperation(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
schemaCompareOperation.Execute(TaskExecutionMode.Execute);

View File

@@ -6,6 +6,7 @@
using Microsoft.SqlServer.Dac;
using Microsoft.SqlTools.ServiceLayer.DacFx;
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.DacFx;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
@@ -14,6 +15,8 @@ using NUnit.Framework;
using System;
using System.IO;
using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper;
using System.Collections.Generic;
using System.Reflection;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
{
@@ -129,25 +132,29 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
// TODO: update with new options. Tracking issue: https://github.com/microsoft/azuredatastudio/issues/15336
//Assert.True(deploymentOptionsProperties.Length == dacDeployProperties.Length - 2, $"Number of properties is not same Deployment options : {deploymentOptionsProperties.Length} DacFx options : {dacDeployProperties.Length}");
foreach (var deployOptionsProp in deploymentOptionsProperties)
foreach (PropertyInfo deployOptionsProp in deploymentOptionsProperties)
{
var dacProp = dacDeployOptions.GetType().GetProperty(deployOptionsProp.Name);
Assert.True(dacProp != null, $"DacDeploy property not present for {deployOptionsProp.Name}");
var deployOptionsValue = deployOptionsProp.GetValue(deploymentOptions);
var changedDacValue = deployOptionsValue != null ? deployOptionsValue.GetType().GetProperty("Value").GetValue(deployOptionsValue) : deployOptionsValue;
var dafaultDacValue = dacProp.GetValue(dacDeployOptions);
if (deployOptionsProp.Name != "ExcludeObjectTypes") // do not compare for ExcludeObjectTypes because it will be different
if (deployOptionsProp.Name != nameof(DeploymentOptions.BooleanOptionsDictionary))
{
Assert.True((deployOptionsValue == null && dafaultDacValue == null)
|| deployOptionsValue.Equals(dafaultDacValue)
|| changedDacValue == null && (dafaultDacValue as string) == string.Empty
|| changedDacValue == null && dafaultDacValue == null
|| (changedDacValue).Equals(dafaultDacValue)
, $"DacFx DacDeploy property not equal to Tools Service DeploymentOptions for { deployOptionsProp.Name}, SchemaCompareOptions value: {changedDacValue} and DacDeployOptions value: {dafaultDacValue} ");
var dacProp = dacDeployOptions.GetType().GetProperty(deployOptionsProp.Name);
Assert.That(dacProp, Is.Not.Null, $"DacDeploy property not present for {deployOptionsProp.Name}");
var defaultP = deployOptionsProp.GetValue(deploymentOptions);
var defaultPValue = defaultP != null ? defaultP.GetType().GetProperty("Value").GetValue(defaultP) : defaultP;
var actualPValue = dacProp.GetValue(dacDeployOptions);
if (deployOptionsProp.Name != nameof(DeploymentOptions.ExcludeObjectTypes)) // do not compare for ExcludeObjectTypes because it will be different
{
// Verifying expected and actual deployment options properties are equal
Assert.True((defaultPValue == null && String.IsNullOrEmpty(actualPValue as string))
|| (defaultPValue).Equals(actualPValue)
, $"DacFx DacDeploy property not equal to Tools Service DeploymentOptions for {deployOptionsProp.Name}, Actual value: {actualPValue} and Default value: {defaultPValue}");
}
}
}
// Verify the booleanOptionsDictionary with the DacDeployOptions property values
VerifyBooleanOptionsDictionary(deploymentOptions.BooleanOptionsDictionary, dacDeployOptions);
}
internal static bool ValidateOptionsEqualsDefault(SchemaCompareOptionsResult options)
@@ -156,26 +163,52 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
DeploymentOptions actualOpt = options.DefaultDeploymentOptions;
System.Reflection.PropertyInfo[] deploymentOptionsProperties = defaultOpt.GetType().GetProperties();
foreach (var v in deploymentOptionsProperties)
foreach (PropertyInfo v in deploymentOptionsProperties)
{
var defaultP = v.GetValue(defaultOpt);
var defaultPValue = defaultP != null ? defaultP.GetType().GetProperty("Value").GetValue(defaultP) : defaultP;
var actualP = v.GetValue(actualOpt);
var actualPValue = actualP.GetType().GetProperty("Value").GetValue(actualP);
if (v.Name != nameof(DeploymentOptions.BooleanOptionsDictionary))
{
var defaultP = v.GetValue(defaultOpt);
var defaultPValue = defaultP != null ? defaultP.GetType().GetProperty("Value").GetValue(defaultP) : defaultP;
var actualP = v.GetValue(actualOpt);
var actualPValue = actualP.GetType().GetProperty("Value").GetValue(actualP);
if (v.Name == "ExcludeObjectTypes")
{
Assert.True((defaultPValue as ObjectType[]).Length == (actualPValue as ObjectType[]).Length, $"Number of excluded objects is different; expected: {(defaultPValue as ObjectType[]).Length} actual: {(actualPValue as ObjectType[]).Length}");
}
else
{
// Verifying expected and actual deployment options properties are equal
Assert.True((defaultPValue == null && String.IsNullOrEmpty(actualPValue as string))
|| (defaultPValue).Equals(actualPValue)
, $"Actual Property from Service is not equal to default property for {v.Name}, Actual value: {actualPValue} and Default value: {defaultPValue}");
if (v.Name == nameof(DeploymentOptions.ExcludeObjectTypes))
{
Assert.That((defaultPValue as ObjectType[]).Length, Is.EqualTo((actualPValue as ObjectType[]).Length), $"Number of excluded objects is different; expected: {(defaultPValue as ObjectType[]).Length} actual: {(actualPValue as ObjectType[]).Length}");
}
else
{
// Verifying expected and actual deployment options properties are equal
Assert.True((defaultPValue == null && String.IsNullOrEmpty(actualPValue as string))
|| (defaultPValue).Equals(actualPValue)
, $"Actual Property from Service is not equal to default property for {v.Name}, Actual value: {actualPValue} and Default value: {defaultPValue}");
}
}
}
// Verify the default booleanOptionsDictionary with the SchemaCompareOptionsResult options property values
DacFxServiceTests dacFxServiceTests = new DacFxServiceTests();
dacFxServiceTests.VerifyExpectedAndActualBooleanOptionsDictionary(defaultOpt.BooleanOptionsDictionary, options.DefaultDeploymentOptions.BooleanOptionsDictionary);
return true;
}
/// <summary>
/// Validates the DeploymentOptions booleanOptionsDictionary with the DacDeployOptions
/// </summary>
/// <param name="expectedBooleanOptionsDictionary"></param>
/// <param name="dacDeployOptions"></param>
private static void VerifyBooleanOptionsDictionary(Dictionary<string, DeploymentOptionProperty<bool>> expectedBooleanOptionsDictionary, DacDeployOptions dacDeployOptions)
{
foreach (KeyValuePair<string, DeploymentOptionProperty<bool>> optionRow in expectedBooleanOptionsDictionary)
{
var dacProp = dacDeployOptions.GetType().GetProperty(optionRow.Key);
Assert.That(dacProp, Is.Not.Null, $"DacDeploy property not present for {optionRow.Key}");
var actualValue = dacProp.GetValue(dacDeployOptions);
var expectedValue = optionRow.Value.Value;
Assert.That(actualValue, Is.EqualTo(expectedValue), $"Actual Property from Service is not equal to default property for {optionRow.Key}");
}
}
}
}