0
votes

I have TIBQuery-TDataSetProvider-TClientDataSet chain in Delphi 2009 (Firebird 3.0) and I execute MyClientDataSet.ApplyUpdates(0). Am I required to call CheckBrowseMode or Post on this CDS before calling ApplyUpdates(0). I am almost sure that I am required to call Post/CheckBrowseMode and I think that no-posted updates will not be applied to the IBQuery, I have no documentation for/against such thinking but it is logical to think so. But sometimes I can observe that MyClientDataSet is in [dsInsert, dsEdit] state before ApplyUpdates(0) and the new values are still posted and saved in query. But there are evidence and reason against that as well. So - I am confused.

Of course, I don't use CachedUpdated for TIBQuery (because there is CDS) and this is not the question about commiting of transactions, I strongly control them and that issue is excluded.

I made test: I put raise Exception in the BeforePost event of MyClientDataSet and MadException gives trace:

TMyDM.MyClientDataSetBeforePost
TDataSet.DoBeforePost
TDataSet.Post
TCustomClientDataSet.Post
TDataSet.CheckBrowseMode
TCustomClientDataSet.ApplyUpdates

So, there is empirical evidence, that CheckBroseMode is called automatically, but is it by accident (e.g. due to some special configuration of DataSetProvider or ClientDataSet) or is it rule that I can find in the documentation?

1

1 Answers

4
votes

or is it rule that I can find in the documentation?

There is a simpler rule, which should be self-evident, I would have thought: If the CDS's state is dsEdit or dsInsert, one might think of it as being in a change-pending state - changes have made (e.g. in a DB-aware control) but not yet been written back to the CDS's record buffer (or buffers if it has nested data). Otoh, the point of calling ApplyUpdates is to write changes in the record buffer back to the source dataset via the DSP. It would seem elementary therefore that one should not attempt to call ApplyUpdates while the CDS is in dsEdit/dsInsert. In any case, CheckBrowse mode is called by TCustomClientDataSet.ApplyUpdates:

function TCustomClientDataSet.ApplyUpdates(MaxErrors: Integer): Integer;
var
  RootDataset: TCustomClientDataset;
begin
  CheckBrowseMode;
  RootDataset := Self;
  while RootDataset.FParentDataSet <> nil do
    RootDataset := RootDataset.FParentDataset;
  with RootDataset do
    if ChangeCount = 0 then
      Result := 0 else
      Reconcile(DoApplyUpdates(Delta, MaxErrors, Result));
end;

It is worth noting that if a dataset's state is dsEdit or dsInsert, CheckBrowseMode does one of three things:

  • Nothing, except calling CheckActive and then DataEvent(deCheckBrowseMode, 0), if the dataset's state is not dsEdit, dsInsert or dsSetKey
  • Calls Post if the current record had been modified
  • Calls Cancel otherwise.

procedure TDataSet.CheckBrowseMode; begin CheckActive; DataEvent(deCheckBrowseMode, 0); case State of dsEdit, dsInsert: begin UpdateRecord; if Modified then Post else Cancel; end; dsSetKey: Post; end; end;