#1 2010-11-08 15:17:06

WladiD
Member
From: Germany
Registered: 2010-10-27
Posts: 35

Please declare TSQLRecord.FillRow as virtual

I think it were very useful, when TSQLRecord.FillRow would be virtual.

For example you hold a calculated value in a field (not table related), but it must get recalculated, if the same instance is reused for iteration (Instance.FillPrepare; while Instance.FillOne do...).

In any descendant I could then implement my custom reset/recalculation code in FillRow and anything were fine. Or is there a better solution already exist?

Last edited by WladiD (2010-11-08 15:17:52)

Offline

#2 2010-11-08 18:25:39

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

Re: Please declare TSQLRecord.FillRow as virtual

Good idea.

I'll do that.
Perhaps not virtual, but dynamic, in order to use less memory for each TSQLRecord instance.

Offline

#3 2010-11-08 19:44:41

WladiD
Member
From: Germany
Registered: 2010-10-27
Posts: 35

Re: Please declare TSQLRecord.FillRow as virtual

You are the master. wink

Offline

#4 2010-11-08 19:57:30

WladiD
Member
From: Germany
Registered: 2010-10-27
Posts: 35

Re: Please declare TSQLRecord.FillRow as virtual

Another idea on the same subject. May be it would be better to introduce a new (dynamic) method, which is empty in TSQLRecord, but will be called by FillRow at the right place. For example:

TSQLRecord = class(TObject)
public
  procedure Reset; dynamic;
end;

???

Offline

#5 2010-11-09 07:24:11

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

Re: Please declare TSQLRecord.FillRow as virtual

I've made the FillRow method virtual.
After 2nd thought, dynamic didn't make a lot of sense here.

About your interesting Reset proposal, I'd rather rely on the FillRow virtual method, and override it with a custom handler. Is this really a problem?

Offline

#6 2010-11-09 08:13:36

WladiD
Member
From: Germany
Registered: 2010-10-27
Posts: 35

Re: Please declare TSQLRecord.FillRow as virtual

May be I figured out me imprecise. Follows a detailed try of my concept.

TSQLRecord = class(TObject)
protected
  procedure FillInitialize; virtual;
public
  procedure FillRow(Row: integer; Dest: TSQLRecord=nil); // can still be static    
end;

implementation

procedure TSQLRecord.FillRow(Row: integer; Dest: TSQLRecord=nil);
var i: integer;
    P: PPropInfo;
    U: PPUTF8CharArray;
begin
  // 0. validate params
  if (self=nil) or (fTable=nil) or (pointer(TableMap)=nil) or
     (cardinal(Row)>cardinal(fTable.RowCount)) then exit;
  U := @fTable.fResults[Row*fTable.FieldCount]; // U=PPUTF8CharArray of this Row
  if Dest=nil then
    Dest := self;
  // 1. get ID field
  if IDMap>=0 then
    Dest.fID := GetInteger(U[IDMap]);
  // 2. update published fields values
  with ClassProp^ do begin
    P := @PropList;
    for i := 0 to PropCount-1 do begin
      if TableMap[i]>=0 then // don't nil missing properties
        P^.SetValue(Dest,U[TableMap[i]]); // update existing value
      P := P^.Next;
    end;
  end;
  Dest.FillInitialize; // <--
end;

procedure TSQLRecord.FillInitialize;
begin
  // Is empty in TSQLRecord, but can be implemented in descendants
end;

Further there are other locations, where the call of FillInitialize would makes sense e.g. in TSQLRecord.CreateCopy.

But at this time it's enough for me, if FillRow is overrideable.

Last edited by WladiD (2010-11-09 09:40:42)

Offline

Board footer

Powered by FluxBB