diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs
index d4ec99d5..25348870 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareGenerateScriptRequest.cs
@@ -13,7 +13,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
///
/// Parameters for a schema compare generate script request.
///
- public class SchemaCompareGenerateScriptParams : SchemaComparePublishChangesParams
+ public class SchemaCompareGenerateScriptParams : SchemaComparePublishDatabaseChangesParams
{
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs
index 28e2d5fc..0da9211a 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishChangesRequest.cs
@@ -39,7 +39,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
///
class SchemaComparePublishChangesRequest
{
- public static readonly RequestType Type =
- RequestType.Create("schemaCompare/publish");
+ public static readonly RequestType Type =
+ RequestType.Create("schemaCompare/publish");
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishDatabaseChangesRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishDatabaseChangesRequest.cs
new file mode 100644
index 00000000..53e5858c
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishDatabaseChangesRequest.cs
@@ -0,0 +1,46 @@
+//
+// 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 publish database changes request.
+ ///
+ public class SchemaComparePublishDatabaseChangesParams
+ {
+ ///
+ /// Operation id of the schema compare operation
+ ///
+ public string OperationId { get; set; }
+
+ ///
+ /// Name of target server
+ ///
+ public string TargetServerName { get; set; }
+
+ ///
+ /// Name of target database
+ ///
+ public string TargetDatabaseName { get; set; }
+
+ ///
+ /// Execution mode for the operation. Default is execution
+ ///
+ public TaskExecutionMode TaskExecutionMode { get; set; }
+ }
+
+ ///
+ /// Defines the Schema Compare publish database changes request type
+ ///
+ class SchemaComparePublishDatabaseChangesRequest
+ {
+ public static readonly RequestType Type =
+ RequestType.Create("schemaCompare/publishDatabase");
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishProjectChangesRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishProjectChangesRequest.cs
new file mode 100644
index 00000000..3d8e4aa8
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaComparePublishProjectChangesRequest.cs
@@ -0,0 +1,47 @@
+//
+// 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;
+using Microsoft.SqlServer.Dac.Compare;
+using Microsoft.SqlTools.Hosting.Protocol.Contracts;
+using Microsoft.SqlTools.ServiceLayer.TaskServices;
+
+namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
+{
+ ///
+ /// Parameters for a schema compare publish project changes request.
+ ///
+ public class SchemaComparePublishProjectChangesParams
+ {
+ ///
+ /// Operation id of the schema compare operation
+ ///
+ public string OperationId { get; set; }
+
+ ///
+ /// Path of project folder
+ ///
+ public string TargetProjectPath { get; set; }
+
+ ///
+ /// folder structure of target folder
+ ///
+ public DacExtractTarget TargetFolderStructure { get; set; }
+
+ ///
+ /// Execution mode for the operation. Default is execution
+ ///
+ public TaskExecutionMode TaskExecutionMode { get; set; }
+ }
+
+ ///
+ /// Defines the Schema Compare publish project changes request type
+ ///
+ class SchemaComparePublishProjectChangesRequest
+ {
+ public static readonly RequestType Type =
+ RequestType.Create("schemaCompare/publishProject");
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs
index 13c1b9bf..5ea2a25c 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs
@@ -12,12 +12,21 @@ using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
{
+ ///
+ /// Types of schema compare endpoints
+ ///
public enum SchemaCompareEndpointType
{
- Database,
- Dacpac
+ Database = 0,
+ Dacpac = 1,
+ Project = 2
+ // must be kept in-sync with SchemaCompareEndpointType in Azure Data Studio
+ // located at \extensions\mssql\src\mssql.d.ts
}
+ ///
+ /// Info needed from endpoints for schema comparison
+ ///
public class SchemaCompareEndpointInfo
{
///
@@ -25,6 +34,21 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts
///
public SchemaCompareEndpointType EndpointType { get; set; }
+ ///
+ /// Gets or sets the project file path
+ ///
+ public string ProjectFilePath { get; set; }
+
+ ///
+ /// Gets or sets the scripts included in project
+ ///
+ public string[] TargetScripts { get; set; }
+
+ ///
+ /// Gets or sets the project data schema provider
+ ///
+ public string DataSchemaProvider { get; set; }
+
///
/// Gets or sets package filepath
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs
index b8cf0d27..b6629114 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs
@@ -100,13 +100,17 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
{
SchemaCompareEndpointInfo endpointInfo = new SchemaCompareEndpointInfo();
- // if the endpoint is a dacpac we don't need to parse the xml
- SchemaCompareDacpacEndpoint dacpacEndpoint = endpoint as SchemaCompareDacpacEndpoint;
- if (dacpacEndpoint != null)
+ // if the endpoint is a dacpac or a project, we don't need to parse the xml
+ if (endpoint is SchemaCompareDacpacEndpoint dacpacEndpoint)
{
endpointInfo.EndpointType = SchemaCompareEndpointType.Dacpac;
endpointInfo.PackageFilePath = dacpacEndpoint.FilePath;
}
+ else if (endpoint is SchemaCompareProjectEndpoint projectEndpoint)
+ {
+ endpointInfo.EndpointType = SchemaCompareEndpointType.Project;
+ endpointInfo.ProjectFilePath = projectEndpoint.ProjectFilePath;
+ }
else
{
// need to parse xml to get connection string of database
@@ -131,7 +135,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
}
catch (Exception e)
{
- ErrorMessage = string.Format(SR.OpenScmpConnectionBasedModelParsingError, ((SchemaCompareDatabaseEndpoint)endpoint).DatabaseName,e.Message);
+ ErrorMessage = string.Format(SR.OpenScmpConnectionBasedModelParsingError, ((SchemaCompareDatabaseEndpoint)endpoint).DatabaseName, e.Message);
Logger.Write(TraceEventType.Error, string.Format("Schema compare open scmp operation failed during xml parsing with exception {0}", e.Message));
throw;
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs
index 16b5d0d7..0f09298b 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishChangesOperation.cs
@@ -2,79 +2,38 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
+using System.Threading;
using Microsoft.SqlServer.Dac.Compare;
-using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
using Microsoft.SqlTools.Utility;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Threading;
namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
{
- ///
- /// Class to represent an in-progress schema compare publish changes operation
- ///
- class SchemaComparePublishChangesOperation : ITaskOperation
+ abstract class SchemaComparePublishChangesOperation : ITaskOperation
{
- private CancellationTokenSource cancellation = new CancellationTokenSource();
-
- ///
- /// Gets the unique id associated with this instance.
- ///
public string OperationId { get; private set; }
- public SchemaComparePublishChangesParams 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 SchemaComparePublishResult PublishResult { get; set; }
+ public string ErrorMessage { get; set; }
- public SchemaComparePublishChangesOperation(SchemaComparePublishChangesParams parameters, SchemaComparisonResult comparisonResult)
+ protected CancellationToken CancellationToken { get { return cancellation.Token; } }
+
+ protected readonly CancellationTokenSource cancellation = new();
+
+ public SchemaComparePublishChangesOperation(SchemaComparisonResult comparisonResult)
{
- Validate.IsNotNull("parameters", parameters);
- this.Parameters = parameters;
- Validate.IsNotNull("comparisonResult", comparisonResult);
- this.ComparisonResult = comparisonResult;
+ Validate.IsNotNull(nameof(comparisonResult), comparisonResult);
+ ComparisonResult = comparisonResult;
}
+
+ public abstract void Execute(TaskExecutionMode mode);
- public void Execute(TaskExecutionMode mode)
- {
- if (this.CancellationToken.IsCancellationRequested)
- {
- throw new OperationCanceledException(this.CancellationToken);
- }
-
- try
- {
- this.PublishResult = this.ComparisonResult.PublishChangesToTarget(this.CancellationToken);
- if (!this.PublishResult.Success)
- {
- // Sending only errors and warnings - because overall message might be too big for task view
- ErrorMessage = string.Join(Environment.NewLine, this.PublishResult.Errors.Where(x => x.MessageType == SqlServer.Dac.DacMessageType.Error || x.MessageType == SqlServer.Dac.DacMessageType.Warning));
- throw new Exception(ErrorMessage);
- }
- }
- 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;
- }
- }
-
- // The schema compare public api doesn't currently take a cancellation token so the operation can't be cancelled
public void Cancel()
{
- this.cancellation.Cancel();
+ cancellation.Cancel();
}
}
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishDatabaseChangesOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishDatabaseChangesOperation.cs
new file mode 100644
index 00000000..9902f2e8
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishDatabaseChangesOperation.cs
@@ -0,0 +1,56 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using Microsoft.SqlServer.Dac.Compare;
+using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
+using Microsoft.SqlTools.ServiceLayer.TaskServices;
+using Microsoft.SqlTools.Utility;
+using Microsoft.SqlServer.Dac;
+
+namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
+{
+ ///
+ /// Class to represent an in-progress schema compare publish database changes operation
+ ///
+ class SchemaComparePublishDatabaseChangesOperation : SchemaComparePublishChangesOperation
+ {
+ public SchemaComparePublishDatabaseChangesParams Parameters { get; }
+
+ public SchemaComparePublishResult PublishResult { get; set; }
+
+ public SchemaComparePublishDatabaseChangesOperation(SchemaComparePublishDatabaseChangesParams parameters, SchemaComparisonResult comparisonResult) : base(comparisonResult)
+ {
+ Validate.IsNotNull(nameof(parameters), parameters);
+ Parameters = parameters;
+ }
+
+ public override void Execute(TaskExecutionMode mode)
+ {
+ CancellationToken.ThrowIfCancellationRequested();
+
+ try
+ {
+ PublishResult = ComparisonResult.PublishChangesToDatabase(CancellationToken);
+
+ if (!PublishResult.Success)
+ {
+ // Sending only errors and warnings - because overall message might be too big for task view
+ ErrorMessage = String.Join(Environment.NewLine, this.PublishResult.Errors.Where(x => x.MessageType == SqlServer.Dac.DacMessageType.Error || x.MessageType == SqlServer.Dac.DacMessageType.Warning));
+ throw new DacServicesException(ErrorMessage);
+ }
+ }
+ catch (Exception e)
+ {
+ ErrorMessage = e.Message;
+ Logger.Write(TraceEventType.Error, string.Format("Schema compare publish database changes operation {0} failed with exception {1}", this.OperationId, e.Message));
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishProjectChangesOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishProjectChangesOperation.cs
new file mode 100644
index 00000000..c90f1d95
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaComparePublishProjectChangesOperation.cs
@@ -0,0 +1,57 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using Microsoft.SqlServer.Dac;
+using Microsoft.SqlServer.Dac.Compare;
+using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
+using Microsoft.SqlTools.ServiceLayer.TaskServices;
+using Microsoft.SqlTools.Utility;
+
+namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
+{
+ ///
+ /// Class to represent an in-progress schema compare publish project changes operation
+ ///
+ class SchemaComparePublishProjectChangesOperation: SchemaComparePublishChangesOperation
+ {
+ public SchemaComparePublishProjectChangesParams Parameters { get; }
+
+ public SchemaComparePublishProjectResult PublishResult { get; set; }
+
+ public SchemaComparePublishProjectChangesOperation(SchemaComparePublishProjectChangesParams parameters, SchemaComparisonResult comparisonResult) : base(comparisonResult)
+ {
+ Validate.IsNotNull(nameof(parameters), parameters);
+ Parameters = parameters;
+ }
+
+ public override void Execute(TaskExecutionMode mode)
+ {
+ if (CancellationToken.IsCancellationRequested)
+ {
+ throw new OperationCanceledException(CancellationToken);
+ }
+
+ try
+ {
+ PublishResult = ComparisonResult.PublishChangesToProject(Parameters.TargetProjectPath, Parameters.TargetFolderStructure);
+
+ if (!PublishResult.Success)
+ {
+ ErrorMessage = PublishResult.ErrorMessage;
+ throw new DacServicesException(ErrorMessage);
+ }
+ }
+ catch (Exception e)
+ {
+ ErrorMessage = e.Message;
+ Logger.Write(TraceEventType.Error, string.Format("Schema compare publish project changes operation {0} failed with exception {1}", OperationId, e.Message));
+ throw;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs
index 157f2eec..a9e0989b 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareService.cs
@@ -52,6 +52,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
serviceHost.SetRequestHandler(SchemaCompareCancellationRequest.Type, this.HandleSchemaCompareCancelRequest);
serviceHost.SetRequestHandler(SchemaCompareGenerateScriptRequest.Type, this.HandleSchemaCompareGenerateScriptRequest);
serviceHost.SetRequestHandler(SchemaComparePublishChangesRequest.Type, this.HandleSchemaComparePublishChangesRequest);
+ serviceHost.SetRequestHandler(SchemaComparePublishDatabaseChangesRequest.Type, this.HandleSchemaComparePublishDatabaseChangesRequest);
+ serviceHost.SetRequestHandler(SchemaComparePublishProjectChangesRequest.Type, this.HandleSchemaComparePublishProjectChangesRequest);
serviceHost.SetRequestHandler(SchemaCompareIncludeExcludeNodeRequest.Type, this.HandleSchemaCompareIncludeExcludeNodeRequest);
serviceHost.SetRequestHandler(SchemaCompareGetDefaultOptionsRequest.Type, this.HandleSchemaCompareGetDefaultOptionsRequest);
serviceHost.SetRequestHandler(SchemaCompareOpenScmpRequest.Type, this.HandleSchemaCompareOpenScmpRequest);
@@ -198,22 +200,19 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
/// Handles request for schema compare publish changes script
///
///
- public async Task HandleSchemaComparePublishChangesRequest(SchemaComparePublishChangesParams parameters, RequestContext requestContext)
+ public async Task HandleSchemaComparePublishChangesRequest(SchemaComparePublishDatabaseChangesParams parameters, RequestContext requestContext)
{
- SchemaComparePublishChangesOperation operation = null;
+ SchemaComparePublishDatabaseChangesOperation operation = null;
try
{
SchemaComparisonResult compareResult = schemaCompareResults.Value[parameters.OperationId];
- operation = new SchemaComparePublishChangesOperation(parameters, compareResult);
- SqlTask sqlTask = null;
+ operation = new SchemaComparePublishDatabaseChangesOperation(parameters, compareResult);
TaskMetadata metadata = new TaskMetadata();
metadata.TaskOperation = operation;
metadata.ServerName = parameters.TargetServerName;
metadata.DatabaseName = parameters.TargetDatabaseName;
metadata.Name = SR.PublishChangesTaskName;
-
- sqlTask = SqlTaskManagerInstance.CreateAndRun(metadata);
-
+ SqlTask sqlTask = SqlTaskManagerInstance.CreateAndRun(metadata);
await requestContext.SendResult(new ResultStatus()
{
Success = true,
@@ -231,6 +230,90 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
}
}
+ ///
+ /// Handles request for schema compare publish database changes script
+ ///
+ ///
+ public async Task HandleSchemaComparePublishDatabaseChangesRequest(SchemaComparePublishDatabaseChangesParams parameters, RequestContext requestContext)
+ {
+ SchemaComparePublishDatabaseChangesOperation operation = null;
+ try
+ {
+ SchemaComparisonResult compareResult = schemaCompareResults.Value[parameters.OperationId];
+ operation = new SchemaComparePublishDatabaseChangesOperation(parameters, compareResult);
+ SqlTask sqlTask = null;
+ TaskMetadata metadata = new TaskMetadata
+ {
+ TaskOperation = operation,
+ ServerName = parameters.TargetServerName,
+ DatabaseName = parameters.TargetDatabaseName,
+ Name = SR.PublishChangesTaskName
+ };
+
+ sqlTask = SqlTaskManagerInstance.CreateAndRun(metadata);
+
+ await requestContext.SendResult(new ResultStatus()
+ {
+ Success = true,
+ ErrorMessage = operation.ErrorMessage
+ });
+ }
+ catch (Exception e)
+ {
+ Logger.Write(TraceEventType.Error, "Failed to publish schema compare database changes. Error: " + e);
+ await requestContext.SendResult(new ResultStatus()
+ {
+ Success = false,
+ ErrorMessage = operation == null ? e.Message : operation.ErrorMessage,
+ });
+ }
+ }
+
+ ///
+ /// Handles request for schema compare publish database changes script
+ ///
+ ///
+ public async Task HandleSchemaComparePublishProjectChangesRequest(SchemaComparePublishProjectChangesParams parameters, RequestContext requestContext)
+ {
+ SchemaComparePublishProjectChangesOperation operation = null;
+ try
+ {
+ SchemaComparisonResult compareResult = schemaCompareResults.Value[parameters.OperationId];
+ operation = new SchemaComparePublishProjectChangesOperation(parameters, compareResult);
+
+ TaskMetadata metadata = new()
+ {
+ TaskOperation = operation,
+ TargetLocation = parameters.TargetProjectPath,
+ Name = SR.PublishChangesTaskName
+ };
+
+ SqlTask sqlTask = SqlTaskManagerInstance.CreateTask(metadata);
+ await sqlTask.RunAsync();
+
+ await requestContext.SendResult(new SchemaComparePublishProjectResult()
+ {
+ ChangedFiles = operation.PublishResult.ChangedFiles,
+ AddedFiles = operation.PublishResult.AddedFiles,
+ DeletedFiles = operation.PublishResult.DeletedFiles,
+ Success = true,
+ ErrorMessage = operation.ErrorMessage
+ });
+ }
+ catch (Exception e)
+ {
+ Logger.Write(TraceEventType.Error, "Failed to publish schema compare database changes. Error: " + e);
+ await requestContext.SendResult(new SchemaComparePublishProjectResult()
+ {
+ ChangedFiles = Array.Empty(),
+ AddedFiles = Array.Empty(),
+ DeletedFiles = Array.Empty(),
+ Success = false,
+ ErrorMessage = operation?.ErrorMessage ?? e.Message
+ });
+ }
+ }
+
///
/// Handles request for exclude incude node in Schema compare result
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs
index 6b30cc85..6a33f178 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs
@@ -114,6 +114,10 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare
{
switch (endpointInfo.EndpointType)
{
+ case SchemaCompareEndpointType.Project:
+ {
+ return new SchemaCompareProjectEndpoint(endpointInfo.ProjectFilePath, endpointInfo.TargetScripts, endpointInfo.DataSchemaProvider);
+ }
case SchemaCompareEndpointType.Dacpac:
{
return new SchemaCompareDacpacEndpoint(endpointInfo.PackageFilePath);
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
index 9686d9f5..8385bd96 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs
@@ -19,6 +19,8 @@ using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using System.Diagnostics;
+using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper;
+using System.Collections.Generic;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
{
@@ -122,7 +124,7 @@ WITH VALUES
}
///
- /// Verify the schema compare request comparing a two databases
+ /// Verify the schema compare request comparing two databases
///
[Test]
public async Task SchemaCompareDatabaseToDatabase()
@@ -160,6 +162,46 @@ WITH VALUES
}
}
+ ///
+ /// Verify the schema compare request comparing two projects
+ ///
+ [Test]
+ public async Task SchemaCompareProjectToProject()
+ {
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareTarget");
+
+ try
+ {
+ string sourceProjectPath = SchemaCompareTestUtils.CreateProject(sourceDb, "SourceProject");
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+
+ string[] sourceScripts = SchemaCompareTestUtils.GetProjectScripts(sourceProjectPath);
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(sourceProjectPath, "SourceProject.sqlproj"), sourceScripts);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ var schemaCompareParams = new SchemaCompareParams
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, null, null);
+ ValidateSchemaCompareWithExcludeIncludeResults(schemaCompareOperation);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(sourceProjectPath);
+ SchemaCompareTestUtils.VerifyAndCleanup(targetProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
///
/// Verify the schema compare request comparing a database to a dacpac
///
@@ -201,6 +243,83 @@ WITH VALUES
}
}
+ ///
+ /// Verify the schema compare request comparing a database and a project
+ ///
+ [Test]
+ public async Task SchemaCompareDatabaseToProject()
+ {
+ TestConnectionResult result = SchemaCompareTestUtils.GetLiveAutoCompleteTestObjects();
+
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareTarget");
+
+ try
+ {
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Database, sourceDb.DatabaseName);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ var schemaCompareParams = new SchemaCompareParams
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, result.ConnectionInfo, null);
+ ValidateSchemaCompareWithExcludeIncludeResults(schemaCompareOperation);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(targetProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
+ ///
+ /// Verify the schema compare request comparing a dacpac and a project
+ ///
+ [Test]
+ public async Task SchemaCompareDacpacToProject()
+ {
+ // create dacpacs from databases
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareTarget");
+ try
+ {
+ string sourceDacpacFilePath = SchemaCompareTestUtils.CreateDacpac(sourceDb);
+
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Dacpac, sourceDacpacFilePath);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ var schemaCompareParams = new SchemaCompareParams
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, null, null);
+ ValidateSchemaCompareWithExcludeIncludeResults(schemaCompareOperation);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(sourceDacpacFilePath);
+ SchemaCompareTestUtils.VerifyAndCleanup(targetProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
///
/// Verify the schema compare generate script request comparing a database to a database
///
@@ -299,6 +418,59 @@ WITH VALUES
}
}
+ ///
+ /// Verify the schema compare generate script request comparing a project to a database
+ ///
+ [Test]
+ public async Task SchemaCompareGenerateScriptProjectToDatabase()
+ {
+ TestConnectionResult result = SchemaCompareTestUtils.GetLiveAutoCompleteTestObjects();
+
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareTarget");
+
+ try
+ {
+ string sourceProjectPath = SchemaCompareTestUtils.CreateProject(sourceDb, "SourceProject");
+ string[] sourceScripts = SchemaCompareTestUtils.GetProjectScripts(sourceProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = new();
+ sourceInfo.EndpointType = SchemaCompareEndpointType.Project;
+ sourceInfo.ProjectFilePath = Path.Combine(sourceProjectPath, "SourceProject.sqlproj");
+ sourceInfo.TargetScripts = sourceScripts;
+ sourceInfo.DataSchemaProvider = "150";
+
+ SchemaCompareEndpointInfo targetInfo = new();
+ targetInfo.EndpointType = SchemaCompareEndpointType.Database;
+ targetInfo.DatabaseName = targetDb.DatabaseName;
+
+ var schemaCompareParams = new SchemaCompareParams
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
+
+ // generate script
+ var generateScriptParams = new SchemaCompareGenerateScriptParams
+ {
+ TargetDatabaseName = targetDb.DatabaseName,
+ OperationId = schemaCompareOperation.OperationId,
+ };
+
+ ValidateSchemaCompareScriptGenerationWithExcludeIncludeResults(schemaCompareOperation, generateScriptParams);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(sourceProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
///
/// Verify the schema compare publish changes request comparing a dacpac to a database
///
@@ -342,13 +514,13 @@ WITH VALUES
Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]"));
// update target
- var publishChangesParams = new SchemaComparePublishChangesParams
+ var publishChangesParams = new SchemaComparePublishDatabaseChangesParams
{
TargetDatabaseName = targetDb.DatabaseName,
OperationId = schemaCompareOperation.OperationId,
};
- SchemaComparePublishChangesOperation publishChangesOperation = new SchemaComparePublishChangesOperation(publishChangesParams, schemaCompareOperation.ComparisonResult);
+ SchemaComparePublishDatabaseChangesOperation publishChangesOperation = new SchemaComparePublishDatabaseChangesOperation(publishChangesParams, schemaCompareOperation.ComparisonResult);
publishChangesOperation.Execute(TaskExecutionMode.Execute);
Assert.True(publishChangesOperation.PublishResult.Success);
Assert.That(publishChangesOperation.PublishResult.Errors, Is.Empty);
@@ -370,6 +542,73 @@ WITH VALUES
}
}
+ ///
+ /// Verify the schema compare publish changes request comparing a project to a database
+ ///
+ [Test]
+ public async Task SchemaComparePublishChangesProjectToDatabase()
+ {
+ TestConnectionResult result = SchemaCompareTestUtils.GetLiveAutoCompleteTestObjects();
+
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "SchemaCompareTarget");
+
+ try
+ {
+ string sourceProjectPath = SchemaCompareTestUtils.CreateProject(sourceDb, "SourceProject");
+ string[] sourceScripts = SchemaCompareTestUtils.GetProjectScripts(sourceProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(sourceProjectPath, "SourceProject.sqlproj"), sourceScripts);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Database, targetDb.DatabaseName);
+
+ SchemaCompareParams schemaCompareParams = new()
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+
+ IEnumerator enumerator = schemaCompareOperation.ComparisonResult.Differences.GetEnumerator();
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table1]"));
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]"));
+
+ // update target
+ SchemaComparePublishDatabaseChangesParams publishChangesParams = new()
+ {
+ TargetDatabaseName = targetDb.DatabaseName,
+ OperationId = schemaCompareOperation.OperationId,
+ };
+
+ SchemaComparePublishDatabaseChangesOperation publishChangesOperation = new(publishChangesParams, schemaCompareOperation.ComparisonResult);
+ publishChangesOperation.Execute(TaskExecutionMode.Execute);
+ Assert.True(publishChangesOperation.PublishResult.Success);
+ Assert.That(publishChangesOperation.PublishResult.Errors, Is.Empty);
+
+ // Verify that there are no differences after the publish by running the comparison again
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.True(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.That(schemaCompareOperation.ComparisonResult.Differences, Is.Empty);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(sourceProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
///
/// Verify the schema compare publish changes request comparing a database to a database
///
@@ -411,13 +650,13 @@ WITH VALUES
Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]"));
// update target
- var publishChangesParams = new SchemaComparePublishChangesParams
+ var publishChangesParams = new SchemaComparePublishDatabaseChangesParams
{
TargetDatabaseName = targetDb.DatabaseName,
OperationId = schemaCompareOperation.OperationId,
};
- SchemaComparePublishChangesOperation publishChangesOperation = new SchemaComparePublishChangesOperation(publishChangesParams, schemaCompareOperation.ComparisonResult);
+ SchemaComparePublishDatabaseChangesOperation publishChangesOperation = new SchemaComparePublishDatabaseChangesOperation(publishChangesParams, schemaCompareOperation.ComparisonResult);
publishChangesOperation.Execute(TaskExecutionMode.Execute);
Assert.True(publishChangesOperation.PublishResult.Success);
Assert.That(publishChangesOperation.PublishResult.Errors, Is.Empty);
@@ -437,6 +676,237 @@ WITH VALUES
}
}
+ ///
+ /// Verify the schema compare publish changes request comparing a dacpac to a project
+ ///
+ [Test]
+ public async Task SchemaComparePublishChangesDacpacToProject()
+ {
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "SchemaCompareTarget");
+
+ string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SchemaCompareTest");
+ Directory.CreateDirectory(folderPath);
+
+ try
+ {
+ string sourceDacpacFilePath = SchemaCompareTestUtils.CreateDacpac(sourceDb);
+
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Dacpac, sourceDacpacFilePath);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ SchemaCompareParams schemaCompareParams = new()
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, null, null);
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+ (schemaCompareOperation.ComparisonResult.Differences as List).RemoveAll(d => !d.Included);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+
+ IEnumerator enumerator = schemaCompareOperation.ComparisonResult.Differences.GetEnumerator();
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table1]"));
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]"));
+
+ // update target
+ SchemaComparePublishProjectChangesParams publishChangesParams = new()
+ {
+ OperationId = schemaCompareOperation.OperationId,
+ TargetProjectPath = targetProjectPath,
+ TargetFolderStructure = SqlServer.Dac.DacExtractTarget.Flat,
+ };
+
+ SchemaComparePublishProjectChangesOperation publishChangesOperation = new(publishChangesParams, schemaCompareOperation.ComparisonResult);
+ publishChangesOperation.Execute(TaskExecutionMode.Execute);
+ Assert.True(publishChangesOperation.PublishResult.Success);
+ Assert.AreEqual(publishChangesOperation.PublishResult.ErrorMessage, "");
+ Assert.AreEqual(publishChangesOperation.PublishResult.ChangedFiles.Length, 0);
+ Assert.AreEqual(publishChangesOperation.PublishResult.AddedFiles.Length, 2);
+ Assert.AreEqual(publishChangesOperation.PublishResult.DeletedFiles.Length, 0);
+
+ targetInfo.TargetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ // Verify that there are no differences after the publish by running the comparison again
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+ (schemaCompareOperation.ComparisonResult.Differences as List).RemoveAll(d => !d.Included);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.True(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.That(schemaCompareOperation.ComparisonResult.Differences, Is.Empty);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(sourceDacpacFilePath);
+ SchemaCompareTestUtils.VerifyAndCleanup(targetProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
+ ///
+ /// Verify the schema compare publish changes request comparing a database to a project
+ ///
+ [Test]
+ public async Task SchemaComparePublishChangesDatabaseToProject()
+ {
+ TestConnectionResult result = SchemaCompareTestUtils.GetLiveAutoCompleteTestObjects();
+
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "SchemaCompareTarget");
+
+ try
+ {
+
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Database, sourceDb.DatabaseName);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ SchemaCompareParams schemaCompareParams = new()
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, result.ConnectionInfo, result.ConnectionInfo);
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+ (schemaCompareOperation.ComparisonResult.Differences as List).RemoveAll(d => !d.Included);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+
+ IEnumerator enumerator = schemaCompareOperation.ComparisonResult.Differences.GetEnumerator();
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table1]"));
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]"));
+
+ // update target
+ SchemaComparePublishProjectChangesParams publishChangesParams = new()
+ {
+ OperationId = schemaCompareOperation.OperationId,
+ TargetProjectPath = targetProjectPath,
+ TargetFolderStructure = SqlServer.Dac.DacExtractTarget.Flat,
+ };
+
+ SchemaComparePublishProjectChangesOperation publishChangesOperation = new(publishChangesParams, schemaCompareOperation.ComparisonResult);
+ publishChangesOperation.Execute(TaskExecutionMode.Execute);
+ Assert.True(publishChangesOperation.PublishResult.Success);
+ Assert.AreEqual(publishChangesOperation.PublishResult.ErrorMessage, String.Empty);
+ Assert.AreEqual(publishChangesOperation.PublishResult.ChangedFiles.Length, 0);
+ Assert.AreEqual(publishChangesOperation.PublishResult.AddedFiles.Length, 2);
+ Assert.AreEqual(publishChangesOperation.PublishResult.DeletedFiles.Length, 0);
+
+ targetInfo.TargetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ // Verify that there are no differences after the publish by running the comparison again
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+ (schemaCompareOperation.ComparisonResult.Differences as List).RemoveAll(d => !d.Included);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.True(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.That(schemaCompareOperation.ComparisonResult.Differences, Is.Empty);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(targetProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
+ ///
+ /// Verify the schema compare publish changes request comparing a project to a project
+ ///
+ [Test]
+ public async Task SchemaComparePublishChangesProjectToProject()
+ {
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "SchemaCompareTarget");
+
+ try
+ {
+ string sourceProjectPath = SchemaCompareTestUtils.CreateProject(sourceDb, "SourceProject");
+ string[] sourceScripts = SchemaCompareTestUtils.GetProjectScripts(sourceProjectPath);
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(sourceProjectPath, "SourceProject.sqlproj"), sourceScripts);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ SchemaCompareParams schemaCompareParams = new()
+ {
+ SourceEndpointInfo = sourceInfo,
+ TargetEndpointInfo = targetInfo
+ };
+
+ SchemaCompareOperation schemaCompareOperation = new(schemaCompareParams, null, null);
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+ (schemaCompareOperation.ComparisonResult.Differences as List).RemoveAll(d => !d.Included);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.False(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.NotNull(schemaCompareOperation.ComparisonResult.Differences);
+
+ IEnumerator enumerator = schemaCompareOperation.ComparisonResult.Differences.GetEnumerator();
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table1]"));
+ enumerator.MoveNext();
+ Assert.True(enumerator.Current.SourceObject.Name.ToString().Equals("[dbo].[table2]"));
+
+ // update target
+ SchemaComparePublishProjectChangesParams publishChangesParams = new()
+ {
+ OperationId = schemaCompareOperation.OperationId,
+ TargetProjectPath = targetProjectPath,
+ TargetFolderStructure = SqlServer.Dac.DacExtractTarget.Flat,
+ };
+
+ SchemaComparePublishProjectChangesOperation publishChangesOperation = new(publishChangesParams, schemaCompareOperation.ComparisonResult);
+ publishChangesOperation.Execute(TaskExecutionMode.Execute);
+ Assert.True(publishChangesOperation.PublishResult.Success);
+ Assert.AreEqual(publishChangesOperation.PublishResult.ErrorMessage, "");
+ Assert.AreEqual(publishChangesOperation.PublishResult.ChangedFiles.Length, 0);
+ Assert.AreEqual(publishChangesOperation.PublishResult.AddedFiles.Length, 2);
+ Assert.AreEqual(publishChangesOperation.PublishResult.DeletedFiles.Length, 0);
+
+ targetInfo.TargetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ // Verify that there are no differences after the publish by running the comparison again
+ schemaCompareOperation.Execute(TaskExecutionMode.Execute);
+ (schemaCompareOperation.ComparisonResult.Differences as List).RemoveAll(d => !d.Included);
+
+ Assert.True(schemaCompareOperation.ComparisonResult.IsValid);
+ Assert.True(schemaCompareOperation.ComparisonResult.IsEqual);
+ Assert.That(schemaCompareOperation.ComparisonResult.Differences, Is.Empty);
+
+ // cleanup
+ SchemaCompareTestUtils.VerifyAndCleanup(sourceProjectPath);
+ SchemaCompareTestUtils.VerifyAndCleanup(targetProjectPath);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
///
/// Verify the schema compare Scmp File Save for database endpoints
///
@@ -458,7 +928,7 @@ WITH VALUES
targetInfo.EndpointType = SchemaCompareEndpointType.Database;
targetInfo.DatabaseName = targetDb.DatabaseName;
- CreateAndValidateScmpFile(sourceInfo, targetInfo, true, true);
+ CreateAndValidateScmpFile(sourceInfo, targetInfo, SchemaCompareEndpointType.Database, SchemaCompareEndpointType.Database);
}
finally
{
@@ -490,7 +960,37 @@ WITH VALUES
targetInfo.EndpointType = SchemaCompareEndpointType.Dacpac;
targetInfo.PackageFilePath = targetDacpac;
- CreateAndValidateScmpFile(sourceInfo, targetInfo, false, false);
+ CreateAndValidateScmpFile(sourceInfo, targetInfo, SchemaCompareEndpointType.Dacpac, SchemaCompareEndpointType.Dacpac);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
+ ///
+ /// Verify the schema compare Scmp File Save for project endpoints
+ ///
+ [Test]
+ public async Task SchemaCompareSaveScmpFileForProjects()
+ {
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareTarget");
+
+ try
+ {
+ string filePath = SchemaCompareTestUtils.CreateScmpPath();
+
+ string sourceProjectPath = SchemaCompareTestUtils.CreateProject(sourceDb, "SourceProject");
+ string[] sourceScripts = SchemaCompareTestUtils.GetProjectScripts(sourceProjectPath);
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(sourceProjectPath, "SourceProject.sqlproj"), sourceScripts);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ CreateAndValidateScmpFile(sourceInfo, targetInfo, SchemaCompareEndpointType.Project, SchemaCompareEndpointType.Project);
}
finally
{
@@ -521,7 +1021,64 @@ WITH VALUES
targetInfo.EndpointType = SchemaCompareEndpointType.Database;
targetInfo.DatabaseName = targetDb.DatabaseName;
- CreateAndValidateScmpFile(sourceInfo, targetInfo, false, true);
+ CreateAndValidateScmpFile(sourceInfo, targetInfo, SchemaCompareEndpointType.Dacpac, SchemaCompareEndpointType.Database);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
+ ///
+ /// Verify the schema compare Scmp File Save for project and db endpoints combination
+ ///
+ [Test]
+ public async Task SchemaCompareSaveScmpFileForProjectToDB()
+ {
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareTarget");
+
+ try
+ {
+ string filePath = SchemaCompareTestUtils.CreateScmpPath();
+
+ string sourceProjectPath = SchemaCompareTestUtils.CreateProject(sourceDb, "SourceProject");
+ string[] sourceScripts = SchemaCompareTestUtils.GetProjectScripts(sourceProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(sourceProjectPath, "SourceProject.sqlproj"), sourceScripts);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Database, targetDb.DatabaseName);
+
+ CreateAndValidateScmpFile(sourceInfo, targetInfo, SchemaCompareEndpointType.Project, SchemaCompareEndpointType.Database);
+ }
+ finally
+ {
+ sourceDb.Cleanup();
+ targetDb.Cleanup();
+ }
+ }
+
+ ///
+ /// Verify the schema compare Scmp File Save for dacpac and project endpoints combination
+ ///
+ [Test]
+ public async Task SchemaCompareSaveScmpFileForDacpacToProject()
+ {
+ SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareSource");
+ SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareTarget");
+
+ try
+ {
+ string filePath = SchemaCompareTestUtils.CreateScmpPath();
+
+ string sourceDacpac = SchemaCompareTestUtils.CreateDacpac(sourceDb);
+ string targetProjectPath = SchemaCompareTestUtils.CreateProject(targetDb, "TargetProject");
+ string[] targetScripts = SchemaCompareTestUtils.GetProjectScripts(targetProjectPath);
+
+ SchemaCompareEndpointInfo sourceInfo = CreateTestEndpoint(SchemaCompareEndpointType.Dacpac, sourceDacpac);
+ SchemaCompareEndpointInfo targetInfo = CreateTestEndpoint(SchemaCompareEndpointType.Project, Path.Combine(targetProjectPath, "TargetProject.sqlproj"), targetScripts);
+
+ CreateAndValidateScmpFile(sourceInfo, targetInfo, SchemaCompareEndpointType.Dacpac, SchemaCompareEndpointType.Project);
}
finally
{
@@ -548,6 +1105,15 @@ WITH VALUES
await CreateAndOpenScmp(SchemaCompareEndpointType.Dacpac, SchemaCompareEndpointType.Database);
}
+ ///
+ /// Verify opening an scmp comparing a project and database
+ ///
+ [Test]
+ public async Task SchemaCompareOpenScmpProjectToDatabaseRequest()
+ {
+ await CreateAndOpenScmp(SchemaCompareEndpointType.Project, SchemaCompareEndpointType.Database);
+ }
+
///
/// Verify opening an scmp comparing two dacpacs
///
@@ -557,6 +1123,24 @@ WITH VALUES
await CreateAndOpenScmp(SchemaCompareEndpointType.Dacpac, SchemaCompareEndpointType.Dacpac);
}
+ ///
+ /// Verify opening an scmp comparing a project and dacpac
+ ///
+ [Test]
+ public async Task SchemaCompareOpenScmpProjectToDacpacRequest()
+ {
+ await CreateAndOpenScmp(SchemaCompareEndpointType.Project, SchemaCompareEndpointType.Dacpac);
+ }
+
+ ///
+ /// Verify opening an scmp comparing two projects
+ ///
+ [Test]
+ public async Task SchemaCompareOpenScmpProjectToProjectRequest()
+ {
+ await CreateAndOpenScmp(SchemaCompareEndpointType.Project, SchemaCompareEndpointType.Project);
+ }
+
///
/// Verify the schema compare Service Calls ends to end
///
@@ -639,14 +1223,14 @@ WITH VALUES
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(targetDb.ConnectionString);
- var publishParams = new SchemaComparePublishChangesParams
+ var publishParams = new SchemaComparePublishDatabaseChangesParams
{
OperationId = operationId,
TargetDatabaseName = targetDb.DatabaseName,
TargetServerName = builder.DataSource,
};
- await SchemaCompareService.Instance.HandleSchemaComparePublishChangesRequest(publishParams, publishRequestContext.Object);
+ await SchemaCompareService.Instance.HandleSchemaComparePublishDatabaseChangesRequest(publishParams, publishRequestContext.Object);
ValidateTask(SR.PublishChangesTaskName);
// Include/Exclude service call
@@ -795,7 +1379,7 @@ WITH VALUES
Assert.True(cek.SourceObject != null, "CEK obect is null");
Assert.True(cek.SourceObject.Name.ToString() == "[CEK_Auto1]", string.Format("CEK object name incorrect. Expected {0}, Actual {1}", "CEK_Auto1", cek.SourceObject.Name.ToString()));
Assert.True(CreateKey.Contains(cek.SourceObject.GetScript().Trim()), string.Format("Expected script : {0}, Actual Script {1}", cek.SourceObject.GetScript(), CreateKey));
-
+
// validate CMK script
var cmk = schemaCompareOperation.ComparisonResult.Differences.First(x => x.Name == "SqlColumnMasterKey");
Assert.NotNull(cmk);
@@ -872,7 +1456,7 @@ WITH VALUES
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");
+ 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);
@@ -1086,7 +1670,7 @@ WITH VALUES
try
{
SchemaCompareEndpoint sourceEndpoint = CreateSchemaCompareEndpoint(sourceDb, sourceEndpointType);
- SchemaCompareEndpoint targetEndpoint = CreateSchemaCompareEndpoint(targetDb, targetEndpointType);
+ SchemaCompareEndpoint targetEndpoint = CreateSchemaCompareEndpoint(targetDb, targetEndpointType, targetEndpointType == SchemaCompareEndpointType.Project);
// create a comparison and exclude the first difference
SchemaComparison compare = new SchemaComparison(sourceEndpoint, targetEndpoint);
@@ -1122,11 +1706,30 @@ WITH VALUES
Assert.That(schemaCompareOpenScmpOperation.Result.ExcludedSourceElements, Is.Not.Empty);
Assert.AreEqual(1, schemaCompareOpenScmpOperation.Result.ExcludedSourceElements.Count());
Assert.That(schemaCompareOpenScmpOperation.Result.ExcludedTargetElements, Is.Empty);
- Assert.AreEqual(targetDb.DatabaseName, schemaCompareOpenScmpOperation.Result.OriginalTargetName);
+
+ if (targetEndpointType == SchemaCompareEndpointType.Project)
+ {
+ Assert.AreEqual(Path.GetFileName((targetEndpoint as SchemaCompareProjectEndpoint).ProjectFilePath), schemaCompareOpenScmpOperation.Result.OriginalTargetName);
+ }
+ else
+ {
+ Assert.AreEqual(targetDb.DatabaseName, schemaCompareOpenScmpOperation.Result.OriginalTargetName);
+ }
+
ValidateResultEndpointInfo(sourceEndpoint, schemaCompareOpenScmpOperation.Result.SourceEndpointInfo, sourceDb.ConnectionString);
ValidateResultEndpointInfo(targetEndpoint, schemaCompareOpenScmpOperation.Result.TargetEndpointInfo, targetDb.ConnectionString);
SchemaCompareTestUtils.VerifyAndCleanup(filePath);
+
+ if (sourceEndpointType == SchemaCompareEndpointType.Project)
+ {
+ SchemaCompareTestUtils.VerifyAndCleanup(Directory.GetParent((sourceEndpoint as SchemaCompareProjectEndpoint).ProjectFilePath).FullName);
+ }
+
+ if (targetEndpointType == SchemaCompareEndpointType.Project)
+ {
+ SchemaCompareTestUtils.VerifyAndCleanup(Directory.GetParent((targetEndpoint as SchemaCompareProjectEndpoint).ProjectFilePath).FullName);
+ }
}
finally
{
@@ -1135,13 +1738,19 @@ WITH VALUES
}
}
- private SchemaCompareEndpoint CreateSchemaCompareEndpoint(SqlTestDb db, SchemaCompareEndpointType endpointType)
+ private SchemaCompareEndpoint CreateSchemaCompareEndpoint(SqlTestDb db, SchemaCompareEndpointType endpointType, bool isProjectTarget = false)
{
if (endpointType == SchemaCompareEndpointType.Dacpac)
{
string dacpacFilePath = SchemaCompareTestUtils.CreateDacpac(db);
return new SchemaCompareDacpacEndpoint(dacpacFilePath);
}
+ else if (endpointType == SchemaCompareEndpointType.Project)
+ {
+ string projectPath = SchemaCompareTestUtils.CreateProject(db, isProjectTarget ? "TargetProject" : "SourceProject");
+ string[] scripts = SchemaCompareTestUtils.GetProjectScripts(projectPath);
+ return new SchemaCompareProjectEndpoint(Path.Combine(projectPath, isProjectTarget ? "TargetProject.sqlproj" : "SourceProject.sqlproj"), scripts, "150");
+ }
else
{
return new SchemaCompareDatabaseEndpoint(db.ConnectionString);
@@ -1155,11 +1764,16 @@ WITH VALUES
SchemaCompareDacpacEndpoint dacpacEndpoint = originalEndpoint as SchemaCompareDacpacEndpoint;
Assert.AreEqual(dacpacEndpoint.FilePath, resultEndpoint.PackageFilePath);
}
+ else if (resultEndpoint.EndpointType == SchemaCompareEndpointType.Project)
+ {
+ SchemaCompareProjectEndpoint projectEndpoint = originalEndpoint as SchemaCompareProjectEndpoint;
+ Assert.AreEqual(projectEndpoint.ProjectFilePath, resultEndpoint.ProjectFilePath);
+ }
else
{
SchemaCompareDatabaseEndpoint databaseEndpoint = originalEndpoint as SchemaCompareDatabaseEndpoint;
Assert.AreEqual(databaseEndpoint.DatabaseName, resultEndpoint.DatabaseName);
- Assert.That(connectionString, Does.Contain(resultEndpoint.ConnectionDetails.ConnectionString), "connectionString has password but resultEndpoint doesn't");
+ Assert.That(connectionString, Does.Contain(resultEndpoint.ConnectionDetails.ConnectionString), "connectionString has password but resultEndpoint doesn't");
}
}
@@ -1193,7 +1807,7 @@ WITH VALUES
Assert.AreEqual(dacFxType, diffObjectTypeType);
}
- private void CreateAndValidateScmpFile(SchemaCompareEndpointInfo sourceInfo, SchemaCompareEndpointInfo targetInfo, bool isSourceDb, bool isTargetDb)
+ private void CreateAndValidateScmpFile(SchemaCompareEndpointInfo sourceInfo, SchemaCompareEndpointInfo targetInfo, SchemaCompareEndpointType sourceType, SchemaCompareEndpointType targetType)
{
string filePath = SchemaCompareTestUtils.CreateScmpPath();
var result = SchemaCompareTestUtils.GetLiveAutoCompleteTestObjects();
@@ -1236,29 +1850,41 @@ WITH VALUES
// Validate with DacFx SchemaComparison object
SchemaComparison sc = new SchemaComparison(filePath);
- if (isSourceDb)
+ if (sourceType == SchemaCompareEndpointType.Database)
{
Assert.True(sc.Source is SchemaCompareDatabaseEndpoint, "Source should be SchemaCompareDatabaseEndpoint");
Assert.True((sc.Source as SchemaCompareDatabaseEndpoint).DatabaseName == sourceInfo.DatabaseName, $"Source Database {(sc.Source as SchemaCompareDatabaseEndpoint).DatabaseName} name does not match the params passed {sourceInfo.DatabaseName}");
}
- else
+ else if (sourceType == SchemaCompareEndpointType.Dacpac)
{
Assert.True(sc.Source is SchemaCompareDacpacEndpoint, "Source should be SchemaCompareDacpacEndpoint");
Assert.True((sc.Source as SchemaCompareDacpacEndpoint).FilePath == sourceInfo.PackageFilePath, $"Source dacpac {(sc.Source as SchemaCompareDacpacEndpoint).FilePath} name does not match the params passed {sourceInfo.PackageFilePath}");
SchemaCompareTestUtils.VerifyAndCleanup(sourceInfo.PackageFilePath);
}
-
- if (isTargetDb)
+ else if (sourceType == SchemaCompareEndpointType.Project)
{
- Assert.True(sc.Target is SchemaCompareDatabaseEndpoint, "Source should be SchemaCompareDatabaseEndpoint");
- Assert.True((sc.Target as SchemaCompareDatabaseEndpoint).DatabaseName == targetInfo.DatabaseName, $"Source Database {(sc.Target as SchemaCompareDatabaseEndpoint).DatabaseName} name does not match the params passed {targetInfo.DatabaseName}");
+ Assert.True(sc.Source is SchemaCompareProjectEndpoint, "Source should be SchemaCompareProjectEndpoint");
+ Assert.True((sc.Source as SchemaCompareProjectEndpoint).ProjectFilePath == sourceInfo.ProjectFilePath, $"Source project {(sc.Source as SchemaCompareProjectEndpoint).ProjectFilePath} name does not match the params passed {sourceInfo.ProjectFilePath}");
+ SchemaCompareTestUtils.VerifyAndCleanup(Directory.GetParent(sourceInfo.ProjectFilePath).FullName);
}
- else
+
+ if (targetType == SchemaCompareEndpointType.Database)
{
- Assert.True(sc.Target is SchemaCompareDacpacEndpoint, "Source should be SchemaCompareDacpacEndpoint");
- Assert.True((sc.Target as SchemaCompareDacpacEndpoint).FilePath == targetInfo.PackageFilePath, $"Source dacpac {(sc.Target as SchemaCompareDacpacEndpoint).FilePath} name does not match the params passed {targetInfo.PackageFilePath}");
+ Assert.True(sc.Target is SchemaCompareDatabaseEndpoint, "Target should be SchemaCompareDatabaseEndpoint");
+ Assert.True((sc.Target as SchemaCompareDatabaseEndpoint).DatabaseName == targetInfo.DatabaseName, $"Target Database {(sc.Target as SchemaCompareDatabaseEndpoint).DatabaseName} name does not match the params passed {targetInfo.DatabaseName}");
+ }
+ else if (targetType == SchemaCompareEndpointType.Dacpac)
+ {
+ Assert.True(sc.Target is SchemaCompareDacpacEndpoint, "Target should be SchemaCompareDacpacEndpoint");
+ Assert.True((sc.Target as SchemaCompareDacpacEndpoint).FilePath == targetInfo.PackageFilePath, $"Target dacpac {(sc.Target as SchemaCompareDacpacEndpoint).FilePath} name does not match the params passed {targetInfo.PackageFilePath}");
SchemaCompareTestUtils.VerifyAndCleanup(targetInfo.PackageFilePath);
}
+ else if (targetType == SchemaCompareEndpointType.Project)
+ {
+ Assert.True(sc.Target is SchemaCompareProjectEndpoint, "Target should be SchemaCompareProjectEndpoint");
+ Assert.True((sc.Target as SchemaCompareProjectEndpoint).ProjectFilePath == targetInfo.ProjectFilePath, $"Target project {(sc.Target as SchemaCompareProjectEndpoint).ProjectFilePath} name does not match the params passed {targetInfo.ProjectFilePath}");
+ SchemaCompareTestUtils.VerifyAndCleanup(Directory.GetParent(targetInfo.ProjectFilePath).FullName);
+ }
Assert.True(!sc.ExcludedTargetObjects.Any(), "Target Excluded Objects are expected to be Empty");
Assert.True(sc.ExcludedSourceObjects.Count == 1, $"Exactly {1} Source Excluded Object Should be present but {sc.ExcludedSourceObjects.Count} found");
@@ -1323,5 +1949,32 @@ WITH VALUES
Console.WriteLine($"ValidateTask{expectedTaskName} completed at retry = {retry}");
TaskService.Instance.TaskManager.Reset();
}
+
+ private SchemaCompareEndpointInfo CreateTestEndpoint(SchemaCompareEndpointType type, string comparisonObjectPath, string[] targetScripts = null)
+ {
+ SchemaCompareEndpointInfo result = new SchemaCompareEndpointInfo
+ {
+ EndpointType = type
+ };
+
+ switch (type)
+ {
+ case SchemaCompareEndpointType.Dacpac:
+ result.PackageFilePath = comparisonObjectPath;
+ break;
+ case SchemaCompareEndpointType.Database:
+ result.DatabaseName = comparisonObjectPath;
+ break;
+ case SchemaCompareEndpointType.Project:
+ result.ProjectFilePath = comparisonObjectPath;
+ result.TargetScripts = targetScripts;
+ result.DataSchemaProvider = "150";
+ break;
+ default:
+ throw new ArgumentException($"Unexpected endpoint type: {type}");
+ }
+
+ return result;
+ }
}
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs
index a4e4d979..75b1b7e0 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareTestUtils.cs
@@ -14,27 +14,34 @@ using NUnit.Framework;
using System;
using System.IO;
using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper;
+using System.Collections.Generic;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
{
internal static class SchemaCompareTestUtils
{
- internal static void VerifyAndCleanup(string filePath)
+ internal static void VerifyAndCleanup(string path)
{
- // Verify it was created
- Assert.True(File.Exists(filePath), $"File {filePath} was expected to exist but did not");
+ // verify it was created...
+ Assert.True(File.Exists(path) || Directory.Exists(path), $"File or directory {path} was expected to exist but did not");
- // Remove the file
- if (File.Exists(filePath))
+ FileAttributes attr = File.GetAttributes(path);
+
+ // ...then clean it up
+ if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
{
- File.Delete(filePath);
+ new DirectoryInfo(path).Delete(recursive: true);
+ }
+ else
+ {
+ File.Delete(path);
}
}
internal static string CreateDacpac(SqlTestDb testdb)
{
var result = GetLiveAutoCompleteTestObjects();
- string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SchemaCompareTest");
+ string folderPath = Path.Combine(Path.GetTempPath(), "SchemaCompareTest");
Directory.CreateDirectory(folderPath);
var extractParams = new ExtractParams
@@ -52,6 +59,34 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SchemaCompare
return extractParams.PackageFilePath;
}
+ internal static string CreateProject(SqlTestDb testdb, string projectName)
+ {
+ var result = GetLiveAutoCompleteTestObjects();
+ string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SchemaCompareTest", projectName);
+ Directory.CreateDirectory(folderPath);
+ File.Create(Path.Combine(folderPath, projectName + ".sqlproj")).Close();
+
+ var extractParams = new ExtractParams
+ {
+ DatabaseName = testdb.DatabaseName,
+ ExtractTarget = DacExtractTarget.Flat,
+ PackageFilePath = folderPath,
+ ApplicationName = "test",
+ ApplicationVersion = "1.0.0.0"
+ };
+
+ DacFxService service = new();
+ ExtractOperation operation = new(extractParams, result.ConnectionInfo);
+ service.PerformOperation(operation, TaskExecutionMode.Execute);
+
+ return folderPath;
+ }
+
+ internal static string[] GetProjectScripts(string projectPath)
+ {
+ return Directory.GetFiles(projectPath, "*.sql", SearchOption.AllDirectories);
+ }
+
internal static string CreateScmpPath()
{
var result = GetLiveAutoCompleteTestObjects();