Add DacFx Generate Deploy Plan Operation (#768)

* initial adding upgrade plan

* upgrade plan request from ADS works

* now data loss operations are returned

* fixes after rebasing

* refactoring to use GenerateDeployPlan instead of UpgradePlan

* improving test

* Addressing comments

* changing abstract execute to virtual

* changed GenerateDeployPlanOepration to use Execute()

* addressing comments

* simplyfing deploy options

* adding deploy options to deploy and generate script operations
This commit is contained in:
kisantia
2019-02-06 17:22:20 -08:00
committed by GitHub
parent 9177a6be8b
commit 0a172f3c8e
7 changed files with 211 additions and 6 deletions

View File

@@ -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.TaskServices;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
{
/// <summary>
/// Parameters for a DacFx generate deploy plan request.
/// </summary>
public class GenerateDeployPlanParams : DacFxParams
{
}
/// <summary>
/// Defines the DacFx generate deploy plan request type
/// </summary>
class GenerateDeployPlanRequest
{
public static readonly RequestType<GenerateDeployPlanParams, GenerateDeployPlanRequestResult> Type =
RequestType<GenerateDeployPlanParams, GenerateDeployPlanRequestResult>.Create("dacfx/generateDeployPlan");
}
/// <summary>
/// Parameters returned from a generate deploy script request.
/// </summary>
public class GenerateDeployPlanRequestResult : DacFxResult
{
/// <summary>
/// An xml string that details the alerts and the operations for deploying the specified dacpac to the database
/// </summary>
public string Report { get; set; }
}
}

View File

@@ -90,5 +90,23 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
}
public abstract void Execute();
protected DacDeployOptions GetDefaultDeployOptions()
{
DacDeployOptions options = new DacDeployOptions
{
AllowDropBlockingAssemblies = true,
AllowIncompatiblePlatform = true,
BlockOnPossibleDataLoss = false,
DropObjectsNotInSource = true,
DropPermissionsNotInSource = true,
DropRoleMembersNotInSource = true,
IgnoreKeywordCasing = false,
IgnoreSemicolonBetweenStatements = false,
IgnoreWhitespace = false,
};
return options;
}
}
}

View File

@@ -44,6 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
serviceHost.SetRequestHandler(ExtractRequest.Type, this.HandleExtractRequest);
serviceHost.SetRequestHandler(DeployRequest.Type, this.HandleDeployRequest);
serviceHost.SetRequestHandler(GenerateDeployScriptRequest.Type, this.HandleGenerateDeployScriptRequest);
serviceHost.SetRequestHandler(GenerateDeployPlanRequest.Type, this.HandleGenerateDeployPlanRequest);
}
/// <summary>
@@ -167,7 +168,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
// want to show filepath in task history instead of server and database
metadata.ServerName = parameters.ScriptFilePath;
metadata.DatabaseName = "";
metadata.DatabaseName = string.Empty;
sqlTask = SqlTaskManagerInstance.CreateAndRun<SqlTask>(metadata);
@@ -175,7 +176,39 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
{
OperationId = operation.OperationId,
Success = true,
ErrorMessage = ""
ErrorMessage = string.Empty
});
}
}
catch (Exception e)
{
await requestContext.SendError(e);
}
}
/// <summary>
/// Handles request to generate deploy plan
/// </summary>
/// <returns></returns>
public async Task HandleGenerateDeployPlanRequest(GenerateDeployPlanParams parameters, RequestContext<GenerateDeployPlanRequestResult> requestContext)
{
try
{
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo != null)
{
GenerateDeployPlanOperation operation = new GenerateDeployPlanOperation(parameters, connInfo);
operation.Execute(parameters.TaskExecutionMode);
await requestContext.SendResult(new GenerateDeployPlanRequestResult()
{
OperationId = operation.OperationId,
Success = true,
ErrorMessage = string.Empty,
Report = operation.DeployReport
});
}
}
@@ -199,7 +232,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
{
OperationId = operation.OperationId,
Success = true,
ErrorMessage = ""
ErrorMessage = string.Empty
});
}

View File

@@ -29,7 +29,8 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
public override void Execute()
{
DacPackage dacpac = DacPackage.Load(this.Parameters.PackageFilePath);
this.DacServices.Deploy(dacpac, this.Parameters.DatabaseName, this.Parameters.UpgradeExisting, null, this.CancellationToken);
DacDeployOptions options = this.GetDefaultDeployOptions();
this.DacServices.Deploy(dacpac, this.Parameters.DatabaseName, this.Parameters.UpgradeExisting, options, this.CancellationToken);
}
}
}

View File

@@ -0,0 +1,38 @@
//
// 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.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
using Microsoft.SqlTools.Utility;
using System;
using System.Data.SqlClient;
using System.Diagnostics;
namespace Microsoft.SqlTools.ServiceLayer.DacFx
{
/// <summary>
/// Class to represent an in-progress generate deploy plan operation
/// </summary>
class GenerateDeployPlanOperation : DacFxOperation
{
public GenerateDeployPlanParams Parameters { get; }
public string DeployReport { get; set; }
public GenerateDeployPlanOperation(GenerateDeployPlanParams parameters, ConnectionInfo connInfo): base(connInfo)
{
Validate.IsNotNull("parameters", parameters);
this.Parameters = parameters;
}
public override void Execute()
{
DacPackage dacpac = DacPackage.Load(this.Parameters.PackageFilePath);
DacDeployOptions options = GetDefaultDeployOptions();
DeployReport = this.DacServices.GenerateDeployReport(dacpac, this.Parameters.DatabaseName, options, this.CancellationToken);
}
}
}

View File

@@ -33,6 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
PublishOptions publishOptions = new PublishOptions();
publishOptions.GenerateDeploymentReport = this.Parameters.GenerateDeploymentReport;
publishOptions.CancelToken = this.CancellationToken;
publishOptions.DeployOptions = this.GetDefaultDeployOptions();
publishOptions.DatabaseScriptPath = this.Parameters.ScriptFilePath;
// 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
publishOptions.MasterDbScriptPath = Path.Combine(Path.GetDirectoryName(this.Parameters.ScriptFilePath), string.Concat("master_", Path.GetFileName(this.Parameters.ScriptFilePath)));