Here are things you should know about RDMP!
- Other Docs
- Commands
- Objects
- Windows Forms Designer
- Icons and resx files
- Release Process
- Database Schema Changes
- Existing Plugins
All technical and repo specific documentation are stored in markdown (.md
format). Below is a list of docs in the repo. There is also a Confluence website which stores documentation on how to perform common user tasks
Code Tutorials
- Overview of RDMP Windows Client GUI application
- Getting started Coding RDMP
- How to create 'non database' CohortBuilder plugins e.g. to REST API
- How to add new tree items to RDMP windows GUI client
- How to add new right click context menu items
- How to add new 'drag and drop' and double click handlers
- Adding Localization (i.e. foreign language support)
- Adding new RDMP plugins
- How to write RDMP unit/integration tests
User Documentation
- Application Changelog
- Main landing page README
- Frequently Asked Questions
- User Manual
- Glossary
- RDMP DQE
- RDMP Command Line
- RDMP Command Line syntaxes
- RDMP upstream dependencies (libraries)
** Performance **
Deep Dives
- How untyped CSV data is parsed by RDMP
- How 'Bulk Insert' function works
- How xls / xlsx files are read by RDMP
- Multiple Linkage Columns (e.g. NHS Number or CHI)
- Storing cohort lists
- Cohort Builder docs including info on list caching
- Tree layout documentation
- Aggregate Graphs
- YamlRepository
- Custom Metadata Reports
The Design Pattern 'Command' is implemented in RDMP. Most functionality in RDMP is undertaken by a command and new features should be implemented as new commands if possible.
All commands implement IAtomicCommand
- it's a good place to start when diagnosing issues.
- If you want to see which command is running when an issue manifests in the windows UI you can use the menu item 'Diagnostics->Last Command Monitor'
- Commands have access to
IBasicActivateItems
which contains modal operations for illiciting user feedback. Bear in mind that some implementations do not support interactive content so always checkIBasicActivateItems.IsInteractive
- UI implementations are
IActivateItems
: windows gui clientConsoleInputManager
: CLI client. May be running in a scriptConsoleGuiActivator
: TUI user interface (cross platform - great for SSH/headless servers)TestActivateItems
: Implementation that can be used in UI tests
RDMP objects inherit from DatabaseEntity
. There are multiple types of IRepository
e.g YamlRepository, CatalogueRepository.
When there is a database backed object store (e.g. CatalogueRepository, DataExportRepository, DQERepository) then it is important
to load/save/create with the correct one. For example you cannot save an Project
to CatalogueRepository, only DataExportRepository.
If you want to see what repository type it is meant to be then look at the constructor e.g. public Project(IDataExportRepository repository, string name)
- In the GUI client if you are ever wondering what an object type is you can right click it and choose 'What is this?'
- All objects have a unique ID. The uniqueness is restricted to the
IRepository
it is in.
- Using the Windows Forms Designer requires renaming SelectedDialog`1.resx to SelectedDialog.resx first. Otherwise you get this bug: #1360
- If creating a new Control or Form you should consider inheriting from
RDMPSingleDatabaseObjectControl<T>
orRDMPUserControl
. If you do this make sure to declare an appropriateTypeDescriptionProvider
(see below). Otherwise it will not open in Designer.
[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<LoggingTab_Design, UserControl>))]
public abstract class LoggingTab_Design : RDMPSingleDatabaseObjectControl<YourSingleObjType>
{
}
In 2001 Microsoft announced the deprecation of System.Drawing.Common. The suggested migration path was to move to alternative libraries e.g. ImageSharp.
RDMP followed this approach. The update was merged in #1355. This means that all resx files must store Byte[]
and code must be manually updated if images are added using the designer.
The approach for adding new icons is:
- Open resx file in designer (e.g. CatalogueIcons.resx)
- Drop new image into designer and save
This creates a new entry in .resx file for example:
<data name="YourImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\YourImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
This must be updated to be a raw Byte[]
. Change the value
tag by replacing everything after the file path (first semicolon) with ;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
For example
<data name="YourImage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\YourImage.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
Next update the .Designer.cs
file (e.g. CatalogueIcons.Designer.cs
). Add a new entry for the new resx file:
/// <summary>
/// Looks up a localized resource of type Image.
/// </summary>
public static Byte[] YourImage
{
get
{
object obj = ResourceManager.GetObject("YourImage", resourceCulture);
return ((Byte[])(obj));
}
}
This Byte[]
can then be turned into either a Windows Forms compatible Bitmap (windows only):
CatalogueIcons.YourImage.ImageToBitmap();
Or a cross platform ImageSharp Image
with:
Image.Load<Rgba32>(CatalogueIcons.YourImage);
RDMP releases are performed by GitHub Actions CI server. The logic for this is in build.yml.
To perform a release merge all branches into develop
then perform the following:
- Update Changelog
- Add a header with the version number and date e.g.
## [7.0.21] - 2022-09-26
- Add a diff link at the bottom e.g.
[7.0.21]: https://github.com/HicServices/RDMP/compare/v7.0.20...v7.0.21
- Add a header with the version number and date e.g.
- Update SharedAssemblyInfo
- Update all 3 versions to your new number e.g.
7.0.21
- Update all 3 versions to your new number e.g.
- Commit and push
When picking a new version number you should strongly consider only bumping the minor version (i.e. the third number). Changes to Major or Minor version number will result in incompatible plugins (until a version of the plugin is released with a bumped dependency) - for more information on this see Plugin Writing.
Next tag the release with git
as the new version number. Do not forget the v
prefix e.g.
git tag v7.0.21
git push --tags
This should push a new release to both NuGet
and GitHub Releases
. If you have a problem with the build CI, you can delete the local AND remote tag then fix the problem then re-tag.
Once the release is built and you have tested the binary in GitHub Releases you can make it live by updating rdmp-client.xml
- Update the
version
tag - Update the
url
tag to the new version - Update the
changelog
tag to have the new version anchor hyperlink
Test that your RDMP client can update with Help->Check for updates
(note that if your xml file change is on develop
you will need to specify this as the update path)
Finally merge develop
into main
and push. This will ensure that the main
branch always has the source of the last RDMP version release.
Avoid making changes to the RDMP schema until you are experienced with the codebase as these changes have the greatest possibility of breaking deployments/plugins.
If you need to record new information about an object consider using ExtendedProperty instead of writting a patch (especially if you are working within a Plugin).
Do not write patches for the CohortCachingDatabase, LoggingDatabase or DataQualityEngine databases. These 3 databases are cross [DBMS] (you can create them in MySql / PostgresSQL and/or Oracle). Patching for cross [DBMS] database schemas is not implemented yet. If you
want to look into writing such a patch you would start with the SortedDictionary<string, Patch> GetAllPatchesInAssembly(DiscoveredDatabase db)
method and adjust the patch SQL generated for each [DBMS].
If after considering all the alternatives you are sure that a new patch is required and it is for the Catalogue or Data Export Databases then the process is as follows:
- Within Visual Studio copy and paste the latest patch in the up folder (e.g. ./Rdmp.Core/Databases/CatalogueDatabase/up/076_AddFolders.sql)
- Rename the file with a higher number and description (e.g. 077BreakRDMP.sql)
- Update the contents of the script
- Script must start with a Version number although if the schema change is backwards compatible it is acceptable to leave this unchanged
- Scripts must be designed to run multiple times without fail (i.e. use
if not exists
to check before adding a column) - Scripts must be backwards compatible where possible (e.g. add new fields but do not delete existing ones)
- If your new column is required (i.e. not null) then you must UPDATE existing values and provid a database default so that older versions of RDMP that are still running do not crash on object creation.
Once the script is written then the next time you run RDMP you will be prompted to apply the new patch.
RDMP supports plugins. The following plugin repositories are used by HIC / EPCC:
- RdmpDicom: Public repository containing DICOM image loading support. Foundation for SmiServices ETL microservice
- HICPlugin: Private repository containing HIC specific components. If you get a 404 trying to access this then ask to be granted rights to read/write the repo
- RdmpExtensions: Private repository containing HIC specific components but which may be more widely useful e.g. run Python scripts. If you get a 404 trying to access this then ask to be granted rights to read/write the repo
[[DBMS]]: ./Documentation/CodeTutorials/Glossary.md#[DBMS]