You are not logged in.
Hi and thanks for the great work.
I have the following Json REST Spec https://testdrive.polarion.com/polarion … nrest.json.
The mopenapi generator creates.
function TPolarionClient.GetAllDocuments(const Fields: TPolarionSparseFields;
PageSize: integer; PageNumber: integer; const Include: RawUtf8;
const Query: RawUtf8; const Sort: RawUtf8;
const Revision: RawUtf8): TPolarionDocumentsListGetResponse;
begin
fClient.Request('GET', '/all/documents', [], [
'page[size]', PageSize,
'page[number]', PageNumber,
'fields', Fields,
'include', Include,
'query', Query,
'sort', Sort,
'revision', Revision], [],
result, TypeInfo(TPolarionDocumentsListGetResponse));
end; The compiler says we are not allowed to put a (packed) record into an array constructor ![]()
polarion.client.pas(7835,15) Error: Wrong type "TPolarionSparseFields" in array constructor
Thanks so much for having a look into it.
Offline
I think there is an additional deduplication error.
"usersSingleGetResponse" in JSON has data.attributes.name. But in the DTO.pas file data "points" to a different attributes record, that has no "name" property (i guess it is pagesSingleGetResponse.data in json and not usersSingleGetResponse.data ) .
Offline
So this is not correct?
TDtoApi2761 = packed record
_Type: TEnumApi8;
Id: RawUtf8;
Revision: RawUtf8;
Attributes: TDtoApi2764;
Relationships: TDtoApi2779;
Links: TDtoApi995;
Meta: TDtoApi1354;
end;
// from #/components/schemas/usersSingleGetResponse
TUsersSingleGetResponse = packed record
Data: TDtoApi2761;
// Related entities might be returned, see <a href="https://docs.sw.siemens.com/en-US/doc/230235217/PL20250606201928474.polarion_help_sc.xid2134849/xid2134871"
// target="_blank">REST API User Guide</a>.
Included: variant;
Links: TDtoApi995;
end;
PUsersSingleGetResponse = ^TUsersSingleGetResponse;Offline
Anyway, please try with
https://github.com/synopse/mORMot2/commit/fe1370e77
It should now at least compile.
Maybe there are still some issues.
Offline
I tried with https://github.com/synopse/mORMot2/commit/fe1370e77
it complies and except for the case mentioned before it seems to work.
one cannot answer the question if the code snippet is correct as one would need to see the content of TDtoApi2764
I draw a small and simplified uml which hopefully shows that the issue becomes apparent one step below the Data record.
https://github.com/D-H-R/various/blob/m … sponse.png
As I'm not sure if the numbers stay constant I also added the generated files: https://github.com/D-H-R/various/tree/m … _generator
Last edited by DirkH (2026-07-07 21:31:29)
Offline
I can confirm it is the deduplication, which would also need to check against the actual types / followed records and not only the names (as far as I understand) of the current record.
This "Hotfix" removes the deduplication completely and "fixes" the issue shown in the previous post.
https://github.com/synopse/mORMot2/comm … a17d1cb762
Offline
I have included your fix:
https://github.com/synopse/mORMot2/commit/81cb28f5e
And also made a sophisticated similar types detection, to reduce the generated source code by more than half:
https://github.com/synopse/mORMot2/commit/e08e33ca3
Note that there are some optDto*Reduce* new options, to be tested if you got something wrong in the final generated code.
Offline
I have tested https://github.com/synopse/mORMot2/commit/e08e33ca3 with my current implementation.
I used GetCurrentUser, GetWorkItem, GetWorkItems, PatchWorkItem from the polarionrest.json of the first topic.
At least two commands had the issues mentioned before and are working with e08e33ca3. Great
! I used default settings (i.e. none of the optDto*Reduce*).
Just out of curiosity, why are you doing
TPolarionDto1573 = TPolarionDto197;
TPolarionDto1570 = packed record
_Type: TPolarionPolarionEnum54;
Attributes: TPolarionDto1571;
Relationships: TPolarionDto1573; //could use TPolarionDto197 directly here?
end;If the answer is "the dedup alogrithm is easier", does the compiler reduce this automagically ?
Last edited by DirkH (2026-07-13 12:26:15)
Offline
Yes the "dedup alogrithm" is easier with its own type, because we don't need to parse all type definitions again and replace all TPolarionDto1573 by TPolarionDto197.
In fact, the "compiler" reduce this automatically, and generate the exact same RTTI and same assembly with a weak type alias like TPolarionDto1573 = TPolarionDto197.
Note that TPolarionDto1573 = type TPolarionDto197 would have created its own separated TypeInfo() which is what we don't want nor need here.
Would it be a good idea to be able to define a set of methods filter, e.g. as CSV GLOBs, to only publish the methods needed, not the whole API?
Currently, we translate in pascal all the types defined in the OpenAPI json/yaml, even some which are not used eventually in the client class.
So it may be at least two commits:
1) detect and emit only the types actually used in the API
2) be able to filter via GLOB the needed methods - and would benefit from point 1) for sure.
Offline
Hi and sorry for the late reply.
thanks for pointing out TPolarionDto1573 = type TPolarionDto197 vs. TPolarionDto1573 = TPolarionDto197
personally I think your proposal for reducing the code is not worth it. But to be honest I dont understand size of .exe anyway.
I have a case study where I am parsing a json with mormot and put it into a virtual stringtree and I have a case study where I'm interfacing polarion and codebeamer with REST Api of cause also with mormot.
the json to stringtree is 6MB after stripping, the one with both REST Apis inside is 3.9 MB. - So I think the impact is not so big.
Nice to have: yes - but I think it would be rarely acutally used. I guess 95% are happy if it runs and won't go the extra step of defining some sort of config.
Besides I have to mention I need some rather small programs that need some bloatware they call "runtime engine" which has 650MB. So maybe I'm not too picky about file sizes ![]()
Offline
Sometimes it is not only about the executable size - but I have started programming as a child with a ZX81 and 1KB of RAM so you know where I come from. ![]()
The main concern is about the RTTI definitions. It takes time and resource to parse and store them, and it pollutes the RTTI hash table for nothing. This was my primary concern. But I may use delayed registration in the future to mitigate this.
- On second thoughts, delaying may not be worth it since the TypeInfo() would be parsed when the client is initialized. But at least it would only parse what is actually needed for its use case.
- After trying implementing delayed text definition, it is not easy as it sounded: the user could in fact register records, but use them as dynamic array by name and delayed registration won't work in that case any more. So I won't go that way now.
Offline