From b44f0d561f37f82fa423cb50818ad762260c7844 Mon Sep 17 00:00:00 2001 From: Sakshi Sharma <57200045+SakshiS-harma@users.noreply.github.com> Date: Fri, 24 Feb 2023 14:24:25 -0800 Subject: [PATCH] Save file structure in scmp file (#1878) * Save file structure in scmp files * Update DacFx version and add test * Address comments * Fix test * try to fix tests --------- Co-authored-by: Kim Santiago --- Packages.props | 2 +- .../Contracts/SchemaCompareRequest.cs | 6 +++ .../SchemaCompare/SchemaCompareUtils.cs | 4 +- .../SchemaCompareServiceTests.cs | 54 ++++++++++++++++++- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/Packages.props b/Packages.props index d662de1e..cd4afd99 100644 --- a/Packages.props +++ b/Packages.props @@ -20,7 +20,7 @@ - + diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs index eaa23505..1e33cec3 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/Contracts/SchemaCompareRequest.cs @@ -5,6 +5,7 @@ #nullable disable using System.Collections.Generic; +using Microsoft.SqlServer.Dac; using Microsoft.SqlServer.Dac.Compare; using Microsoft.SqlTools.Hosting.Protocol.Contracts; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; @@ -70,6 +71,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts /// Connection details /// public ConnectionDetails ConnectionDetails { get; set; } + + /// + /// Extract target of the project used when extracting a database to file system or updating the project from database + /// + public DacExtractTarget? ExtractTarget { get; set; } } /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs index 3b4e3392..b85c6e24 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareUtils.cs @@ -176,7 +176,9 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare { case SchemaCompareEndpointType.Project: { - return new SchemaCompareProjectEndpoint(endpointInfo.ProjectFilePath, endpointInfo.TargetScripts, endpointInfo.DataSchemaProvider); + return endpointInfo?.ExtractTarget != null + ? new SchemaCompareProjectEndpoint(endpointInfo.ProjectFilePath, endpointInfo.TargetScripts, endpointInfo.DataSchemaProvider, (DacExtractTarget)endpointInfo?.ExtractTarget) + : new SchemaCompareProjectEndpoint(endpointInfo.ProjectFilePath, endpointInfo.TargetScripts, endpointInfo.DataSchemaProvider); } case SchemaCompareEndpointType.Dacpac: { diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs index 944bb946..0911959d 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs @@ -1200,6 +1200,41 @@ WITH VALUES await CreateAndOpenScmp(SchemaCompareEndpointType.Project, SchemaCompareEndpointType.Project); } + /// + /// Verify folder structure gets stored in scmp file for project endpoint + /// + [Test] + public async Task VerifyExtractTargetInScmpFile() + { + SqlTestDb sourceDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, SourceScript, "SchemaCompareOpenScmpSource"); + SqlTestDb targetDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, TargetScript, "SchemaCompareOpenScmpTarget"); + + try + { + SchemaCompareEndpoint sourceEndpoint = CreateSchemaCompareEndpoint(sourceDb, SchemaCompareEndpointType.Database); + SchemaCompareEndpoint targetEndpoint = CreateSchemaCompareEndpoint(targetDb, SchemaCompareEndpointType.Project, true); + + // create a comparison and exclude the first difference + SchemaComparison compare = new SchemaComparison(sourceEndpoint, targetEndpoint); + SchemaComparisonResult result = compare.Compare(); + Assert.That(result.Differences, Is.Not.Empty); + + // save to scmp + string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SchemaCompareTest"); + Directory.CreateDirectory(folderPath); + string filePath = Path.Combine(folderPath, string.Format("SchemaCompareOpenScmpTest{0}.scmp", DateTime.Now.ToFileTime())); + compare.SaveToFile(filePath); + + SchemaCompareTestUtils.VerifyAndCleanup(Directory.GetParent((targetEndpoint as SchemaCompareProjectEndpoint).ProjectFilePath).FullName); + await VerifyContentAndCleanupAsync(filePath, "ObjectType"); + } + finally + { + sourceDb.Cleanup(); + targetDb.Cleanup(); + } + } + /// /// Verify the schema compare Service Calls ends to end /// @@ -1594,6 +1629,23 @@ WITH VALUES } } + private async Task VerifyContentAndCleanupAsync(string outputFilePath, string textToMatch) + { + // Verify it was created + Assert.True(File.Exists(outputFilePath), "The output file did not get generated."); + + //Verify the contents contain the stringToMatch + string output = await File.ReadAllTextAsync(outputFilePath); + + Assert.True(output.Contains(textToMatch), $"The output doesn't contain the string. Pattern expected {Environment.NewLine} {textToMatch} {Environment.NewLine} Actual file {Environment.NewLine} {output}"); + + // Remove the file + if (File.Exists(outputFilePath)) + { + File.Delete(outputFilePath); + } + } + private void ValidateSchemaCompareWithExcludeIncludeResults(SchemaCompareOperation schemaCompareOperation, int? expectedDifferencesCount = null) { schemaCompareOperation.Execute(TaskExecutionMode.Execute); @@ -1794,7 +1846,7 @@ WITH VALUES { string projectPath = SchemaCompareTestUtils.CreateProject(db, isProjectTarget ? "TargetProject" : "SourceProject"); string[] scripts = SchemaCompareTestUtils.GetProjectScripts(projectPath); - return new SchemaCompareProjectEndpoint(Path.Combine(projectPath, isProjectTarget ? "TargetProject.sqlproj" : "SourceProject.sqlproj"), scripts, "150"); + return new SchemaCompareProjectEndpoint(Path.Combine(projectPath, isProjectTarget ? "TargetProject.sqlproj" : "SourceProject.sqlproj"), scripts, "150", DacExtractTarget.ObjectType); } else {