Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 16 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
390 changes: 58 additions & 332 deletions src/Microsoft.SqlTools.ServiceLayer/DacFx/Contracts/DeploymentOptions.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ internal static DacDeployOptions CreateSchemaCompareOptions(DeploymentOptions de
PropertyInfo[] deploymentOptionsProperties = deploymentOptions.GetType().GetProperties();
ssreerama marked this conversation as resolved.
Show resolved Hide resolved

DacDeployOptions dacOptions = new DacDeployOptions();
var optionsMapTable = new Dictionary<string, DeploymentOptionProperty<bool>>();
ssreerama marked this conversation as resolved.
Show resolved Hide resolved

// Get the optionsMapTable property which has the updated option values
foreach (var deployOptionsProp in deploymentOptionsProperties)
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
{
var prop = dacOptions.GetType().GetProperty(deployOptionsProp.Name);
Expand All @@ -36,14 +39,27 @@ internal static DacDeployOptions CreateSchemaCompareOptions(DeploymentOptions de
var val = deployOptionsProp.GetValue(deploymentOptions);
var selectedVal = val.GetType().GetProperty("Value").GetValue(val);

// 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))
// Set the excludeObjectTypes values to the DacDeployOptions
if (selectedVal != null && deployOptionsProp.Name == "ExcludeObjectTypes")
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
{
selectedVal = Convert.ToInt32(selectedVal);
prop.SetValue(dacOptions, selectedVal);
}
}

// Exclude the direct properties values and considering the optionsMapTable values
if (deployOptionsProp.Name == "OptionsMapTable")
{
optionsMapTable = deploymentOptions.OptionsMapTable as Dictionary<string, DeploymentOptionProperty<bool>>;
}
}

// Iterating through the updated boolean options coming from the optionsMapTable and assigning them to DacDeployOptions
foreach (var deployOptionsProp in optionsMapTable)
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
{
var prop = dacOptions.GetType().GetProperty(deployOptionsProp.Value.PropertyName);
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
if (prop != null)
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
{
var selectedVal = deployOptionsProp.Value.Value;
prop.SetValue(dacOptions, selectedVal);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,11 +586,13 @@ public async Task DeployWithOptions()
UpgradeExisting = true,
DeploymentOptions = new DeploymentOptions()
{
DropObjectsNotInSource = new DeploymentOptionProperty<bool>(false),
ExcludeObjectTypes = new DeploymentOptionProperty<ObjectType[]>(new[] { ObjectType.Views })
}
};

// Updating the OptionsMapTable Since the deployment options model to the DacFx is generated using OptionsMapTable
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
deployParams.DeploymentOptions.OptionsMapTable["Drop objects not in source"].Value = false;
ssreerama marked this conversation as resolved.
Show resolved Hide resolved

// 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);

Expand Down Expand Up @@ -664,11 +666,13 @@ public async Task GenerateDeployScriptWithOptions()
DatabaseName = targetDb.DatabaseName,
DeploymentOptions = new DeploymentOptions()
{
DropObjectsNotInSource = new DeploymentOptionProperty<bool>(false),
ExcludeObjectTypes = new DeploymentOptionProperty<ObjectType[]>(new[] { ObjectType.Views })
}
};

// Updating the OptionsMapTable Since the deployment options model to the DacFx is generated using OptionsMapTable
generateScriptFalseOptionParams.DeploymentOptions.OptionsMapTable["Drop objects not in source"].Value = false;

var generateScriptFalseOptionOperation = new GenerateDeployScriptOperation(generateScriptFalseOptionParams, result.ConnectionInfo);
service.PerformOperation(generateScriptFalseOptionOperation, TaskExecutionMode.Execute);

Expand All @@ -682,7 +686,6 @@ public async Task GenerateDeployScriptWithOptions()
DatabaseName = targetDb.DatabaseName,
DeploymentOptions = new DeploymentOptions()
{
DropObjectsNotInSource = new DeploymentOptionProperty<bool>(true),
ExcludeObjectTypes = new DeploymentOptionProperty<ObjectType[]>( new[] { ObjectType.Views })
}
};
Expand Down Expand Up @@ -727,10 +730,10 @@ public async Task GetOptionsFromProfile()
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.OptionsMapTable["Include composite objects"].Value = true;
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
expectedResults.OptionsMapTable["Block on possible data loss"].Value = true;
expectedResults.OptionsMapTable["Allow incompatible platform"].Value = true;
expectedResults.OptionsMapTable["Disable indexes for data phase"].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()));
Expand All @@ -755,7 +758,7 @@ public async Task GetOptionsFromProfileWithoutOptions()
{
DeploymentOptions expectedResults = DeploymentOptions.GetDefaultPublishOptions();
expectedResults.ExcludeObjectTypes = null;
expectedResults.DisableIndexesForDataPhase = new DeploymentOptionProperty<bool>(false);
expectedResults.OptionsMapTable["Disable indexes for data phase"].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()));
Expand Down Expand Up @@ -842,26 +845,37 @@ private bool ValidateStreamingJobErrors(ValidateStreamingJobResult expected, Val
private bool ValidateOptions(DeploymentOptions expected, DeploymentOptions actual)
{
System.Reflection.PropertyInfo[] deploymentOptionsProperties = expected.GetType().GetProperties();
var optionsMapTable = new Dictionary<string, DeploymentOptionProperty<bool>>();
ssreerama marked this conversation as resolved.
Show resolved Hide resolved
foreach (var 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 != "OptionsMapTable")
{
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 == "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}");
optionsMapTable = v.GetValue(expected) as Dictionary<string, DeploymentOptionProperty<bool>>;
}
}

// Verify expected and actual DeploymentOptions OptionsMapTables
VerifyExpectedAndActualOptionsMapTables(optionsMapTable, actual.OptionsMapTable);

return true;
}

Expand Down Expand Up @@ -895,5 +909,21 @@ private void VerifyAndCleanup(string filePath)
File.Delete(filePath);
}
}

/// <summary>
/// Verify expected and actual DeploymentOptions OptionsMapTables values
/// </summary>
/// <param name="expectedOptionsMapTable"></param>
/// <param name="actualOptionsMapTable"></param>
public void VerifyExpectedAndActualOptionsMapTables(Dictionary<string, DeploymentOptionProperty<bool>> expectedOptionsMapTable, Dictionary<string, DeploymentOptionProperty<bool>> actualOptionsMapTable)
{
foreach (var optionRow in expectedOptionsMapTable)
{
var expectedValue = optionRow.Value.Value;
var actualValue = actualOptionsMapTable[optionRow.Key].Value;

Assert.AreEqual(actualValue, expectedValue, $"Actual Property from Service is not equal to default property for {optionRow.Value.PropertyName}, Actual value: {actualValue} and Expected value: {expectedValue}");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ INSERT @returntable
private DeploymentOptions GetIgnoreColumnOptions()
{
var options = new DeploymentOptions();
options.IgnoreColumnOrder = new DeploymentOptionProperty<bool>(true);
options.OptionsMapTable["Ignore column order"].Value = true;
return options;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1823,22 +1823,21 @@ private void CreateAndValidateScmpFile(SchemaCompareEndpointInfo sourceInfo, Sch
{
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.OptionsMapTable["Allow drop blocking assemblies"].Value = true;
schemaCompareParams.DeploymentOptions.OptionsMapTable["Drop constraints not in source"].Value = true;
schemaCompareParams.DeploymentOptions.OptionsMapTable["Ignore ANSI nulls"].Value = true;
schemaCompareParams.DeploymentOptions.OptionsMapTable["No alter statements to change Clr types"].Value = false;
schemaCompareParams.DeploymentOptions.OptionsMapTable["Populate files on File groups"].Value = false;
schemaCompareParams.DeploymentOptions.OptionsMapTable["Verify deployment"].Value = false;
schemaCompareParams.DeploymentOptions.OptionsMapTable["Disable indexes for data phase"].Value = false;
ssreerama marked this conversation as resolved.
Show resolved Hide resolved

SchemaCompareSaveScmpOperation schemaCompareOperation = new SchemaCompareSaveScmpOperation(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
schemaCompareOperation.Execute(TaskExecutionMode.Execute);

Expand Down
Loading