#1 2016-12-28 00:30:39

donaldshimoda
Member
From: Argentina
Registered: 2016-12-09
Posts: 25
Website

Get called 3 times?

Just trying sample 1, try to change the get of a property to see how it behaves.

  TSQLSampleRecord = class(TSQLRecord)
  private
    fQuestion: RawUTF8;
    fName: RawUTF8;
    fTime: TModTime;
    function GetQuestion: RawUTF8;
  published
    property Time: TModTime read fTime write fTime;
    property Name: RawUTF8 read fName write fName;
    //property Question: RawUTF8 read fQuestion write fQuestion;
    property Question: RawUTF8 read GetQuestion write fQuestion;
  end;  

function TSQLSampleRecord.GetQuestion: RawUTF8;
begin
  result := 'Msg: '+ fQuestion;
end;    

i put this test "test message" and click add the message.

When i retrieve the message this is the result:

Result seems called 3 times!

"Msg: Msg: Msg: test message"

What im doing wrong?

Offline

#2 2016-12-28 13:46:50

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

Re: Get called 3 times?

This code is plenty wrong, I'm afraid.
You are changing the way a property is expected to work.

Input / output should be equipotent.
During the JSON serialization and data transmission within the ORM, your getter method breaks this expectation, so the content is changed.

Offline

#3 2016-12-28 14:38:58

turrican
Member
From: Barcelona
Registered: 2015-06-05
Posts: 94
Website

Re: Get called 3 times?

IMHO this is better aproach.

 
 TSQLSampleRecord = class(TSQLRecord)
  private
    fQuestion: RawUTF8;
    fName: RawUTF8;
    fTime: TModTime;
  public
    function GetQuestion: RawUTF8;
  published
    property Time: TModTime read fTime write fTime;
    property Name: RawUTF8 read fName write fName;
    property Question: RawUTF8 read fQuestion write fQuestion;
    
  end;  

function TSQLSampleRecord.GetQuestion: RawUTF8;
begin
  result := 'Msg: '+ fQuestion;
end;   

Last edited by turrican (2016-12-29 09:15:13)

Offline

#4 2016-12-28 20:44:46

donaldshimoda
Member
From: Argentina
Registered: 2016-12-09
Posts: 25
Website

Re: Get called 3 times?

Can please explain why? Is some internal need for TSQLRecord? fGetQuestion is not ever a function for that class. Don't assorted to the property either.
If i think in delphi/pascal terms, my solution is ok.

Last edited by donaldshimoda (2016-12-28 20:45:32)

Offline

#5 2016-12-28 22:22:07

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

Re: Get called 3 times?

It breaks the whole serialization process.

As such it is not OK. ?

Offline

#6 2016-12-28 22:28:59

donaldshimoda
Member
From: Argentina
Registered: 2016-12-09
Posts: 25
Website

Re: Get called 3 times?

ab wrote:

It breaks the whole serialization process.

As such it is not OK. ?

Ok, then is not possible to use standard property methods? like in standard Delphi classes?

Offline

#7 2016-12-28 23:29:28

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

Re: Get called 3 times?

If you use them properly, yes of course you can.

Offline

#8 2016-12-29 00:36:26

donaldshimoda
Member
From: Argentina
Registered: 2016-12-09
Posts: 25
Website

Re: Get called 3 times?

ab wrote:

If you use them properly, yes of course you can.

Can you please explain me how has to be used, using my code and showing what is wrong there and which will be the correct usage?

Offline

#9 2016-12-29 07:52:30

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

Re: Get called 3 times?

Getter / Setter methods of published properties should be equipotent, to let serialization work as expected:

...
    property Question: RawUTF8 read GetQuestion write SetQuestion;   
  end;  

function TSQLSampleRecord.GetQuestion: RawUTF8;
begin
  result := 'Msg: '+ fQuestion;
end;   

procedure TSQLSampleRecord.SetQuestion(const value: RawUTF8);
begin
  if copy(value,1,5)='Msg: ' then
   fQuestion := copy(value,6,maxInt);
end;

So here fQuestion will be filled back with the expected value.

If you need to change on the fly a property value for representation purposes (e.g. return a date as text), use a function or a public (not published) property.

Offline

#10 2016-12-29 13:38:03

donaldshimoda
Member
From: Argentina
Registered: 2016-12-09
Posts: 25
Website

Re: Get called 3 times?

ab wrote:

Getter / Setter methods of published properties should be equipotent, to let serialization work as expected:

...
    property Question: RawUTF8 read GetQuestion write SetQuestion;   
  end;  

function TSQLSampleRecord.GetQuestion: RawUTF8;
begin
  result := 'Msg: '+ fQuestion;
end;   

procedure TSQLSampleRecord.SetQuestion(const value: RawUTF8);
begin
  if copy(value,1,5)='Msg: ' then
   fQuestion := copy(value,6,maxInt);
end;

So here fQuestion will be filled back with the expected value.

If you need to change on the fly a property value for representation purposes (e.g. return a date as text), use a function or a public (not published) property.

Sorry, it seems like a freak hack to the normal behavior you expect from a object. That answer my question: you cannot use getter and setter on the tsqlrecords. Calling a function to change a value will by *by hand* not automatic when you get or set the property, as work in normal OOP.

Best regards.

Offline

#11 2016-12-29 15:53:35

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

Re: Get called 3 times?

I'm sorry, but you are wrong.
You can use getters and setters on TSQLRecord.

For published properties, you have to ensure that getter and setter are equipotent.
And it is not tied to TSQLRecord or mORMot.
It is mandatory for ANY persistence mechanism, even for Delphi TPersistent streaming.

Offline

Board footer

Powered by FluxBB