#1 2016-09-09 05:13:22

Peter Evans
Member
Registered: 2016-07-03
Posts: 32

Generate code for FMX on Windows and Android for mORMot

I have been working to convert a Delphi with DataSnap program to its Delphi with mORMot equivalent.

On 2016-08-09 I posted in the thread 'Windows FMX Client versus Android FMX Client'
(see http://synopse.info/forum/viewtopic.php?id=3418) a link to a sample project group. That code is still relevant.

There were two missing pieces in the puzzle:

1) Records need to be hand coded from an Object. How to automate this?

2) A Parameter that is a TObjectList does not work. How to fix this problem?

I now provide a Delphi project group that has two (2) projects. It is located
at  http://www.cocolsoft.com.au/ba/GenerateRec_Version1.zip

The program GenerateRec :-

From the ReadMe "This program is used to generate record units based on object units.

The motivation for this program is to automate the process of making record units. If you have a large mORMot program with many objects you will need a corresponding record for each object. This supposes that you are running on Windows and Android.

Record units are required if you wish to use mORMot with Delphi FireMonkey on Windows and Delphi FireMonkey on Android.

Note : If you are only targeting Delphi FireMonkey on Windows then you may be able to do this using objects. You probably won't need records. In that case this program is not required.".

The program GenerateObjectList :-

From the ReadMe "This program is used to generate object list units based on an object name.

The motivation for this program is to automate the process of making object list units.
If you have a large mORMot program with many objects you may need to convert an object list into JSON or convert JSON into an object list.

Each generated unit has two main routines. One routine converts an object to JSON.
The other routine converts JSON into an object list. The JSON string can be passed as a parameter in an interface call. The generated unit has conditional compilation for Windows and Android.".

In this forum there have been proposed various ways to achieve the generation of object lists. I believe I use a different approach to those.

As well as the two ReadMe files there is a screen shot of their main forms.

The program GenerateRec requires you to simply markup your Object unit with the comment "{MormotGenerateRecord}". A Mustache template file is used in the generation of the record units. These have code for Windows and Android. A sample Object unit is provided.

The program GenerateObjectList uses a Mustache template file in the generation of the units. These have code for Windows and Android. This has been unit tested on Windows and unit tested on Android. (The unit tests are not provided.)

Enjoy the productivity.

Offline

#2 2016-09-09 07:18:17

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,236
Website

Re: Generate code for FMX on Windows and Android for mORMot

Thanks a lot for sharing!

I still don't understand the propose of GenerateRec: AFAIK the records type definitions are already generated by mORMotWrappers.pas unit.
What is missing/wrong?

About GenerateObjectList, it may benefit also from being part of mORMotWrappers.pas, using TObjectList<> on the client side, and e.g. T*ObjArray on the server side.

But sharing your solutions to those problems is very positive, and helpful.
Thanks again.

Offline

#3 2016-09-10 08:12:50

MMihelic
Member
Registered: 2016-09-06
Posts: 5

Re: Generate code for FMX on Windows and Android for mORMot

Good morning.

I also had some problems. I think I had a scenario where I didn't want the list to be recreated which it was by default.
I ended up adding an overload method:

//:MM:I want to use the same list...
procedure TSQLRest.RetrieveList(Table: TSQLRecordClass; const FieldNames,
  SQLWhere: string; const BoundsSQLWhere: array of const; var destObjectList: TObjectList);
var rows: TSQLTableJSON;
    rec: TSQLRecord;
begin
  destObjectList.Clear;
  rows := MultiFieldValues(Table,FieldNames,SQLWhere,BoundsSQLWhere);
  if rows<>nil then
    try
      repeat
        rec := Table.Create;
        if not rows.FillOne(rec) then begin
          rec.Free;
          break;
        end;
        destObjectList.Add(rec);
      until false;
    finally
      rows.Free;
    end;
end;
//EOF:MM:

Offline

#4 2016-09-10 09:59:35

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,236
Website

Re: Generate code for FMX on Windows and Android for mORMot

Honestly Clear + Add is of no/little benefit in comparison to Create + Add + replacing the TObjectList instance.

Offline

#5 2016-09-11 02:14:04

Peter Evans
Member
Registered: 2016-07-03
Posts: 32

Re: Generate code for FMX on Windows and Android for mORMot

MMihelic: You may wish to create a new Topic for your issue.
Your issue is completely different.

Offline

#6 2016-09-11 02:15:06

Peter Evans
Member
Registered: 2016-07-03
Posts: 32

Re: Generate code for FMX on Windows and Android for mORMot

ab: Thank you for your feedback.

In regards to GenerateRec. You are right, the records type definitions are
already generated by 'mORMotWrappers.pas' unit to 'mORMotClient.pas'.

I want to reference the records on the Server. On the Server I convert from
an object to a record, and from a record to an object. So I need to have
the two routines written.

On the Server I would have to have :-
  USES
    mORMotClient;

I do not know what the implications of this are. Pulling in cross platform units.
Perhaps I have done unnecessary work?

When I develop my programs I write the Interfaces first. Then I write the implementation
that the Server references. For this to compile I need the records. Perhaps one could
run the ServerWrapper program at this point in time?

Offline

#7 2016-09-11 11:00:29

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,236
Website

Re: Generate code for FMX on Windows and Android for mORMot

Yes, the idea is to create dedicated DTO (Data Transfer Objects), e.g. as plain record types, which will be used only for transmission of the information of your services interfaces.
For most services, you create several interfaces, and in each interface method, most of the time a set of parameters with simple types (string, integer, enumerates) is enough.
Don't forget about enumerates and sets, which are much more explicit than booleans or integers, and are perfect e.g. to return error codes or a set of values - under the hood, they will be transmitted as integer.
Records are only needed when you need more complex content, including e.g. dynamic arrays.

BTW, if you use records and dynamic arrays for you DTO, you do not have to manage their memory, no need to use TObjectList<> or such...

So the idea is that you could safely include mORMotClient to your client side.
The dependency will be very small, since it will use only standard types (like string or integer).
And when the server interface changes, you regenerate mORMotClient.pas from the server, and you can be sure that your client will be in synch with the new interfaces, and their parameters.

Offline

Board footer

Powered by FluxBB