diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
index 679310f4..d51390b6 100755
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
@@ -2925,6 +2925,30 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
+ public static string IncludeNodeTaskName
+ {
+ get
+ {
+ return Keys.GetString(Keys.IncludeNodeTaskName);
+ }
+ }
+
+ public static string ExcludeNodeTaskName
+ {
+ get
+ {
+ return Keys.GetString(Keys.ExcludeNodeTaskName);
+ }
+ }
+
+ public static string SchemaCompareExcludeIncludeNodeNotFound
+ {
+ get
+ {
+ return Keys.GetString(Keys.SchemaCompareExcludeIncludeNodeNotFound);
+ }
+ }
+
public static string ConnectionServiceListDbErrorNotConnected(string uri)
{
return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri);
@@ -4257,6 +4281,15 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string PublishChangesTaskName = "PublishChangesTaskName";
+
+
+ public const string IncludeNodeTaskName = "IncludeNodeTaskName";
+
+
+ public const string ExcludeNodeTaskName = "ExcludeNodeTaskName";
+
+
+ public const string SchemaCompareExcludeIncludeNodeNotFound = "SchemaCompareExcludeIncludeNodeNotFound";
private Keys()
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
index 433bb93f..f28f51b6 100755
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
@@ -1715,4 +1715,16 @@
Apply schema compare changes
+
+ Include schema compare node
+
+
+
+ Exclude schema compare node
+
+
+
+ Failed to find the specified change in the model
+
+
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/DeploymentOptions.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/DeploymentOptions.cs
index 59cb3b94..5c6e7018 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/DeploymentOptions.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/DeploymentOptions.cs
@@ -41,7 +41,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public bool IgnoreLockHintsOnIndexes { get; set; }
public bool IgnoreKeywordCasing { get; set; }
-
+
public bool IgnoreIndexPadding { get; set; }
public bool IgnoreIndexOptions { get; set; }
@@ -51,21 +51,21 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public bool IgnoreIdentitySeed { get; set; }
public bool IgnoreUserSettingsObjects { get; set; }
-
+
public bool IgnoreFullTextCatalogFilePath { get; set; }
-
+
public bool IgnoreWhitespace { get; set; }
public bool IgnoreWithNocheckOnForeignKeys { get; set; }
-
+
public bool VerifyCollationCompatibility { get; set; }
-
+
public bool UnmodifiableObjectWarnings { get; set; }
public bool TreatVerificationErrorsAsWarnings { get; set; }
-
+
public bool ScriptRefreshModule { get; set; }
-
+
public bool ScriptNewConstraintValidation { get; set; }
public bool ScriptFileSize { get; set; }
@@ -81,7 +81,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public bool RunDeploymentPlanExecutors { get; set; }
public bool RegisterDataTierApplication { get; set; }
-
+
public bool PopulateFilesOnFileGroups { get; set; }
public bool NoAlterStatementsToChangeClrTypes { get; set; }
@@ -93,17 +93,17 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public bool AllowUnsafeRowLevelSecurityDataMovement { get; set; }
public bool IgnoreWithNocheckOnCheckConstraints { get; set; }
-
+
public bool IgnoreFillFactor { get; set; }
-
+
public bool IgnoreFileSize { get; set; }
-
+
public bool IgnoreFilegroupPlacement { get; set; }
-
+
public bool DoNotAlterReplicatedObjects { get; set; }
-
+
public bool DoNotAlterChangeDataCaptureObjects { get; set; }
-
+
public bool DisableAndReenableDdlTriggers { get; set; }
public bool DeployDatabaseInSingleUserMode { get; set; }
@@ -113,11 +113,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public bool CompareUsingTargetCollation { get; set; }
public bool CommentOutSetVarDeclarations { get; set; }
-
+
public int CommandTimeout { get; set; } = 120;
public bool BlockWhenDriftDetected { get; set; }
-
+
public bool BlockOnPossibleDataLoss { get; set; }
public bool BackupDatabaseBeforeChanges { get; set; }
@@ -129,15 +129,15 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public string AdditionalDeploymentContributorArguments { get; set; }
public string AdditionalDeploymentContributors { get; set; }
-
+
public bool DropConstraintsNotInSource { get; set; }
-
+
public bool DropDmlTriggersNotInSource { get; set; }
-
+
public bool DropExtendedPropertiesNotInSource { get; set; }
-
+
public bool DropIndexesNotInSource { get; set; }
-
+
public bool IgnoreFileAndLogFilePath { get; set; }
public bool IgnoreExtendedProperties { get; set; }
@@ -151,9 +151,9 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public bool IgnoreDdlTriggerState { get; set; }
public bool IgnoreDdlTriggerOrder { get; set; }
-
+
public bool IgnoreCryptographicProviderFilePath { get; set; }
-
+
public bool VerifyDeployment { get; set; }
public bool IgnoreComments { get; set; }
@@ -161,17 +161,17 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public bool IgnoreColumnCollation { get; set; }
public bool IgnoreAuthorizer { get; set; }
-
+
public bool IgnoreAnsiNulls { get; set; }
public bool GenerateSmartDefaults { get; set; }
-
+
public bool DropStatisticsNotInSource { get; set; }
public bool DropRoleMembersNotInSource { get; set; }
public bool DropPermissionsNotInSource { get; set; }
-
+
public bool DropObjectsNotInSource { get; set; }
public bool IgnoreColumnOrder { get; set; }
@@ -208,11 +208,13 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
{
DacDeployOptions options = new DacDeployOptions();
System.Reflection.PropertyInfo[] deploymentOptionsProperties = this.GetType().GetProperties();
-
+
foreach (var deployOptionsProp in deploymentOptionsProperties)
{
var prop = options.GetType().GetProperty(deployOptionsProp.Name);
- if (prop != null)
+
+ // Note that we set excluded object types here since dacfx has this value as null;
+ if (prop != null && deployOptionsProp.Name != "ExcludeObjectTypes")
{
deployOptionsProp.SetValue(this, prop.GetValue(options));
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareIncludeExcludeNodeRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareIncludeExcludeNodeRequest.cs
new file mode 100644
index 00000000..ae9e8071
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareIncludeExcludeNodeRequest.cs
@@ -0,0 +1,43 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.Hosting.Protocol.Contracts;
+using Microsoft.SqlTools.ServiceLayer.TaskServices;
+using Microsoft.SqlTools.ServiceLayer.Utility;
+
+namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
+{
+ ///
+ /// Parameters for a schema compare include specific node request
+ ///
+ public class SchemaCompareNodeParams
+ {
+ ///
+ /// Operation id of the schema compare operation
+ ///
+ public string OperationId { get; set; }
+
+ ///
+ /// Difference to Include or exclude
+ ///
+ public DiffEntry DiffEntry { get; set; }
+
+ ///
+ /// Indicator for include or exclude request
+ ///
+ public bool IncludeRequest { get; set; }
+
+ ///
+ /// Execution mode for the operation. Default is execution
+ ///
+ public TaskExecutionMode TaskExecutionMode { get; set; }
+ }
+
+ class SchemaCompareIncludeExcludeNodeRequest
+ {
+ public static readonly RequestType Type =
+ RequestType.Create("schemaCompare/includeExcludeNode");
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareOptionsRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareOptionsRequest.cs
new file mode 100644
index 00000000..d2073596
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareOptionsRequest.cs
@@ -0,0 +1,37 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.Hosting.Protocol.Contracts;
+using Microsoft.SqlTools.ServiceLayer.Utility;
+
+namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
+{
+ ///
+ /// Defines paramaters for Get default options call
+ /// No parameters required so far
+ ///
+ public class SchemaCompareGetOptionsParams
+ {
+ }
+
+ ///
+ /// Gets or sets the result of get default options call
+ ///
+ public class SchemaCompareOptionsResult : ResultStatus
+ {
+ public DeploymentOptions DefaultDeploymentOptions { get; set; }
+ }
+
+ ///
+ /// Defines the Schema Compare request type
+ ///
+ class SchemaCompareGetDefaultOptionsRequest
+ {
+ public static readonly RequestType Type =
+ RequestType.Create("schemaCompare/getDefaultOptions");
+ }
+
+
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs
index 4203f127..ffd4e520 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs
@@ -79,15 +79,15 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
public class DiffEntry
{
- public SchemaUpdateAction UpdateAction;
- public SchemaDifferenceType DifferenceType;
- public string Name;
- public string SourceValue;
- public string TargetValue;
- public DiffEntry Parent;
- public List Children;
- public string SourceScript;
- public string TargetScript;
+ public SchemaUpdateAction UpdateAction { get; set; }
+ public SchemaDifferenceType DifferenceType { get; set; }
+ public string Name { get; set; }
+ public string SourceValue { get; set; }
+ public string TargetValue { get; set; }
+ public DiffEntry Parent { get; set; }
+ public List Children { get; set; }
+ public string SourceScript { get; set; }
+ public string TargetScript { get; set; }
}
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareGenerateScriptOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareGenerateScriptOperation.cs
index ad13ba8c..c7d064a0 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareGenerateScriptOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareGenerateScriptOperation.cs
@@ -78,5 +78,17 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
public void Cancel()
{
}
+
+ ///
+ /// Disposes the operation.
+ ///
+ public void Dispose()
+ {
+ if (!disposed)
+ {
+ this.Cancel();
+ disposed = true;
+ }
+ }
}
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs
new file mode 100644
index 00000000..c890c43c
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareIncludeExcludeNodeOperation.cs
@@ -0,0 +1,128 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+using Microsoft.SqlServer.Dac.Compare;
+using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
+using Microsoft.SqlTools.ServiceLayer.TaskServices;
+using Microsoft.SqlTools.Utility;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Threading;
+
+namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
+{
+ ///
+ /// Class to represent an in-progress schema compare include/exclude Node operation
+ ///
+ class SchemaCompareIncludeExcludeNodeOperation : ITaskOperation
+ {
+ private CancellationTokenSource cancellation = new CancellationTokenSource();
+ private bool disposed = false;
+
+ ///
+ /// Gets the unique id associated with this instance.
+ ///
+ public string OperationId { get; private set; }
+
+ public SchemaCompareNodeParams Parameters { get; }
+
+ protected CancellationToken CancellationToken { get { return this.cancellation.Token; } }
+
+ public string ErrorMessage { get; set; }
+
+ public SqlTask SqlTask { get; set; }
+
+ public SchemaComparisonResult ComparisonResult { get; set; }
+
+ public bool Success { get; set; }
+
+ public SchemaCompareIncludeExcludeNodeOperation(SchemaCompareNodeParams parameters, SchemaComparisonResult comparisonResult)
+ {
+ Validate.IsNotNull("parameters", parameters);
+ this.Parameters = parameters;
+ Validate.IsNotNull("comparisonResult", comparisonResult);
+ this.ComparisonResult = comparisonResult;
+ }
+
+ public void Execute(TaskExecutionMode mode)
+ {
+ this.CancellationToken.ThrowIfCancellationRequested();
+
+ try
+ {
+ SchemaDifference node = this.FindDifference(this.ComparisonResult.Differences, this.Parameters.DiffEntry);
+ if (node == null)
+ {
+ throw new InvalidOperationException(SR.SchemaCompareExcludeIncludeNodeNotFound);
+ }
+
+ this.Success = this.Parameters.IncludeRequest ? this.ComparisonResult.Include(node) : this.ComparisonResult.Exclude(node);
+ }
+ catch (Exception e)
+ {
+ ErrorMessage = e.Message;
+ Logger.Write(TraceEventType.Error, string.Format("Schema compare publish changes operation {0} failed with exception {1}", this.OperationId, e.Message));
+ throw;
+ }
+ }
+
+ private SchemaDifference FindDifference(IEnumerable differences, DiffEntry diffEntry)
+ {
+ foreach (var difference in differences)
+ {
+ if (IsEqual(difference, diffEntry))
+ {
+ return difference;
+ }
+ else
+ {
+ var childDiff = FindDifference(difference.Children, diffEntry);
+ if (childDiff != null)
+ {
+ return childDiff;
+ }
+ }
+ }
+ return null;
+ }
+
+ private bool IsEqual(SchemaDifference difference, DiffEntry diffEntry)
+ {
+ bool result = true;
+ // Create a diff entry from difference and check if it matches the diff entry passed
+ DiffEntry entryFromDifference = SchemaCompareOperation.CreateDiffEntry(difference, null);
+
+ System.Reflection.PropertyInfo[] properties = diffEntry.GetType().GetProperties();
+ foreach (var prop in properties)
+ {
+ result = result &&
+ ((prop.GetValue(diffEntry) == null &&
+ prop.GetValue(entryFromDifference) == null) ||
+ prop.GetValue(diffEntry).SafeToString().Equals(prop.GetValue(entryFromDifference).SafeToString()));
+ }
+
+ return result;
+ }
+
+ // The schema compare public api doesn't currently take a cancellation token so the operation can't be cancelled
+ public void Cancel()
+ {
+ }
+
+ ///
+ /// Disposes the operation.
+ ///
+ public void Dispose()
+ {
+ if (!disposed)
+ {
+ this.Cancel();
+ disposed = true;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs
index 1de38af5..2d05e9d5 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOperation.cs
@@ -41,8 +41,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
public List Differences;
- public DacDeployOptions DefaultOptions;
-
public SchemaCompareOperation(SchemaCompareParams parameters, ConnectionInfo sourceConnInfo, ConnectionInfo targetConnInfo)
{
Validate.IsNotNull("parameters", parameters);
@@ -134,8 +132,13 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
return dacOptions;
}
- private DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent)
+ internal static DiffEntry CreateDiffEntry(SchemaDifference difference, DiffEntry parent)
{
+ if(difference == null)
+ {
+ return null;
+ }
+
DiffEntry diffEntry = new DiffEntry();
diffEntry.UpdateAction = difference.UpdateAction;
diffEntry.DifferenceType = difference.DifferenceType;
@@ -207,13 +210,13 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
return ConnectionService.BuildConnectionString(connInfo.ConnectionDetails);
}
- private string RemoveExcessWhitespace(string script)
+ private static string RemoveExcessWhitespace(string script)
{
// replace all multiple spaces with single space
return Regex.Replace(script, " {2,}", " ");
}
- private string GetName(string name)
+ private static string GetName(string name)
{
// remove brackets from name
return Regex.Replace(name, @"[\[\]]", "");
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs
index bc046a1e..940106b2 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs
@@ -19,7 +19,6 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
class SchemaComparePublishChangesOperation : ITaskOperation
{
private CancellationTokenSource cancellation = new CancellationTokenSource();
- private bool disposed = false;
///
/// Gets the unique id associated with this instance.
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs
index 3a3a908b..9d7630b4 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs
@@ -44,6 +44,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCopmare
serviceHost.SetRequestHandler(SchemaCompareRequest.Type, this.HandleSchemaCompareRequest);
serviceHost.SetRequestHandler(SchemaCompareGenerateScriptRequest.Type, this.HandleSchemaCompareGenerateScriptRequest);
serviceHost.SetRequestHandler(SchemaComparePublishChangesRequest.Type, this.HandleSchemaComparePublishChangesRequest);
+ serviceHost.SetRequestHandler(SchemaCompareIncludeExcludeNodeRequest.Type, this.HandleSchemaCompareIncludeExcludeNodeRequest);
+ serviceHost.SetRequestHandler(SchemaCompareGetDefaultOptionsRequest.Type, this.HandleSchemaCompareGetDefaultOptionsRequest);
}
///
@@ -174,6 +176,61 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCopmare
}
}
+ public async Task HandleSchemaCompareIncludeExcludeNodeRequest(SchemaCompareNodeParams parameters, RequestContext requestContext)
+ {
+ SchemaCompareIncludeExcludeNodeOperation operation = null;
+ try
+ {
+ SchemaComparisonResult compareResult = schemaCompareResults.Value[parameters.OperationId];
+ operation = new SchemaCompareIncludeExcludeNodeOperation(parameters, compareResult);
+ SqlTask sqlTask = null;
+ TaskMetadata metadata = new TaskMetadata();
+ metadata.TaskOperation = operation;
+ metadata.Name = parameters.IncludeRequest ? SR.IncludeNodeTaskName : SR.ExcludeNodeTaskName;
+
+ sqlTask = SqlTaskManagerInstance.CreateAndRun(metadata);
+
+ await requestContext.SendResult(new ResultStatus()
+ {
+ Success = true,
+ ErrorMessage = operation.ErrorMessage
+ });
+ }
+ catch (Exception e)
+ {
+ await requestContext.SendResult(new ResultStatus()
+ {
+ Success = false,
+ ErrorMessage = operation == null ? e.Message : operation.ErrorMessage,
+ });
+ }
+ }
+
+ public async Task HandleSchemaCompareGetDefaultOptionsRequest(SchemaCompareGetOptionsParams parameters, RequestContext requestContext)
+ {
+ try
+ {
+ // this does not need to be an async operation since this only creates and resturn the default opbject
+ DeploymentOptions options = new DeploymentOptions();
+
+ await requestContext.SendResult(new SchemaCompareOptionsResult()
+ {
+ DefaultDeploymentOptions = options,
+ Success = true,
+ ErrorMessage = null
+ });
+ }
+ catch (Exception e)
+ {
+ await requestContext.SendResult(new SchemaCompareOptionsResult()
+ {
+ DefaultDeploymentOptions = null,
+ Success = false,
+ ErrorMessage = e.Message
+ });
+ }
+ }
+
private SqlTaskManager SqlTaskManagerInstance
{
get
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceOptionsTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceOptionsTests.cs
index 6f2bd153..a63fa439 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceOptionsTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceOptionsTests.cs
@@ -3,9 +3,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Protocol;
-using Microsoft.SqlTools.ServiceLayer.DacFx;
-using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
-using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
@@ -16,6 +13,7 @@ using System;
using System.IO;
using System.Threading.Tasks;
using Xunit;
+using Microsoft.SqlTools.ServiceLayer.SchemaCopmare;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
{
@@ -111,7 +109,6 @@ END
private async Task>> SendAndValidateSchemaCompareRequestDacpacToDacpacWithOptions(string sourceScript, string targetScript, DeploymentOptions nodiffOption, DeploymentOptions shouldDiffOption)
{
-
var result = SchemaCompareTestUtils.GetLiveAutoCompleteTestObjects();
var schemaCompareRequestContext = new Mock>();
schemaCompareRequestContext.Setup(x => x.SendResult(It.IsAny())).Returns(Task.FromResult(new object()));
@@ -373,17 +370,21 @@ END
}
///
- /// Verify the schema compare script generation comparing dacpac and db with and excluding table valued function
+ /// Verify the schema compare default creation test
///
[Fact]
- public void ValidateSchemaCompareOptionsDefault()
+ public void ValidateSchemaCompareOptionsDefaultAgainstDacFx()
{
DeploymentOptions deployOptions = new DeploymentOptions();
DacDeployOptions dacOptions = new DacDeployOptions();
System.Reflection.PropertyInfo[] deploymentOptionsProperties = deployOptions.GetType().GetProperties();
System.Reflection.PropertyInfo[] ddProperties = dacOptions.GetType().GetProperties();
-
+
+ // Note that DatabaseSpecification and sql cmd variables list is not present in Sqltools service - its not settable and is not used by ADS options.
+ // TODO : update this test if the above options are added later
+ Assert.True(deploymentOptionsProperties.Length == ddProperties.Length - 2 , $"Number of properties is not same Deployment options : {deploymentOptionsProperties.Length} DacFx options : {ddProperties.Length}");
+
foreach (var deployOptionsProp in deploymentOptionsProperties)
{
var dacProp = dacOptions.GetType().GetProperty(deployOptionsProp.Name);
@@ -391,10 +392,49 @@ END
var deployOptionsValue = deployOptionsProp.GetValue(deployOptions);
var dacValue = dacProp.GetValue(dacOptions);
-
- Assert.True((deployOptionsValue == null && dacValue == null) || deployOptionsValue.Equals(dacValue), $"DacFx DacDeploy property not equal to Tools Service DeploymentOptions for { deployOptionsProp.Name}, SchemaCompareOptions value: {deployOptionsValue} and DacDeployOptions value: {dacValue} ");
+
+ if (deployOptionsProp.Name != "ExcludeObjectTypes") // do not compare for ExcludeObjectTypes because it will be different
+ {
+ Assert.True((deployOptionsValue == null && dacValue == null) || deployOptionsValue.Equals(dacValue), $"DacFx DacDeploy property not equal to Tools Service DeploymentOptions for { deployOptionsProp.Name}, SchemaCompareOptions value: {deployOptionsValue} and DacDeployOptions value: {dacValue} ");
+ }
}
}
+ ///
+ /// Verify the schema compare default creation test
+ ///
+ [Fact]
+ public async void ValidateSchemaCompareGetDefaultOptionsCallFromService()
+ {
+ DeploymentOptions deployOptions = new DeploymentOptions();
+ var schemaCompareRequestContext = new Mock>();
+ schemaCompareRequestContext.Setup(x => x.SendResult(It.IsAny())).Returns(Task.FromResult(new object()));
+ schemaCompareRequestContext.Setup((RequestContext x) => x.SendResult(It.Is((options) => this.OptionsEqualsDefault(options) == true))).Returns(Task.FromResult(new object()));
+
+ SchemaCompareGetOptionsParams p = new SchemaCompareGetOptionsParams();
+ await SchemaCompareService.Instance.HandleSchemaCompareGetDefaultOptionsRequest(p, schemaCompareRequestContext.Object);
+ }
+
+ private bool OptionsEqualsDefault(SchemaCompareOptionsResult options)
+ {
+ DeploymentOptions defaultOpt = new DeploymentOptions();
+ DeploymentOptions actualOpt = options.DefaultDeploymentOptions;
+
+ System.Reflection.PropertyInfo[] deploymentOptionsProperties = defaultOpt.GetType().GetProperties();
+ foreach(var v in deploymentOptionsProperties)
+ {
+ var defaultP = v.GetValue(defaultOpt);
+ var actualP = v.GetValue(actualOpt);
+ if (v.Name == "ExcludeObjectTypes")
+ {
+ Assert.True((defaultP as ObjectType[]).Length == (actualP as ObjectType[]).Length, $"Number of excluded objects is different; expected: {(defaultP as ObjectType[]).Length} actual: {(actualP as ObjectType[]).Length}");
+ }
+ else
+ {
+ Assert.True((defaultP == null && actualP == null) || defaultP.Equals(actualP), $"Actual Property from Service is not equal to default property for { v.Name}, Actual value: {actualP} and Default value: {defaultP}");
+ }
+ }
+ return true;
+ }
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
index baa0b71b..3dacc9a1 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
@@ -3,9 +3,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Protocol;
-using Microsoft.SqlTools.ServiceLayer.DacFx;
-using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
-using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
@@ -13,6 +10,7 @@ using Microsoft.SqlTools.ServiceLayer.Test.Common;
using Moq;
using System;
using System.IO;
+using System.Linq;
using System.Threading.Tasks;
using Xunit;
@@ -73,11 +71,7 @@ CREATE TABLE [dbo].[table3]
};
SchemaCompareOperation schemaCompareOperation = new SchemaCompareOperation(schemaCompareParams, null, null);
- schemaCompareOperation.Execute(TaskExecutionMode.Execute);
-
- Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
- Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
- Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+ ValidateSchemaCompareWithExcludeIncludeResults(schemaCompareOperation);
// cleanup
SchemaCompareTestUtils.VerifyAndCleanup(sourceDacpacFilePath);
@@ -120,11 +114,7 @@ CREATE TABLE [dbo].[table3]
};
SchemaCompareOperation schemaCompareOperation = new SchemaCompareOperation(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
- schemaCompareOperation.Execute(TaskExecutionMode.Execute);
-
- Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
- Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
- Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+ ValidateSchemaCompareWithExcludeIncludeResults(schemaCompareOperation);
}
finally
{
@@ -163,11 +153,7 @@ CREATE TABLE [dbo].[table3]
};
SchemaCompareOperation schemaCompareOperation = new SchemaCompareOperation(schemaCompareParams, result.ConnectionInfo, null);
- schemaCompareOperation.Execute(TaskExecutionMode.Execute);
-
- Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
- Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
- Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+ ValidateSchemaCompareWithExcludeIncludeResults(schemaCompareOperation);
// cleanup
SchemaCompareTestUtils.VerifyAndCleanup(targetDacpacFilePath);
@@ -208,13 +194,8 @@ CREATE TABLE [dbo].[table3]
};
SchemaCompareOperation schemaCompareOperation = new SchemaCompareOperation(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
- schemaCompareOperation.Execute(TaskExecutionMode.Execute);
-
- Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
- Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
- Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
-
- // generate script
+
+ // generate script params
var generateScriptParams = new SchemaCompareGenerateScriptParams
{
TargetDatabaseName = targetDb.DatabaseName,
@@ -222,8 +203,7 @@ CREATE TABLE [dbo].[table3]
ScriptFilePath = Path.Combine(folderPath, string.Concat(sourceDb.DatabaseName, "_", "Update.publish.sql"))
};
- SchemaCompareGenerateScriptOperation generateScriptOperation = new SchemaCompareGenerateScriptOperation(generateScriptParams, schemaCompareOperation.ComparisonResult);
- generateScriptOperation.Execute(TaskExecutionMode.Execute);
+ ValidateSchemaCompareScriptGenerationWithExcludeIncludeResults(schemaCompareOperation, generateScriptParams);
// cleanup
SchemaCompareTestUtils.VerifyAndCleanup(generateScriptParams.ScriptFilePath);
@@ -266,11 +246,6 @@ CREATE TABLE [dbo].[table3]
};
SchemaCompareOperation schemaCompareOperation = new SchemaCompareOperation(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
- schemaCompareOperation.Execute(TaskExecutionMode.Execute);
-
- Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
- Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
- Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
// generate script
var generateScriptParams = new SchemaCompareGenerateScriptParams
@@ -280,9 +255,8 @@ CREATE TABLE [dbo].[table3]
ScriptFilePath = Path.Combine(folderPath, string.Concat(sourceDb.DatabaseName, "_", "Update.publish.sql"))
};
- SchemaCompareGenerateScriptOperation generateScriptOperation = new SchemaCompareGenerateScriptOperation(generateScriptParams, schemaCompareOperation.ComparisonResult);
- generateScriptOperation.Execute(TaskExecutionMode.Execute);
-
+ ValidateSchemaCompareScriptGenerationWithExcludeIncludeResults(schemaCompareOperation, generateScriptParams);
+
// cleanup
SchemaCompareTestUtils.VerifyAndCleanup(generateScriptParams.ScriptFilePath);
SchemaCompareTestUtils.VerifyAndCleanup(sourceDacpacFilePath);
@@ -354,7 +328,7 @@ CREATE TABLE [dbo].[table3]
Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
Assert.True(schemaCompareOperation.ComparisonResult.IsEqual);
Assert.Empty(schemaCompareOperation.ComparisonResult.Differences);
-
+
// cleanup
SchemaCompareTestUtils.VerifyAndCleanup(sourceDacpacFilePath);
}
@@ -429,7 +403,108 @@ CREATE TABLE [dbo].[table3]
}
return schemaCompareRequestContext;
}
+
+ private void ValidateSchemaCompareWithExcludeIncludeResults(SchemaCompareOperation schemaCompareOperation)
+ {
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+
+ // create Diff Entry from Difference
+
+ DiffEntry diff = SchemaCompareOperation.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.First(), null);
+
+ int initial = schemaCompareOperation.ComparisonResult.Differences.Count();
+ SchemaCompareNodeParams schemaCompareExcludeNodeParams = new SchemaCompareNodeParams()
+ {
+ OperationId = schemaCompareOperation.OperationId,
+ DiffEntry = diff,
+ IncludeRequest = false,
+ TaskExecutionMode = TaskExecutionMode.Execute
+ };
+ SchemaCompareIncludeExcludeNodeOperation nodeExcludeOperation = new SchemaCompareIncludeExcludeNodeOperation(schemaCompareExcludeNodeParams, schemaCompareOperation.ComparisonResult);
+ nodeExcludeOperation.Execute(TaskExecutionMode.Execute);
+
+ int afterExclude = schemaCompareOperation.ComparisonResult.Differences.Count();
+
+ Assert.True(initial == afterExclude, $"Changes should be same again after excluding/including, before {initial}, now {afterExclude}");
+
+ SchemaCompareNodeParams schemaCompareincludeNodeParams = new SchemaCompareNodeParams()
+ {
+ OperationId = schemaCompareOperation.OperationId,
+ DiffEntry = diff,
+ IncludeRequest = true,
+ TaskExecutionMode = TaskExecutionMode.Execute
+ };
+
+ SchemaCompareIncludeExcludeNodeOperation nodeIncludeOperation = new SchemaCompareIncludeExcludeNodeOperation(schemaCompareincludeNodeParams, schemaCompareOperation.ComparisonResult);
+ nodeIncludeOperation.Execute(TaskExecutionMode.Execute);
+ int afterInclude = schemaCompareOperation.ComparisonResult.Differences.Count();
+
+
+ Assert.True(initial == afterInclude, $"Changes should be same again after excluding/including, before:{initial}, now {afterInclude}");
+ }
+
+ private void ValidateSchemaCompareScriptGenerationWithExcludeIncludeResults(SchemaCompareOperation schemaCompareOperation, SchemaCompareGenerateScriptParams generateScriptParams)
+ {
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+
+ SchemaCompareGenerateScriptOperation generateScriptOperation = new SchemaCompareGenerateScriptOperation(generateScriptParams, schemaCompareOperation.ComparisonResult);
+ generateScriptOperation.Execute(TaskExecutionMode.Execute);
+
+ string initialScript = File.ReadAllText(generateScriptParams.ScriptFilePath);
+
+ // create Diff Entry from on Difference
+ DiffEntry diff = SchemaCompareOperation.CreateDiffEntry(schemaCompareOperation.ComparisonResult.Differences.First(), null);
+
+ int initial = schemaCompareOperation.ComparisonResult.Differences.Count();
+ SchemaCompareNodeParams schemaCompareExcludeNodeParams = new SchemaCompareNodeParams()
+ {
+ OperationId = schemaCompareOperation.OperationId,
+ DiffEntry = diff,
+ IncludeRequest = false,
+ TaskExecutionMode = TaskExecutionMode.Execute
+ };
+ SchemaCompareIncludeExcludeNodeOperation nodeExcludeOperation = new SchemaCompareIncludeExcludeNodeOperation(schemaCompareExcludeNodeParams, schemaCompareOperation.ComparisonResult);
+ nodeExcludeOperation.Execute(TaskExecutionMode.Execute);
+
+ int afterExclude = schemaCompareOperation.ComparisonResult.Differences.Count();
+
+ Assert.True(initial == afterExclude, $"Changes should be same again after excluding/including, before {initial}, now {afterExclude}");
+
+ generateScriptOperation = new SchemaCompareGenerateScriptOperation(generateScriptParams, schemaCompareOperation.ComparisonResult);
+ generateScriptOperation.Execute(TaskExecutionMode.Execute);
+
+ string afterExcludeScript = File.ReadAllText(generateScriptParams.ScriptFilePath);
+ Assert.True(initialScript.Length > afterExcludeScript.Length, $"Script should be affected (less statements) exclude operation, before {initialScript}, now {afterExcludeScript}");
+
+ SchemaCompareNodeParams schemaCompareincludeNodeParams = new SchemaCompareNodeParams()
+ {
+ OperationId = schemaCompareOperation.OperationId,
+ DiffEntry = diff,
+ IncludeRequest = true,
+ TaskExecutionMode = TaskExecutionMode.Execute
+ };
+
+ SchemaCompareIncludeExcludeNodeOperation nodeIncludeOperation = new SchemaCompareIncludeExcludeNodeOperation(schemaCompareincludeNodeParams, schemaCompareOperation.ComparisonResult);
+ nodeIncludeOperation.Execute(TaskExecutionMode.Execute);
+ int afterInclude = schemaCompareOperation.ComparisonResult.Differences.Count();
+
+ Assert.True(initial == afterInclude, $"Changes should be same again after excluding/including:{initial}, now {afterInclude}");
+
+ generateScriptOperation = new SchemaCompareGenerateScriptOperation(generateScriptParams, schemaCompareOperation.ComparisonResult);
+ generateScriptOperation.Execute(TaskExecutionMode.Execute);
+
+ string afterIncludeScript = File.ReadAllText(generateScriptParams.ScriptFilePath);
+ Assert.True(initialScript.Length == afterIncludeScript.Length, $"Changes should be same as inital since we included what we excluded, before {initialScript}, now {afterIncludeScript}");
+ }
+
///
/// Verify the schema compare request comparing two dacpacs
///
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs
index d9c7a0b6..f764304d 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs
@@ -10,6 +10,7 @@ using Microsoft.SqlTools.ServiceLayer.Test.Common;
using NUnit.Framework;
using System;
using System.IO;
+using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
{
@@ -50,7 +51,21 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
internal static LiveConnectionHelper.TestConnectionResult GetLiveAutoCompleteTestObjects()
{
- var result = LiveConnectionHelper.InitLiveConnectionInfo();
+ // Adding retry for reliability - otherwise it caused test to fail in lab
+ TestConnectionResult result = null;
+ int retry = 3;
+
+ while (retry > 0)
+ {
+ result = LiveConnectionHelper.InitLiveConnectionInfo();
+ if (result != null && result.ConnectionInfo != null)
+ {
+ return result;
+ }
+ System.Threading.Thread.Sleep(1000);
+ retry--;
+ }
+
return result;
}
}