delphitclientdatasettdatasetprovider

Does TClientDataSet.ApplyUpdates(0) require to execute CheckBrowseMode/Post before?


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?


Solution

  • 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:

    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;