From 95a094438efa945e6c41a7ec604ae3d01ca39f16 Mon Sep 17 00:00:00 2001
From: Kim Santiago <31145923+kisantia@users.noreply.github.com>
Date: Mon, 26 Jun 2023 14:01:28 -1000
Subject: [PATCH] Fix for schema compare dropping constraints (#2120)
* fix for scripts that are displayed in schema compare drop constraints bug
* update DacFx version
* add more comments
---
Packages.props | 2 +-
...chemaCompareIncludeExcludeNodeOperation.cs | 8 ++---
.../SchemaCompare/SchemaCompareOperation.cs | 2 +-
.../SchemaCompare/SchemaCompareUtils.cs | 32 ++++++++++++++-----
.../SchemaCompareServiceTests.cs | 8 ++---
5 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/Packages.props b/Packages.props
index 1788f1bb..a792e2b9 100644
--- a/Packages.props
+++ b/Packages.props
@@ -22,7 +22,7 @@
-
+
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs
index 0373f384..1e2f73db 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs
@@ -71,21 +71,21 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
if(this.Parameters.IncludeRequest)
{
IEnumerable affectedDependencies = this.ComparisonResult.GetIncludeDependencies(node);
- this.AffectedDependencies = affectedDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null)).ToList();
+ this.AffectedDependencies = affectedDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null, schemaComparisonResult: this.ComparisonResult)).ToList();
}
else
{ // if exclude was successful, the possible affected dependencies are given by GetIncludedDependencies()
if(this.Success)
{
IEnumerable affectedDependencies = this.ComparisonResult.GetIncludeDependencies(node);
- this.AffectedDependencies = affectedDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null)).ToList();
+ this.AffectedDependencies = affectedDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null, schemaComparisonResult: this.ComparisonResult)).ToList();
}
// if not successful, send back the exclude dependencies that caused it to fail
else
{
IEnumerable blockingDependencies = this.ComparisonResult.GetExcludeDependencies(node);
blockingDependencies = blockingDependencies.Where(difference => difference.Included == node.Included);
- this.BlockingDependencies = blockingDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null)).ToList();
+ this.BlockingDependencies = blockingDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null, schemaComparisonResult: this.ComparisonResult)).ToList();
}
}
@@ -122,7 +122,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
{
bool result = true;
// Create a diff entry from difference and check if it matches the diff entry passed
- DiffEntry entryFromDifference = SchemaCompareUtils.CreateDiffEntry(difference, null);
+ DiffEntry entryFromDifference = SchemaCompareUtils.CreateDiffEntry(difference, null, schemaComparisonResult: this.ComparisonResult);
System.Reflection.PropertyInfo[] properties = diffEntry.GetType().GetProperties();
foreach (var prop in properties)
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs
index 1b20bb38..e0493699 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs
@@ -121,7 +121,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
foreach (SchemaDifference difference in this.ComparisonResult.Differences)
{
- DiffEntry diffEntry = SchemaCompareUtils.CreateDiffEntry(difference, null);
+ DiffEntry diffEntry = SchemaCompareUtils.CreateDiffEntry(difference, null, this.ComparisonResult);
this.Differences.Add(diffEntry);
}
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs
index ef8ec253..2c7f91cf 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs
@@ -24,7 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
///
internal static partial class SchemaCompareUtils
{
- internal static DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent)
+ internal static DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent, SchemaComparisonResult schemaComparisonResult)
{
if (difference == null)
{
@@ -56,15 +56,31 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
// set source and target scripts
if (difference.SourceObject != null)
{
- string sourceScript;
- difference.SourceObject.TryGetScript(out sourceScript);
- diffEntry.SourceScript = FormatScript(sourceScript);
+ string sourceScript = schemaComparisonResult.GetDiffEntrySourceScript(difference);
+
+ // Child scripts that do not use alter need to be added if they are being changed, ex: "EXECUTE sp_addextendedproperty...".
+ // Don't add scripts that start with alter because those are handled by a top level element's create
+ // ex: if a column changes, then the parent table's script will have the column updated, but GetDiffEntrySourceScript() on the child
+ // will return an alter table statement for updating that column when getting the child script. The child's alter script is unecessary
+ // for displaying the script in schema compare because the comparison displays the create scripts
+ if (!sourceScript.ToLowerInvariant().StartsWith("alter"))
+ {
+ diffEntry.SourceScript = FormatScript(sourceScript);
+ }
}
if (difference.TargetObject != null)
{
- string targetScript;
- difference.TargetObject.TryGetScript(out targetScript);
- diffEntry.TargetScript = FormatScript(targetScript);
+ string targetScript = schemaComparisonResult.GetDiffEntryTargetScript(difference);
+
+ // Child scripts that do not use alter need to be added if they are being changed, ex: "EXECUTE sp_addextendedproperty...".
+ // Don't add scripts that start with alter because those are handled by a top level element's create
+ // ex: if a column changes, then the parent table's script will have the column updated, but GetDiffEntrySourceScript() on the child
+ // will return an alter table script for updating that column when getting the child script. The child's alter script is unecessary
+ // for displaying the script in schema compare because the comparison displays the create scripts
+ if (!targetScript.ToLowerInvariant().StartsWith("alter"))
+ {
+ diffEntry.TargetScript = FormatScript(targetScript);
+ }
}
}
@@ -72,7 +88,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
foreach (SchemaDifference child in difference.Children)
{
- diffEntry.Children.Add(CreateDiffEntry(child, diffEntry));
+ diffEntry.Children.Add(CreateDiffEntry(child, diffEntry, schemaComparisonResult));
}
return diffEntry;
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
index a803e7c5..e28967f1 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
@@ -1568,7 +1568,7 @@ WITH VALUES
Assert.IsNull(schemaCompareOperation.ErrorMessage);
// try to exclude
- DiffEntry t2Diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "t2").First(), null);
+ DiffEntry t2Diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "t2").First(), null, schemaCompareOperation.ComparisonResult);
SchemaCompareNodeParams t2ExcludeParams = new SchemaCompareNodeParams()
{
OperationId = schemaCompareOperation.OperationId,
@@ -1585,7 +1585,7 @@ WITH VALUES
Assert.True(t2ExcludeOperation.BlockingDependencies[0].SourceValue[1] == "v1", "Dependency should be View v1");
// exclude view v1, then t2 should also get excluded by this
- DiffEntry v1Diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "v1").First(), null);
+ DiffEntry v1Diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "v1").First(), null, schemaCompareOperation.ComparisonResult);
SchemaCompareNodeParams v1ExcludeParams = new SchemaCompareNodeParams()
{
OperationId = schemaCompareOperation.OperationId,
@@ -1712,7 +1712,7 @@ WITH VALUES
}
// create Diff Entry from Difference
- DiffEntry diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.First(), null);
+ DiffEntry diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.First(), null, schemaCompareOperation.ComparisonResult);
int initial = schemaCompareOperation.ComparisonResult.Differences.Count();
SchemaCompareNodeParams schemaCompareExcludeNodeParams = new SchemaCompareNodeParams()
@@ -1761,7 +1761,7 @@ WITH VALUES
string initialScript = generateScriptOperation.ScriptGenerationResult.Script;
// create Diff Entry from on Difference
- DiffEntry diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.First(), null);
+ DiffEntry diff = SchemaCompareUtils.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.First(), null, schemaCompareOperation.ComparisonResult);
//Validate Diff Entry creation for object type
ValidateDiffEntryCreation(diff, schemaCompareOperation.ComparisonResult.Differences.First());