You are not logged in.
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
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.
Offline
Thank you AB!
It's nice and clean now, and everything is getting more and more clear.
mORMot rules!
Offline