diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareIncludeExcludeNodeRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareIncludeExcludeNodeRequest.cs index aa9e2c3f..deecce66 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareIncludeExcludeNodeRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareIncludeExcludeNodeRequest.cs @@ -47,6 +47,15 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts /// public class SchemaCompareIncludeExcludeResult : ResultStatus { - public List ChangedDifferences { get; set; } + /// + /// Dependencies that may have been affected by the include/exclude request + /// + public List AffectedDependencies { get; set; } + + /// + /// Dependencies that caused the include/exclude to fail + /// + public List BlockingDependencies { get; set; } + } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs index 537000ef..3843f25a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs @@ -39,7 +39,9 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare public bool Success { get; set; } - public List ChangedDifferences; + public List AffectedDependencies; + public List BlockingDependencies; + public SchemaCompareIncludeExcludeNodeOperation(SchemaCompareNodeParams parameters, SchemaComparisonResult comparisonResult) { @@ -66,26 +68,29 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare throw new InvalidOperationException(SR.SchemaCompareExcludeIncludeNodeNotFound); } - // Check first if the dependencies will allow this if it's an exclude request - if (!this.Parameters.IncludeRequest) - { - IEnumerable dependencies = this.ComparisonResult.GetExcludeDependencies(node); - - bool block = dependencies.Any(d => d.Included); - if (block) - { - this.Success = false; - return; - } - } - this.Success = this.Parameters.IncludeRequest ? this.ComparisonResult.Include(node) : this.ComparisonResult.Exclude(node); - // create list of affected dependencies of this request - if (this.Success) + // if include request (pass or fail), send dependencies that might have been affected by this request, given by GetIncludeDependencies() + if(this.Parameters.IncludeRequest) { - IEnumerable dependencies = this.ComparisonResult.GetIncludeDependencies(node); - this.ChangedDifferences = dependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference, null)).ToList(); + IEnumerable affectedDependencies = this.ComparisonResult.GetIncludeDependencies(node); + this.AffectedDependencies = affectedDependencies.Select(difference => SchemaCompareUtils.CreateDiffEntry(difference: difference, parent: null)).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(); + } + // 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(); + } + } } catch (Exception e) diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs index 7df42d91..dcd9d5ed 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs @@ -255,7 +255,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare { Success = operation.Success, ErrorMessage = operation.ErrorMessage, - ChangedDifferences = operation.ChangedDifferences + AffectedDependencies = operation.AffectedDependencies, + BlockingDependencies = operation.BlockingDependencies }); } catch (Exception e) diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs index fa323634..86c982ca 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs @@ -864,8 +864,10 @@ WITH VALUES t2ExcludeOperation.Execute(TaskExecutionMode.Execute); Assert.False(t2ExcludeOperation.Success, "Excluding Table t2 should fail because view v1 depends on it"); Assert.True(t2ExcludeOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "t2").First().Included, "Difference Table t2 should still be included because the exclude request failed"); + Assert.True(t2ExcludeOperation.BlockingDependencies.Count == 1, "There should be one dependency"); + Assert.True(t2ExcludeOperation.BlockingDependencies[0].SourceValue[1] == "v1", "Dependency should be View v1"); - // exclude view first, then excluding t2 should work + // 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); SchemaCompareNodeParams v1ExcludeParams = new SchemaCompareNodeParams() { @@ -878,12 +880,10 @@ WITH VALUES SchemaCompareIncludeExcludeNodeOperation v1ExcludeOperation = new SchemaCompareIncludeExcludeNodeOperation(v1ExcludeParams, schemaCompareOperation.ComparisonResult); v1ExcludeOperation.Execute(TaskExecutionMode.Execute); Assert.True(v1ExcludeOperation.Success, "Excluding View v1 should succeed"); - Assert.False(t2ExcludeOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "v1").First().Included, "Difference View v1 should be excluded"); - - // try to exclude t2 again and it should succeed this time - t2ExcludeOperation.Execute(TaskExecutionMode.Execute); - Assert.True(t2ExcludeOperation.Success, "Excluding Table t2 should succeed"); - Assert.False(t2ExcludeOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "t2").First().Included, "Difference Table t2 should still be excluded"); + Assert.False(v1ExcludeOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "v1").First().Included, "Difference View v1 should be excluded"); + Assert.False(v1ExcludeOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "t2").First().Included, "Difference Table t2 should be excluded"); + Assert.True(v1ExcludeOperation.AffectedDependencies.Count == 1, "There should be one dependency"); + Assert.False(v1ExcludeOperation.AffectedDependencies[0].Included, "The dependency Table t2 should be excluded"); // including v1 should also include t2 SchemaCompareNodeParams v1IncludeParams = new SchemaCompareNodeParams() @@ -899,8 +899,8 @@ WITH VALUES Assert.True(v1IncludeOperation.Success, "Including v1 should succeed"); Assert.True(v1IncludeOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "v1").First().Included, "Difference View v1 should be included"); Assert.True(v1IncludeOperation.ComparisonResult.Differences.Where(x => x.SourceObject != null && x.SourceObject.Name.Parts[1] == "t2").First().Included, "Difference Table t2 should still be included"); - Assert.True(v1IncludeOperation.ChangedDifferences != null && v1IncludeOperation.ChangedDifferences.Count == 1, "There should be one difference"); - Assert.True(v1IncludeOperation.ChangedDifferences.First().SourceValue[1] == "t2", "The affected difference of including v1 should be t2"); + Assert.True(v1IncludeOperation.AffectedDependencies != null && v1IncludeOperation.AffectedDependencies.Count == 1, "There should be one difference"); + Assert.True(v1IncludeOperation.AffectedDependencies.First().SourceValue[1] == "t2", "The affected difference of including v1 should be t2"); // cleanup SchemaCompareTestUtils.VerifyAndCleanup(targetDacpacFilePath);