//
// 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;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.SchemaCompare;
using Microsoft.SqlServer.Dac.Compare;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.SchemaCopmare
{
///
/// Main class for SchemaCompare service
///
class SchemaCompareService
{
private static ConnectionService connectionService = null;
private SqlTaskManager sqlTaskManagerInstance = null;
private static readonly Lazy instance = new Lazy(() => new SchemaCompareService());
private Lazy> schemaCompareResults =
new Lazy>(() => new ConcurrentDictionary());
///
/// Gets the singleton instance object
///
public static SchemaCompareService Instance
{
get { return instance.Value; }
}
///
/// Initializes the service instance
///
///
public void InitializeService(ServiceHost serviceHost)
{
serviceHost.SetRequestHandler(SchemaCompareRequest.Type, this.HandleSchemaCompareRequest);
serviceHost.SetRequestHandler(SchemaCompareGenerateScriptRequest.Type, this.HandleSchemaCompareGenerateScriptRequest);
serviceHost.SetRequestHandler(SchemaComparePublishChangesRequest.Type, this.HandleSchemaComparePublishChangesRequest);
}
///
/// Handles schema compare request
///
///
public async Task HandleSchemaCompareRequest(SchemaCompareParams parameters, RequestContext requestContext)
{
try
{
ConnectionInfo sourceConnInfo;
ConnectionInfo targetConnInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.SourceEndpointInfo.OwnerUri,
out sourceConnInfo);
ConnectionServiceInstance.TryFindConnection(
parameters.TargetEndpointInfo.OwnerUri,
out targetConnInfo);
Task schemaCompareTask = Task.Run(async () =>
{
SchemaCompareOperation operation = null;
try
{
operation = new SchemaCompareOperation(parameters, sourceConnInfo, targetConnInfo);
operation.Execute(parameters.TaskExecutionMode);
// add result to dictionary of results
schemaCompareResults.Value[operation.OperationId] = operation.ComparisonResult;
await requestContext.SendResult(new SchemaCompareResult()
{
OperationId = operation.OperationId,
Success = true,
ErrorMessage = operation.ErrorMessage,
AreEqual = operation.ComparisonResult.IsEqual,
Differences = operation.Differences
});
}
catch(Exception e)
{
await requestContext.SendResult(new SchemaCompareResult()
{
OperationId = operation != null ? operation.OperationId : null,
Success = false,
ErrorMessage = operation == null ? e.Message : operation.ErrorMessage,
});
}
});
}
catch (Exception e)
{
await requestContext.SendError(e);
}
}
///
/// Handles request for schema compare generate deploy script
///
///
public async Task HandleSchemaCompareGenerateScriptRequest(SchemaCompareGenerateScriptParams parameters, RequestContext requestContext)
{
SchemaCompareGenerateScriptOperation operation = null;
try
{
SchemaComparisonResult compareResult = schemaCompareResults.Value[parameters.OperationId];
operation = new SchemaCompareGenerateScriptOperation(parameters, compareResult);
SqlTask sqlTask = null;
TaskMetadata metadata = new TaskMetadata();
metadata.TaskOperation = operation;
// want to show filepath in task history instead of server and database
metadata.ServerName = parameters.ScriptFilePath;
metadata.DatabaseName = string.Empty;
metadata.Name = SR.GenerateScriptTaskName;
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,
});
}
}
///
/// Handles request for schema compare publish changes script
///
///
public async Task HandleSchemaComparePublishChangesRequest(SchemaComparePublishChangesParams parameters, RequestContext requestContext)
{
SchemaComparePublishChangesOperation operation = null;
try
{
SchemaComparisonResult compareResult = schemaCompareResults.Value[parameters.OperationId];
operation = new SchemaComparePublishChangesOperation(parameters, compareResult);
SqlTask sqlTask = null;
TaskMetadata metadata = new TaskMetadata();
metadata.TaskOperation = operation;
metadata.ServerName = parameters.TargetServerName;
metadata.DatabaseName = parameters.TargetDatabaseName;
metadata.Name = SR.PublishChangesTaskName;
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,
});
}
}
private SqlTaskManager SqlTaskManagerInstance
{
get
{
if (sqlTaskManagerInstance == null)
{
sqlTaskManagerInstance = SqlTaskManager.Instance;
}
return sqlTaskManagerInstance;
}
set
{
sqlTaskManagerInstance = value;
}
}
internal static ConnectionService ConnectionServiceInstance
{
get
{
if (connectionService == null)
{
connectionService = ConnectionService.Instance;
}
return connectionService;
}
set
{
connectionService = value;
}
}
}
}