mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-17 02:51:45 -05:00
Update DacFx deploy and generate script with options (#998)
* update deploy and generate script to accept deployment options * add tests * add test with option set to true
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,11 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
|
|||||||
/// Gets or sets SQLCMD variables for deployment
|
/// Gets or sets SQLCMD variables for deployment
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, string> SqlCommandVariableValues { get; set; }
|
public IDictionary<string, string> SqlCommandVariableValues { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the options for deployment
|
||||||
|
/// </summary>
|
||||||
|
public DeploymentOptions DeploymentOptions { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
|
namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
|
||||||
{
|
{
|
||||||
@@ -26,6 +27,11 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts
|
|||||||
/// Gets or sets SQLCMD variables for script generation
|
/// Gets or sets SQLCMD variables for script generation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IDictionary<string, string> SqlCommandVariableValues { get; set; }
|
public IDictionary<string, string> SqlCommandVariableValues { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the options for deployment
|
||||||
|
/// </summary>
|
||||||
|
public DeploymentOptions DeploymentOptions { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
using Microsoft.SqlServer.Dac;
|
using Microsoft.SqlServer.Dac;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.SchemaCompare;
|
||||||
using Microsoft.SqlTools.Utility;
|
using Microsoft.SqlTools.Utility;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
||||||
@@ -25,7 +26,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
|||||||
public override void Execute()
|
public override void Execute()
|
||||||
{
|
{
|
||||||
DacPackage dacpac = DacPackage.Load(this.Parameters.PackageFilePath);
|
DacPackage dacpac = DacPackage.Load(this.Parameters.PackageFilePath);
|
||||||
DacDeployOptions options = this.GetDefaultDeployOptions();
|
DacDeployOptions options = this.Parameters.DeploymentOptions != null ? SchemaCompareUtils.CreateSchemaCompareOptions(this.Parameters.DeploymentOptions) : this.GetDefaultDeployOptions();
|
||||||
|
|
||||||
if (this.Parameters.SqlCommandVariableValues != null)
|
if (this.Parameters.SqlCommandVariableValues != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,15 +2,16 @@
|
|||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// 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;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Microsoft.SqlServer.Dac;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.SchemaCompare;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.TaskServices;
|
||||||
|
using Microsoft.SqlTools.Utility;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
||||||
{
|
{
|
||||||
@@ -35,7 +36,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
|
|||||||
PublishOptions publishOptions = new PublishOptions();
|
PublishOptions publishOptions = new PublishOptions();
|
||||||
publishOptions.GenerateDeploymentReport = this.Parameters.GenerateDeploymentReport;
|
publishOptions.GenerateDeploymentReport = this.Parameters.GenerateDeploymentReport;
|
||||||
publishOptions.CancelToken = this.CancellationToken;
|
publishOptions.CancelToken = this.CancellationToken;
|
||||||
publishOptions.DeployOptions = this.GetDefaultDeployOptions();
|
publishOptions.DeployOptions = this.Parameters.DeploymentOptions != null ? SchemaCompareUtils.CreateSchemaCompareOptions(this.Parameters.DeploymentOptions) : this.GetDefaultDeployOptions();
|
||||||
|
|
||||||
if (this.Parameters.SqlCommandVariableValues != null)
|
if (this.Parameters.SqlCommandVariableValues != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System.IO;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using Microsoft.SqlServer.Dac;
|
using Microsoft.SqlServer.Dac;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.Hosting.Protocol;
|
using Microsoft.SqlTools.Hosting.Protocol;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.DacFx;
|
using Microsoft.SqlTools.ServiceLayer.DacFx;
|
||||||
@@ -35,6 +36,8 @@ CREATE TABLE [dbo].[table2]
|
|||||||
[col1] NCHAR(10) NULL
|
[col1] NCHAR(10) NULL
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
private const string SourceViewScript = @"CREATE VIEW [dbo].[view1] AS SELECT dbo.table1.* FROM dbo.table1";
|
||||||
|
|
||||||
private const string TargetScript = @"CREATE TABLE [dbo].[table2]
|
private const string TargetScript = @"CREATE TABLE [dbo].[table2]
|
||||||
(
|
(
|
||||||
[ID] INT NOT NULL PRIMARY KEY,
|
[ID] INT NOT NULL PRIMARY KEY,
|
||||||
@@ -537,6 +540,163 @@ RETURN 0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Verify that options are set correctly for a deploy request
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async void DeployWithOptions()
|
||||||
|
{
|
||||||
|
var result = GetLiveAutoCompleteTestObjects();
|
||||||
|
SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, query: SourceScript, dbNamePrefix: "DacFxDeployOptionsTestSource");
|
||||||
|
sourceDb.RunQuery(SourceViewScript);
|
||||||
|
SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, query: TargetScript, dbNamePrefix: "DacFxDeployOptionsTestTarget");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DacFxService service = new DacFxService();
|
||||||
|
// First extract a db to have a dacpac to deploy later
|
||||||
|
string dacpacPath = InitialExtract(service, sourceDb, result);
|
||||||
|
|
||||||
|
// Deploy the created dacpac with options
|
||||||
|
var deployParams = new DeployParams
|
||||||
|
{
|
||||||
|
PackageFilePath = dacpacPath,
|
||||||
|
DatabaseName = targetDb.DatabaseName,
|
||||||
|
UpgradeExisting = true,
|
||||||
|
DeploymentOptions = new DeploymentOptions()
|
||||||
|
{
|
||||||
|
DropObjectsNotInSource = false,
|
||||||
|
ExcludeObjectTypes = new[] { ObjectType.Views }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// expect table3 to not have been dropped and view1 to not have been created
|
||||||
|
await VerifyDeployWithOptions(deployParams, targetDb, service, result.ConnectionInfo, expectedTableResult: "table3", expectedViewResult: null);
|
||||||
|
|
||||||
|
// Deploy the created dacpac with options
|
||||||
|
var deployNoOptionsParams = new DeployParams
|
||||||
|
{
|
||||||
|
PackageFilePath = dacpacPath,
|
||||||
|
DatabaseName = targetDb.DatabaseName,
|
||||||
|
UpgradeExisting = true
|
||||||
|
};
|
||||||
|
|
||||||
|
// expect table3 to be dropped and view1 created
|
||||||
|
await VerifyDeployWithOptions(deployNoOptionsParams, targetDb, service, result.ConnectionInfo, expectedTableResult: null, expectedViewResult: "view1");
|
||||||
|
|
||||||
|
VerifyAndCleanup(dacpacPath);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sourceDb.Cleanup();
|
||||||
|
if (targetDb != null)
|
||||||
|
{
|
||||||
|
targetDb.Cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task VerifyDeployWithOptions(DeployParams deployParams, SqlTestDb targetDb, DacFxService service, ConnectionInfo connInfo, string expectedTableResult, string expectedViewResult)
|
||||||
|
{
|
||||||
|
var deployOperation = new DeployOperation(deployParams, connInfo);
|
||||||
|
service.PerformOperation(deployOperation, TaskExecutionMode.Execute);
|
||||||
|
|
||||||
|
using (SqlConnection conn = new SqlConnection(targetDb.ConnectionString))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await conn.OpenAsync();
|
||||||
|
var deployedResult = (string)ReliableConnectionHelper.ExecuteScalar(conn, $"SELECT TABLE_NAME FROM {targetDb.DatabaseName}.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'table3'; ");
|
||||||
|
Assert.Equal(expectedTableResult, deployedResult);
|
||||||
|
|
||||||
|
deployedResult = (string)ReliableConnectionHelper.ExecuteScalar(conn, $"SELECT TABLE_NAME FROM {targetDb.DatabaseName}.INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'view1'; ");
|
||||||
|
Assert.Equal(expectedViewResult, deployedResult);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
conn.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
/// Verify that options are set correctly for a generate script request
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async void GenerateDeployScriptWithOptions()
|
||||||
|
{
|
||||||
|
var result = GetLiveAutoCompleteTestObjects();
|
||||||
|
SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, query: SourceScript, dbNamePrefix: "DacFxDeployOptionsTestSource");
|
||||||
|
sourceDb.RunQuery(SourceViewScript);
|
||||||
|
SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, query: TargetScript, dbNamePrefix: "DacFxDeployOptionsTestTarget");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DacFxService service = new DacFxService();
|
||||||
|
// First extract a db to have a dacpac to deploy later
|
||||||
|
string dacpacPath = InitialExtract(service, sourceDb, result);
|
||||||
|
|
||||||
|
// generate script to deploy the created dacpac with options
|
||||||
|
var generateScriptFalseOptionParams = new GenerateDeployScriptParams
|
||||||
|
{
|
||||||
|
PackageFilePath = dacpacPath,
|
||||||
|
DatabaseName = targetDb.DatabaseName,
|
||||||
|
DeploymentOptions = new DeploymentOptions()
|
||||||
|
{
|
||||||
|
DropObjectsNotInSource = false,
|
||||||
|
ExcludeObjectTypes = new[] { ObjectType.Views }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var generateScriptFalseOptionOperation = new GenerateDeployScriptOperation(generateScriptFalseOptionParams, result.ConnectionInfo);
|
||||||
|
service.PerformOperation(generateScriptFalseOptionOperation, TaskExecutionMode.Execute);
|
||||||
|
|
||||||
|
Assert.DoesNotContain("table3", generateScriptFalseOptionOperation.Result.DatabaseScript);
|
||||||
|
Assert.DoesNotContain("CREATE VIEW", generateScriptFalseOptionOperation.Result.DatabaseScript);
|
||||||
|
|
||||||
|
// try to deploy with the option set to true to make sure it works
|
||||||
|
var generateScriptTrueOptionParams = new GenerateDeployScriptParams
|
||||||
|
{
|
||||||
|
PackageFilePath = dacpacPath,
|
||||||
|
DatabaseName = targetDb.DatabaseName,
|
||||||
|
DeploymentOptions = new DeploymentOptions()
|
||||||
|
{
|
||||||
|
DropObjectsNotInSource = true,
|
||||||
|
ExcludeObjectTypes = new[] { ObjectType.Views }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var generateScriptTrueOptionOperation = new GenerateDeployScriptOperation(generateScriptTrueOptionParams, result.ConnectionInfo);
|
||||||
|
service.PerformOperation(generateScriptTrueOptionOperation, TaskExecutionMode.Execute);
|
||||||
|
|
||||||
|
Assert.Contains("DROP TABLE [dbo].[table3]", generateScriptTrueOptionOperation.Result.DatabaseScript);
|
||||||
|
Assert.DoesNotContain("CREATE VIEW", generateScriptTrueOptionOperation.Result.DatabaseScript);
|
||||||
|
|
||||||
|
// now generate script without options
|
||||||
|
var generateScriptNoOptionsParams = new GenerateDeployScriptParams
|
||||||
|
{
|
||||||
|
PackageFilePath = dacpacPath,
|
||||||
|
DatabaseName = targetDb.DatabaseName,
|
||||||
|
};
|
||||||
|
|
||||||
|
var generateScriptNoOptionsOperation = new GenerateDeployScriptOperation(generateScriptNoOptionsParams, result.ConnectionInfo);
|
||||||
|
service.PerformOperation(generateScriptNoOptionsOperation, TaskExecutionMode.Execute);
|
||||||
|
|
||||||
|
Assert.Contains("table3", generateScriptNoOptionsOperation.Result.DatabaseScript);
|
||||||
|
Assert.Contains("CREATE VIEW", generateScriptNoOptionsOperation.Result.DatabaseScript);
|
||||||
|
|
||||||
|
VerifyAndCleanup(dacpacPath);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
sourceDb.Cleanup();
|
||||||
|
if (targetDb != null)
|
||||||
|
{
|
||||||
|
targetDb.Cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// <summary>
|
// <summary>
|
||||||
/// Verify that options can get retrieved from publish profile
|
/// Verify that options can get retrieved from publish profile
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user