From a8d7913121dcf14d180a9723cc3d84b0b71a39fd Mon Sep 17 00:00:00 2001 From: jas88 Date: Fri, 23 Jun 2023 18:40:56 -0500 Subject: [PATCH] Syntax update, build against RDMP git --- .gitmodules | 4 + .../BasicAutomationCommandExecution.cs | 2 +- .../Data/AutomateExtraction.cs | 7 +- .../Data/AutomateExtractionSchedule.cs | 74 +++++++------------ .../AutomateExtractionRepositoryFinder.cs | 5 +- .../AutomatedExtractionPipelineChecker.cs | 9 +-- ...ineHackerExecuteDatasetExtractionSource.cs | 3 +- .../ExtractionPipeline/DeltaHacker.cs | 40 +++++----- .../IdentifierAccumulator.cs | 12 +-- .../SuccessfullyExtractedResultsDocumenter.cs | 9 ++- ...odules.Extensions.AutomationPlugins.csproj | 2 +- .../DeAnonymise/DeAnonymiseAgainstCohort.cs | 8 +- .../DeAnonymise/DeAnonymiseAgainstCohortUI.cs | 35 +++++---- .../LoadModules.Extensions.Interactive.csproj | 5 +- .../AutomationTests/AllowAnythingTicketing.cs | 7 +- .../NeverAllowAnythingTicketing.cs | 7 +- .../AutomationTests/ObjectCreationTests.cs | 14 ++-- ...tsRequiringAnAutomationPluginRepository.cs | 12 +-- .../DeAnonymiseAgainstCohortTests.cs | 10 ++- .../LoadModules.Extensions.Tests.csproj | 10 ++- .../NuspecIsCorrectTests.cs | 20 ++--- .../Python/ScriptExecutionTests.cs | 39 +++++----- .../Python/Unit/Python2And3InstalledTests.cs | 2 +- .../Python/Unit/Python2InstalledTests.cs | 2 +- .../Python/Unit/Python3InstalledTests.cs | 34 +++++---- .../Python/Unit/PythonNotInstalledTests.cs | 4 +- .../Python/Unit/TestsThatWorkRegardless.cs | 22 +++--- LoadModules.Extensions.sln | 30 ++++++++ Plugin/main/main.csproj | 1 - .../DataProvider/PythonDataProvider.cs | 6 +- .../LoadModules.Extensions.Python.csproj | 2 +- RDMP | 1 + ...adModules.Extensions.ReleasePlugins.csproj | 4 +- .../NotifyEventArgsProxy.cs | 5 +- .../RemoteRDMPDataReleaseDestination.cs | 19 +++-- .../RemoteRDMPReleaseEngine.cs | 17 ++--- .../RemoteRDMPReleaseEngineSettings.cs | 2 +- SharedAssemblyInfo.cs | 9 ++- .../Attachers/RStudioAttacher.cs | 56 ++++++++------ .../Attachers/SasAttacher.cs | 51 +++++++------ ...es.Extensions.StatsScriptsExecution.csproj | 2 +- 41 files changed, 331 insertions(+), 272 deletions(-) create mode 100644 .gitmodules create mode 160000 RDMP diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a664f89 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "RDMP"] + path = RDMP + url = https://github.com/HicServices/RDMP.git + branch = feature/rc4 diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/BasicAutomationCommandExecution.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/BasicAutomationCommandExecution.cs index 79d3063..5e73632 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/BasicAutomationCommandExecution.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/BasicAutomationCommandExecution.cs @@ -17,7 +17,7 @@ public BasicAutomationCommandExecution(IBasicActivateItems activator):base(activ } catch (System.Exception e) { - SetImpossible("No Automation Repository Found:" + e.Message); + SetImpossible($"No Automation Repository Found:{e.Message}"); return; } diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtraction.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtraction.cs index 5e7ce35..b906556 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtraction.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtraction.cs @@ -135,7 +135,8 @@ public DataTable GetIdentifiersTable() public SuccessfullyExtractedResults GetSuccessIfAnyFor(IExtractableDataSet ds) { - return _repository.GetAllObjects(@"WHERE ExtractableDataSet_ID = " + ds.ID + " AND AutomateExtraction_ID = " + ID).SingleOrDefault(); + return _repository.GetAllObjects( + $@"WHERE ExtractableDataSet_ID = {ds.ID} AND AutomateExtraction_ID = {ID}").SingleOrDefault(); } public void ClearBaselines() @@ -143,10 +144,10 @@ public void ClearBaselines() using (var con = _repository.DiscoveredServer.GetConnection()) { con.Open(); - new SqlCommand(@"Delete From + new SqlCommand($@"Delete From [ReleaseIdentifiersSeen] where - AutomateExtraction_ID = " + ID, (SqlConnection) con).ExecuteNonQuery(); + AutomateExtraction_ID = {ID}", (SqlConnection) con).ExecuteNonQuery(); } foreach (SuccessfullyExtractedResults r in _repository.GetAllObjectsWithParent(this)) diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtractionSchedule.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtractionSchedule.cs index 5c5a3cf..1108082 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtractionSchedule.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/AutomateExtractionSchedule.cs @@ -33,60 +33,60 @@ public class AutomateExtractionSchedule : DatabaseEntity, INamed public AutomationTimeScale ExecutionTimescale { - get { return _executionTimescale; } - set { SetField(ref _executionTimescale, value); } + get => _executionTimescale; + set => SetField(ref _executionTimescale, value); } public string UserRequestingRefresh { - get { return _userRequestingRefresh; } - set { SetField(ref _userRequestingRefresh, value); } + get => _userRequestingRefresh; + set => SetField(ref _userRequestingRefresh, value); } public DateTime? UserRequestingRefreshDate { - get { return _userRequestingRefreshDate; } - set { SetField(ref _userRequestingRefreshDate, value); } + get => _userRequestingRefreshDate; + set => SetField(ref _userRequestingRefreshDate, value); } public string Ticket { - get { return _ticket; } - set { SetField(ref _ticket, value); } + get => _ticket; + set => SetField(ref _ticket, value); } public string Name { - get { return _name; } - set { SetField(ref _name, value); } + get => _name; + set => SetField(ref _name, value); } public string Comment { - get { return _comment; } - set { SetField(ref _comment, value); } + get => _comment; + set => SetField(ref _comment, value); } public bool Disabled { - get { return _disabled; } - set { SetField(ref _disabled, value); } + get => _disabled; + set => SetField(ref _disabled, value); } public int Project_ID { - get { return _project_ID; } - set { SetField(ref _project_ID, value); } + get => _project_ID; + set => SetField(ref _project_ID, value); } public int? Pipeline_ID { - get { return _pipeline_ID; } - set { SetField(ref _pipeline_ID, value); } + get => _pipeline_ID; + set => SetField(ref _pipeline_ID, value); } public TimeSpan ExecutionTimeOfDay { - get { return _executionTimeOfDay; } - set { SetField(ref _executionTimeOfDay , value); } + get => _executionTimeOfDay; + set => SetField(ref _executionTimeOfDay , value); } public int? ReleasePipeline_ID { - get { return _releasePipelineId; } - set { SetField(ref _releasePipelineId , value); } + get => _releasePipelineId; + set => SetField(ref _releasePipelineId , value); } #endregion @@ -94,34 +94,16 @@ public int? ReleasePipeline_ID #region Database Relationships [NoMappingToDatabase] - public IPipeline Pipeline { get - { - return Pipeline_ID != null ? _repository.CatalogueRepository.GetObjectByID(Pipeline_ID.Value) : null; - } } + public IPipeline Pipeline => Pipeline_ID != null ? _repository.CatalogueRepository.GetObjectByID(Pipeline_ID.Value) : null; [NoMappingToDatabase] - public IPipeline ReleasePipeline - { - get - { - return ReleasePipeline_ID != null ? _repository.CatalogueRepository.GetObjectByID(ReleasePipeline_ID.Value) : null; - } - } + public IPipeline ReleasePipeline => ReleasePipeline_ID != null ? _repository.CatalogueRepository.GetObjectByID(ReleasePipeline_ID.Value) : null; [NoMappingToDatabase] - public IProject Project - { - get - { - return _repository.DataExportRepository.GetObjectByID(Project_ID); - } } + public IProject Project => _repository.DataExportRepository.GetObjectByID(Project_ID); [NoMappingToDatabase] - public AutomateExtraction[] AutomateExtractions { get - { - return _repository.GetAllObjectsWithParent(this); - } } - + public AutomateExtraction[] AutomateExtractions => _repository.GetAllObjectsWithParent(this); #endregion @@ -131,7 +113,7 @@ public AutomateExtractionSchedule(PluginRepository repository, IProject project) repository.InsertAndHydrate(this, new Dictionary() { {"Project_ID",project.ID}, - {"Name","New Schedule"+Guid.NewGuid()}, + {"Name", $"New Schedule{Guid.NewGuid()}" }, {"ExecutionTimescale",AutomationTimeScale.Never}, {"ExecutionTimeOfDay","12:00:00"} }); @@ -201,7 +183,7 @@ public void CheckTicketing(ICheckNotifier notifier) notifier.OnCheckPerformed( new CheckEventArgs( - "Ticket '" + Ticket + "' is " + evaluation + ". Reason given was:" + Environment.NewLine + reason, + $"Ticket '{Ticket}' is {evaluation}. Reason given was:{Environment.NewLine}{reason}", CheckResult.Fail, exc)); } diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/Repository/AutomateExtractionRepositoryFinder.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/Repository/AutomateExtractionRepositoryFinder.cs index cab8bd5..3beaa85 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/Repository/AutomateExtractionRepositoryFinder.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Data/Repository/AutomateExtractionRepositoryFinder.cs @@ -26,9 +26,8 @@ public override PluginRepository GetRepositoryIfAny() .Where(e => e.WasCreatedBy(patcher)).ToArray(); if (compatibleServers.Length > 1) - throw new Exception("There are 2+ ExternalDatabaseServers of type '" + patcher.Name + - "'. This is not allowed, you must delete one. The servers were called:" + - string.Join(",", compatibleServers.Select(s => s.ToString()))); + throw new Exception( + $"There are 2+ ExternalDatabaseServers of type '{patcher.Name}'. This is not allowed, you must delete one. The servers were called:{string.Join(",", compatibleServers.Select(s => s.ToString()))}"); if (compatibleServers.Length == 0) return null; diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/AutomatedExtractionPipelineChecker.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/AutomatedExtractionPipelineChecker.cs index bd2ef1d..ac00588 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/AutomatedExtractionPipelineChecker.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/AutomatedExtractionPipelineChecker.cs @@ -27,7 +27,8 @@ public void Check(ICheckNotifier notifier) if (_automateExtractionPipeline.PipelineComponents.Any(c => c.Class == typeof (SuccessfullyExtractedResultsDocumenter).FullName)) notifier.OnCheckPerformed(new CheckEventArgs("Found SuccessfullyExtractedResultsDocumenter plugin component",CheckResult.Success)); else - notifier.OnCheckPerformed(new CheckEventArgs("Automated Extraction can only take place through Pipelines that include a "+typeof(SuccessfullyExtractedResultsDocumenter).Name+" plugin component", CheckResult.Fail)); + notifier.OnCheckPerformed(new CheckEventArgs( + $"Automated Extraction can only take place through Pipelines that include a {typeof(SuccessfullyExtractedResultsDocumenter).Name} plugin component", CheckResult.Fail)); var source = _automateExtractionPipeline.Source; @@ -38,14 +39,12 @@ public void Check(ICheckNotifier notifier) } if (source.Class == typeof (BaselineHackerExecuteDatasetExtractionSource).FullName) - notifier.OnCheckPerformed(new CheckEventArgs("Found Compatible Source " + source.Class, + notifier.OnCheckPerformed(new CheckEventArgs($"Found Compatible Source {source.Class}", CheckResult.Success)); else notifier.OnCheckPerformed( new CheckEventArgs( - "Source Component " + source.Class + " of Pipeline " + _automateExtractionPipeline + - " is not a " + typeof (BaselineHackerExecuteDatasetExtractionSource).FullName + - " (Deltas will never be created)", CheckResult.Warning)); + $"Source Component {source.Class} of Pipeline {_automateExtractionPipeline} is not a {typeof(BaselineHackerExecuteDatasetExtractionSource).FullName} (Deltas will never be created)", CheckResult.Warning)); } catch (Exception e) { diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/BaselineHackerExecuteDatasetExtractionSource.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/BaselineHackerExecuteDatasetExtractionSource.cs index c1681e8..eacd2a1 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/BaselineHackerExecuteDatasetExtractionSource.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/BaselineHackerExecuteDatasetExtractionSource.cs @@ -24,7 +24,8 @@ public override string HackExtractionSQL(string sql, IDataLoadEventListener list if (hacker.ExecuteHackIfAllowed(listener, out hackSql) == BaselineHackEvaluation.Allowed) { var newSql = sql + hackSql; - listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information, "Full Hacked Query is now:" + Environment.NewLine + newSql)); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information, + $"Full Hacked Query is now:{Environment.NewLine}{newSql}")); return newSql; } diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/DeltaHacker.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/DeltaHacker.cs index d32f538..1f30dda 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/DeltaHacker.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/DeltaHacker.cs @@ -39,11 +39,13 @@ public BaselineHackEvaluation ExecuteHackIfAllowed(IDataLoadEventListener listen var configId = _extractDatasetCommand.Configuration.ID; //find the automation record - var automateExtraction = _repository.GetAllObjects("WHERE ExtractionConfiguration_ID = " + configId ); + var automateExtraction = _repository.GetAllObjects( + $"WHERE ExtractionConfiguration_ID = {configId}"); //there should be one! and only 1 if(automateExtraction.Length != 1) - throw new Exception("No AutomateExtraction was found for ExtractionConfiguration '" + _extractDatasetCommand.Configuration +"'"); + throw new Exception( + $"No AutomateExtraction was found for ExtractionConfiguration '{_extractDatasetCommand.Configuration}'"); if(automateExtraction[0].BaselineDate == null) return BaselineHackEvaluation.NoCompatibleBaselineAvailable; @@ -62,7 +64,8 @@ public BaselineHackEvaluation ExecuteHackIfAllowed(IDataLoadEventListener listen //nope, the SQL is different, maybe the user has snuck in an extra column or some other thing if(!string.Equals(currentSQL.Trim(),oldSQL.Trim(),StringComparison.CurrentCultureIgnoreCase)) { - listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Warning, "SQL is out of date for baseline of " + _extractDatasetCommand + ". The old success will be deleted now and a new baseline will be executed", + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Warning, + $"SQL is out of date for baseline of {_extractDatasetCommand}. The old success will be deleted now and a new baseline will be executed", new ExpectedIdenticalStringsException("SQL strings did not match",currentSQL.Trim().ToLower(),oldSQL.Trim().ToLower()))); //either way the SQL is screwey so lets nuke the baseline and make them do a full baseline @@ -81,27 +84,28 @@ public BaselineHackEvaluation ExecuteHackIfAllowed(IDataLoadEventListener listen var tblForJoin = _repository.DiscoveredServer.GetCurrentDatabase().ExpectTable("ReleaseIdentifiersSeen"); if(!tblForJoin.Exists()) - throw new Exception("Table '" + tblForJoin + " did not exist!"); + throw new Exception($"Table '{tblForJoin} did not exist!"); var tableForJoinName = tblForJoin.GetFullyQualifiedName(); - hackSql = @" + hackSql = $@" AND ( ( --new cohorts - " + cohortReleaseIdentifier + @" - not in (Select ReleaseId from " + tableForJoinName + @" where AutomateExtraction_ID = "+ automateExtraction[0].ID+ @") + {cohortReleaseIdentifier} + not in (Select ReleaseId from {tableForJoinName} where AutomateExtraction_ID = {automateExtraction[0].ID}) ) OR ( --new records - " + validFromField.Name + " > '" + automateExtraction[0].BaselineDate.Value + @"' + {validFromField.Name} > '{automateExtraction[0].BaselineDate.Value}' ) ) "; - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Generated the following Delta Hack SQL:" + Environment.NewLine + hackSql)); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"Generated the following Delta Hack SQL:{Environment.NewLine}{hackSql}")); return BaselineHackEvaluation.Allowed; } @@ -119,7 +123,8 @@ public ColumnInfo GetValidFromField(IDataLoadEventListener listener) //table doesn't have a if(col == null) { - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "TableInfo " + tableInfo + " did not have a ColumnInfo called '" + validFromFieldName + "'")); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"TableInfo {tableInfo} did not have a ColumnInfo called '{validFromFieldName}'")); continue; } @@ -136,8 +141,8 @@ public ColumnInfo GetValidFromField(IDataLoadEventListener listener) if (tableInfo.IsPrimaryExtractionTable) { //should never happen to be honest I'm pretty sure QueryBuilder will be super angry if you have 2+ TableInfos both with IsPrimary and ColumnNames should be unique anyway but who knows - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, - "There were multiple ColumnInfos called " + validFromFieldName + " both from IsPrimaryExtractionTable TableInfos (" + validFromField + "," + col + ")" + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, + $"There were multiple ColumnInfos called {validFromFieldName} both from IsPrimaryExtractionTable TableInfos ({validFromField},{col})" )); return null; } @@ -155,9 +160,8 @@ public ColumnInfo GetValidFromField(IDataLoadEventListener listener) else { //neither the previous or ourselves are primary - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, "There were multiple ColumnInfos called " + validFromFieldName + - " (" + validFromField + - "," + col + ") try setting one of your TableInfos to IsPrimaryExtractionTable")); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, + $"There were multiple ColumnInfos called {validFromFieldName} ({validFromField},{col}) try setting one of your TableInfos to IsPrimaryExtractionTable")); return null; } } @@ -167,11 +171,13 @@ public ColumnInfo GetValidFromField(IDataLoadEventListener listener) if (validFromField == null) { - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "No ColumnInfos were found called '" + validFromFieldName + "'")); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, + $"No ColumnInfos were found called '{validFromFieldName}'")); return null; } - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Found valid from field '" + validFromField + "'")); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"Found valid from field '{validFromField}'")); return validFromField; } } diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/IdentifierAccumulator.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/IdentifierAccumulator.cs index ebe6b6a..01297b8 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/IdentifierAccumulator.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/IdentifierAccumulator.cs @@ -28,7 +28,7 @@ public static IdentifierAccumulator GetInstance(DataLoadInfo dataLoadInfo) private IdentifierAccumulator() { - _commitTblName = "Temp"+Guid.NewGuid().ToString().Replace("-", ""); + _commitTblName = $"Temp{Guid.NewGuid().ToString().Replace("-", "")}"; } HashSet identifiers = new HashSet(); @@ -60,7 +60,7 @@ public void CommitCurrentState(AutomateExtractionRepository repository, Automate using (var con = repository.DiscoveredServer.GetConnection()) { con.Open(); - var query = "SELECT TOP 0 * INTO " + tempTable.GetFullyQualifiedName()+" FROM ReleaseIdentifiersSeen"; + var query = $"SELECT TOP 0 * INTO {tempTable.GetFullyQualifiedName()} FROM ReleaseIdentifiersSeen"; repository.DiscoveredServer.GetCommand(query, con).ExecuteNonQuery(); } @@ -73,13 +73,13 @@ public void CommitCurrentState(AutomateExtractionRepository repository, Automate using (SqlConnection con = new SqlConnection(repository.ConnectionString)) { con.Open(); - string sql = @"INSERT ReleaseIdentifiersSeen (AutomateExtraction_ID, ReleaseID) + string sql = $@"INSERT ReleaseIdentifiersSeen (AutomateExtraction_ID, ReleaseID) SELECT AutomateExtraction_ID, ReleaseID -FROM "+_commitTblName+@" +FROM {_commitTblName} WHERE NOT EXISTS (SELECT 1 FROM ReleaseIdentifiersSeen A2 WHERE -A2.AutomateExtraction_ID = " + _commitTblName + @".AutomateExtraction_ID +A2.AutomateExtraction_ID = {_commitTblName}.AutomateExtraction_ID AND -A2.ReleaseID = " + _commitTblName + @".ReleaseID )"; +A2.ReleaseID = {_commitTblName}.ReleaseID )"; SqlCommand cmd = new SqlCommand(sql, con); cmd.ExecuteNonQuery(); } diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/SuccessfullyExtractedResultsDocumenter.cs b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/SuccessfullyExtractedResultsDocumenter.cs index deed874..052138b 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/SuccessfullyExtractedResultsDocumenter.cs +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/Execution/ExtractionPipeline/SuccessfullyExtractedResultsDocumenter.cs @@ -55,10 +55,12 @@ private DataTable ProcessPipelineData(ExtractDatasetCommand ds, DataTable toProc if(_repo == null) throw new Exception("Could not create AutomateExtractionRepository, are you missing an AutomationPluginsDatabase?"); - var matches = _repo.GetAllObjects("WHERE ExtractionConfiguration_ID = " + ds.Configuration.ID); + var matches = _repo.GetAllObjects( + $"WHERE ExtractionConfiguration_ID = {ds.Configuration.ID}"); if(matches.Length == 0) - throw new Exception("ExtractionConfiguration '" + ds.Configuration + "' does not have an entry in the AutomateExtractionRepository"); + throw new Exception( + $"ExtractionConfiguration '{ds.Configuration}' does not have an entry in the AutomateExtractionRepository"); //index ensure you can't have multiple so this shouldn't blow up _automateExtraction = matches.Single(); @@ -90,7 +92,8 @@ private DataTable ProcessPipelineData(ExtractDatasetCommand ds, DataTable toProc private DataTable ProcessPipelineData(ExtractGlobalsCommand globalData, DataTable toProcess, IDataLoadEventListener listener, GracefulCancellationToken cancellationToken) { - listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Warning, "Global Data is not audited and supported by " + GetType().Name)); + listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Warning, + $"Global Data is not audited and supported by {GetType().Name}")); //we don't do these yet return toProcess; diff --git a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/LoadModules.Extensions.AutomationPlugins.csproj b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/LoadModules.Extensions.AutomationPlugins.csproj index 74d5fb9..e881480 100644 --- a/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/LoadModules.Extensions.AutomationPlugins.csproj +++ b/AutomationPlugins/LoadModules.Extensions.AutomationPlugins/LoadModules.Extensions.AutomationPlugins.csproj @@ -31,7 +31,7 @@ - + diff --git a/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohort.cs b/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohort.cs index 09c9e0d..db8486f 100644 --- a/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohort.cs +++ b/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohort.cs @@ -39,12 +39,14 @@ public DataTable ProcessPipelineData(DataTable toProcess, IDataLoadEventListener if (ConfigurationGetter.OverrideReleaseIdentifier != null) { - string replacementName = new MicrosoftQuerySyntaxHelper().GetRuntimeName(ConfigurationGetter.ChosenCohort.GetReleaseIdentifier()); + var replacementName = MicrosoftQuerySyntaxHelper.Instance.GetRuntimeName(ConfigurationGetter.ChosenCohort.GetReleaseIdentifier()); if (!toProcess.Columns.Contains(ConfigurationGetter.OverrideReleaseIdentifier)) - throw new ArgumentException("Cannot DeAnonymise cohort because you specified OverrideReleaseIdentifier of '" + ConfigurationGetter.OverrideReleaseIdentifier + "' but the DataTable toProcess did not contain a column of that name"); + throw new ArgumentException( + $"Cannot DeAnonymise cohort because you specified OverrideReleaseIdentifier of '{ConfigurationGetter.OverrideReleaseIdentifier}' but the DataTable toProcess did not contain a column of that name"); - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Renaming DataTable column " + ConfigurationGetter.OverrideReleaseIdentifier + " to " + replacementName)); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"Renaming DataTable column {ConfigurationGetter.OverrideReleaseIdentifier} to {replacementName}")); toProcess.Columns[ConfigurationGetter.OverrideReleaseIdentifier].ColumnName = replacementName; } diff --git a/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohortUI.cs b/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohortUI.cs index 15833d5..f75d2a2 100644 --- a/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohortUI.cs +++ b/Interactive/LoadModules.Extensions.Interactive/DeAnonymise/DeAnonymiseAgainstCohortUI.cs @@ -16,15 +16,15 @@ namespace LoadModules.Extensions.Interactive.DeAnonymise; public partial class DeAnonymiseAgainstCohortUI : Form, IDeAnonymiseAgainstCohortConfigurationFulfiller { private readonly DataTable _toProcess; - private readonly IBasicActivateItems activator; - private IDataExportRepository _dataExportRepository; + private readonly IBasicActivateItems _activator; + private readonly IDataExportRepository _dataExportRepository; public IExtractableCohort ChosenCohort { get; set; } public string OverrideReleaseIdentifier { get; set; } public DeAnonymiseAgainstCohortUI(DataTable toProcess, IBasicActivateItems activator) { _toProcess = toProcess; - this.activator = activator; + _activator = activator; InitializeComponent(); try @@ -42,8 +42,10 @@ public DeAnonymiseAgainstCohortUI(DataTable toProcess, IBasicActivateItems activ foreach (DataColumn column in toProcess.Columns) { - Button b = new Button(); - b.Text = column.ColumnName; + var b = new Button + { + Text = column.ColumnName + }; flowLayoutPanel1.Controls.Add(b); b.Click += b_Click; } @@ -59,28 +61,25 @@ void b_Click(object sender, EventArgs e) private void btnChooseCohort_Click(object sender, EventArgs e) { var dialog = new SelectDialog( - new DialogArgs() {WindowTitle = "Choose Cohort" }, (IActivateItems)activator, _dataExportRepository.GetAllObjects(), false); + new DialogArgs() {WindowTitle = "Choose Cohort" }, (IActivateItems)_activator, _dataExportRepository.GetAllObjects(), false); - if(dialog.ShowDialog() == DialogResult.OK) - if (dialog.Selected != null) - { - ChosenCohort = (ExtractableCohort)dialog.Selected; - CheckCohortHasCorrectColumns(); - } + if (dialog.ShowDialog() != DialogResult.OK) return; + if (dialog.Selected == null) return; + ChosenCohort = (ExtractableCohort)dialog.Selected; + CheckCohortHasCorrectColumns(); } private void CheckCohortHasCorrectColumns() { - string release = OverrideReleaseIdentifier ?? new MicrosoftQuerySyntaxHelper().GetRuntimeName(ChosenCohort.GetReleaseIdentifier()); + var release = OverrideReleaseIdentifier ?? MicrosoftQuerySyntaxHelper.Instance.GetRuntimeName(ChosenCohort.GetReleaseIdentifier()); if (!_toProcess.Columns.Contains(release)) checksUI1.OnCheckPerformed( new CheckEventArgs( - "Cannot deanonymise table because it contains no release identifier field (should be called " + - release + ")", CheckResult.Fail)); + $"Cannot deanonymise table because it contains no release identifier field (should be called {release})", CheckResult.Fail)); else - checksUI1.OnCheckPerformed(new CheckEventArgs("Found column " + release + " in your DataTable", + checksUI1.OnCheckPerformed(new CheckEventArgs($"Found column {release} in your DataTable", CheckResult.Success)); lblExpectedReleaseIdentifierColumn.Text = release; @@ -99,7 +98,7 @@ private void cbOverrideReleaseIdentifierColumn_CheckedChanged(object sender, Eve private void btnOk_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; - this.Close(); + Close(); } private void button1_Click(object sender, EventArgs e) @@ -107,7 +106,7 @@ private void button1_Click(object sender, EventArgs e) ChosenCohort = null; OverrideReleaseIdentifier = null; DialogResult = DialogResult.Cancel; - this.Close(); + Close(); } } diff --git a/Interactive/LoadModules.Extensions.Interactive/LoadModules.Extensions.Interactive.csproj b/Interactive/LoadModules.Extensions.Interactive/LoadModules.Extensions.Interactive.csproj index 6876f64..7d35709 100644 --- a/Interactive/LoadModules.Extensions.Interactive/LoadModules.Extensions.Interactive.csproj +++ b/Interactive/LoadModules.Extensions.Interactive/LoadModules.Extensions.Interactive.csproj @@ -14,10 +14,11 @@ - - + + + Form diff --git a/LoadModules.Extensions.Tests/AutomationTests/AllowAnythingTicketing.cs b/LoadModules.Extensions.Tests/AutomationTests/AllowAnythingTicketing.cs index 1108491..f052666 100644 --- a/LoadModules.Extensions.Tests/AutomationTests/AllowAnythingTicketing.cs +++ b/LoadModules.Extensions.Tests/AutomationTests/AllowAnythingTicketing.cs @@ -1,11 +1,9 @@ using System; -using System.ComponentModel.Composition; using Rdmp.Core.Ticketing; using Rdmp.Core.ReusableLibraryCode.Checks; namespace LoadModules.Extensions.AutomationPlugins.Tests; -[Export(typeof(ITicketingSystem))] public class AllowAnythingTicketing:ITicketingSystem { public void Check(ICheckNotifier notifier) @@ -31,8 +29,5 @@ public TicketingReleaseabilityEvaluation GetDataReleaseabilityOfTicket(string ma return TicketingReleaseabilityEvaluation.Releaseable; } - public string GetProjectFolderName(string masterTicket) - { - return "Project " + masterTicket; - } + public string GetProjectFolderName(string masterTicket) => $"Project {masterTicket}"; } \ No newline at end of file diff --git a/LoadModules.Extensions.Tests/AutomationTests/NeverAllowAnythingTicketing.cs b/LoadModules.Extensions.Tests/AutomationTests/NeverAllowAnythingTicketing.cs index f2172fb..e8b3eec 100644 --- a/LoadModules.Extensions.Tests/AutomationTests/NeverAllowAnythingTicketing.cs +++ b/LoadModules.Extensions.Tests/AutomationTests/NeverAllowAnythingTicketing.cs @@ -1,11 +1,9 @@ using System; -using System.ComponentModel.Composition; using Rdmp.Core.Ticketing; using Rdmp.Core.ReusableLibraryCode.Checks; namespace LoadModules.Extensions.AutomationPlugins.Tests; -[Export(typeof(ITicketingSystem))] public class NeverAllowAnythingTicketing:ITicketingSystem { public void Check(ICheckNotifier notifier) @@ -31,8 +29,5 @@ public TicketingReleaseabilityEvaluation GetDataReleaseabilityOfTicket(string ma return TicketingReleaseabilityEvaluation.NotReleaseable; } - public string GetProjectFolderName(string masterTicket) - { - return "Project " + masterTicket; - } + public string GetProjectFolderName(string masterTicket) => $"Project {masterTicket}"; } \ No newline at end of file diff --git a/LoadModules.Extensions.Tests/AutomationTests/ObjectCreationTests.cs b/LoadModules.Extensions.Tests/AutomationTests/ObjectCreationTests.cs index 84bd31c..3b689b2 100644 --- a/LoadModules.Extensions.Tests/AutomationTests/ObjectCreationTests.cs +++ b/LoadModules.Extensions.Tests/AutomationTests/ObjectCreationTests.cs @@ -23,12 +23,14 @@ public void CreateAllObjects() Assert.AreEqual(schedule.Project_ID , proj.ID); //Configurations - var config = new ExtractionConfiguration(Repo.DataExportRepository, proj); - config.Name = "Configuration1"; + var config = new ExtractionConfiguration(Repo.DataExportRepository, proj) + { + Name = "Configuration1" + }; config.SaveToDatabase(); //Permission to use a given configuration - AutomateExtraction automate = new AutomateExtraction(Repo,schedule,config); + var automate = new AutomateExtraction(Repo,schedule,config); Assert.AreEqual(automate.ExtractionConfiguration_ID,config.ID); Assert.AreEqual(automate.Disabled ,false); Assert.IsNull(automate.BaselineDate); @@ -49,10 +51,10 @@ public void CreateAllObjects() [Test] public void CreateQueuedExecution() { - Project project = new Project(Repo.DataExportRepository,"proj"); - ExtractionConfiguration configuration= new ExtractionConfiguration(Repo.DataExportRepository,project); + var project = new Project(Repo.DataExportRepository,"proj"); + var configuration= new ExtractionConfiguration(Repo.DataExportRepository,project); - Pipeline p = new Pipeline(Repo.CatalogueRepository); + var p = new Pipeline(Repo.CatalogueRepository); var que = new QueuedExtraction(Repo, configuration, p, DateTime.Now.AddHours(1)); Assert.IsTrue(que.Exists()); diff --git a/LoadModules.Extensions.Tests/AutomationTests/TestsRequiringAnAutomationPluginRepository.cs b/LoadModules.Extensions.Tests/AutomationTests/TestsRequiringAnAutomationPluginRepository.cs index d1c9b1b..8ca4910 100644 --- a/LoadModules.Extensions.Tests/AutomationTests/TestsRequiringAnAutomationPluginRepository.cs +++ b/LoadModules.Extensions.Tests/AutomationTests/TestsRequiringAnAutomationPluginRepository.cs @@ -31,12 +31,14 @@ public static AutomateExtractionRepository CreateAutomationDatabaseStatic(Discov var patcher = new AutomateExtractionPluginPatcher(); - MasterDatabaseScriptExecutor executor = new MasterDatabaseScriptExecutor(db); + var executor = new MasterDatabaseScriptExecutor(db); executor.CreateAndPatchDatabase(patcher, new AcceptAllCheckNotifier()); - var server = new ExternalDatabaseServer(repositoryLocator.CatalogueRepository, "Automation Server", patcher); - server.Server = db.Server.Name; - server.Database = db.GetRuntimeName(); + var server = new ExternalDatabaseServer(repositoryLocator.CatalogueRepository, "Automation Server", patcher) + { + Server = db.Server.Name, + Database = db.GetRuntimeName() + }; server.SaveToDatabase(); return new AutomateExtractionRepository(repositoryLocator, server); @@ -54,7 +56,7 @@ public static Pipeline GetValidExtractionPipelineStatic(ICatalogueRepository cat var source = new PipelineComponent(catalogueRepository, validPipeline, typeof(BaselineHackerExecuteDatasetExtractionSource), 0); source.CreateArgumentsForClassIfNotExists(); - var broadcaster = new PipelineComponent(catalogueRepository, validPipeline, typeof(SuccessfullyExtractedResultsDocumenter), 1); + _=new PipelineComponent(catalogueRepository, validPipeline, typeof(SuccessfullyExtractedResultsDocumenter), 1); var destination = new PipelineComponent(catalogueRepository, validPipeline, typeof(ExecuteDatasetExtractionFlatFileDestination), 2); destination.CreateArgumentsForClassIfNotExists(); diff --git a/LoadModules.Extensions.Tests/Interactive/DeAnonymiseAgainstCohortTests.cs b/LoadModules.Extensions.Tests/Interactive/DeAnonymiseAgainstCohortTests.cs index 1b67ea0..7ce56c5 100644 --- a/LoadModules.Extensions.Tests/Interactive/DeAnonymiseAgainstCohortTests.cs +++ b/LoadModules.Extensions.Tests/Interactive/DeAnonymiseAgainstCohortTests.cs @@ -31,6 +31,7 @@ public void setup() public void Normal_ReleaseDeAnonToPrivateKeys(bool doRedundantOverride) { using var dt = new DataTable(); + dt.BeginLoadData(); dt.Columns.Add("ReleaseID"); dt.Columns.Add("Animal"); @@ -40,8 +41,9 @@ public void Normal_ReleaseDeAnonToPrivateKeys(bool doRedundantOverride) if (doRedundantOverride) OverrideReleaseIdentifier = "ReleaseID"; + dt.EndLoadData(); using var clone = dt.Copy(); // Grab a copy of the pre-pipeline data to compare - var result = _deAnonymiseAgainstCohort.ProcessPipelineData(dt, new ThrowImmediatelyDataLoadEventListener(), new GracefulCancellationToken()); + var result = _deAnonymiseAgainstCohort.ProcessPipelineData(dt, ThrowImmediatelyDataLoadEventListener.Quiet, new GracefulCancellationToken()); Assert.IsTrue(result.Columns.Contains("PrivateID")); @@ -70,7 +72,7 @@ public void Freaky_ColumnNameOverriding() try { using var clone = dt.Copy(); // Grab a copy of the pre-pipeline data to compare - using var result = _deAnonymiseAgainstCohort.ProcessPipelineData(dt, new ThrowImmediatelyDataLoadEventListener(), new GracefulCancellationToken()); + using var result = _deAnonymiseAgainstCohort.ProcessPipelineData(dt, ThrowImmediatelyDataLoadEventListener.Quiet, new GracefulCancellationToken()); Assert.IsTrue(result.Columns.Contains("PrivateID")); @@ -96,7 +98,7 @@ public void Throws_ColumnMissing() foreach (var (key, value) in _cohortKeysGenerated) dt.Rows.Add("fish"); - var ex = Assert.Throws(() => _deAnonymiseAgainstCohort.ProcessPipelineData(dt, new ThrowImmediatelyDataLoadEventListener(), new GracefulCancellationToken())); + var ex = Assert.Throws(() => _deAnonymiseAgainstCohort.ProcessPipelineData(dt, ThrowImmediatelyDataLoadEventListener.Quiet, new GracefulCancellationToken())); Assert.IsTrue(ex?.Message.StartsWith("Column 'ReleaseID' does not belong to table"),$"Exception text was '{ex?.Message}'"); } @@ -112,7 +114,7 @@ public void Throws_ColumnMissingWithOverride() OverrideReleaseIdentifier = "HappyFace"; - var ex = Assert.Throws(() => _deAnonymiseAgainstCohort.ProcessPipelineData(dt, new ThrowImmediatelyDataLoadEventListener(), new GracefulCancellationToken())); + var ex = Assert.Throws(() => _deAnonymiseAgainstCohort.ProcessPipelineData(dt, ThrowImmediatelyDataLoadEventListener.Quiet, new GracefulCancellationToken())); Assert.AreEqual(ex.Message,"Cannot DeAnonymise cohort because you specified OverrideReleaseIdentifier of 'HappyFace' but the DataTable toProcess did not contain a column of that name"); } diff --git a/LoadModules.Extensions.Tests/LoadModules.Extensions.Tests.csproj b/LoadModules.Extensions.Tests/LoadModules.Extensions.Tests.csproj index 2e4c78f..a71a56b 100644 --- a/LoadModules.Extensions.Tests/LoadModules.Extensions.Tests.csproj +++ b/LoadModules.Extensions.Tests/LoadModules.Extensions.Tests.csproj @@ -13,13 +13,18 @@ false + + + + + + - - + @@ -27,6 +32,7 @@ + diff --git a/LoadModules.Extensions.Tests/NuspecIsCorrectTests.cs b/LoadModules.Extensions.Tests/NuspecIsCorrectTests.cs index 120951b..e0057a8 100644 --- a/LoadModules.Extensions.Tests/NuspecIsCorrectTests.cs +++ b/LoadModules.Extensions.Tests/NuspecIsCorrectTests.cs @@ -44,18 +44,18 @@ public void TestDependencyCorrect(string csproj, string nuspec, string packagesM Assert.Fail("Could not find file {0}", packagesMarkdown); // - Regex rPackageRef = new Regex(@" - Regex rDependencyRef = new Regex(@"m.Message.Equals("1"))); + Assert.AreEqual(5, toMemory.EventsReceivedBySender[py].Count(m=>m.Message.Equals("1"))); } @@ -66,8 +67,7 @@ public void SlowRollerTest() [Test] public void SlowRollerAsync() { - var script = - @"import time + const string script = @"import time import sys print (""GetReady"") @@ -83,9 +83,11 @@ import sys File.WriteAllText(file.FullName, script); try { - var py = new PythonDataProvider(); - py.FullPathToPythonScriptToRun = file.FullName; - py.Version = PythonVersion.Version3; + var py = new PythonDataProvider + { + FullPathToPythonScriptToRun = file.FullName, + Version = PythonVersion.Version3 + }; var tomemory = new ToMemoryDataLoadJob(); @@ -121,8 +123,7 @@ import sys [Test] public void WriteToErrorAndStandardOut() { - var script = - @"from __future__ import print_function + const string script = @"from __future__ import print_function import sys def eprint(*args, **kwargs): @@ -138,9 +139,11 @@ def eprint(*args, **kwargs): File.WriteAllText(file.FullName, script); try { - var py = new PythonDataProvider(); - py.FullPathToPythonScriptToRun = file.FullName; - py.Version = PythonVersion.Version3; + var py = new PythonDataProvider + { + FullPathToPythonScriptToRun = file.FullName, + Version = PythonVersion.Version3 + }; var tomem = new ToMemoryDataLoadJob(true); py.Fetch(tomem, new GracefulCancellationToken()); diff --git a/LoadModules.Extensions.Tests/Python/Unit/Python2And3InstalledTests.cs b/LoadModules.Extensions.Tests/Python/Unit/Python2And3InstalledTests.cs index 14dc96a..19fc6c1 100644 --- a/LoadModules.Extensions.Tests/Python/Unit/Python2And3InstalledTests.cs +++ b/LoadModules.Extensions.Tests/Python/Unit/Python2And3InstalledTests.cs @@ -37,7 +37,7 @@ public void PythonScript_OverrideExecutablePath_VersionMismatch() //so we now know that version 3 is installed, and we have overriden the python path to the .exe explicitly and we are trying to launch with Version2 enum now var ex = Assert.Throws(()=> { - provider.Check(new ThrowImmediatelyCheckNotifier()); + provider.Check(ThrowImmediatelyCheckNotifier.Quiet); //provider.Fetch(MockRepository.GenerateStub(), new GracefulCancellationToken()); }); StringAssert.Contains(@"which is incompatible with the desired version 2.7.1",ex?.Message); diff --git a/LoadModules.Extensions.Tests/Python/Unit/Python2InstalledTests.cs b/LoadModules.Extensions.Tests/Python/Unit/Python2InstalledTests.cs index f8959f5..c05e3f3 100644 --- a/LoadModules.Extensions.Tests/Python/Unit/Python2InstalledTests.cs +++ b/LoadModules.Extensions.Tests/Python/Unit/Python2InstalledTests.cs @@ -54,7 +54,7 @@ public void PythonScript_Version2_GoodSyntax(bool wrapFilename) //call with accept all provider.Check(new AcceptAllCheckNotifier()); - provider.Check(new ThrowImmediatelyCheckNotifier() { ThrowOnWarning = true }); + provider.Check(ThrowImmediatelyCheckNotifier.QuietPicky); provider.Fetch(new ThrowImmediatelyDataLoadJob(), new GracefulCancellationToken()); } diff --git a/LoadModules.Extensions.Tests/Python/Unit/Python3InstalledTests.cs b/LoadModules.Extensions.Tests/Python/Unit/Python3InstalledTests.cs index 57fc18f..ccd2117 100644 --- a/LoadModules.Extensions.Tests/Python/Unit/Python3InstalledTests.cs +++ b/LoadModules.Extensions.Tests/Python/Unit/Python3InstalledTests.cs @@ -15,13 +15,15 @@ public class Python3InstalledTests [SetUp] public void IsPython3Installed() { - PythonDataProvider p = new PythonDataProvider(); - p.Version = PythonVersion.Version3; + var p = new PythonDataProvider + { + Version = PythonVersion.Version3 + }; try { - string version = p.GetPythonVersion(); + var version = p.GetPythonVersion(); - Console.WriteLine("Found python version:" + version); + Console.WriteLine($"Found python version:{version}"); } catch (Exception e) { @@ -35,15 +37,17 @@ public void IsPython3Installed() [Test] public void PythonScript_Version3_DodgySyntax() { - string MyPythonScript = @"print 'Hello World'"; + var MyPythonScript = @"print 'Hello World'"; File.Delete("Myscript.py"); File.WriteAllText("Myscript.py", MyPythonScript); - PythonDataProvider provider = new PythonDataProvider(); - provider.Version = PythonVersion.Version3; - provider.FullPathToPythonScriptToRun = "Myscript.py"; - provider.MaximumNumberOfSecondsToLetScriptRunFor = 0; + var provider = new PythonDataProvider + { + Version = PythonVersion.Version3, + FullPathToPythonScriptToRun = "Myscript.py", + MaximumNumberOfSecondsToLetScriptRunFor = 0 + }; //call with accept all provider.Check(new AcceptAllCheckNotifier()); @@ -57,15 +61,17 @@ public void PythonScript_Version3_DodgySyntax() [Test] public void PythonScript_ValidScript() { - string MyPythonScript = @"print (""Hello World"")"; + var MyPythonScript = @"print (""Hello World"")"; File.Delete("Myscript.py"); File.WriteAllText("Myscript.py", MyPythonScript); - PythonDataProvider provider = new PythonDataProvider(); - provider.Version = PythonVersion.Version3; - provider.FullPathToPythonScriptToRun = "Myscript.py"; - provider.MaximumNumberOfSecondsToLetScriptRunFor = 0; + var provider = new PythonDataProvider + { + Version = PythonVersion.Version3, + FullPathToPythonScriptToRun = "Myscript.py", + MaximumNumberOfSecondsToLetScriptRunFor = 0 + }; //call with accept all provider.Check(new AcceptAllCheckNotifier()); diff --git a/LoadModules.Extensions.Tests/Python/Unit/PythonNotInstalledTests.cs b/LoadModules.Extensions.Tests/Python/Unit/PythonNotInstalledTests.cs index 5c41cac..a482ba6 100644 --- a/LoadModules.Extensions.Tests/Python/Unit/PythonNotInstalledTests.cs +++ b/LoadModules.Extensions.Tests/Python/Unit/PythonNotInstalledTests.cs @@ -21,12 +21,12 @@ public void PythonIsNotInstalled(PythonVersion version) Version = version }; - var ex = Assert.Throws(()=>provider.Check(new ThrowImmediatelyCheckNotifier())); + var ex = Assert.Throws(()=>provider.Check(ThrowImmediatelyCheckNotifier.Quiet)); Assert.IsTrue(ex?.Message.Contains("Failed to launch")); } - private void InconclusiveIfPythonIsInstalled(PythonVersion version) + private static void InconclusiveIfPythonIsInstalled(PythonVersion version) { var provider = new PythonDataProvider { diff --git a/LoadModules.Extensions.Tests/Python/Unit/TestsThatWorkRegardless.cs b/LoadModules.Extensions.Tests/Python/Unit/TestsThatWorkRegardless.cs index 8d09665..08bf69b 100644 --- a/LoadModules.Extensions.Tests/Python/Unit/TestsThatWorkRegardless.cs +++ b/LoadModules.Extensions.Tests/Python/Unit/TestsThatWorkRegardless.cs @@ -12,9 +12,9 @@ public class TestsThatWorkRegardless [Test] public void PythonVersionNotSetYet() { - PythonDataProvider provider = new PythonDataProvider(); - var ex = Assert.Throws(()=>provider.Check(new ThrowImmediatelyCheckNotifier())); - Assert.AreEqual("Version of Python required for script has not been selected",ex.Message); + var provider = new PythonDataProvider(); + var ex = Assert.Throws(()=>provider.Check(ThrowImmediatelyCheckNotifier.Quiet)); + Assert.AreEqual("Version of Python required for script has not been selected",ex?.Message); } @@ -22,22 +22,24 @@ public void PythonVersionNotSetYet() [Test] public void PythonScript_OverrideExecutablePath_FileDoesntExist() { - string MyPythonScript = @"s = raw_input ('==>')"; + var MyPythonScript = @"s = raw_input ('==>')"; var py = Path.Combine(TestContext.CurrentContext.WorkDirectory, "Myscript.py"); File.Delete(py); File.WriteAllText(py, MyPythonScript); - PythonDataProvider provider = new PythonDataProvider(); - provider.Version = PythonVersion.Version2; - provider.FullPathToPythonScriptToRun = py; - provider.MaximumNumberOfSecondsToLetScriptRunFor = 5; - provider.OverridePythonExecutablePath = new FileInfo(@"C:\fishmongers\python"); + var provider = new PythonDataProvider + { + Version = PythonVersion.Version2, + FullPathToPythonScriptToRun = py, + MaximumNumberOfSecondsToLetScriptRunFor = 5, + OverridePythonExecutablePath = new FileInfo(@"C:\fishmongers\python") + }; //call with accept all var ex = Assert.Throws(()=>provider.Check(new AcceptAllCheckNotifier())); - StringAssert.Contains(@"The specified OverridePythonExecutablePath:C:\fishmongers\python does not exist",ex.Message); + StringAssert.Contains(@"The specified OverridePythonExecutablePath:C:\fishmongers\python does not exist",ex?.Message); } diff --git a/LoadModules.Extensions.sln b/LoadModules.Extensions.sln index e3eff55..33dd0d0 100644 --- a/LoadModules.Extensions.sln +++ b/LoadModules.Extensions.sln @@ -43,6 +43,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "main", "Plugin\main\main.cs EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "windows", "Plugin\windows\windows.csproj", "{07F9F874-1306-4FE6-A03F-A483592BBC7F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rdmp.Core", "RDMP\Rdmp.Core\Rdmp.Core.csproj", "{8A840E89-4825-4F3C-B822-6EF946DC9B99}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Rdmp.UI", "RDMP\Rdmp.UI\Rdmp.UI.csproj", "{60721BCE-E328-45CF-B6D2-B627364FBBFA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.Common", "RDMP\Tests.Common\Tests.Common.csproj", "{9C2B07F4-2996-44BE-8067-7AA94C448A23}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -115,6 +121,30 @@ Global {07F9F874-1306-4FE6-A03F-A483592BBC7F}.Release|Any CPU.Build.0 = Release|Any CPU {07F9F874-1306-4FE6-A03F-A483592BBC7F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {07F9F874-1306-4FE6-A03F-A483592BBC7F}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Release|Any CPU.Build.0 = Release|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {8A840E89-4825-4F3C-B822-6EF946DC9B99}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Release|Any CPU.Build.0 = Release|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {60721BCE-E328-45CF-B6D2-B627364FBBFA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Release|Any CPU.Build.0 = Release|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9C2B07F4-2996-44BE-8067-7AA94C448A23}.Release|Mixed Platforms.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Plugin/main/main.csproj b/Plugin/main/main.csproj index 72b9cde..2949d94 100644 --- a/Plugin/main/main.csproj +++ b/Plugin/main/main.csproj @@ -6,7 +6,6 @@ Copyright © 2019 - diff --git a/Python/LoadModules.Extensions.Python/DataProvider/PythonDataProvider.cs b/Python/LoadModules.Extensions.Python/DataProvider/PythonDataProvider.cs index 6e5edcb..4b5796b 100644 --- a/Python/LoadModules.Extensions.Python/DataProvider/PythonDataProvider.cs +++ b/Python/LoadModules.Extensions.Python/DataProvider/PythonDataProvider.cs @@ -192,8 +192,10 @@ private int ExecuteProcess(IDataLoadEventListener listener, ProcessStartInfo pro try { - p = new Process(); - p.StartInfo = processStartInfo; + p = new Process + { + StartInfo = processStartInfo + }; p.OutputDataReceived += (s, e) => allOutputDataConsumed = OutputDataReceived(s, e, listener,false); p.ErrorDataReceived += (s, e) => allErrorDataConsumed = OutputDataReceived(s, e, listener,true); diff --git a/Python/LoadModules.Extensions.Python/LoadModules.Extensions.Python.csproj b/Python/LoadModules.Extensions.Python/LoadModules.Extensions.Python.csproj index 1f0dd5e..390b620 100644 --- a/Python/LoadModules.Extensions.Python/LoadModules.Extensions.Python.csproj +++ b/Python/LoadModules.Extensions.Python/LoadModules.Extensions.Python.csproj @@ -12,6 +12,6 @@ - + \ No newline at end of file diff --git a/RDMP b/RDMP new file mode 160000 index 0000000..54be368 --- /dev/null +++ b/RDMP @@ -0,0 +1 @@ +Subproject commit 54be36839b5c8c840bf12a38d50f1cca2bbf2acd diff --git a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/LoadModules.Extensions.ReleasePlugins.csproj b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/LoadModules.Extensions.ReleasePlugins.csproj index 1d9f1d8..7223c98 100644 --- a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/LoadModules.Extensions.ReleasePlugins.csproj +++ b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/LoadModules.Extensions.ReleasePlugins.csproj @@ -29,9 +29,11 @@ - + + + \ No newline at end of file diff --git a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/NotifyEventArgsProxy.cs b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/NotifyEventArgsProxy.cs index 4dde4a0..d67f98d 100644 --- a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/NotifyEventArgsProxy.cs +++ b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/NotifyEventArgsProxy.cs @@ -1,11 +1,10 @@ -using System; -using Rdmp.Core.ReusableLibraryCode.Progress; +using Rdmp.Core.ReusableLibraryCode.Progress; namespace LoadModules.Extensions.ReleasePlugins.Data; public class NotifyEventArgsProxy : NotifyEventArgs { - public NotifyEventArgsProxy() : base(ProgressEventType.Information, String.Empty, null) + public NotifyEventArgsProxy() : base(ProgressEventType.Information, string.Empty, null) { } } \ No newline at end of file diff --git a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPDataReleaseDestination.cs b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPDataReleaseDestination.cs index 771bc4f..90aca5c 100644 --- a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPDataReleaseDestination.cs +++ b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPDataReleaseDestination.cs @@ -35,8 +35,8 @@ public ReleaseAudit ProcessPipelineData(ReleaseAudit releaseAudit, IDataLoadEven releaseAudit.ReleaseFolder = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"))); if (!releaseAudit.ReleaseFolder.Exists) releaseAudit.ReleaseFolder.Create(); - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "No destination folder specified! Did you forget to introduce and initialize the ReleaseFolderProvider in the pipeline? " + - "The release output will be located in " + releaseAudit.ReleaseFolder.FullName)); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, + $"No destination folder specified! Did you forget to introduce and initialize the ReleaseFolderProvider in the pipeline? The release output will be located in {releaseAudit.ReleaseFolder.FullName}")); } if (_releaseData.ReleaseState == ReleaseState.DoingPatch) @@ -58,7 +58,8 @@ public ReleaseAudit ProcessPipelineData(ReleaseAudit releaseAudit, IDataLoadEven } } - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Deleted " + recordsDeleted + " old CumulativeExtractionResults (That were not included in the final Patch you are preparing)")); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"Deleted {recordsDeleted} old CumulativeExtractionResults (That were not included in the final Patch you are preparing)")); } _remoteRDMPReleaseEngineengine = new RemoteRDMPReleaseEngine(_project, RDMPReleaseSettings, listener, releaseAudit.ReleaseFolder); @@ -85,7 +86,8 @@ public void Dispose(IDataLoadEventListener listener, Exception pipelineFailureEx } if (remnantsDeleted > 0) - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Because release failed we are deleting ReleaseLogEntries, this resulted in " + remnantsDeleted + " deleted records, you will likely need to re-extract these datasets")); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"Because release failed we are deleting ReleaseLogEntries, this resulted in {remnantsDeleted} deleted records, you will likely need to re-extract these datasets")); } catch (Exception e1) { @@ -96,7 +98,8 @@ public void Dispose(IDataLoadEventListener listener, Exception pipelineFailureEx if (pipelineFailureExceptionIfAny == null) { - listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Data release succeded into: " + RDMPReleaseSettings.RemoteRDMP.Name)); + listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"Data release succeded into: {RDMPReleaseSettings.RemoteRDMP.Name}")); // we can freeze the configuration now: foreach (var config in _configurationReleased) @@ -132,15 +135,15 @@ public void Check(ICheckNotifier notifier) private string GetSafeHavenFolder(string masterTicket) { - if (String.IsNullOrWhiteSpace(masterTicket)) - return "Proj-" + _project.ProjectNumber; + if (string.IsNullOrWhiteSpace(masterTicket)) + return $"Proj-{_project.ProjectNumber}"; var catalogueRepository = _project.DataExportRepository.CatalogueRepository; var factory = new TicketingSystemFactory(catalogueRepository); var system = factory.CreateIfExists(catalogueRepository.GetTicketingSystem()); if (system == null) - return String.Empty; + return string.Empty; return system.GetProjectFolderName(masterTicket).Replace("/", ""); } diff --git a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPReleaseEngine.cs b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPReleaseEngine.cs index 59dd627..c3d7f31 100644 --- a/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPReleaseEngine.cs +++ b/ReleasePlugins/LoadModules.Extensions.ReleasePlugins/RemoteRDMPReleaseEngine.cs @@ -35,7 +35,7 @@ public override void DoRelease(Dictionary\"" + fullPrintPath.Replace('\\', '/') + "\""; + var command = + $"--vanilla --default-packages={DefaultPackages} \"{FullPathToRScript.FullName.Replace('\\', '/')}\" {InputDatabase.Server} {InputDatabase.Database} {_dbInfo.Server} {_dbInfo.GetRuntimeName()} \"{actualOutputDir.TrimEnd('\\').Replace('\\', '/')}/\" >\"{fullPrintPath.Replace('\\', '/')}\""; - var info = new ProcessStartInfo(rscriptFullPath); - info.Arguments = command; + var info = new ProcessStartInfo(rscriptFullPath) + { + Arguments = command + }; return info; } private string GetConnectionString(DiscoveredDatabase db) { - return String.Format("Server={0};Database={1};IntegratedSecurity=true;DRIVER=SQL Server", db.Server.Name, db.GetRuntimeName()); + return string.Format("Server={0};Database={1};IntegratedSecurity=true;DRIVER=SQL Server", db.Server.Name, db.GetRuntimeName()); } private string GetConnectionString(ExternalDatabaseServer db) { - return String.Format("Server={0};Database={1};IntegratedSecurity=true;DRIVER=SQL Server", db.Server, db.Database); + return string.Format("Server={0};Database={1};IntegratedSecurity=true;DRIVER=SQL Server", db.Server, db.Database); } private string CreateActualOutputDir(string scriptFileName) { var timeStampString = DateTime.Now.ToString("yyyyMMddTHHmmss"); - var dir = Path.Combine(OutputDirectory.FullName, timeStampString + "_" + scriptFileName); + var dir = Path.Combine(OutputDirectory.FullName, $"{timeStampString}_{scriptFileName}"); try { diff --git a/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/Attachers/SasAttacher.cs b/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/Attachers/SasAttacher.cs index 1c5ef88..306125e 100644 --- a/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/Attachers/SasAttacher.cs +++ b/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/Attachers/SasAttacher.cs @@ -38,17 +38,21 @@ public override void Check(ICheckNotifier notifier) try { if (!SASRootDirectory.Exists) - throw new DirectoryNotFoundException("The specified SAS root directory: " + SASRootDirectory.FullName + " does not exist"); + throw new DirectoryNotFoundException( + $"The specified SAS root directory: {SASRootDirectory.FullName} does not exist"); var fullPathToSasExe = Path.Combine(SASRootDirectory.FullName, "sas.exe"); if (!File.Exists(fullPathToSasExe)) - throw new FileNotFoundException("The specified SAS root directory: " + SASRootDirectory.FullName + " does not contain sas.exe"); + throw new FileNotFoundException( + $"The specified SAS root directory: {SASRootDirectory.FullName} does not contain sas.exe"); if (!FullPathToSASScript.Exists) - throw new FileNotFoundException("The specified SAS script to run: " + FullPathToSASScript.FullName + " does not exist"); + throw new FileNotFoundException( + $"The specified SAS script to run: {FullPathToSASScript.FullName} does not exist"); if (!OutputDirectory.Exists) - throw new DirectoryNotFoundException("The specified output directory: " + OutputDirectory.FullName + " does not exist"); + throw new DirectoryNotFoundException( + $"The specified output directory: {OutputDirectory.FullName} does not exist"); } catch (Exception e) { @@ -75,7 +79,8 @@ public override ExitCodeType Attach(IDataLoadJob job, GracefulCancellationToken return ExitCodeType.Error; } - job.OnNotify(this, new NotifyEventArgs(exitCode == 0 ? ProgressEventType.Information : ProgressEventType.Error, "SAS script terminated with exit code " + exitCode)); + job.OnNotify(this, new NotifyEventArgs(exitCode == 0 ? ProgressEventType.Information : ProgressEventType.Error, + $"SAS script terminated with exit code {exitCode}")); return exitCode == 0 ? ExitCodeType.Success : ExitCodeType.Error; } @@ -90,16 +95,20 @@ private int ExecuteProcess(ProcessStartInfo processStartInfo, int scriptTimeout, Process p; try { - p = new Process(); - p.StartInfo = processStartInfo; + p = new Process + { + StartInfo = processStartInfo + }; - job.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "commandline: " + processStartInfo.Arguments)); + job.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, + $"commandline: {processStartInfo.Arguments}")); p.Start(); } catch (Exception e) { - throw new Exception("Failed to launch:" + Environment.NewLine + processStartInfo.FileName + Environment.NewLine + " with Arguments:" + processStartInfo.Arguments, e); + throw new Exception( + $"Failed to launch:{Environment.NewLine}{processStartInfo.FileName}{Environment.NewLine} with Arguments:{processStartInfo.Arguments}", e); } var startTime = DateTime.Now; @@ -118,7 +127,8 @@ private int ExecuteProcess(ProcessStartInfo processStartInfo, int scriptTimeout, killed = false; } - throw new TimeoutException("Process command " + processStartInfo.FileName + " with arguments " + processStartInfo.Arguments + " did not complete after " + scriptTimeout + " seconds " + (killed ? "(After timeout we killed the process successfully)" : "(We also failed to kill the process after the timeout expired)")); + throw new TimeoutException( + $"Process command {processStartInfo.FileName} with arguments {processStartInfo.Arguments} did not complete after {scriptTimeout} seconds {(killed ? "(After timeout we killed the process successfully)" : "(We also failed to kill the process after the timeout expired)")}"); } } @@ -139,22 +149,19 @@ private ProcessStartInfo CreateCommand() var actualOutputDir = CreateActualOutputDir(scriptFileName); var sasFullPath = Path.Combine(SASRootDirectory.FullName, "sas.exe"); - var fullPrintPath = Path.Combine(actualOutputDir, scriptFileName + ".out"); - var fullLogPath = Path.Combine(actualOutputDir, scriptFileName + ".log"); + var fullPrintPath = Path.Combine(actualOutputDir, $"{scriptFileName}.out"); + var fullLogPath = Path.Combine(actualOutputDir, $"{scriptFileName}.log"); var dataInConnection = GetSASConnectionString(InputDatabase); var dataOutConnection = GetSASConnectionString(_dbInfo); - var command = "-set output \"" + actualOutputDir + "\"" + - " -set connect \"" + dataInConnection + "\"" + - " -set connectout \"" + dataOutConnection + "\"" + - " -sysin \"" + FullPathToSASScript.FullName + "\"" + - " -nosplash -noterminal -nostatuswin -noicon" + - " -print \"" + fullPrintPath + "\"" + - " -log \"" + fullLogPath + "\""; + var command = + $"-set output \"{actualOutputDir}\" -set connect \"{dataInConnection}\" -set connectout \"{dataOutConnection}\" -sysin \"{FullPathToSASScript.FullName}\" -nosplash -noterminal -nostatuswin -noicon -print \"{fullPrintPath}\" -log \"{fullLogPath}\""; - var info = new ProcessStartInfo(sasFullPath); - info.Arguments = command; + var info = new ProcessStartInfo(sasFullPath) + { + Arguments = command + }; return info; } @@ -172,7 +179,7 @@ private string GetSASConnectionString(ExternalDatabaseServer db) private string CreateActualOutputDir(string scriptFileName) { var timeStampString = DateTime.Now.ToString("yyyyMMddTHHmmss"); - var dir = Path.Combine(OutputDirectory.FullName, timeStampString + "_" + scriptFileName); + var dir = Path.Combine(OutputDirectory.FullName, $"{timeStampString}_{scriptFileName}"); try { diff --git a/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution.csproj b/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution.csproj index bd1be43..6c1758d 100644 --- a/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution.csproj +++ b/StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution/LoadModules.Extensions.StatsScriptsExecution.csproj @@ -10,6 +10,6 @@ - + \ No newline at end of file