diff --git a/src/DacFXTool/Program.cs b/src/DacFXTool/Program.cs index 28c3b39..dfc0810 100644 --- a/src/DacFXTool/Program.cs +++ b/src/DacFXTool/Program.cs @@ -202,35 +202,6 @@ public static async System.Threading.Tasks.Task Main(string[] args) return 0; } - // compare true "" "connectionString" - if (args.Length == 4 - && (args[0] == "compare") - && bool.TryParse(args[1], out bool databaseIsSource)) - { - if (!new FileInfo(args[2]).Exists) - { - await Console.Out.WriteLineAsync("Error:"); - await Console.Out.WriteLineAsync($"DACPAC file '{args[2]}' not found"); - return 1; - } - - var script = DacPackageComparer.Compare(args[2], args[3], databaseIsSource); - - var path = Path.Join(Path.GetTempPath(), "SqlProjDiff.sql"); - - if (string.IsNullOrEmpty(script)) - { - script = "-- No differences found"; - } - - await File.WriteAllTextAsync(path, script, Encoding.UTF8); - - await Console.Out.WriteLineAsync("Result:"); - await Console.Out.WriteLineAsync(path); - - return 0; - } - // visualcompare "" "connectionString" if (args.Length == 4 && args[0] == "visualcompare" diff --git a/src/DacFXToolLib/DacPackageComparer.cs b/src/DacFXToolLib/DacPackageComparer.cs index 8495d67..21ee564 100644 --- a/src/DacFXToolLib/DacPackageComparer.cs +++ b/src/DacFXToolLib/DacPackageComparer.cs @@ -1,5 +1,3 @@ -using System.Globalization; -using System.Text; using DacFXToolLib.Common; using Microsoft.Data.SqlClient; using Microsoft.SqlServer.Dac.Compare; @@ -84,64 +82,5 @@ public static VisualCompareResult CompareVisual(string dacpacPath, string connec }; } - public static string Compare(string dacpacPath, string connectionString, bool databaseIsSource) - { - var databaseName = new SqlConnectionStringBuilder(connectionString).InitialCatalog; - - var dacpac = new SchemaCompareDacpacEndpoint(dacpacPath); - var database = new SchemaCompareDatabaseEndpoint(connectionString); - - var comparison = databaseIsSource - ? new SchemaComparison(database, dacpac) - : new SchemaComparison(dacpac, database); - var compareResult = comparison.Compare(); - - var errors = string.Empty; - - if (compareResult.GetErrors().Any()) - { - errors = string.Join(Environment.NewLine, compareResult.GetErrors().Select(e => "--" + e.Message)); - } - - if (!compareResult.IsValid) - { - throw new InvalidOperationException("Schema comparison failed to complete."); - } - - if (compareResult.IsEqual) - { - return string.Empty; - } - - if (!databaseIsSource) - { - var result = compareResult.GenerateScript(databaseName); - - if (!result.Success) - { - if (result.Exception != null) - { - throw result.Exception; - } - - throw new InvalidOperationException($"Script generation encountered errors: {result.Message}"); - } - - return errors + Environment.NewLine + result.Script; - } - - var diffScript = new StringBuilder(); - - diffScript.Append(string.Empty); - - foreach (var difference in compareResult.Differences) - { - diffScript.AppendLine(); - diffScript.AppendLine(CultureInfo.InvariantCulture, $"-- Difference: {difference.SourceObject.Name} ({difference.SourceObject.ObjectType.Name})"); - diffScript.AppendLine(compareResult.GetDiffEntrySourceScript(difference)); - } - - return diffScript.ToString(); - } } } diff --git a/src/Vsix/Commands/CompareCommand.cs b/src/Vsix/Commands/CompareCommand.cs deleted file mode 100644 index a1e41ea..0000000 --- a/src/Vsix/Commands/CompareCommand.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace SqlProjectsPowerTools -{ - [Command(PackageIds.cmdidCompare)] - internal sealed class CompareCommand : BaseCommand - { - protected override void BeforeQueryStatus(EventArgs e) - { - ThreadHelper.JoinableTaskFactory.Run(async () => - { - Command.Enabled = await Command.IsEnabledForModernSqlProjectAsync(); - }); - } - - protected override async Task ExecuteAsync(OleMenuCmdEventArgs e) - { - var project = await VS.Solutions.GetActiveProjectAsync(); - if (project != null) - { - await CompareHandler.GenerateAsync(project); - } - } - } -} diff --git a/src/Vsix/Handlers/CompareHandler.cs b/src/Vsix/Handlers/CompareHandler.cs deleted file mode 100644 index a411d35..0000000 --- a/src/Vsix/Handlers/CompareHandler.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using DacFXToolLib.Common; -using DacFXToolLib.Dab; -using Microsoft.VisualStudio.Shell.Interop; - -namespace SqlProjectsPowerTools -{ - internal static class CompareHandler - { - public static async Task GenerateAsync(Project project) - { - await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - - try - { - if (await VSHelper.IsDebugModeAsync()) - { - VSHelper.ShowError("Cannot generate code while debugging"); - return; - } - - var options = new DataApiBuilderOptions(); - - var info = await ChooseDataBaseConnectionAsync(options); - - if (info.DatabaseModel == null) - { - return; - } - - var dbInfo = await GetDatabaseInfoAsync(options); - - if (dbInfo == null) - { - return; - } - - var dacOptions = new DataApiBuilderOptions - { - Dacpac = project.FullPath, - ConnectionString = dbInfo.ConnectionString, - DatabaseType = DatabaseType.SQLServerDacpac, - }; - - var dacpacInfo = await HandlerHelper.GetDatabaseInfoAsync(dacOptions); - - if (dacpacInfo == null) - { - return; - } - - await VS.StatusBar.ShowMessageAsync("Comparing database schemas..."); - - // Use threaded wait dialog for better UX feedback - IVsThreadedWaitDialog2 dialog = null; - - try - { - string result = null; - var dialogFactory = await VS.GetServiceAsync(); - dialogFactory?.CreateInstance(out dialog); - - dialog?.StartWaitDialog( - szWaitCaption: "SQL Database Project Power Tools", - szWaitMessage: "Comparing database schemas...", - szProgressText: null, - varStatusBmpAnim: null, - szStatusBarText: "Comparing database schemas...", - iDelayToShowDialog: 0, - fIsCancelable: false, - fShowMarqueeProgress: true); - - result = await RunCompareAsync(info.DatabaseIsSource, dacOptions.Dacpac, dbInfo.ConnectionString); - - if (!string.IsNullOrEmpty(result)) - { - await VS.Documents.OpenInPreviewTabAsync(result); - } - } - finally - { - dialog?.EndWaitDialog(out int _); - } - } - catch (AggregateException ae) - { - foreach (var innerException in ae.Flatten().InnerExceptions) - { - await VS.MessageBox.ShowErrorAsync("SQL Database Project Power Tools", innerException.Message); - } - } - catch (Exception exception) - { - await VS.MessageBox.ShowErrorAsync("SQL Database Project Power Tools", exception.Message); - } - finally - { - await VS.StatusBar.ClearAsync(); - } - } - - private static async Task RunCompareAsync(bool databaseIsSource, string dacpacPath, string connectionString) - { - var launcher = new ProcessLauncher(); - return await launcher.GetCompareAsync(databaseIsSource, dacpacPath, connectionString); - } - - private static async Task GetDatabaseInfoAsync(DataApiBuilderOptions options) - { - await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - - var dbInfo = new DatabaseConnectionModel(); - - if (!string.IsNullOrEmpty(options.ConnectionString)) - { - dbInfo.ConnectionString = options.ConnectionString; - dbInfo.DatabaseType = options.DatabaseType; - } - - if (dbInfo.DatabaseType == DatabaseType.Undefined) - { - VSHelper.ShowError($"Unsupported provider"); - return null; - } - - return dbInfo; - } - - private static async Task<(DatabaseConnectionModel DatabaseModel, bool DatabaseIsSource)> ChooseDataBaseConnectionAsync(DataApiBuilderOptions options) - { - var vsDataHelper = new VsDataHelper(); - var databaseList = await vsDataHelper.GetDataConnectionsAsync(); - - var psd = PackageManager.Package.GetView(); - - if (databaseList != null && databaseList.Any()) - { - psd.PublishConnections(databaseList.Select(m => new DatabaseConnectionModel - { - ConnectionName = m.Value.ConnectionName, - ConnectionString = m.Value.ConnectionString, - DatabaseType = m.Value.DatabaseType, - DataConnection = m.Value.DataConnection, - })); - } - - psd.PublishFileGenerationMode(GetCodeGenerationModes()); - - var pickDataSourceResult = psd.ShowAndAwaitUserResponse(true); - if (!pickDataSourceResult.ClosedByOK) - { - return (null, false); - } - - if (pickDataSourceResult.Payload.Connection != null) - { - options.ConnectionString = pickDataSourceResult.Payload.Connection.ConnectionString; - options.DatabaseType = pickDataSourceResult.Payload.Connection.DatabaseType; - } - - return (pickDataSourceResult.Payload.Connection, - pickDataSourceResult.Payload.GetDatabaseOptions); - } - - private static List GetCodeGenerationModes() - { - var list = new List - { - new CodeGenerationItem { Key = 0, Value = "Compare" }, - }; - return list; - } - } - } diff --git a/src/Vsix/Handlers/ProcessLauncher.cs b/src/Vsix/Handlers/ProcessLauncher.cs index cd424b2..4f23850 100644 --- a/src/Vsix/Handlers/ProcessLauncher.cs +++ b/src/Vsix/Handlers/ProcessLauncher.cs @@ -77,17 +77,6 @@ public async Task GetVisualCompareAsync(bool databaseIsSource, string da return filePath; } - public async Task GetCompareAsync(bool databaseIsSource, string dacpacPath, string connectionString) - { - var option = "compare "; - - var arguments = option + databaseIsSource.ToString() + " \"" + dacpacPath.Replace("\"", "\\\"") + "\" " + " \"" + connectionString.Replace("\"", "\\\"") + "\""; - - var filePath = await GetDiagramInternalAsync(arguments); - - return filePath; - } - public async Task GetDatabaseSettingsAsync(string connectionString) { var option = "getdboptions "; diff --git a/src/Vsix/VSCommandTable.cs b/src/Vsix/VSCommandTable.cs index f8ead9d..68864c9 100644 --- a/src/Vsix/VSCommandTable.cs +++ b/src/Vsix/VSCommandTable.cs @@ -32,7 +32,6 @@ internal sealed partial class PackageIds public const int cmdidSqlProjectMenuGroup = 0x0004; public const int cmdidAnalyze = 0x0001; public const int cmdidImport = 0x0002; - public const int cmdidCompare = 0x0005; public const int cmdidErDiagram = 0x0007; public const int cmdidReverseEngineerDab = 0x0012; public const int cmdidAbout = 0x0006; diff --git a/src/Vsix/VSCommandTable.vsct b/src/Vsix/VSCommandTable.vsct index a72b70d..300b203 100644 --- a/src/Vsix/VSCommandTable.vsct +++ b/src/Vsix/VSCommandTable.vsct @@ -70,17 +70,6 @@ - -