diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8abd1b66..41507201 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [2.1.7] 2020-08-17
+
+### Fixed
+
+- Allow the PACS to send us lossy compressed versions if it wants, otherwise we won't be able to receive anything it has in that format
+
+### Added
+
+- Accept video (MPEG/HEVC) content if the PACS offers it
+- Added new cache source `ProcessBasedCacheSource` that calls out to a remote process
+
## [2.1.6] 2020-06-17
### Fixed
diff --git a/Packages.md b/Packages.md
index 916ed39f..425b02d5 100644
--- a/Packages.md
+++ b/Packages.md
@@ -10,4 +10,4 @@
| Package | Source Code | Version | License | Purpose | Additional Risk Assessment |
| ------- | ------------| --------| ------- | ------- | -------------------------- |
| HIC.DicomTypeTranslation | [GitHub](https://github.com/HicServices/DicomTypeTranslation) | [2.3.0](https://www.nuget.org/packages/HIC.DicomTypeTranslation/2.3.0) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Translate dicom types into C# / database types | |
-| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.4](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.4) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | |
+| HIC.RDMP.Plugin | [GitHub](https://github.com/HicServices/RDMP) | [4.1.7](https://www.nuget.org/packages/HIC.RDMP.Plugin/4.1.7) | [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.html) | Interact with RDMP objects, base classes for plugin components etc | |
diff --git a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj
index ce0afd5b..dc7d84b5 100644
--- a/Plugin/netcoreapp2.2/netcoreapp2.2.csproj
+++ b/Plugin/netcoreapp2.2/netcoreapp2.2.csproj
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/Rdmp.Dicom.Library.nuspec b/Rdmp.Dicom.Library.nuspec
index 00a39d1a..a7ed2a4e 100644
--- a/Rdmp.Dicom.Library.nuspec
+++ b/Rdmp.Dicom.Library.nuspec
@@ -14,7 +14,7 @@
Copyright 2018-2019
-
+
diff --git a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj
index da694188..dbd93a9b 100644
--- a/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj
+++ b/Rdmp.Dicom.Tests/Rdmp.Dicom.Tests.csproj
@@ -37,8 +37,8 @@
-
-
+
+
diff --git a/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs
new file mode 100644
index 00000000..231834b5
--- /dev/null
+++ b/Rdmp.Dicom.Tests/TestProcessBasedCacheSource.cs
@@ -0,0 +1,80 @@
+using MapsDirectlyToDatabaseTable;
+using NUnit.Framework;
+using Rdmp.Core.Caching.Requests;
+using Rdmp.Core.Caching.Requests.FetchRequestProvider;
+using Rdmp.Core.Curation;
+using Rdmp.Core.Curation.Data;
+using Rdmp.Core.Curation.Data.Cache;
+using Rdmp.Core.DataFlowPipeline;
+using Rdmp.Core.Startup;
+using Rdmp.Dicom.Cache.Pipeline;
+using ReusableLibraryCode.Checks;
+using ReusableLibraryCode.Progress;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Tests.Common;
+
+namespace Rdmp.Dicom.Tests
+{
+ class TestProcessBasedCacheSource : UnitTests
+ {
+ [Test]
+ public void TestWithEcho()
+ {
+ var source = new ProcessBasedCacheSource();
+
+ if(IsLinux)
+ {
+ source.Command = "/bin/echo";
+ source.Args = "Hey Thomas go get %s and store in %d";
+ }
+ else
+ {
+ source.Command = "cmd.exe";
+ source.Args = "/c echo Hey Thomas go get %s and store in %d";
+ }
+ source.TimeFormat = "dd/MM/yy";
+ source.ThrowOnNonZeroExitCode = true;
+
+ // What dates to load
+ var cp = WhenIHaveA();
+ cp.CacheFillProgress = new DateTime(2001,12,24);
+ cp.SaveToDatabase();
+
+ // Where to put files
+ var lmd = cp.LoadProgress.LoadMetadata;
+
+ var dir = new DirectoryInfo(TestContext.CurrentContext.WorkDirectory);
+ var loadDir = LoadDirectory.CreateDirectoryStructure(dir,"blah",true);
+
+ lmd.LocationOfFlatFiles = loadDir.RootPath.FullName;
+ lmd.SaveToDatabase();
+
+ source.PreInitialize(new CacheFetchRequestProvider(cp), new ThrowImmediatelyDataLoadEventListener());
+ source.PreInitialize(cp.CatalogueRepository,new ThrowImmediatelyDataLoadEventListener());
+ source.PreInitialize(new PermissionWindow(cp.CatalogueRepository),new ThrowImmediatelyDataLoadEventListener());
+
+ var toMem = new ToMemoryDataLoadEventListener(true);
+ var fork = new ForkDataLoadEventListener(toMem,new ThrowImmediatelyDataLoadEventListener(){WriteToConsole = true});
+
+ source.GetChunk(fork,new GracefulCancellationToken());
+
+ Assert.Contains($"Hey Thomas go get 24/12/01 and store in {Path.Combine(loadDir.Cache.FullName,"ALL")}",toMem.GetAllMessagesByProgressEventType()[ProgressEventType.Information].Select(v=>v.Message).ToArray());
+
+
+
+ }
+
+ public static bool IsLinux
+ {
+ get
+ {
+ int p = (int) Environment.OSVersion.Platform;
+ return (p == 4) || (p == 6) || (p == 128);
+ }
+ }
+ }
+}
diff --git a/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs b/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs
index 3944fedd..bec0968b 100644
--- a/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs
+++ b/Rdmp.Dicom.UI/CreateNewImagingDatasetUI.cs
@@ -51,23 +51,26 @@ private bool CreateDatabaseIfNotExists(DiscoveredDatabase db)
private void btnCreateSuiteWithTemplate_Click(object sender, EventArgs e)
{
- OpenFileDialog ofd = new OpenFileDialog();
- ofd.Filter = "Imaging Template|*.it";
+ string filename;
+ using (OpenFileDialog ofd = new OpenFileDialog()
+ {
+ Filter = "Imaging Template|*.it"
+ })
+ {
+ if (ofd.ShowDialog() != DialogResult.OK)
+ return;
+ filename = ofd.FileName;
+ }
- if (ofd.ShowDialog() == DialogResult.OK)
+ try
+ {
+ var yaml = File.ReadAllText(filename);
+ var template = ImageTableTemplateCollection.LoadFrom(yaml);
+ CreateSuite(template);
+ }
+ catch (Exception exception)
{
- try
- {
- var yaml = File.ReadAllText(ofd.FileName);
-
- var template = ImageTableTemplateCollection.LoadFrom(yaml);
-
- CreateSuite(template);
- }
- catch (Exception exception)
- {
- ExceptionViewer.Show(exception);
- }
+ ExceptionViewer.Show(exception);
}
}
@@ -78,17 +81,19 @@ private void CreateSuite(ImageTableTemplateCollection template)
if (!CreateDatabaseIfNotExists(db))
return;
-
- FolderBrowserDialog dialog = new FolderBrowserDialog();
- DirectoryInfo dir = null;
- dialog.Description = "Select Project Directory (For Sql scripts/Executables etc)";
- //if we are creating a load we need to know where to store load scripts etc
- if(cbCreateLoad.Checked)
- if (dialog.ShowDialog() == DialogResult.OK)
- dir = new DirectoryInfo(dialog.SelectedPath);
- else
- return;
+ DirectoryInfo dir = null;
+ using (FolderBrowserDialog dialog = new FolderBrowserDialog() {
+ Description = "Select Project Directory (For Sql scripts/Executables etc)"
+ })
+ {
+ //if we are creating a load we need to know where to store load scripts etc
+ if (cbCreateLoad.Checked)
+ if (dialog.ShowDialog() == DialogResult.OK)
+ dir = new DirectoryInfo(dialog.SelectedPath);
+ else
+ return;
+ }
var cmd = new ExecuteCommandCreateNewImagingDatasetSuite(_activator.RepositoryLocator, db,dir);
cmd.DicomSourceType = rbJsonSources.Checked ? typeof(DicomDatasetCollectionSource) : typeof(DicomFileCollectionSource);
diff --git a/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj b/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj
index 9d8670be..174c5f80 100644
--- a/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj
+++ b/Rdmp.Dicom.UI/Rdmp.Dicom.UI.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/Rdmp.Dicom.UI/TagElevationXmlUI.cs b/Rdmp.Dicom.UI/TagElevationXmlUI.cs
index c1d7dbc8..78dc168e 100644
--- a/Rdmp.Dicom.UI/TagElevationXmlUI.cs
+++ b/Rdmp.Dicom.UI/TagElevationXmlUI.cs
@@ -84,7 +84,7 @@ private void RunChecks()
try
{
- var collection = new TagElevationRequestCollection(queryEditor.Text);
+ new TagElevationRequestCollection(queryEditor.Text);
RagSmiley1.OnCheckPerformed(new CheckEventArgs("Succesfully created elevator",CheckResult.Success));
}
catch(Exception ex)
diff --git a/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs b/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs
index d31036bd..787c4770 100644
--- a/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs
+++ b/Rdmp.Dicom/Attachers/Routing/AutoRoutingAttacher.cs
@@ -5,7 +5,6 @@
using System.Linq;
using System.Text.RegularExpressions;
using FAnsi.Implementations.MySql;
-using MySql.Data.MySqlClient;
using Rdmp.Core.Curation.Data;
using Rdmp.Core.Curation.Data.DataLoad;
using Rdmp.Core.Curation.Data.Pipelines;
@@ -171,9 +170,6 @@ public IPipelineUseCase GetDesignTimePipelineUseCase(RequiredPropertyInfo proper
#region Process Results Of Pipeline Read
public DataTable ProcessPipelineData(DataTable toProcess, IDataLoadEventListener listener,GracefulCancellationToken cancellationToken)
{
-
- //todo: This really shouldn't be needed surely
- MySqlConnection.ClearAllPools();
MySqlBulkCopy.BulkInsertBatchTimeoutInSeconds = int.MaxValue; //forever
_sw.Start();
diff --git a/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs b/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs
index a049e66e..931c72d4 100644
--- a/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs
+++ b/Rdmp.Dicom/Cache/Pipeline/CachingSCP.cs
@@ -27,6 +27,23 @@ public class CachingSCP : DicomService, IDicomServiceProvider, IDicomCStoreProvi
DicomTransferSyntax.JPEGProcess14SV1,
DicomTransferSyntax.JPEGProcess14,
DicomTransferSyntax.RLELossless,
+
+ // Lossy - if that's all the PACS has, that's all it can give us
+ DicomTransferSyntax.JPEGLSNearLossless,
+ DicomTransferSyntax.JPEG2000Lossy,
+ DicomTransferSyntax.JPEGProcess1,
+ DicomTransferSyntax.JPEGProcess2_4,
+
+ // Also allow video files, just in case
+ DicomTransferSyntax.HEVCH265Main10ProfileLevel51,
+ DicomTransferSyntax.HEVCH265MainProfileLevel51,
+ DicomTransferSyntax.MPEG2,
+ DicomTransferSyntax.MPEG2MainProfileHighLevel,
+ DicomTransferSyntax.MPEG4AVCH264BDCompatibleHighProfileLevel41,
+ DicomTransferSyntax.MPEG4AVCH264HighProfileLevel41,
+ DicomTransferSyntax.MPEG4AVCH264HighProfileLevel42For2DVideo,
+ DicomTransferSyntax.MPEG4AVCH264HighProfileLevel42For3DVideo,
+ DicomTransferSyntax.MPEG4AVCH264StereoHighProfileLevel42,
// Uncompressed
DicomTransferSyntax.ExplicitVRLittleEndian,
diff --git a/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs b/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs
index 13a96f96..5330efa4 100644
--- a/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs
+++ b/Rdmp.Dicom/Cache/Pipeline/Dicom/DicomRequestSender.cs
@@ -70,7 +70,7 @@ public void ThrottleRequest(DicomClient client, CancellationToken cancellationTo
SendRequest(client,cancellationToken);
transferTimer.Stop();
//valuein mills
- var delay = ((int)(_dicomConfiguration.RequestDelayFactor * (1000 * transferTimer.Elapsed.Seconds)) + _dicomConfiguration.RequestCooldownInMilliseconds);
+ var delay = ((int)(_dicomConfiguration.RequestDelayFactor * (1000f * transferTimer.Elapsed.Seconds)) + _dicomConfiguration.RequestCooldownInMilliseconds);
if (delay > 0)
{
_listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Requests sleeping for " + delay / 1000 + "seconds"));
diff --git a/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs b/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs
index ff09f457..e40eaa99 100644
--- a/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs
+++ b/Rdmp.Dicom/Cache/Pipeline/Ordering/HierarchyBasedOrder.cs
@@ -411,10 +411,7 @@ public int Total()
{
foreach (var series in study.Series.Values)
{
- foreach (var image in series.Images.Values)
- {
- count++;
- }
+ count += series.Images.Values.Count;
}
}
}
diff --git a/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs
new file mode 100644
index 00000000..29e8b8c8
--- /dev/null
+++ b/Rdmp.Dicom/Cache/Pipeline/ProcessBasedCacheSource.cs
@@ -0,0 +1,106 @@
+using Rdmp.Core.Caching.Pipeline.Sources;
+using Rdmp.Core.Caching.Requests;
+using Rdmp.Core.Curation;
+using Rdmp.Core.Curation.Data;
+using Rdmp.Core.DataFlowPipeline;
+using ReusableLibraryCode.Checks;
+using ReusableLibraryCode.Progress;
+using System;
+using System.Diagnostics;
+
+namespace Rdmp.Dicom.Cache.Pipeline
+{
+ public class ProcessBasedCacheSource : CacheSource
+ {
+ [DemandsInitialization(@"Process to start (path only)",Mandatory = true)]
+ public string Command {get;set;}
+
+ [DemandsInitialization(@"Arguments to provide to the Process. Template with
+%s start time
+%e end time time to fetch
+%d directory to put files fetched
+Example:. './GetImages.exe ""%s"" ""%e%""'")]
+ public string Args {get;set;}
+
+ [DemandsInitialization("The datetime format for %s and %e.",Mandatory = true,DefaultValue = "yyyy-MM-dd HH:mm:ss")]
+ public string TimeFormat {get;set;}
+
+ [DemandsInitialization("True to throw an Exception if the process run returns a nonzero exit code", DefaultValue = true)]
+ public bool ThrowOnNonZeroExitCode {get;set;}
+
+ public override void Abort(IDataLoadEventListener listener)
+ {
+
+ }
+
+ public override void Check(ICheckNotifier notifier)
+ {
+
+ }
+
+ public override void Dispose(IDataLoadEventListener listener, Exception pipelineFailureExceptionIfAny)
+ {
+
+ }
+
+ public override SMIDataChunk DoGetChunk(ICacheFetchRequest request, IDataLoadEventListener listener, GracefulCancellationToken cancellationToken)
+ {
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,$"ProcessBasedCacheSource version is {typeof(ProcessBasedCacheSource).Assembly.GetName().Version}. Assembly is {typeof(ProcessBasedCacheSource).Assembly} " ));
+
+ // Where we are putting the files
+ var cacheDir = new LoadDirectory(Request.CacheProgress.LoadProgress.LoadMetadata.LocationOfFlatFiles).Cache;
+ var cacheLayout = new SMICacheLayout(cacheDir, new SMICachePathResolver("ALL"));
+
+ Chunk = new SMIDataChunk(Request)
+ {
+ FetchDate = Request.Start,
+ Modality = "ALL",
+ Layout = cacheLayout
+ };
+
+ var workingDirectory = cacheLayout.GetLoadCacheDirectory(listener);
+
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Working directory is:" + workingDirectory));
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch Start is:" + request.Start));
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Fetch End is:" + request.End));
+
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Command is:" + Command));
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Args template is:" + Args));
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Datetime format is:" + TimeFormat));
+
+
+ string args = Args
+ .Replace("%s",request.Start.ToString(TimeFormat))
+ .Replace("%e",request.End.ToString(TimeFormat))
+ .Replace("%d",workingDirectory.FullName);
+
+ listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,"Args resolved is:" + args));
+
+ using(var p = new Process())
+ {
+ p.StartInfo.FileName = Command;
+ p.StartInfo.Arguments = args;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.RedirectStandardOutput = true;
+ p.OutputDataReceived += (sender, a) => listener.OnNotify(this,new NotifyEventArgs(ProgressEventType.Information,a.Data));
+
+ p.Start();
+ p.BeginOutputReadLine();
+
+ p.WaitForExit();
+
+ listener.OnNotify(this,new NotifyEventArgs( p.ExitCode == 0 ? ProgressEventType.Information : ProgressEventType.Warning , "Process exited with code " + p.ExitCode));
+
+ if(p.ExitCode != 0 && ThrowOnNonZeroExitCode)
+ throw new Exception("Process exited with code " + p.ExitCode);
+ }
+
+ return Chunk;
+ }
+
+ public override SMIDataChunk TryGetPreview()
+ {
+ return null;
+ }
+ }
+}
diff --git a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs
index 31db50ba..4f811faf 100644
--- a/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs
+++ b/Rdmp.Dicom/CommandExecution/ExecuteCommandCreateNewImagingDatasetSuite.cs
@@ -113,9 +113,11 @@ bool createLoad
public override void Execute()
{
if (DicomSourceType == null)
+ {
SetImpossible("You must specify a Type for DicomSourceType");
+ throw new ImpossibleCommandException(this, ReasonCommandImpossible);
+ }
-
base.Execute();
List tablesCreated = new List();
@@ -258,12 +260,16 @@ private string GetNameWithPrefix(string name)
private void SetArgument(IArgument[] args, string property, object value)
{
+ if (value == null)
+ throw new ArgumentNullException(nameof(value));
+
var arg = args.Single(a => a.Name.Equals(property));
var mef = ((CatalogueRepository) arg.Repository).MEF;
- var found = mef.GetType(value.GetType().FullName);
+ if (mef.GetType(value.GetType().FullName) == null)
+ throw new ArgumentException($"No type found for { value.GetType().FullName }");
- //if this fails, look to see if found is null (indicates that your Type is not loaded by MEF). Look at mef.DescribeBadAssembliesIfAny() to investigate this issue
+ //if this fails, look to see if GetType returned null (indicates that your Type is not loaded by MEF). Look at mef.DescribeBadAssembliesIfAny() to investigate this issue
arg.SetValue(value);
arg.SaveToDatabase();
}
diff --git a/Rdmp.Dicom/Extraction/MappingRepository.cs b/Rdmp.Dicom/Extraction/MappingRepository.cs
index ae29b662..acdc3999 100644
--- a/Rdmp.Dicom/Extraction/MappingRepository.cs
+++ b/Rdmp.Dicom/Extraction/MappingRepository.cs
@@ -98,32 +98,34 @@ public void InsertMappings(UIDMapping[] newMappings)
var table = _database.ExpectTable(_tableName);
// Create data table
- var dt = new DataTable(_tableName);
- using (var conn = (SqlConnection) _server.GetConnection())
+ using (var dt = new DataTable(_tableName))
{
- conn.Open();
- var da = new SqlDataAdapter(table.GetTopXSql(0), conn);
- da.Fill(dt);
- }
+ using (var conn = (SqlConnection)_server.GetConnection())
+ {
+ conn.Open();
+ using (var da = new SqlDataAdapter(table.GetTopXSql(0), conn))
+ da.Fill(dt);
+ }
- // Fill up the data table
- foreach (var mapping in newMappings)
- {
- var row = dt.NewRow();
- row["PrivateUID"] = mapping.PrivateUID;
- row["ReleaseUID"] = mapping.ReleaseUID;
- row["ProjectNumber"] = mapping.ProjectNumber;
- row["UIDType"] = mapping.UIDType;
- row["IsExternalReference"] = mapping.IsExternalReference;
- dt.Rows.Add(row);
- }
+ // Fill up the data table
+ foreach (var mapping in newMappings)
+ {
+ var row = dt.NewRow();
+ row["PrivateUID"] = mapping.PrivateUID;
+ row["ReleaseUID"] = mapping.ReleaseUID;
+ row["ProjectNumber"] = mapping.ProjectNumber;
+ row["UIDType"] = mapping.UIDType;
+ row["IsExternalReference"] = mapping.IsExternalReference;
+ dt.Rows.Add(row);
+ }
- // Perform the bulk copy
- using (var conn = (SqlConnection) _server.GetConnection())
- {
- conn.Open();
- using (var bulkCopy = table.BeginBulkInsert())
- bulkCopy.Upload(dt);
+ // Perform the bulk copy
+ using (var conn = (SqlConnection)_server.GetConnection())
+ {
+ conn.Open();
+ using (var bulkCopy = table.BeginBulkInsert())
+ bulkCopy.Upload(dt);
+ }
}
}
diff --git a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs
index a2e5c7af..3ff63eba 100644
--- a/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs
+++ b/Rdmp.Dicom/PipelineComponents/DicomSources/DicomFileCollectionSource.cs
@@ -64,30 +64,33 @@ public override DataTable GetChunk(IDataLoadEventListener listener, GracefulCanc
if (!_fileWorklist.GetNextFileOrDirectoryToProcess(out directory, out file))
return null;
- if(file != null && directory == null)
- dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(file.FullPath));
- else if (directory != null)
- dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(directory.Name));
- else
+ // Exactly one of file/directory must be null:
+ if ((file!=null) == (directory!=null))
throw new Exception("Expected IDicomProcessListProvider to return either a DirectoryInfo or a FileInfo not both/neither");
-
- if(directory != null)
- {
- ProcessDirectoryAsync(dt, directory, listener);
- Task.WaitAll(tasks.ToArray());
- }
- else
- //Input is a single zip file
- if (file.FullPath.EndsWith(".zip"))
+
+ if (file != null)
{
- ProcessZipArchive(dt, listener, file.FullPath);
+ dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(file.FullPath));
+ if (file.FullPath.EndsWith(".zip"))
+ {
+ //Input is a single zip file
+ ProcessZipArchive(dt, listener, file.FullPath);
+ }
+ else
+ {
+ var df = file.GetDataset(_zipPool);
+ ProcessDataset(file.FullPath, df.Dataset, dt, listener);
+ }
}
- else
+
+ if (directory!=null)
{
- var df = file.GetDataset(_zipPool);
- ProcessDataset(file.FullPath, df.Dataset, dt, listener);
+ // Processing a directory
+ dt.TableName = QuerySyntaxHelper.MakeHeaderNameSensible(Path.GetFileNameWithoutExtension(directory.Name));
+ ProcessDirectoryAsync(dt, directory, listener);
+ Task.WaitAll(tasks.ToArray());
}
-
+
}
finally
{
diff --git a/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs b/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs
index 8c942b16..39fba540 100644
--- a/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs
+++ b/Rdmp.Dicom/PipelineComponents/PrimaryKeyCollisionIsolationMutilation.cs
@@ -60,10 +60,11 @@ public void Check(ICheckNotifier notifier)
//if there are multiple tables then we must know how to join them
if (TablesToIsolate.Length >1 && TablesToIsolate.Count(t => t.IsPrimaryExtractionTable) != 1)
{
+ var primaryTables = TablesToIsolate.Where(t => t.IsPrimaryExtractionTable).ToArray();
+
notifier.OnCheckPerformed(
new CheckEventArgs(
- "There are " + TablesToIsolate.Length +
- " tables to operate on but none are marked IsPrimaryExtractionTable. This should be set on the top level table e.g. Study",
+ $"There are {TablesToIsolate.Length} tables to operate on but {primaryTables.Length} are marked IsPrimaryExtractionTable ({string.Join(",",primaryTables.Select(t=>t.Name))}). This should be set on a single top level table only e.g. Study",
CheckResult.Fail));
}
diff --git a/Rdmp.Dicom/Rdmp.Dicom.csproj b/Rdmp.Dicom/Rdmp.Dicom.csproj
index e9a44202..63ef5a5f 100644
--- a/Rdmp.Dicom/Rdmp.Dicom.csproj
+++ b/Rdmp.Dicom/Rdmp.Dicom.csproj
@@ -26,6 +26,6 @@
-
+
diff --git a/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs b/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs
index 8ee231e0..b5563482 100644
--- a/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs
+++ b/Rdmp.Dicom/TagPromotionSchema/TagColumnAdder.cs
@@ -83,7 +83,7 @@ public void Check(ICheckNotifier notifier)
try
{
var cSharpType = db.Server.GetQuerySyntaxHelper().TypeTranslater.GetCSharpTypeForSQLDBType(_datatype);
- notifier.OnCheckPerformed(new CheckEventArgs("Datatype is compatible with TypeTranslater",CheckResult.Success));
+ notifier.OnCheckPerformed(new CheckEventArgs($"Datatype { _datatype } is compatible with TypeTranslater as { cSharpType }",CheckResult.Success));
}
catch (Exception ex)
{
diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs
index b0952eb9..15c35b7e 100644
--- a/SharedAssemblyInfo.cs
+++ b/SharedAssemblyInfo.cs
@@ -7,6 +7,6 @@
[assembly: AssemblyCulture("")]
// These should be replaced with correct values by the release process
-[assembly: AssemblyVersion("2.1.6")]
-[assembly: AssemblyFileVersion("2.1.6")]
-[assembly: AssemblyInformationalVersion("2.1.6")]
+[assembly: AssemblyVersion("2.1.7")]
+[assembly: AssemblyFileVersion("2.1.7")]
+[assembly: AssemblyInformationalVersion("2.1.7")]