You are not logged in.
Pages: 1
How to implement a Recursif Record Reference in the same table?
is Record Class Defininition like bellow correct?
TSQLAccount= class(TSQLRecord)
private
fAccountNumber: TRawUTF8;
fAccountName: TRawUTF8;
fAccountLevel: Integer;
...
...
fHeaderAccount: TSQLAccount;
published
...
HeaderAccount: TSQLAccount read fHeaderAccount write fHeaderAccount;
AccountLevel: Integer read fAccountLevel write fAccountLevel;
...
end;
so i can do something like this
var
aAccount:TSQLAccount;
aHeaderAccount:TSQLAccount;
begin
...
...
aHeaderAccount:=aAccount.HeaderAccount;
aAccount.Level:=aHeaderAccount.Level+1;
...
...
end;
thanks.
Offline
The published properties of TSQLRecord children are not class instances, but a pointer(ID) or TObject(ID).
(the only exception is the TSQLRecordMany properties, which are automatic created instances of pivot tables)
So aHeaderAccount.Level+1 (or aAccount.HeaderAccount.Level+1) won't work.
It will raise a GPF.
aAccount.HeaderAccount is not a TSQLAccount class instance, but TSQLAccount(HeaderAccountID).
You'll have to typecast it to integer(aAccount.HeaderAccount) or even better to PtrInt(aAccount.HeaderAccount) in order to retrieve the record ID, then ask the database for the record content, or just one field value in your case.
There is also the ID property which could be used to make this typecast: the GetID method will detect that self is not a class instance, but a record ID, and return ID.
You'll have to use something like that:
aAccount.Level := GetInteger(Client.OneFieldValue(TSQLAccount,'Level',PtrInt(aAccount.HeaderAccount)));
or even more easy to read:
aAccount.Level := GetInteger(Client.OneFieldValue(TSQLAccount,'Level',aAccount.HeaderAccount.ID));
Or even retrieve the associated Header account:
aHeaderAccount := TSQLAccount.Create(Client,aAccount.HeaderAccount.ID));
I've just added a new constructor:
{{ this constructor initializes the object and fill its content from a client
or server connection, from a TSQLRecord published property content
- is just a wrapper around Create(aClient,PtrInt(aPublishedRecord))
or Create(aClient,aPublishedRecord.ID)
- a published TSQLRecord property is not a class instance, but a typecast to
TObject(RecordID) - you can also use its ID property
- if ForUpdate is true, the REST method is LOCK and not GET: it tries to lock
the corresponding record, then retrieve its content; caller has to call
UnLock() method after Value usage, to release the record }
constructor Create(aClient: TSQLRest; aPublishedRecord: TSQLRecord;
ForUpdate: boolean=false); overload;
which will allow to write such code:
aHeaderAccount := TSQLAccount.Create(Client,aAccount.HeaderAccount));
Another way of getting the aHeaderAccount class instance is perhaps:
aHeaderAccount := TSQLAccount.Create;
(...)
Client.Retrieve(aAccount.HeaderAccount.ID,aHeaderAccount);
Offline
Pages: 1