Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set extraction pks #1339

Merged
merged 7 commits into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added 'Set Description' command to [AggregateConfiguration] context menu
- Template cohort builder aggregates can be dragged onto extraction datasets to import the container tree [#1307](https://github.com/HicServices/RDMP/issues/1307)
- Having a JoinInfo between 2 columns that have different collations is now flagged by ProblemProvider [#1288](https://github.com/HicServices/RDMP/issues/1288)
- Added command `SetExtractionPrimaryKeys` for controlling which columns (if any) will make the primary key when extracting to database [#1335](https://github.com/HicServices/RDMP/issues/1335)
- Added ability to pop out tooltips/problems into modal popup [#1334](https://github.com/HicServices/RDMP/issues/1334)

### Changed
Expand Down
8 changes: 7 additions & 1 deletion Rdmp.Core/CommandExecution/AtomicCommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,15 @@ public IEnumerable<IAtomicCommand> CreateCommands(object o)
yield return new ExecuteCommandMakeCatalogueProjectSpecific(_activator, c, null) {
Weight = -99.0009f, SuggestedCategory = Extraction };
}

yield return new ExecuteCommandSetExtractionIdentifier(_activator, c, null, null) {
Weight = -99.0008f, SuggestedCategory = Extraction };

yield return new ExecuteCommandSetExtractionPrimaryKeys(_activator, c, null, null)
{
Weight = -99.0007f,
SuggestedCategory = Extraction
};
}

yield return new ExecuteCommandExportObjectsToFile(_activator, new[] {c}) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Copyright (c) The University of Dundee 2018-2019
// This file is part of the Research Data Management Platform (RDMP).
// RDMP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
// RDMP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with RDMP. If not, see <https://www.gnu.org/licenses/>.

using System;
using System.Linq;
using Rdmp.Core.Curation.Data;
using Rdmp.Core.DataExport.Data;

namespace Rdmp.Core.CommandExecution.AtomicCommands
{
public abstract class ExecuteCommandSetColumnSettingBase : BasicCommandExecution, IAtomicCommand
{
private ICatalogue _catalogue;
private ExtractionInformation[] _extractionInformations;
private ExtractionInformation[] _alreadyMarked;

private readonly IExtractionConfiguration _inConfiguration;
private readonly string _commandName;
private ConcreteColumn[] _selectedDataSetColumns;
private ConcreteColumn[] _alreadyMarkedInConfiguration;

/// <summary>
/// Explicit columns to pick rather than prompting to choose at runtime
/// </summary>
private string[] toPick;
private readonly string _commandProperty;

/// <summary>
///
/// </summary>
/// <param name="activator"></param>
/// <param name="catalogue">The dataset you want to change the setting for</param>
/// <param name="inConfiguration">Optional - If setting should only be applied to a specific extraction or Null for the Catalogue itself (will affect all future extractions)</param>
/// <param name="column">"Optional - The Column name(s) you want to select as the new selection(s). Comma seperate multiple entries if needed"</param>
/// <param name="commandName">Describe what is being changed from user perspective e.g. "Set IsExtractionIdentifier"</param>
/// <param name="commandProperty">Name of property being changed by this command e.g "Extraction Identifier"</param>
public ExecuteCommandSetColumnSettingBase(
IBasicActivateItems activator,ICatalogue catalogue,IExtractionConfiguration inConfiguration,string column,
string commandName, string commandProperty
) : base(activator)
{
_catalogue = catalogue;
_inConfiguration = inConfiguration;
_commandName = commandName;
_catalogue.ClearAllInjections();
_commandProperty = commandProperty;

if (inConfiguration != null)
{
SetImpossibleIfReadonly(_inConfiguration);

var allEds = inConfiguration.GetAllExtractableDataSets();
var eds = allEds.FirstOrDefault(sds => sds.Catalogue_ID == _catalogue.ID);
if (eds == null)
{
SetImpossible($"Catalogue '{_catalogue}' is not part of ExtractionConfiguration '{inConfiguration}'");
return;
}

_selectedDataSetColumns = inConfiguration.GetAllExtractableColumnsFor(eds);

if (_selectedDataSetColumns.Length == 0)
{
SetImpossible($"Catalogue '{_catalogue}' in '{inConfiguration}' does not have any extractable columns");
return;
}

_alreadyMarkedInConfiguration = _selectedDataSetColumns.Where(c => Getter(c)).ToArray();
}
else
{
_extractionInformations = _catalogue.GetAllExtractionInformation(ExtractionCategory.Any);

if (_extractionInformations.Length == 0)
{
SetImpossible("Catalogue does not have any extractable columns");
return;
}

_alreadyMarked = _extractionInformations.Where(c=>Getter(c)).ToArray();
}

if (!string.IsNullOrWhiteSpace(column))
{
toPick = column.Split(',', StringSplitOptions.RemoveEmptyEntries);
}
}


public override string GetCommandName()
{
if (!string.IsNullOrWhiteSpace(OverrideCommandName))
return OverrideCommandName;

var cols = _alreadyMarked ?? _alreadyMarkedInConfiguration;

if (cols == null || cols.Length == 0)
return _commandName;

return _commandName + " (" + string.Join(",", cols.Select(e => e.GetRuntimeName())) + ")";
}
public override void Execute()
{
base.Execute();

var oldCols = _alreadyMarked ?? _alreadyMarkedInConfiguration;

string initialSearchText = oldCols.Length == 1 ? oldCols[0].GetRuntimeName() : null;

if (_inConfiguration != null)
{
ChangeFor(initialSearchText, _selectedDataSetColumns);
Publish(_inConfiguration);
}
else
{
ChangeFor(initialSearchText, _extractionInformations);
Publish(_catalogue);
}
}
private void ChangeFor(string initialSearchText, ConcreteColumn[] allColumns)
{
ConcreteColumn[] selected = null;

if (toPick != null && toPick.Length > 0)
{
selected = allColumns.Where(a => toPick.Contains(a.GetRuntimeName())).ToArray();

if (selected.Length != toPick.Length)
{
throw new Exception($"Could not find column(s) {string.Join(',', toPick)} amongst available columns ({string.Join(',', allColumns.Select(c => c.GetRuntimeName()))})");
}
}
else
{
if (SelectMany(new DialogArgs {
InitialObjectSelection = _alreadyMarked ?? _alreadyMarkedInConfiguration,
AllowSelectingNull = true,
WindowTitle = $"Set {_commandProperty}",
TaskDescription = $"Choose which columns will make up the new {_commandProperty}. Or select null to clear"
}, allColumns, out selected))
{
if (selected == null || selected.Length == 0)
if (!YesNo($"Do you want to clear the {_commandProperty}?", $"Clear {_commandProperty}?"))
return;
if(!IsValidSelection(selected))
return;
}
else
return;
}

foreach (var ec in allColumns)
{
bool newValue = selected != null && selected.Contains(ec);

if (Getter(ec) != newValue)
{
Setter(ec,newValue);
ec.SaveToDatabase();
}
}
}

/// <summary>
/// Value getter to determine if a given <see cref="ConcreteColumn"/> is included in the current selection for your setting
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
protected abstract bool Getter(ConcreteColumn c);

/// <summary>
/// Value setter to assign new inclusion/exclusion status for the column (if command is executed and a new selection confirmed)
/// </summary>
/// <param name="c"></param>
/// <param name="newValue">New status, true = include in selection, false = exclude</param>
protected abstract void Setter(ConcreteColumn c, bool newValue);

/// <summary>
/// Show any warnings if applicable and then return false if user changes their mind about <paramref name="selected"/>
/// </summary>
/// <param name="selected"></param>
/// <returns></returns>
protected abstract bool IsValidSelection(ConcreteColumn[] selected);
}
}
Loading