#1 2024-11-22 03:51:13

mrbar2000
Member
From: Brazil
Registered: 2016-10-26
Posts: 100

RecordToObject and ObjectToRecord

There are some way to mapping property with names diferents between record and object. i.e:

TDTOAPerson                     TClient
    Name                ---->         ClientName
    BirthDay            ---->         BirthDay

I see something about TMapRTTI on last version of mormot, but i dont see on forum, blog or documentation nothing about this.

Offline

#2 2024-11-22 08:55:14

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

Re: RecordToObject and ObjectToRecord

The documentation is part of the source comments of TRttiMap.

See also test.core.base.pas line 2456 and following.

Offline

#3 2024-11-26 12:42:22

mrbar2000
Member
From: Brazil
Registered: 2016-10-26
Posts: 100

Re: RecordToObject and ObjectToRecord

ab wrote:

The documentation is part of the source comments of TRttiMap.
See also test.core.base.pas line 2456 and following.

Thanks i read all.

1) There are some list to register many TRttiMap like RegisterFromText?

2) What u think that pass some method to be called during ToA or ToB where I can make copyvalue or no!?

ex: m.ToA(@MeuRecord, @MyConvertMethodToA)

function MyConvertMethodToA(A, B: pointer; PropName: String; pA, pB: PPRttiCustomProp): Boolean;
var
  v: TVarData;
begin
  if PropnameB = 'Name' then
  begin
    v := 'Sr. ' + GetValueVariant(A, v)  <<< i think that don't work this way, just to explain the idea
    // here i can change the value to be put in A property "Name".
    pA^.SetValueVariant(A, v);  <<< something like this
    Result := True
  end else 
    Result := False;
end;
procedure TRttiMap.ToA(A, B, MethodToA: pointer);
var
  ...
  handled: boolean;
begin
  ...
  repeat
    if MethodToA <> Nil then
      handled := MethodToA(A, B, PropName, pA, pB)  <<< I dont know if will need all this params
    if not handled and (pa^ <>) nil then
      pb^.CopyValue(A, B, pa^); // copy this mapped property value
    ...
  until n = 0;
end;

What u think?

Offline

#4 2024-11-26 16:25:55

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

Re: RecordToObject and ObjectToRecord

The usecase of TRttiMap is to easily copy field values by names.

What you are supposed to do is:
- use TRttiMap to copy field values by name
- leave the dest field name as '' to ignore a field
- add your own custom code for those ignored fields, which may need additional process

This "custom code" would be easy and nice, with no RTTI involved.
Using a MethodToA() function sounds clearly over-complicated to me.

Offline

#5 2024-11-29 17:30:48

mrbar2000
Member
From: Brazil
Registered: 2016-10-26
Posts: 100

Re: RecordToObject and ObjectToRecord

ab wrote:

The usecase of TRttiMap is to easily copy field values by names.

What you are supposed to do is:
- use TRttiMap to copy field values by name
- leave the dest field name as '' to ignore a field
- add your own custom code for those ignored fields, which may need additional process

This "custom code" would be easy and nice, with no RTTI involved.
Using a MethodToA() function sounds clearly over-complicated to me.

MyConvertMethod is to specific cases, where we cant convert A to B, o B to A directly

a new function in TRttimap
   function TRttiMap.CustomMap(MyConvertMethod): PRttiMap;

Sample of use:

TDTOClient.Date is String;
TOrmClient.DateFinal is TDateTime;

map.Init(TypeInfo(TDTOClient), TOrmClient)
  .AutoMap
  .Map([
     'FatherName', '',   // ignore in A
     '', 'MatherName'   // ignore in B
  ])
  .Map('Date', 'DateFinal')
  .CustomMap(MyConvertMethod);

procedure TMyService.MyConvertMethod(map: TRttimap; AToB: Boolean; propertyName: String; A, B: pointer)
begin
  if AToB and (propertyName = 'Date') then then
    map.SetValue(B, propertyName, ConvertIsoString2DateTime(map.GetValue(A, propertyName)))
  else 
    map.SetValue(A, propertyName, ConvertDateTime2IsoString(map.GetValue(B, propertyName)));
end;

Offline

#6 2024-11-29 18:49:14

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

Re: RecordToObject and ObjectToRecord

Yes, I understood what you meant.

But my idea is to use functions for the conversion.
It is safer, faster and cleaner.

function ToOrm(const client: TDTOClient): TOrmClient; overload;
begin
  result := mapClient.ToB(@client);
  result.DateFinal := ConvertIsoString2DateTime(client.Date);
end;

The main benefit is to use strong typing.
You could just use ToOrm() and ToDto() with no doubt, and the pointers are hidden.

Just to prove my point, your callback function is incorrect, if AToB is true and the property is not 'Date".
Even for you, such a callback function is overcomplicated.

Offline

#7 2024-11-29 19:51:48

mrbar2000
Member
From: Brazil
Registered: 2016-10-26
Posts: 100

Re: RecordToObject and ObjectToRecord

Are u completly correct. Thanks AB

Offline

Board footer

Powered by FluxBB