Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Midas/TClientDataSet    [ Add a report in this area ]  
Report #:  2333   Status: Closed
Incorrect Delta after ApplyUpdates(0) with poPropogateChanges
Project:  Delphi Build #:  6.240
Version:    7.0 Submitted By:   Vlad Horsun
Report Type:  Basic functionality failure Date Reported:  9/12/2002 4:44:47 AM
Severity:    Commonly encountered problem Last Updated: 10/6/2006 6:50:47 AM
Platform:    All platforms Internal Tracking #:   148824
Resolution: Fixed (Resolution Comments) Resolved in Build: : 7.0.8.1
Duplicate of:  None
Voting and Rating
Overall Rating: (7 Total Ratings)
3.57 out of 5
Total Votes: 7
Description
  We have a server with rule - 'Capital' must be at least 3 character length. Also server add ' !' to value entered by the user and propagate it back to client.

  If user violate server rule - he correct data and again apply it to server.

  After secondary call ApplyUpdates (returned 0 - successful call) Delta has records and ChangeCount still not 0.
Steps to Reproduce:
0. Download,  compile and run project in attachments

1. Click 'Open'

2. Edit field 'Capital' of first record - assign '1'
   (this violates server rules)

3. Post the record.
    ChangeCount in first status bar panel is 1 - its OK

4. Click 'Apply' - see 'Length must be 3 or more !' server error.
    ChangeCount in first status bar panel is 1 - its OK
    In second status bar panel see 'Last apply errors = 1' - its OK

5. Edit field 'Capital' of first record - assign '12345'
   (this not violates server rules)

6. Post the record.
    ChangeCount in first status bar panel is 1 - OK

7. Click 'Apply'.
    ChangeCount in first status bar panel is 1 - its WRONG,
    In second status bar panel see 'Last apply errors = 0' - its OK
    Field 'Capital' changed by the server ('12345 !' ) and return
to the client (thanks to poPropogateChanges in DataSetProvider1.Options)

8. Click 'Delta' - see 2 records - its WRONG

9. Click refresh on navigator panel - see 'Must apply updates...' - its WRONG
Workarounds
if (ApplyUpdates(0) = 0) and (ChangeCount <> 0)
then MergeChangeLog

This is a right workaround if you call ApplyUpdates(0), and useless if you call ApplyUpdates with non zero MaxErrors :(

---------

DBCLIENT.PAS
(***) (* Delphi 5.0 - 7.0 *)
(* Fix for QC2333. Incorrect Delta after ApplyUpdates(0) with poPropogateChanges
   NOTE:
   This fix is only intented for use with ApplyUpdates(0) *)
(* Dave Rowntree 3/7/03 *)
function TCustomClientDataSet.Reconcile(const Results: OleVariant): Boolean;


  (***) (* add this function *)
  function ResultsErrorFree(RDP: OleVariant): Boolean;
  var
    cdsT: TClientDataSet;
  begin
    Result := True;
    cdsT := TClientDataSet.Create(nil);
    try
      with cdsT do
      begin
        Data := RDP;
        First;
        While not Eof and (Result = True) do
          if (FieldByName('ERROR_CODE').AsInteger = 0) then
            Next else
            Result := False;
      end;
    finally
      cdsT.Free;
    end;
  end;


var
  RCB: Pointer;
  I: Integer;
  AField: TField;
begin
  if VarIsNull(Results) then MergeChangeLog else
  begin
    UpdateCursorPos;
    if Assigned(FOnReconcileError) then
      RCB := @TCustomClientDataSet.ReconcileCallback else
      RCB := nil;
    FReconcileDataSet := TCustomClientDataSet.Create(Self);
    try
      Check(FDSBase.Clone(0, True, False, FReconcileDataSet.FDSBase));
      FReconcileDataSet.ObjectView := True;
      FReconcileDataSet.Open;
      for I := 0 to FReconcileDataSet.FieldCount - 1 do
      begin
        AField := Self.FindField(FReconcileDataSet.Fields[I].FieldName);
        if Assigned(AField) then
          FReconcileDataSet.Fields[I].DisplayLabel := AField.DisplayLabel;
      end;
      Check(FDSBase.Reconcile_MD(FReconcileDataSet.FDSBase, FDeltaPacket,
        VarToDataPacket(Results), Integer(Self), RCB));

      if ResultsErrorFree(Results) then FDSBase.AcceptChanges; (***) (* add this line *)

    finally
      FReconcileDataSet.Free;
      FReconcileDataSet := nil;
    end;
    Resync([]);
  end;
  Result := (ChangeCount = 0);
end;
Attachment
2333.zip
Comments

Dave Rowntree at 9/20/2002 2:06:23 AM -
I have rated this report '1'.

Please provide a description of the problem in 'Description'.

Please provide a _compileable_ test case in 'Attachments'.

Please provide a description of how to use the test case to demonstrate the problem in 'Steps'.

Thank you.

Vlad Horsun at 10/1/2002 7:05:54 AM -
Now I have found time and made test project and more detailed descripton and steps.
Will you reconsider your rating, Dave ?

Thank you.

Dave Rowntree at 10/7/2002 9:26:47 AM -
Vlad Horsun said - "Now I have found time and made test project and more detailed descripton and steps.
Will you reconsider your rating, Dave ?

Certainly. Thank you for updating the report. I have amended my rating.

I have added an alternative test case to the attachments zip file.

Your test case:
1. Uses the BDE.
2. Uses ResolveToDataSet.

Since the BDE is deprecated in D7, and use of ResolveToDataSet is not particularly recommended, my initial thought was that it might be something related to the use of these. So I created a test case that used ADO as the DSP.DataSet and did not use ResolveToDataSet. The problem still persists so I added my test case to the report in addition to yours.

This problem also occurs in D7.

Andres Allkivi at 10/3/2002 4:20:39 AM -
I have also observed this behaviour in D5

Dave Rowntree at 10/7/2002 9:29:26 AM -
I have amended the Severity from 1 to 2.

Thomas Wilk at 11/10/2002 6:34:16 AM -
All,

Would a call to MergeChangeLog after ApplyUpdates be a work-around for this?   I seem to remember that I had this problem in the past and calling MergeChangeLog seemed to fix it.    Thoughts?

Tom Wilk

Vlad Horsun at 11/11/2002 5:09:27 AM -
This can be a right workaround only if all the changes was applied successfully.

Mathias Burbach at 4/16/2003 4:36:35 PM -
Hello Vlad,

assuming that ApplyUpdates returns a zero but ChangeCount is still greater zero, would it be save to call MergeChangeLog?

Salut,
  Mathias

Vlad Horsun at 4/24/2003 12:30:03 AM -
Yes, seems that this code:

if (ApplyUpdates() = 0) and (ChangeCount <> 0)
then MergeChangeLog

can be a partial workaround.

This is a right workaround if you call ApplyUpdates(0), and useless if you call ApplyUpdates with non zero MaxErrors :(

Pascal Desjardins at 3/6/2003 12:13:16 PM -
This also happens in Delphi version 5.01

Dave Rowntree at 5/17/2003 5:50:00 AM -
This problem also occurs in D7.

adrian gallero at 9/10/2003 8:03:10 AM -
Hi,

I am having what I think is this problem, but I don't know it it qualifies as the same or not. The thing is, you don't really need to have an exception on the server.

Try this on the test case:

    Select the fisrt row
    Set capital to 'this is a test'
    Select the second row. (so the record get posted) We don't really need to select another row, just post the changes.
    Select the first row again.
    Set Capital to 'another test'
    Select Second Row again. (To post)
    Apply updates.

    Look at the delta, it is still there (pointing to the first record). Canceling updates will give the "key violation" error and applying again will give "record not found or changed by another user"

As said, I don't know if this is the same bug, but I hope it helps to localize it. I am trying to make a briefcase app, so users can change many records before Applying updates, and this bug is making the whole thing unusable. I do need to have an Applyupdates(-1), as when they sincronyze data on the briefaces, I want to apply as much records as is possible.

With my best regards,
   Adrian.

Dave Rowntree at 5/11/2004 3:23:47 AM -
Fixed in Midas.dll

Server Response from: CODE1