diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index befd64bd40..7dc0d81696 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,7 +71,7 @@ jobs: mv `find coverage -type f` db-ui.lcov dotnet test Rdmp.Core.Tests/Rdmp.Core.Tests.csproj --nologo --collect:"XPlat Code Coverage" --no-build --verbosity minimal -c Release -e AWS_ENDPOINT_URL="http://127.0.0.1:9000" --results-directory coverage -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=lcov mv `find coverage -type f` db-core.lcov - - uses: coverallsapp/github-action@v2.3.0 + - uses: coverallsapp/github-action@v2.3.3 with: github-token: ${{ secrets.github_token }} files: ./db-ui.lcov ./db-core.lcov @@ -137,7 +137,7 @@ jobs: mv `find coverage -type f` fs-ui.lcov dotnet test Rdmp.Core.Tests/Rdmp.Core.Tests.csproj --nologo --collect:"XPlat Code Coverage" --no-build --verbosity minimal -c Release -e AWS_ENDPOINT_URL="http://127.0.0.1:9000" --results-directory coverage -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=lcov mv `find coverage -type f` fs-core.lcov - - uses: coverallsapp/github-action@v2.3.0 + - uses: coverallsapp/github-action@v2.3.3 with: github-token: ${{ secrets.github_token }} files: ./fs-ui.lcov ./fs-core.lcov @@ -176,7 +176,6 @@ jobs: cp -r Application/ResearchDataManagementPlatform/bin/Release/net8.0-windows/win-x64/runtimes ./PublishWinForms cp -r Application/ResearchDataManagementPlatform/bin/Release/net8.0-windows/win-x64/x64 ./PublishWinForms cp Application/ResearchDataManagementPlatform/bin/Release/net8.0-windows/win-x64/D3DCompiler_47_cor3.dll ./PublishWinForms - cp Application/ResearchDataManagementPlatform/bin/Release/net8.0-windows/win-x64/mongocrypt.dll ./PublishWinForms cp Application/ResearchDataManagementPlatform/bin/Release/net8.0-windows/win-x64/PenImc_cor3.dll ./PublishWinForms cp Application/ResearchDataManagementPlatform/bin/Release/net8.0-windows/win-x64/PresentationNative_cor3.dll ./PublishWinForms cp Application/ResearchDataManagementPlatform/bin/Release/net8.0-windows/win-x64/vcruntime140_cor3.dll ./PublishWinForms diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f286a9d56..6139cb239d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add Ordering to Filters -## [8.3.1] - Unreleased +## [8.3.1] - 2024-10-22 - Improve Performance of regenerating problems with child providers - Update UI Tab opening Logic diff --git a/Directory.Packages.props b/Directory.Packages.props index 2fc0aebf8b..d85d9441bb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,22 +1,22 @@ - - - - + + + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -37,7 +37,7 @@ - + diff --git a/Rdmp.Core/Logging/LogManager.cs b/Rdmp.Core/Logging/LogManager.cs index 7376316c9b..f17ce88f48 100644 --- a/Rdmp.Core/Logging/LogManager.cs +++ b/Rdmp.Core/Logging/LogManager.cs @@ -63,7 +63,8 @@ public string[] ListDataTasks(bool hideTests = false) using var con = Server.GetConnection(); con.Open(); - using var cmd = Server.GetCommand("SELECT * FROM DataLoadTask", con); + var sh = Server.GetQuerySyntaxHelper(); + using var cmd = Server.GetCommand($"SELECT * FROM {sh.EnsureWrapped("DataLoadTask")}", con); using var r = cmd.ExecuteReader(); while (r.Read()) if (!hideTests || !(bool)r["isTest"]) @@ -113,7 +114,8 @@ public string[] ListDataSets() using var con = Server.GetConnection(); con.Open(); - using var cmd = Server.GetCommand("SELECT * FROM DataSet", con); + var sh = Server.GetQuerySyntaxHelper(); + using var cmd = Server.GetCommand($"SELECT * FROM {sh.EnsureWrapped("DataSet")}", con); using var r = cmd.ExecuteReader(); while (r.Read()) tasks.Add(r["dataSetID"].ToString()); @@ -133,7 +135,8 @@ public IEnumerable GetArchivalDataLoadInfos(string dataTas int? specificDataLoadRunIDOnly = null, int? topX = null) { var db = Server.GetCurrentDatabase(); - var run = db.ExpectTable("DataLoadRun"); + var sh = Server.GetQuerySyntaxHelper(); + var run = db.ExpectTable(sh.EnsureWrapped("DataLoadRun")); using var con = Server.GetConnection(); con.Open(); @@ -144,11 +147,11 @@ public IEnumerable GetArchivalDataLoadInfos(string dataTas string where; if (specificDataLoadRunIDOnly != null) { - where = $"WHERE ID={specificDataLoadRunIDOnly.Value}"; + where = $"WHERE {sh.EnsureWrapped("ID")}={specificDataLoadRunIDOnly.Value}"; } else { - where = "WHERE dataLoadTaskID = @dataTaskId"; + where = $"WHERE {sh.EnsureWrapped("dataLoadTaskID")} = @dataTaskId"; var p = cmd.CreateParameter(); p.ParameterName = "@dataTaskId"; p.Value = dataTaskId; @@ -158,13 +161,13 @@ public IEnumerable GetArchivalDataLoadInfos(string dataTas TopXResponse top = null; if (topX.HasValue) - top = Server.GetQuerySyntaxHelper().HowDoWeAchieveTopX(topX.Value); + top = sh.HowDoWeAchieveTopX(topX.Value); var sb = new StringBuilder("SELECT "); if (top?.Location == QueryComponent.SELECT) sb.AppendLine(top.SQL); - sb.AppendLine($" * FROM {run.GetFullyQualifiedName()} {where} ORDER BY ID desc"); + sb.AppendLine($" * FROM {run.GetFullyQualifiedName()} {where} ORDER BY {sh.EnsureWrapped("ID")} desc"); if (top?.Location == QueryComponent.Postfix) sb.AppendLine(top.SQL); @@ -204,7 +207,8 @@ public IEnumerable GetArchivalDataLoadInfos(string dataTas private static int GetDataTaskId(string dataTask, DiscoveredServer server, DbConnection con) { - using var cmd = server.GetCommand("SELECT ID FROM DataLoadTask WHERE name = @name", con); + var sh = server.GetQuerySyntaxHelper(); + using var cmd = server.GetCommand($"SELECT {sh.EnsureWrapped("ID")} FROM {sh.EnsureWrapped("DataLoadTask")} WHERE name = @name", con); var p = cmd.CreateParameter(); p.ParameterName = "@name"; p.Value = dataTask; @@ -236,9 +240,10 @@ public IDataLoadInfo CreateDataLoadInfo(string dataLoadTaskName, string packageN public void CreateNewLoggingTask(int id, string dataSetID) { using var conn = Server.GetConnection(); + var sh = Server.GetQuerySyntaxHelper(); conn.Open(); var sql = - $"INSERT INTO DataLoadTask (ID, description, name, createTime, userAccount, statusID, isTest, dataSetID) VALUES ({id}, @dataSetID, @dataSetID, @date, @username, 1, 0, @dataSetID)"; + $"INSERT INTO {sh.EnsureWrapped("DataLoadTask")} ({sh.EnsureWrapped("ID")}, description, name, {sh.EnsureWrapped("createTime")}, {sh.EnsureWrapped("userAccount")}, {sh.EnsureWrapped("statusID")}, {sh.EnsureWrapped("isTest")}, {sh.EnsureWrapped("dataSetID")}) VALUES ({id}, @dataSetID, @dataSetID, @date, @username, 1, {sh.False}, @dataSetID)"; using var cmd = Server.GetCommand(sql, conn); Server.AddParameterWithValueToCommand("@date", cmd, DateTime.Now); @@ -251,9 +256,10 @@ public void CreateNewLoggingTask(int id, string dataSetID) private void CreateNewDataSet(string datasetName) { using var conn = Server.GetConnection(); + var sh = Server.GetQuerySyntaxHelper(); conn.Open(); { - const string sql = "INSERT INTO DataSet (dataSetID,name) VALUES (@datasetName,@datasetName)"; + var sql = $"INSERT INTO {sh.EnsureWrapped("DataSet")} ({sh.EnsureWrapped("dataSetID")},name) VALUES (@datasetName,@datasetName)"; using var cmd = Server.GetCommand(sql, conn); Server.AddParameterWithValueToCommand("@datasetName", cmd, datasetName.Substring(Math.Max(0, datasetName.Length - 150))); @@ -274,8 +280,9 @@ public void CreateNewLoggingTaskIfNotExists(string toCreate) private int GetMaxTaskID() { using var conn = Server.GetConnection(); + var sh = Server.GetQuerySyntaxHelper(); conn.Open(); - const string sql = "SELECT MAX(ID) FROM DataLoadTask"; + var sql = $"SELECT MAX({sh.EnsureWrapped("ID")}) FROM {sh.EnsureWrapped("DataLoadTask")}"; using var cmd = Server.GetCommand(sql, conn); var result = cmd.ExecuteScalar(); @@ -285,9 +292,10 @@ private int GetMaxTaskID() public void ResolveFatalErrors(int[] ids, DataLoadInfo.FatalErrorStates newState, string newExplanation) { using var conn = Server.GetConnection(); + var sh = Server.GetQuerySyntaxHelper(); conn.Open(); var sql = - $"UPDATE FatalError SET explanation =@explanation, statusID=@statusID where ID in ({string.Join(",", ids)})"; + $"UPDATE {sh.EnsureWrapped("FatalError")} SET explanation =@explanation, {sh.EnsureWrapped("statusID")}=@statusID where {sh.EnsureWrapped("ID")} in ({string.Join(",", ids)})"; using var cmd = Server.GetCommand(sql, conn); Server.AddParameterWithValueToCommand("@explanation", cmd, newExplanation); @@ -298,4 +306,4 @@ public void ResolveFatalErrors(int[] ids, DataLoadInfo.FatalErrorStates newState throw new Exception( $"Query {sql} resulted in {affectedRows}, we were expecting there to be {ids.Length} updates because that is how many FatalError IDs that were passed to this method"); } -} \ No newline at end of file +} diff --git a/Tools/rdmp/CommandLine/Gui/ConsoleGuiCohortIdentificationConfigurationUI.cs b/Tools/rdmp/CommandLine/Gui/ConsoleGuiCohortIdentificationConfigurationUI.cs index d25ef2f160..1361e18d0b 100644 --- a/Tools/rdmp/CommandLine/Gui/ConsoleGuiCohortIdentificationConfigurationUI.cs +++ b/Tools/rdmp/CommandLine/Gui/ConsoleGuiCohortIdentificationConfigurationUI.cs @@ -140,38 +140,40 @@ private void Tableview1_CellActivated(TableView.CellActivatedEventArgs obj) var o = RowObjects[obj.Row]; if (o == null) return; + var col = tableview1.Table.Columns[obj.Col]; - if (col.ColumnName.Equals("Name")) + switch (col.ColumnName) { - var factory = new ConsoleGuiContextMenuFactory(_activator); - var menu = factory.Create(Array.Empty(), o); - - if (menu != null) + case "Name": { var p = tableview1.CellToScreen(obj.Col, obj.Row); if (p == null) return; - menu.Position = p.Value; - _contextMenuShowing = true; - menu.Show(); - menu.MenuBar.MenuAllClosed += () => _contextMenuShowing = false; + var factory = new ConsoleGuiContextMenuFactory(_activator); + var menu = factory.Create(p.Value.X, p.Value.Y, Array.Empty(), o); + if (menu != null) + { + menu.Position = p.Value; + _contextMenuShowing = true; + menu.Show(); + menu.MenuBar.MenuAllClosed += () => _contextMenuShowing = false; + } + + break; } - } - - if (col.ColumnName.Equals("Working")) - { - var key = Common.GetKey(o); - if (key?.CrashMessage != null) + case "Working": { - _activator.ShowException("Task Crashed", key.CrashMessage); - return; + var key = Common.GetKey(o); + if (key?.CrashMessage != null) _activator.ShowException("Task Crashed", key.CrashMessage); + break; } + case "Execute": + Common.ExecuteOrCancel(o, int.MaxValue); + break; } - - if (col.ColumnName.Equals("Execute")) Common.ExecuteOrCancel(o, Common.Timeout); } private bool IsValidSelection(int col, int row) diff --git a/Tools/rdmp/CommandLine/Gui/ConsoleGuiContextMenuFactory.cs b/Tools/rdmp/CommandLine/Gui/ConsoleGuiContextMenuFactory.cs index b232ba777c..a08111813a 100644 --- a/Tools/rdmp/CommandLine/Gui/ConsoleGuiContextMenuFactory.cs +++ b/Tools/rdmp/CommandLine/Gui/ConsoleGuiContextMenuFactory.cs @@ -28,7 +28,7 @@ public ConsoleGuiContextMenuFactory(IBasicActivateItems activator) this.activator = activator; } - public ContextMenu Create(object[] many, object single) + public ContextMenu Create(int x,int y,object[] many, object single) { var commands = GetCommands(activator, many, single).ToArray(); @@ -65,18 +65,16 @@ public ContextMenu Create(object[] many, object single) items.Add(bar); } - // we can do nothing if theres no menu items + // we can do nothing if there are no menu items if (items.Count == 0) return null; var withSpacers = AddSpacers(items, order); - var menu = new ContextMenu + return new ContextMenu(x, y, new MenuBarItem(withSpacers)) { - MenuItems = new MenuBarItem(withSpacers) + UseSubMenusSingleFrame = true }; - - return menu; } private static MenuItem[] AddSpacers(List items, Dictionary order) diff --git a/Tools/rdmp/CommandLine/Gui/ConsoleMainWindow.cs b/Tools/rdmp/CommandLine/Gui/ConsoleMainWindow.cs index 64f7e53e3b..ec7fe1d2f3 100644 --- a/Tools/rdmp/CommandLine/Gui/ConsoleMainWindow.cs +++ b/Tools/rdmp/CommandLine/Gui/ConsoleMainWindow.cs @@ -17,6 +17,7 @@ using Rdmp.Core.MapsDirectlyToDatabaseTable; using Rdmp.Core.Providers; using Rdmp.Core.Providers.Nodes; +using Rdmp.Core.ReusableLibraryCode.Annotations; using Rdmp.Core.ReusableLibraryCode.Settings; using Terminal.Gui; using Terminal.Gui.Trees; @@ -27,7 +28,7 @@ internal class ConsoleMainWindow { private Window _win; private TreeView _treeView; - private IBasicActivateItems _activator; + private readonly IBasicActivateItems _activator; /// /// The last passed to this UI. @@ -167,7 +168,7 @@ internal void SetUp(Toplevel top) var statusBar = new StatusBar(new StatusItem[] { new(Key.Q | Key.CtrlMask, "~^Q~ Quit", Quit), - new(Key.R | Key.CtrlMask, "~^R~ Run", action: Run), + new(Key.R | Key.CtrlMask, "~^R~ Run", Run), new(Key.F | Key.CtrlMask, "~^F~ Find", Find), new(Key.N | Key.CtrlMask, "~^N~ New", New), new(Key.F5, "~F5~ Refresh", Publish) @@ -252,21 +253,18 @@ private void _treeView_ObjectActivated(ObjectActivatedEventArgs obj) private string AspectGetter(object model) { - if (model is IContainer container) return $"{container} ({container.Operation})"; - - if (model is CohortAggregateContainer setContainer) return $"{setContainer} ({setContainer.Operation})"; - - if (model is ExtractionInformation ei) return $"{ei} ({ei.ExtractionCategory})"; - - if (model is CatalogueItemsNode cin) return $"{cin} ({cin.CatalogueItems.Length})"; - - if (model is TableInfoServerNode server) return $"{server.ServerName} ({server.DatabaseType})"; - - if (model is IDisableable d) return d.IsDisabled ? $"{d} (Disabled)" : d.ToString(); - - return model is IArgument arg - ? $"{arg} ({(string.IsNullOrWhiteSpace(arg.Value) ? "Null" : arg.Value)})" - : model?.ToString() ?? "Null Object"; + return model switch + { + IContainer container => $"{container} ({container.Operation})", + CohortAggregateContainer setContainer => $"{setContainer} ({setContainer.Operation})", + ExtractionInformation ei => $"{ei} ({ei.ExtractionCategory})", + CatalogueItemsNode cin => $"{cin} ({cin.CatalogueItems.Length})", + TableInfoServerNode server => $"{server.ServerName} ({server.DatabaseType})", + IDisableable d => d.IsDisabled ? $"{d} (Disabled)" : d.ToString(), + _ => model is IArgument arg + ? $"{arg} ({(string.IsNullOrWhiteSpace(arg.Value) ? "Null" : arg.Value)})" + : model?.ToString() ?? "Null Object" + }; } private void Publish() @@ -337,7 +335,7 @@ private void Show(object selected) _treeView.SetNeedsDisplay(); } - private void _treeView_SelectionChanged(object sender, SelectionChangedEventArgs e) + private void _treeView_SelectionChanged(object sender, [NotNull] SelectionChangedEventArgs e) { if (e.NewValue != null) _treeView.RefreshObject(e.NewValue); @@ -346,13 +344,9 @@ private void _treeView_SelectionChanged(object sender, SelectionChangedEventArgs private void Menu() { var factory = new ConsoleGuiContextMenuFactory(_activator); - var menu = factory.Create(_treeView.GetAllSelectedObjects().ToArray(), _treeView.SelectedObject); - - if (menu == null) - return; - - menu.Position = DateTime.Now.Subtract(_lastMouseMove).TotalSeconds < 1 ? _lastMousePos : new Point(10, 5); - menu.Show(); + var position = DateTime.Now.Subtract(_lastMouseMove).TotalSeconds < 1 ? _lastMousePos : new Point(10, 5); + var menu = factory.Create(position.X,position.Y,_treeView.GetAllSelectedObjects().ToArray(), _treeView.SelectedObject); + menu?.Show(); } diff --git a/rdmp-client.xml b/rdmp-client.xml index 0132d9c97a..c4285dc766 100644 --- a/rdmp-client.xml +++ b/rdmp-client.xml @@ -1,7 +1,7 @@ - 8.2.3.0 - https://github.com/HicServices/RDMP/releases/download/v8.3.0/rdmp-8.3.0-client.zip + 8.3.1.0 + https://github.com/HicServices/RDMP/releases/download/v8.3.1/rdmp-8.3.1-client.zip https://github.com/HicServices/RDMP/blob/main/CHANGELOG.md#7 true