From 96df91c8fab4aa8996ba3fd7d4223b0787ffcd73 Mon Sep 17 00:00:00 2001 From: Sakshi Sharma <57200045+SakshiS-harma@users.noreply.github.com> Date: Mon, 27 Apr 2020 18:35:19 -0700 Subject: [PATCH] Sql Proj Extract from database to Sql files (#949) * SqlToolsServices changes for Sql Proj Extract from database to Sql files * Bumped DacFx version. Addressed comments. --- .../DacFx/Contracts/ExtractRequest.cs | 8 +- .../DacFx/DacFxService.cs | 4 +- .../DacFx/ExtractOperation.cs | 9 +- .../Localization/sr.cs | 11 +++ .../Localization/sr.resx | 4 + .../Localization/sr.strings | 1 + .../Localization/sr.xlf | 5 ++ .../Microsoft.SqlTools.ServiceLayer.csproj | 2 +- ...ManagedBatchParser.IntegrationTests.csproj | 2 +- .../DacFx/DacFxserviceTests.cs | 83 ++++++++++++++++++- ...Tools.ServiceLayer.IntegrationTests.csproj | 2 +- 11 files changed, 122 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.SqlTools.ServiceLayer/DacFx/Contracts/ExtractRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/DacFx/Contracts/ExtractRequest.cs index 5eb3ef13..51f5163e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/DacFx/Contracts/ExtractRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/DacFx/Contracts/ExtractRequest.cs @@ -2,10 +2,11 @@ // 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 Microsoft.SqlServer.Dac; using Microsoft.SqlTools.Hosting.Protocol.Contracts; using Microsoft.SqlTools.ServiceLayer.TaskServices; using Microsoft.SqlTools.ServiceLayer.Utility; -using System; namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts { @@ -23,6 +24,11 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx.Contracts /// Gets or sets the version of the DAC application /// public string ApplicationVersion { get; set; } + + /// + /// Gets or sets the target for extraction + /// + public DacExtractTarget ExtractTarget { get; set; } } /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs b/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs index 82519aac..954427df 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/DacFx/DacFxService.cs @@ -2,6 +2,7 @@ // 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.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts; @@ -117,7 +118,8 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx // Set connection details database name to ensure the connection string gets created correctly for DW(extract doesn't work if connection is to master) connInfo.ConnectionDetails.DatabaseName = parameters.DatabaseName; ExtractOperation operation = new ExtractOperation(parameters, connInfo); - ExecuteOperation(operation, parameters, SR.ExtractDacpacTaskName, requestContext); + string taskName = parameters.ExtractTarget == DacExtractTarget.DacPac ? SR.ExtractDacpacTaskName : SR.ProjectExtractTaskName; + ExecuteOperation(operation, parameters, taskName, requestContext); } } catch (Exception e) diff --git a/src/Microsoft.SqlTools.ServiceLayer/DacFx/ExtractOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/DacFx/ExtractOperation.cs index 57d58748..75afd735 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/DacFx/ExtractOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/DacFx/ExtractOperation.cs @@ -30,7 +30,8 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx public override void Execute() { Version version = ParseVersion(this.Parameters.ApplicationVersion); - this.DacServices.Extract(this.Parameters.PackageFilePath, this.Parameters.DatabaseName, this.Parameters.ApplicationName, version, null, null, null, this.CancellationToken); + DacExtractOptions extractOptions = GetExtractOptions(this.Parameters.ExtractTarget); + this.DacServices.Extract(this.Parameters.PackageFilePath, this.Parameters.DatabaseName, this.Parameters.ApplicationName, version, applicationDescription:null, tables:null, extractOptions:extractOptions, cancellationToken:this.CancellationToken); } public static Version ParseVersion(string incomingVersion) @@ -43,5 +44,11 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx return parsedVersion; } + + private DacExtractOptions GetExtractOptions(DacExtractTarget extractTarget) + { + DacExtractOptions extractOptions = new DacExtractOptions() { ExtractTarget = extractTarget }; + return extractOptions; + } } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index e8fcbac5..8e7aae92 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -2941,6 +2941,14 @@ namespace Microsoft.SqlTools.ServiceLayer } } + public static string ProjectExtractTaskName + { + get + { + return Keys.GetString(Keys.ProjectExtractTaskName); + } + } + public static string ExtractInvalidVersion { get @@ -4390,6 +4398,9 @@ namespace Microsoft.SqlTools.ServiceLayer public const string GenerateScriptTaskName = "GenerateScriptTaskName"; + public const string ProjectExtractTaskName = "ProjectExtractTaskName"; + + public const string ExtractInvalidVersion = "ExtractInvalidVersion"; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index c656689d..027ae7cc 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -1748,6 +1748,10 @@ Generate script + + Extract project files + + Invalid version '{0}' passed. Version must be in the format x.x.x.x where x is a number. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index 1773a7c5..16ec5fb8 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -809,6 +809,7 @@ ImportBacpacTaskName = Import bacpac ExtractDacpacTaskName = Extract dacpac DeployDacpacTaskName = Deploy dacpac GenerateScriptTaskName = Generate script +ProjectExtractTaskName = Extract project files ExtractInvalidVersion = Invalid version '{0}' passed. Version must be in the format x.x.x.x where x is a number. ############################################################################ diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index eab50707..2605049f 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -2082,6 +2082,11 @@ . Parameters: 0 - editionCode (int) + + Extract project files + Extract project files + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj b/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj index 99d1ebc0..229bbf3f 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj +++ b/src/Microsoft.SqlTools.ServiceLayer/Microsoft.SqlTools.ServiceLayer.csproj @@ -21,7 +21,7 @@ - + diff --git a/test/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj b/test/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj index f3751afb..2fe0d8e6 100644 --- a/test/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj +++ b/test/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests/Microsoft.SqlTools.ManagedBatchParser.IntegrationTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DacFx/DacFxserviceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DacFx/DacFxserviceTests.cs index 09e909b7..14affe59 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DacFx/DacFxserviceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/DacFx/DacFxserviceTests.cs @@ -2,6 +2,10 @@ // 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.IO; +using System.Threading.Tasks; +using Microsoft.SqlServer.Dac; using Microsoft.SqlTools.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.DacFx; using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts; @@ -9,9 +13,6 @@ using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility; using Microsoft.SqlTools.ServiceLayer.TaskServices; using Microsoft.SqlTools.ServiceLayer.Test.Common; using Moq; -using System; -using System.IO; -using System.Threading.Tasks; using Xunit; namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.DacFx @@ -159,6 +160,82 @@ CREATE TABLE [dbo].[table3] } } + /// + /// Verify the extract request to create Sql file + /// + [Fact] + public async void ExtractDBToFileTarget() + { + var result = GetLiveAutoCompleteTestObjects(); + SqlTestDb testdb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, doNotCleanupDb:false, databaseName:null, query:SourceScript, dbNamePrefix:"DacFxExtractDBToFileTarget"); + string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DacFxTest"); + Directory.CreateDirectory(folderPath); + + try + { + var extractParams = new ExtractParams + { + DatabaseName = testdb.DatabaseName, + PackageFilePath = Path.Combine(folderPath, string.Format("{0}.sql", testdb.DatabaseName)), + ApplicationName = "test", + ApplicationVersion = "1.0.0.0", + ExtractTarget = DacExtractTarget.File + }; + + DacFxService service = new DacFxService(); + ExtractOperation operation = new ExtractOperation(extractParams, result.ConnectionInfo); + service.PerformOperation(operation, TaskExecutionMode.Execute); + + VerifyAndCleanup(extractParams.PackageFilePath); + } + finally + { + testdb.Cleanup(); + } + } + + /// + /// Verify the extract request to create a Flat file structure + /// + [Fact] + public async void ExtractDBToFlatTarget() + { + var result = GetLiveAutoCompleteTestObjects(); + SqlTestDb testdb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, doNotCleanupDb: false, databaseName: null, query: SourceScript, dbNamePrefix: "DacFxExtractDBToFlatTarget"); + string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DacFxTest","FlatExtract"); + Directory.CreateDirectory(folderPath); + + try + { + var extractParams = new ExtractParams + { + DatabaseName = testdb.DatabaseName, + PackageFilePath = folderPath, + ApplicationName = "test", + ApplicationVersion = "1.0.0.0", + ExtractTarget = DacExtractTarget.Flat + }; + + DacFxService service = new DacFxService(); + ExtractOperation operation = new ExtractOperation(extractParams, result.ConnectionInfo); + service.PerformOperation(operation, TaskExecutionMode.Execute); + + // Verify two sql files are generated in the target folder path + int actualCnt = Directory.GetFiles(folderPath, "*.sql", SearchOption.AllDirectories).Length; + Assert.Equal(actualCnt, 2); + + // Remove the directory + if (Directory.Exists(folderPath)) + { + Directory.Delete(folderPath, true); + } + } + finally + { + testdb.Cleanup(); + } + } + /// /// Verify the deploy dacpac request /// diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj index c0677be8..563d0f66 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Microsoft.SqlTools.ServiceLayer.IntegrationTests.csproj @@ -33,7 +33,7 @@ - +