コード例 #1
0
        public LiveVsTemplateComparer(ITableInfo table, ImageTableTemplateCollection templateCollection)
        {
            // locate the live table and script it as it stands today
            var discoveredTable = table.Discover(DataAccessContext.InternalDataProcessing);

            LiveSql = discoveredTable.ScriptTableCreation(false, false, false);

            LiveSql = TailorLiveSql(LiveSql, discoveredTable.Database.Server.DatabaseType);

            // The live table name e.g. CT_StudyTable
            var liveTableName = discoveredTable.GetRuntimeName();
            // Without the prefix e.g. StudyTable
            var liveTableNameWithoutPrefix = liveTableName.Substring(liveTableName.IndexOf("_", StringComparison.Ordinal) + 1);

            var template = templateCollection.Tables.FirstOrDefault(
                c => c.TableName.Equals(liveTableName, StringComparison.CurrentCultureIgnoreCase) ||
                c.TableName.Equals(liveTableNameWithoutPrefix, StringComparison.CurrentCultureIgnoreCase));

            if (template == null)
            {
                throw new Exception($"Could not find a Template called '{liveTableName}' or '{liveTableNameWithoutPrefix}'.  Templates in file were {string.Join(",",templateCollection.Tables.Select(t=>t.TableName))}");
            }

            //script the template
            var creator = new ImagingTableCreation(discoveredTable.Database.Server.GetQuerySyntaxHelper());

            TemplateSql = creator.GetCreateTableSql(discoveredTable.Database, liveTableName, template, discoveredTable.Schema);

            TemplateSql = TailorTemplateSql(TemplateSql);
        }
コード例 #2
0
        private void btnCreateSuiteWithTemplate_Click(object sender, EventArgs e)
        {
            string filename;

            using (OpenFileDialog ofd = new OpenFileDialog
            {
                Filter = "Imaging Template|*.it"
            })
            {
                if (ofd.ShowDialog() != DialogResult.OK)
                {
                    return;
                }
                filename = ofd.FileName;
            }

            try
            {
                var yaml     = File.ReadAllText(filename);
                var template = ImageTableTemplateCollection.LoadFrom(yaml);
                CreateSuite(template);
            }
            catch (Exception exception)
            {
                ExceptionViewer.Show(exception);
            }
        }
コード例 #3
0
        private ImageTableTemplateCollection GetDefaultTemplate(FAnsi.DatabaseType databaseType)
        {
            var collection = ImageTableTemplateCollection.LoadFrom(DefaultTemplateYaml);

            collection.DatabaseType = databaseType;
            return(collection);
        }
コード例 #4
0
        public void TestLargeImageDatasets(DatabaseType databaseType, int numberOfImages)
        {
            foreach (Pipeline p in CatalogueRepository.GetAllObjects <Pipeline>())
            {
                p.DeleteInDatabase();
            }

            var db = GetCleanedServer(databaseType);

            var d = CatalogueRepository.GetServerDefaults();

            d.ClearDefault(PermissableDefaults.RAWDataLoadServer);

            var template = ImageTableTemplateCollection.LoadFrom(_templateXml);

            _globals = new GlobalOptionsFactory().Load();

            _globals.DicomRelationalMapperOptions.DatabaseNamerType            = typeof(MyFixedStagingDatabaseNamer).FullName;
            _globals.DicomRelationalMapperOptions.QoSPrefetchCount             = ushort.MaxValue;
            _globals.DicomRelationalMapperOptions.MinimumBatchSize             = numberOfImages;
            _globals.DicomRelationalMapperOptions.UseInsertIntoForRAWMigration = true;

            _helper = new DicomRelationalMapperTestHelper();
            _helper.SetupSuite(db, RepositoryLocator, _globals, typeof(DicomDatasetCollectionSource), root: null, template: template, persistentRaw: true);

            //do not use an explicit RAW data load server
            d.ClearDefault(PermissableDefaults.RAWDataLoadServer);

            Random r = new Random(123);

            List <DicomDataset> allImages;

            using (var generator = new DicomDataGenerator(r, null, "CT"))
                allImages = generator.GenerateImages(numberOfImages, r);

            Assert.AreEqual(numberOfImages, allImages.Count);

            using (var tester = new MicroserviceTester(_globals.RabbitOptions, _globals.DicomRelationalMapperOptions))
            {
                using (var host = new DicomRelationalMapperHost(_globals))
                {
                    tester.SendMessages(_globals.DicomRelationalMapperOptions, allImages.Select(GetFileMessageForDataset), true);

                    Console.WriteLine("Starting Host");
                    host.Start();

                    Stopwatch sw = Stopwatch.StartNew();
                    new TestTimelineAwaiter().Await(() => host.Consumer.AckCount == numberOfImages, null, 20 * 60 * 100); //1 minute

                    Console.Write("Time For DLE:" + sw.Elapsed.TotalSeconds + "s");
                    host.Stop("Test finished");
                }
            }

            foreach (Pipeline allObject in CatalogueRepository.GetAllObjects <Pipeline>())
            {
                allObject.DeleteInDatabase();
            }
        }
コード例 #5
0
        private void CreateSuite(ImageTableTemplateCollection template)
        {
            var db = serverDatabaseTableSelector1.GetDiscoveredDatabase();

            if (!CreateDatabaseIfNotExists(db))
            {
                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)
            {
                DicomSourceType = rbJsonSources.Checked
                    ? typeof(DicomDatasetCollectionSource)
                    : typeof(DicomFileCollectionSource),
                CreateCoalescer = cbMergeNullability.Checked,
                CreateLoad      = cbCreateLoad.Checked,
                TablePrefix     = tbPrefix.Text,
                Template        = template
            };

            cmd.Execute();

            var firstCata = cmd.NewCataloguesCreated.First();

            if (firstCata != null)
            {
                _activator.Publish(firstCata);
            }

            MessageBox.Show("Create Suite Completed");
        }
        public ExecuteCommandCreateNewImagingDatasetSuite(
            IRDMPPlatformRepositoryServiceLocator repositoryLocator,
            DiscoveredDatabase databaseToCreateInto,
            DirectoryInfo projectDirectory,

            [DemandsInitialization("The pipeline source for reading dicom tags from e.g. from files or from serialized JSON", TypeOf = typeof(DicomSource))]
            Type dicomSourceType,
            string tablePrefix,
            FileInfo templateFile,
            bool persistentRaw,
            bool createLoad
            ) : this(repositoryLocator, databaseToCreateInto, projectDirectory)
        {
            DicomSourceType = dicomSourceType ?? typeof(DicomFileCollectionSource);
            TablePrefix     = tablePrefix;
            Template        = ImageTableTemplateCollection.LoadFrom(File.ReadAllText(templateFile.FullName));
            PersistentRaw   = persistentRaw;
            CreateLoad      = createLoad;
        }
コード例 #7
0
        public override void Execute()
        {
            base.Execute();

            // Get the template for diff
            var file = Activator.SelectFile("Template File", "Imaging Template", "*.it");

            if (file == null)
            {
                return;
            }

            var templateCollection = ImageTableTemplateCollection.LoadFrom(File.ReadAllText(file.FullName));

            var comparer = new LiveVsTemplateComparer(_tableInfo, templateCollection);

            var viewer = new SQLBeforeAndAfterViewer(comparer.LiveSql, comparer.TemplateSql, "Your Database", "Template", "Differences between live table and image template", MessageBoxButtons.OK); // lgtm[cs/local-not-disposed]

            viewer.Show();
        }
コード例 #8
0
        private void btnCreateSuiteWithTemplate_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.Filter = "Imaging Template|*.it";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    var yaml = File.ReadAllText(ofd.FileName);

                    var template = ImageTableTemplateCollection.LoadFrom(yaml);

                    CreateSuite(template);
                }
                catch (Exception exception)
                {
                    ExceptionViewer.Show(exception);
                }
            }
        }
コード例 #9
0
        public void TestBulkInsertOnly(DatabaseType databaseType, int numberOfImages)
        {
            foreach (Pipeline p in CatalogueRepository.GetAllObjects <Pipeline>())
            {
                p.DeleteInDatabase();
            }

            var db = GetCleanedServer(databaseType);

            var template = ImageTableTemplateCollection.LoadFrom(_templateXml);

            _globals = new GlobalOptionsFactory().Load();

            _globals.DicomRelationalMapperOptions.DatabaseNamerType            = typeof(MyFixedStagingDatabaseNamer).FullName;
            _globals.DicomRelationalMapperOptions.QoSPrefetchCount             = ushort.MaxValue;
            _globals.DicomRelationalMapperOptions.MinimumBatchSize             = numberOfImages;
            _globals.DicomRelationalMapperOptions.UseInsertIntoForRAWMigration = true;

            _helper = new DicomRelationalMapperTestHelper();
            _helper.SetupSuite(db, RepositoryLocator, _globals, typeof(DicomDatasetCollectionSource), root: null, template: template, persistentRaw: true);

            //do not use an explicit RAW data load server
            CatalogueRepository.GetServerDefaults().ClearDefault(PermissableDefaults.RAWDataLoadServer);

            Random r = new Random(123);

            List <DicomDataset> allImages;

            using (var generator = new DicomDataGenerator(r, null, "CT"))
                allImages = generator.GenerateImages(numberOfImages, r);

            DicomDatasetCollectionSource source = new DicomDatasetCollectionSource();

            source.PreInitialize(new ExplicitListDicomDatasetWorklist(allImages.ToArray(), "amagad.dcm", new Dictionary <string, string>()
            {
                { "MessageGuid", "0x123" }
            }), new ThrowImmediatelyDataLoadEventListener());;
            source.FilenameField = "gggg";

            var dt = source.GetChunk(new ThrowImmediatelyDataLoadEventListener(), new GracefulCancellationToken());

            source.Dispose(new ThrowImmediatelyDataLoadEventListener()
            {
                WriteToConsole = true
            }, null);

            Assert.AreEqual(numberOfImages, allImages.Count);
            Assert.AreEqual(numberOfImages, dt.Rows.Count);

            var tables = _helper.LoadMetadata.GetDistinctTableInfoList(false);

            var config = new HICDatabaseConfiguration(_helper.LoadMetadata, new SuffixBasedNamer());

            var job = Mock.Of <IDataLoadJob>(
                j => j.RegularTablesToLoad == tables.Cast <ITableInfo>().ToList() &&
                j.DataLoadInfo == _dli &&
                j.Configuration == config);

            var attacher = new AutoRoutingAttacher();

            attacher.Job = job;

            //Drop Primary Keys
            using (var con = db.Server.GetConnection())
            {
                con.Open();

                var cmd = db.Server.GetCommand(
                    databaseType == DatabaseType.MicrosoftSQLServer ?
                    @"ALTER TABLE ImageTable DROP CONSTRAINT PK_ImageTable
                    ALTER TABLE SeriesTable DROP CONSTRAINT PK_SeriesTable
                    ALTER TABLE StudyTable DROP CONSTRAINT PK_StudyTable" :

                    @"ALTER TABLE ImageTable DROP PRIMARY KEY;
                    ALTER TABLE SeriesTable  DROP PRIMARY KEY;
                    ALTER TABLE StudyTable  DROP PRIMARY KEY;"
                    , con);

                cmd.ExecuteNonQuery();
            }

            attacher.Initialize(LoadDirectory.CreateDirectoryStructure(new DirectoryInfo(TestContext.CurrentContext.TestDirectory), "IgnoreMe", true), db);
            try
            {
                attacher.ProcessPipelineData(dt, new ThrowImmediatelyDataLoadEventListener(), new GracefulCancellationToken());
                attacher.Dispose(new ThrowImmediatelyDataLoadEventListener(), null);
            }
            catch (Exception e)
            {
                attacher.Dispose(new ThrowImmediatelyDataLoadEventListener(), e);
                throw;
            }

            foreach (var tableInfo in tables)
            {
                Assert.AreEqual(numberOfImages,
                                tableInfo.Discover(DataAccessContext.InternalDataProcessing).GetRowCount(),
                                "Row count was wrong for " + tableInfo);
            }

            foreach (Pipeline allObject in CatalogueRepository.GetAllObjects <Pipeline>())
            {
                allObject.DeleteInDatabase();
            }
        }
コード例 #10
0
        private static int RunDatabaseTarget(TargetDatabase configDatabase, ProgramOptions opts)
        {
            var batchSize = Math.Max(1, configDatabase.Batches);

            //if we are going into a database we definitely do not need pixels!
            if (opts.NoPixels == false)
            {
                opts.NoPixels = true;
            }


            Stopwatch swTotal = new Stopwatch();

            swTotal.Start();

            string neverDistinct = "SOPInstanceUID";

            if (!File.Exists(configDatabase.Template))
            {
                Console.WriteLine($"Listed template file '{configDatabase.Template}' does not exist");
                return(-1);
            }

            ImageTableTemplateCollection template;

            try
            {
                template = ImageTableTemplateCollection.LoadFrom(File.ReadAllText(configDatabase.Template));
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error reading yaml from '{configDatabase.Template}'");
                Console.WriteLine(e.ToString());
                return(-2);
            }

            ImplementationManager.Load <MySqlImplementation>();
            ImplementationManager.Load <PostgreSqlImplementation>();
            ImplementationManager.Load <OracleImplementation>();
            ImplementationManager.Load <MicrosoftSQLImplementation>();

            var server = new DiscoveredServer(configDatabase.ConnectionString, configDatabase.DatabaseType);

            try
            {
                server.TestConnection();
            }
            catch (Exception e)
            {
                Console.WriteLine($"Could not reach target server '{server.Name}'");
                Console.WriteLine(e);
                return(-2);
            }


            var db = server.ExpectDatabase(configDatabase.DatabaseName);

            if (!db.Exists())
            {
                Console.WriteLine($"Creating Database '{db.GetRuntimeName()}'");
                db.Create();
                Console.WriteLine("Database Created");
            }
            else
            {
                Console.WriteLine($"Found Database '{db.GetRuntimeName()}'");
            }

            var creator = new ImagingTableCreation(db.Server.GetQuerySyntaxHelper());

            Console.WriteLine($"Image template contained schemas for {template.Tables.Count} tables.  Looking for existing tables..");

            //setting up bulk inserters
            DiscoveredTable[] tables  = new DiscoveredTable[template.Tables.Count];
            DataTable[][]     batches = new DataTable[batchSize][];

            for (var i = 0; i < batches.Length; i++)
            {
                batches[i] = new DataTable[template.Tables.Count];
            }

            IBulkCopy[][] uploaders = new IBulkCopy[batchSize][];

            for (int i = 0; i < uploaders.Length; i++)
            {
                uploaders[i] = new IBulkCopy[template.Tables.Count];
            }

            string[] pks = new string[template.Tables.Count];

            for (var i = 0; i < template.Tables.Count; i++)
            {
                var tableSchema = template.Tables[i];
                var tbl         = db.ExpectTable(tableSchema.TableName);
                tables[i] = tbl;

                if (configDatabase.MakeDistinct)
                {
                    var col = tableSchema.Columns.Where(c => c.IsPrimaryKey).ToArray();

                    if (col.Length > 1)
                    {
                        Console.WriteLine("MakeDistinct only works with single column primary keys e.g. StudyInstanceUID / SeriesInstanceUID");
                    }

                    pks[i] = col.SingleOrDefault()?.ColumnName;

                    if (pks[i] != null)
                    {
                        //if it is sop instance uid then we shouldn't be trying to deduplicate
                        if (string.Equals(pks[i], neverDistinct, StringComparison.CurrentCultureIgnoreCase))
                        {
                            pks[i] = null;
                        }
                        else
                        {
                            //we will make this a primary key later on
                            col.Single().IsPrimaryKey = false;
                            Console.WriteLine($"MakeDistinct will apply to '{pks[i]}' on '{tbl.GetFullyQualifiedName()}'");
                        }
                    }
                }

                bool create = true;

                if (tbl.Exists())
                {
                    if (configDatabase.DropTables)
                    {
                        Console.WriteLine($"Dropping existing table '{tbl.GetFullyQualifiedName()}'");
                        tbl.Drop();
                    }
                    else
                    {
                        Console.WriteLine($"Table '{tbl.GetFullyQualifiedName()}' already existed (so will not be created)");
                        create = false;
                    }
                }

                if (create)
                {
                    Console.WriteLine($"About to create '{tbl.GetFullyQualifiedName()}'");
                    creator.CreateTable(tbl, tableSchema);
                    Console.WriteLine($"Successfully created create '{tbl.GetFullyQualifiedName()}'");
                }

                Console.WriteLine($"Creating uploader for '{tbl.GetRuntimeName()}''");

                for (int j = 0; j < batchSize; j++)
                {
                    //fetch schema
                    var dt = tbl.GetDataTable();
                    dt.Rows.Clear();

                    batches[j][i]   = dt;
                    uploaders[j][i] = tbl.BeginBulkInsert();
                }
            }
            var tasks = new Task[batchSize];

            IPersonCollection identifiers = GetPeople(opts, out Random r);

            for (int i = 0; i < batchSize; i++)
            {
                var batch = i;
                tasks[i] = new Task(() =>  // lgtm[cs/local-not-disposed]
                {
                    RunBatch(identifiers, opts, r, batches[batch], uploaders[batch]);
                });
                tasks[i].Start();
            }

            Task.WaitAll(tasks);

            swTotal.Stop();

            for (var i = 0; i < tables.Length; i++)
            {
                if (pks[i] == null)
                {
                    continue;
                }

                Console.WriteLine($"{DateTime.Now} Making table '{tables[i]}' distinct (this may take a long time)");
                var tbl = tables[i];
                tbl.MakeDistinct(500000000);

                Console.WriteLine($"{DateTime.Now} Creating primary key on '{tables[i]}' of '{pks[i]}'");
                tbl.CreatePrimaryKey(500000000, tbl.DiscoverColumn(pks[i]));
            }

            Console.WriteLine("Final Row Counts:");

            foreach (DiscoveredTable t in tables)
            {
                Console.WriteLine($"{t.GetFullyQualifiedName()}: {t.GetRowCount():0,0}");
            }

            Console.WriteLine("Total Running Time:" + swTotal.Elapsed);
            return(0);
        }
コード例 #11
0
        public void SetupSuite(DiscoveredDatabase databaseToCreateInto, IRDMPPlatformRepositoryServiceLocator repositoryLocator, GlobalOptions globalOptions, Type pipelineDicomSourceType, string root = null, ImageTableTemplateCollection template = null, bool persistentRaw = false, string modalityPrefix = null)
        {
            ImageTable  = databaseToCreateInto.ExpectTable(modalityPrefix + "ImageTable");
            SeriesTable = databaseToCreateInto.ExpectTable(modalityPrefix + "SeriesTable");
            StudyTable  = databaseToCreateInto.ExpectTable(modalityPrefix + "StudyTable");

            try
            {
                File.Copy(typeof(InvalidDataHandling).Assembly.Location, Path.Combine(TestContext.CurrentContext.TestDirectory, "Rdmp.Dicom.dll"), true);
            }
            catch (System.IO.IOException)
            {
                //nevermind, it's probably locked
            }


            //The Rdmp.Dicom assembly should be loaded as a plugin, this simulates it.
            foreach (var type in typeof(InvalidDataHandling).Assembly.GetTypes())
            {
                repositoryLocator.CatalogueRepository.MEF.AddTypeToCatalogForTesting(type);
            }


            ICatalogueRepository  catalogueRepository  = repositoryLocator.CatalogueRepository;
            IDataExportRepository dataExportRepository = repositoryLocator.DataExportRepository;

            foreach (var t in new[] { ImageTable, SeriesTable, StudyTable })
            {
                if (t.Exists())
                {
                    t.Drop();
                }
            }

            var suite = new ExecuteCommandCreateNewImagingDatasetSuite(repositoryLocator, databaseToCreateInto, new DirectoryInfo(TestContext.CurrentContext.TestDirectory));

            suite.Template = template ?? GetDefaultTemplate(databaseToCreateInto.Server.DatabaseType);

            suite.PersistentRaw = persistentRaw;
            suite.TablePrefix   = modalityPrefix;

            suite.DicomSourceType = pipelineDicomSourceType;
            suite.CreateCoalescer = true;

            suite.Execute();
            DicomSourcePipelineComponent = suite.DicomSourcePipelineComponent; //store the component created so we can inject/adjust the arguments e.g. adding ElevationRequests to it

            LoadMetadata = suite.NewLoadMetadata;


            var tableInfos = LoadMetadata.GetAllCatalogues().SelectMany(c => c.GetTableInfoList(false)).Distinct().ToArray();

            ImageTableInfo  = (TableInfo)tableInfos.Single(t => t.GetRuntimeName().Equals(ImageTable.GetRuntimeName()));
            SeriesTableInfo = (TableInfo)tableInfos.Single(t => t.GetRuntimeName().Equals(SeriesTable.GetRuntimeName()));
            StudyTableInfo  = (TableInfo)tableInfos.Single(t => t.GetRuntimeName().Equals(StudyTable.GetRuntimeName()));

            // Override the options with stuff coming from Core RDMP DatabaseTests (TestDatabases.txt)
            globalOptions.FileSystemOptions.FileSystemRoot = root ?? TestContext.CurrentContext.TestDirectory;

            globalOptions.RDMPOptions.CatalogueConnectionString  = ((TableRepository)catalogueRepository).DiscoveredServer.Builder.ConnectionString;
            globalOptions.RDMPOptions.DataExportConnectionString = ((TableRepository)dataExportRepository).DiscoveredServer.Builder.ConnectionString;

            globalOptions.DicomRelationalMapperOptions.LoadMetadataId               = LoadMetadata.ID;
            globalOptions.DicomRelationalMapperOptions.MinimumBatchSize             = 1;
            globalOptions.DicomRelationalMapperOptions.UseInsertIntoForRAWMigration = true;

            //Image table now needs all the UIDs in order to be extractable
            var adder = new TagColumnAdder("StudyInstanceUID", "varchar(100)", ImageTableInfo, new AcceptAllCheckNotifier());

            adder.Execute();
        }