diff --git a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs index 36f7ac32..268e4fe1 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/SchemaCompare/SchemaCompareOpenScmpOperation.cs @@ -10,6 +10,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Xml.Linq; +using Microsoft.SqlServer.Dac; using Microsoft.SqlServer.Dac.Compare; using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts; using Microsoft.SqlTools.ServiceLayer.SchemaCompare.Contracts; @@ -102,23 +103,19 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare { SchemaCompareEndpointInfo endpointInfo = new SchemaCompareEndpointInfo(); - // if the endpoint is a dacpac or a project, we don't need to parse the xml + // if the endpoint is a dacpac, we don't need to parse the xml if (endpoint is SchemaCompareDacpacEndpoint dacpacEndpoint) { endpointInfo.EndpointType = SchemaCompareEndpointType.Dacpac; endpointInfo.PackageFilePath = dacpacEndpoint.FilePath; } - else if (endpoint is SchemaCompareProjectEndpoint projectEndpoint) - { - endpointInfo.EndpointType = SchemaCompareEndpointType.Project; - endpointInfo.ProjectFilePath = projectEndpoint.ProjectFilePath; - } else { - // need to parse xml to get connection string of database - var result = this.scmpInfo.Descendants("ConnectionBasedModelProvider"); + bool isProjectEndpoint = endpoint is SchemaCompareProjectEndpoint; + IEnumerable result = isProjectEndpoint ? this.scmpInfo.Descendants("ProjectBasedModelProvider"): this.scmpInfo.Descendants("ConnectionBasedModelProvider"); string searchingFor = source ? "Source" : "Target"; - + + // need to parse xml try { if (result != null) @@ -127,17 +124,24 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare { if (node.Parent.Name.ToString().Contains(searchingFor)) { - endpointInfo.ConnectionDetails = SchemaCompareService.ConnectionServiceInstance.ParseConnectionString(node.Value); - endpointInfo.ConnectionDetails.ConnectionString = node.Value; - endpointInfo.DatabaseName = endpointInfo.ConnectionDetails.DatabaseName; - endpointInfo.EndpointType = SchemaCompareEndpointType.Database; + if(isProjectEndpoint) + { + SetProjectEndpointInfoFromXML(result, endpointInfo, ((SchemaCompareProjectEndpoint)endpoint).ProjectFilePath); + break; + } + else + { + SetDatabaseEndpointInfoFromXML(node, endpointInfo); + break; + } } } } } catch (Exception e) { - ErrorMessage = string.Format(SR.OpenScmpConnectionBasedModelParsingError, ((SchemaCompareDatabaseEndpoint)endpoint).DatabaseName, e.Message); + string info = isProjectEndpoint ? ((SchemaCompareProjectEndpoint)endpoint).ProjectFilePath : ((SchemaCompareDatabaseEndpoint)endpoint).DatabaseName; + ErrorMessage = string.Format(SR.OpenScmpConnectionBasedModelParsingError, info, e.Message); Logger.Write(TraceEventType.Error, string.Format("Schema compare open scmp operation failed during xml parsing with exception {0}", e.Message)); throw; } @@ -146,6 +150,39 @@ namespace Microsoft.SqlTools.ServiceLayer.SchemaCompare return endpointInfo; } + private void SetDatabaseEndpointInfoFromXML(XElement node, SchemaCompareEndpointInfo endpointInfo) + { + // get connection string of database + endpointInfo.ConnectionDetails = SchemaCompareService.ConnectionServiceInstance.ParseConnectionString(node.Value); + endpointInfo.ConnectionDetails.ConnectionString = node.Value; + endpointInfo.DatabaseName = endpointInfo.ConnectionDetails.DatabaseName; + endpointInfo.EndpointType = SchemaCompareEndpointType.Database; + } + + private void SetProjectEndpointInfoFromXML(IEnumerable result, SchemaCompareEndpointInfo endpointInfo, string filePath) + { + // get dsp information + IEnumerable dsp = result.Descendants("Dsp"); + if (dsp != null) + { + endpointInfo.DataSchemaProvider = dsp.FirstOrDefault().Value; + } + + // get folder structure information + IEnumerable fs = result.Descendants("FolderStructure"); + if (fs != null) + { + DacExtractTarget extractTarget; + if (Enum.TryParse(fs.FirstOrDefault().Value, out extractTarget)) + { + endpointInfo.ExtractTarget = extractTarget; + } + } + + endpointInfo.EndpointType = SchemaCompareEndpointType.Project; + endpointInfo.ProjectFilePath = filePath; + } + private List GetExcludedElements(IList excludedObjects) { List excludedElements = new List(); diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs index 17c309ab..8ef7e3ef 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/SchemaCompare/SchemaCompareServiceTests.cs @@ -1859,17 +1859,19 @@ WITH VALUES if (resultEndpoint.EndpointType == SchemaCompareEndpointType.Dacpac) { SchemaCompareDacpacEndpoint dacpacEndpoint = originalEndpoint as SchemaCompareDacpacEndpoint; - Assert.AreEqual(dacpacEndpoint.FilePath, resultEndpoint.PackageFilePath); + Assert.AreEqual(dacpacEndpoint.FilePath, resultEndpoint.PackageFilePath, "Package filepath didn't match"); } else if (resultEndpoint.EndpointType == SchemaCompareEndpointType.Project) { SchemaCompareProjectEndpoint projectEndpoint = originalEndpoint as SchemaCompareProjectEndpoint; - Assert.AreEqual(projectEndpoint.ProjectFilePath, resultEndpoint.ProjectFilePath); + Assert.AreEqual(projectEndpoint.ProjectFilePath, resultEndpoint.ProjectFilePath, "ProjectFilePath didn't match"); + Assert.AreEqual(resultEndpoint.ExtractTarget, DacExtractTarget.ObjectType, "Extract target didn't match"); + Assert.AreEqual(resultEndpoint.DataSchemaProvider, "150", "Dsp didn't match"); } else { SchemaCompareDatabaseEndpoint databaseEndpoint = originalEndpoint as SchemaCompareDatabaseEndpoint; - Assert.AreEqual(databaseEndpoint.DatabaseName, resultEndpoint.DatabaseName); + Assert.AreEqual(databaseEndpoint.DatabaseName, resultEndpoint.DatabaseName, "Database name didn't match"); } } @@ -2057,6 +2059,7 @@ WITH VALUES result.ProjectFilePath = comparisonObjectPath; result.TargetScripts = targetScripts; result.DataSchemaProvider = "160"; + result.ExtractTarget = DacExtractTarget.Schema; break; default: throw new ArgumentException($"Unexpected endpoint type: {type}");