Duplicate Details Fetch

Hello,
i’ve discovered a bug in fetching details mechanism in your latest release. Sometimes details are fetched even if they were already fetched before. You can try it on a little sample that i’ve attached.

There’s a little specific course of steps to achieve an error, so please follow exactly this scenario.

  1. Open the sample - you can see the detail table’s record count in the left down corner of the form.
  2. Click on record with ID 19 (PDAs) on the master table (it’s the one on the top) - you can see that there’s an eight records in the detail table.
  3. Click on records “Fax-modems”, “Flash drives” and “Keyboards” - these have no details
  4. Click back on record 19 (PDAs) - you can see that there’s a sixteen records in details and each on si duplicate (there was an eight records in step 2)

I’ve discovered that the cause of the problem is in TDADataTable.FetchMastersDetails where on the line 3212 method “IsNeedToFetch” is tested and even if it should return False, it returns true. True reason of that is in the changes that you’ve made in TDAMasterKeyList class. In the previous release there was a sort before IndexOf. Now the mechanism was probably replaced in the method Add that should secure that the list is allways sorted. But there’s a bug in that method (TDAMasterKeyList.Add).

Code:
if C > 0 then
inherited Add(aKey)
else
Insert(I, aKey);

should be IMHO replaced with:
if C > 0 then
Insert(I, aKey)
else
inherited Add(aKey);

… an author gets a position of a duplicate key but finally he doesn’t use it and places the AKey on the last position by calling the inherited Add method. I’ve modified code this way and everything works fine.

BUT there’s another thing i don’t understand. Back to the method TDADataTable.FetchMastersDetails somewhere near the line 3239 there’s a try/except sequence that should raise an “err_MasterRecordSHasBeenFetchedTwice” and there i see two problems.

  1. Master record %s has been fetched twice’ - needs a string to be formated but there’s “key” (TDAMasterKeyID) used as an argument. So if program comes to that line, it ends up with format error instead of an intended exception.

  2. TDAMasterKeyList allows to have a duplicates in it so there’s no exception raised if i try tu add duplicate key in it. If it should’n allow duplicates then there shoudl be an exception raised on in the TDAMasterKeyList.Add instead if calling Insert(I, AKey); I’ve tried this modification but then i get many exceptions, cause mostly there’s no check of adding a duplicate key in TDADataTable.DoCascadeRemoteAllInOneFetch_ProcessDetailTable.

Regards, Jaroslav

daSample.zip (667.1 KB)

Thanks, logged as bugs://73164

bugs://73164 got closed with status fixed.

can you apply this patch and retest in your environment, pls
uDADataTable.pas:

function TDAMasterKeyList_Compare(aKey1, aKey2: pointer):integer;
..
    Result := TDAMasterKeyID(aKey1)[i] - TDAMasterKeyID(aKey2)[i]; //changed

procedure TDAMasterKeyList.Add(aKey: TDAMasterKeyID);
..
  if C < 0 then begin
    if L < Count then
      Insert(L, aKey)
    else
      inherited Add(aKey)
  end
  else
    Insert(I, aKey); // fixed
end; 

earlier masterkey was generated as string.
nowadays it was changed and now it is binary data.
pls replace

          try
            AddMasterKey(key, True);
          except
            DAError(True,err_MasterRecordSHasBeenFetchedTwice, [key]);
          end;

with

          if fFetchedMasters.IndexOf(Key) = -1  then
            AddMasterKey(key, True)
          else
            DAError(True,err_MasterRecordSHasBeenFetchedTwice, ['']);

fix was added into #73164

Hi Evgeny,

thanks for fixes, it works OK.

Regards, Jaroslav