Page 1 of 1

Refresh or Close/Open

Posted: 31.07.2007, 18:30
by trob
Could somebody tell me what is the difference between Refresh and Close-Open? Actually i would like to know which is better for ZReadOnlyDataset's refreshing.

Posted: 31.07.2007, 21:14
by gto
Well, refresh only reload the current record. Close/open redo the entire query, which reload the entire result set.

Posted: 01.08.2007, 00:45
by trob
Thank You.

Posted: 01.08.2007, 09:12
by mdaems
gto,
Well, refresh only reload the current record. Close/open redo the entire query, which reload the entire result set.
Are you sure about this? Delphi documentation on ZDataSet.Refresh tells an other story. What's more : Firmos wrote a new feature TZAbstractDataset.RefreshCurrentRow(const RefreshDetails:Boolean) to refresh just one row. (Available in Testing branch only)

trob,

I would advise you to read the Delphi documentation on this issue. Maybe it's not 100% similar, but I think the main ideas will hold.

Mark

Posted: 01.08.2007, 12:19
by gto
You're right mdaems! I've tried again, and refresh currently refreshes the entire dataset, just like close-open.

I remember to have tested sometime ago and it only refreshed the current row.. anyway :)

Posted: 03.08.2007, 03:11
by trob
gto wrote:You're right mdaems! I've tried again, and refresh currently refreshes the entire dataset, just like close-open.

I remember to have tested sometime ago and it only refreshed the current row.. anyway :)
I have tried it too. :D The datas of two separeted record are refreshed in the grid.

So what is the difference?
I know, that when i call, refresh the afterscroll doesn't run bacause of some reason. But after open it run.

Posted: 03.08.2007, 12:00
by gto
trob wrote:
gto wrote:You're right mdaems! I've tried again, and refresh currently refreshes the entire dataset, just like close-open.

I remember to have tested sometime ago and it only refreshed the current row.. anyway :)
I have tried it too. :D The datas of two separeted record are refreshed in the grid.

So what is the difference?
I know, that when i call, refresh the afterscroll doesn't run bacause of some reason. But after open it run.
Hum, the main difference seems that refresh lock the position in the same record while close/open should reset the current record postion to the first.

Posted: 03.08.2007, 13:50
by trob
gto wrote:
trob wrote:
gto wrote:You're right mdaems! I've tried again, and refresh currently refreshes the entire dataset, just like close-open.

I remember to have tested sometime ago and it only refreshed the current row.. anyway :)
I have tried it too. :D The datas of two separeted record are refreshed in the grid.

So what is the difference?
I know, that when i call, refresh the afterscroll doesn't run bacause of some reason. But after open it run.
Hum, the main difference seems that refresh lock the position in the same record while close/open should reset the current record postion to the first.
So, The difference is not the speed, cpu-work, data transmission, etc. Hm?

Posted: 03.08.2007, 14:28
by gto
Let's go deep into the code:

The Close/Open procedures, aside from the Active property management, make use of InternalOpen and InternalClose, defined as virtual and abstract (to be implemented by component who inherits it).

The complete way is:
Open/Close -> SetActive -> OpenCursor/CloseCursor -> DoInternalOpen/DoInternalClose -> InternalOpen/InternalClose.

If we look at ZAbstractRODataset (the main ancestor of Zeos Datasets), InternalOpen and InternalClose are the procedures which really do the hard work, creating the ResultSet, sorting and all the stuff.

With refresh, the way is something different, but the goal is the same:
Refresh -> InternalRefresh -> InternalOpen/InternalClose.

The InternalRefresh procedure, at ZAbstractRODataset, is defined as follows:

Code: Select all

{**
  Performs an internal refreshing.
}

procedure TZAbstractRODataset.InternalRefresh;
var
   RowNo: Integer;
   Found: Boolean;
   KeyFields: string;
   Temp: TZVariantDynArray;
   KeyValues: Variant;
   FieldRefs: TObjectDynArray;
   OnlyDataFields: Boolean;
begin
   FieldRefs := nil;
   if Active then
   begin
      if CurrentRow > 0 then
      begin
         RowNo := Integer(CurrentRows[CurrentRow - 1]);
         if ResultSet.GetRow <> RowNo then
            ResultSet.MoveAbsolute(RowNo);

         if Properties.Values['KeyFields'] <> '' then
            KeyFields := Properties.Values['KeyFields']
         else
            KeyFields := DefineKeyFields(Fields);
         FieldRefs := DefineFields(Self, KeyFields, OnlyDataFields);
         SetLength(Temp, Length(FieldRefs));
         RetrieveDataFieldsFromResultSet(FieldRefs, ResultSet, Temp);
         if Length(FieldRefs) = 1 then
            KeyValues := EncodeVariant(Temp[0])
         else KeyValues := EncodeVariantArray(Temp);
      end
      else
      begin
         KeyFields := '';
         KeyValues := Unassigned;
      end;

      DisableControls;
      try
         try
            FRefreshInProgress := True;
            InternalClose;
            InternalOpen;
         finally
            FRefreshInProgress := False;
         end;

         DoBeforeScroll;
         if KeyFields <> '' then
            Found := Locate(KeyFields, KeyValues, [])
         else Found := False;
      finally
         EnableControls;
      end;

      if not Found then
      begin
         DoBeforeScroll;
         DoAfterScroll;
      end;
   end;
end;
You can clearly see the InternalClose/InternalOpen call here.

Now, from a practical view, the Close/Open method use a long road to achieve the same objectives. And Close/Open were meant to be used when you really want to Close or Open the dataset. I have not much spare time for now, but it should be calling some procedure more than refresh would do. This is a question that only tests will answer with precision :)

And a little finalle: The refresh method uses Locate, when the dataset has KeyFields, to find the previous selected record. If it's found, so the dataset don't fire Scroll events, as the selected record still the same. But if it's not found, then they're fired.