Tuesday, August 1, 2017

mORMot on FHIR - Part 2 - ORM

In this blog, I want to try out some ORM feature of mORMot first.

Fist step, we save the Echo project from previous part to ORM project, and make a copy of SampleData.pas from mORMot's sample 01 to ORM's project folder, add this unit to the project:

Open SampleData.pas, we can see a class TSQLSampleRecord is defined, we can then add this class to the model when a TSQLModel is created so that the model now has one table/class:

Run the application and it has no problem. But we don't see where the table is created as the data server is a memory server, no persistence to any media, it is better to change the server to one of real database server, for convenience, we will use the default Sqlite database server.

The default Sqlite server class is TSQLRestServerDB, so we change the class TECHOServer to inherit from TSQLRestServerDB:

TECHOServer = class (TSQLRestServerDB)
  published
    procedure Echo(Ctxt: TSQLRestServerURIContext);
  end;
And the parameters for creating such a server is different from TSQLRestServerFullMemory, we just need to tell the server where the database file is:
aServer := TECHOServer.Create(aModel,
    ChangeFileExt(ExeVersion.ProgramFileName,'.db3'));
We can then ask the server to create the schema for us:
TSQLRestServerDB(aServer).CreateMissingTables;
That is it! (of cause, you need to add use units as we have changed the class)

After running the application, we can check the database file and there is the table created:


As you can see, without doing any explicit mapping configuration, the database schema is created automatically.

Saturday, July 29, 2017

mORMot on FHIR - Part 1 - RESTful Echo

My goal is to use Delphi mORMot framework to implement a FHIR server.

So what are FHIR and mORMot?

FHIR stands for Fast Health Interoperability Resource, a framework focussed on exchanging health data via RESTful API, thus a FHIR server is normally a RESTful server.

mORMot is a Delphi framework that has features such as ORM an SOA etc, it supports REST service out of the box.

So why mORMot for FHIR?

mORMot is all about REST server, i.e., provides service via RESTful API, taking request and returning response in JSON format, it matches what a FHIR server is doing perfectly.

So how easy can we build up a RESTful server in mORMot to take a JSON request and return a JSON response?

I strongly recommend you to download mORMot source code by using Git client so that you can update the source code easily as it is still being updated actively. So I save the source code in "C:\MyDev\mORMot\Git Version". We will start with a new console project:



and save it as ECHO project:


 The goal of this project is to build a server that can echo a HTTP post. First, we need to define a RESTful server:

TECHOServer = class (TSQLRestServerFullMemory)
  published
    procedure Echo(Ctxt: TSQLRestServerURIContext);
  end;
And the implementation of Echo is quite simple, assigning the input to output and returning HTTP 200 to client:
procedure TECHOServer.Echo(Ctxt: TSQLRestServerURIContext);
  begin
    Ctxt.Call.Outbody := Ctxt.Call.InBody;
    Ctxt.Call.OutStatus :=200;
  end;
Then we need to start the RESTful server, as mORMot ties data model, data server and HTTP server together, thus we need to initialize a model and a server before we start a HTTP server:
aModel := TSQLModel.Create([],'service');
  try
    aServer := TECHOServer.Create(aModel);
    try
      aHTTPServer := TSQLHttpServer.Create('7878',aServer,'+',useHttpApiRegisteringURI);
      write('Press [Enter] to close the server.');
      try
        readln;
      finally
        FreeAndNil(aHTTPServer);
      end;
    finally
      FreeAndNil(aServer);
    end;
  finally
    FreeAndNil(aModel);
  end;

And the whole souce code is as simple as below (less than 50 lines):
program Echo;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  mORMot,
  mORMotHttpServer;

type
  TECHOServer = class (TSQLRestServerFullMemory)
  published
    procedure Echo(Ctxt: TSQLRestServerURIContext);
  end;
  procedure TECHOServer.Echo(Ctxt: TSQLRestServerURIContext);
  begin
    Ctxt.Call.Outbody := Ctxt.Call.InBody;
    Ctxt.Call.OutStatus :=200;
  end;

var
  aModel: TSQLModel;
  aServer : TECHOServer;
  aHTTPServer: TSQLHttpServer;

begin
  aModel := TSQLModel.Create([],'service');
  try
    aServer := TECHOServer.Create(aModel);
    try
      aHTTPServer := TSQLHttpServer.Create('7878',aServer,'+',useHttpApiRegisteringURI);
      write('Press [Enter] to close the server.');
      try
        readln;
      finally
        FreeAndNil(aHTTPServer);
      end;
    finally
      FreeAndNil(aServer);
    end;
  finally
    FreeAndNil(aModel);
  end;
end.
Compile and run it:

Now it is time to test it:



 It works!

As you can see, use mORMot to build a RESTful server it pretty simple.

In the next part, I will try to deserialize the input JSON so that we can use the resource as an object internally.






Tuesday, April 4, 2017

Experience with NHAPI is not so happy–how to get a list of group name?

NHapi is a port of the original project HAPI.

NHapi allows Microsoft .NET developers to easily use an HL7 2.x object model. This object model allows for parsing and encoding HL7 2.x data to/from Pipe Delimited or XML formats. A very handy program for use in the health care industry.

With 7 years experience of developing HL7 related applications (HL7 messaging and integration), I have found that in reality, people do not always conformant with HL7’s specification, thus there are always something more or less in the actual HL7 message than what the specification says. This makes the static object model sometime not able to represent the HL7 it is processing, to solve this problem, Terser is introduced to read values from the HL7 regardless the static structure of a particular version of HL7. Terser uses path to locate a particular value. The path consists of segment, field and component, sub component. Unfortunately, the segment consists of group and the name of segment, but group are vary from version to version of HL7, for example, a PRD of REF^I12 in version 2.3.1 is under group PROVIDER, but it is not in any group in version 2.4. Another problem is that I have not been able to find a document in which tells you what groups are in a type of message for each version of HL7, this then leaves you only way to figure out is by guessing. After I have gain more experience of NHAPI, I now can use following code to print out a whole path picture of a specified message:

static void PrintNames(string ident,IStructure s)
        {
            Console.Write(ident);
            Console.Write(s.GetStructureName());
            if (! (s is IGroup))
            {
                Console.WriteLine("");
                return;
            }
            Console.WriteLine("(Group)");

            IGroup g = (IGroup)s;
            foreach (var sn in (g.Names))
            {               
                IStructure ss = g.GetStructure(sn);
                if (ss is IGroup)
                {
                  
                    PrintNames(ident + "    ", ss);
                }
                else
                {
                    Console.Write(ident + "    ");
                    Console.WriteLine(sn);

                }
                //Console.WriteLine("");
            }
        }

 

Call it with

REF_I12 r= new REF_I12;

PrintNames(“”,r)

we can get the path tree:

REF_I12(Group)
    MSH
    RF1
    AUTHORIZATION_CONTACT(Group)
        AUT
        CTD
    PROVIDER(Group)
        PRD
        CTD
    PID
    NK1
    GT1
    INSURANCE(Group)
        IN1
        IN2
        IN3
    ACC
    DG1
    DRG
    AL1
    PROCEDURE(Group)
        PR1
        AUTHORIZATION_CONTACT(Group)
            AUT
            CTD
    OBSERVATION(Group)
        OBR
        NTE
        RESULTS_NOTES(Group)
            OBX
            NTE
    PATIENT_VISIT(Group)
        PV1
        PV2
    NTE

Friday, February 3, 2017

Create multiple folders with command "MD"

The other day, I was trying to create a folder "SQL Server" but I was missing the quotes, so I issued command "md sql server" in the CMD window, then I used "cd sql server" to change the current directly but failed, with a "dir", I found there were two new folders "sql" and "server" instead of "sql server". If you check the help of the command "md" (I checked with Windows 10), there is no such usage in it. It seems that it is an undocumented and nice feature! If the folder contains space, you just need to double quoted your folder's name such as:
    md "folder 1" "folder 2"