#1 2015-01-26 19:42:36

aivanov
Member
Registered: 2014-06-30
Posts: 6

Using CrossPlatform generated code, trying to use TSQLRecord as param

Hello fellow mORMot lovers,

I'm still learning (a lot) and I'm stuck with a simple question.
Here is the situation, I was trying to avoid having a dedicated DTO for some SOA calls and use TSQLRecord descendants instead. I like to retrieve a TSQLContact from the server by the ID, and return a boolean to indicate success. This is the generated code, CrossPlatform, client side:

// this code is generated (mORMotClient.pas)

function TServiceContactAdministration.GetContact(const contactID: Integer; var theContact: TSQLContact): Boolean;
var res: TVariantDynArray;
begin
  fClient.CallRemoteService(self,'GetContact',2, // raise EServiceException on error
    [contactID,ObjectToVariant(theContact)],res);
  theContact := TSQLContact.CreateFromVariant(res[0]);
  Result := res[1];
end;

My problem is: how to call this code? If I instantiate theContact before calling, there will be a memory leak. If I don't instantiate theContact, I will have a problem on the server. This is what I'm talking about:

// this is on the server side.
// two options:

// option 1 - create theContact inside the function. This works, but will generate a memory leak

function TContactAdministration.GetContact(const contactID: Integer; var theContact: TSQLContact): Boolean;
begin
  theContact :=  TSQLContact.Create(ServiceContext.Request.Server, contactID); // or CreateJoined
  Result := (theContact.ID > 0) and (theContact.ID = contactID)
end;

// option 2 - retrieve theContact (no create) inside the function. This does not work if theContact is not instantiated on the client side

function TContactAdministration.GetContact(const contactID: Integer; var theContact: TSQLContact): Boolean;
begin
//  theContact :=  TSQLContact.Create(ServiceContext.Request.Server, contactID); // or CreateJoined
  ServiceContext.Request.Server.Retrieve(ContactID, theContact);
  Result := (theContact.ID > 0) and (theContact.ID = contactID)
end;

So, what to do? Do I have to give up using TSQLRecord as parameter?

Last edited by aivanov (2015-01-26 19:43:51)

Offline

#2 2015-01-26 20:12:23

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

Re: Using CrossPlatform generated code, trying to use TSQLRecord as param

By convention, the TSQLContact should be always instantiated by the caller.
This is what will occur on the server side: the TSQLRestServer instance will always instantiate one TSQLContact befor passing it to the method implementation.
The same should better be made on the client side.

So the current template generating  theContact := TSQLContact.CreateFromVariant(res[0]); is not enough.
You may try http://synopse.info/fossil/info/a530e87625

But in your precise case, I would change the "var" into "out".
You do not care about the incoming value.

See http://synopse.info/files/html/Synopse% … #TITLE_345

Offline

#3 2015-01-27 12:38:33

aivanov
Member
Registered: 2014-06-30
Posts: 6

Re: Using CrossPlatform generated code, trying to use TSQLRecord as param

Thank you AB!

It's nice and clean now, and everything is getting more and more clear.

mORMot rules!

Offline

Board footer

Powered by FluxBB