// // 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.ServiceLayer.Connection; 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.Threading; namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare { /// /// Class to represent an in-progress schema compare generate script operation /// class SchemaCompareGenerateScriptOperation : 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 SchemaCompareGenerateScriptParams 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 SchemaCompareScriptGenerationResult ScriptGenerationResult { get; set; } public SchemaCompareGenerateScriptOperation(SchemaCompareGenerateScriptParams parameters, SchemaComparisonResult comparisonResult) { Validate.IsNotNull("parameters", parameters); this.Parameters = parameters; Validate.IsNotNull("comparisonResult", comparisonResult); this.ComparisonResult = comparisonResult; } public void Execute(TaskExecutionMode mode) { if (this.CancellationToken.IsCancellationRequested) { throw new OperationCanceledException(this.CancellationToken); } try { this.ScriptGenerationResult = this.ComparisonResult.GenerateScript(this.Parameters.TargetDatabaseName, this.CancellationToken); // tests don't create a SqlTask, so only add the script when the SqlTask isn't null if (this.SqlTask != null) { this.SqlTask.AddScript(SqlTaskStatus.Succeeded, this.ScriptGenerationResult.Script); if (!string.IsNullOrEmpty(this.ScriptGenerationResult.MasterScript)) { // master script is only used if the target is Azure SQL db and the script contains all operations that must be done against the master database this.SqlTask.AddScript(SqlTaskStatus.Succeeded, ScriptGenerationResult.MasterScript); } } if (!this.ScriptGenerationResult.Success) { ErrorMessage = this.ScriptGenerationResult.Message; throw new Exception(ErrorMessage); } } catch (Exception e) { ErrorMessage = e.Message; Logger.Write(TraceEventType.Error, string.Format("Schema compare generate script 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(); } /// /// Disposes the operation. /// public void Dispose() { if (!disposed) { this.Cancel(); disposed = true; } } } }