Menu ▾ ▴

#540 LocateRecord on a readonly Table fails

Unknown
open
nobody
None
Bug Report
2021-11-19
2021-11-15
hemmingway
No

LocateRecord on a readonly Table fails in TZAbstractRODataset.SetFieldData:
if not RequestLive and (Field.FieldKind = fkData) then RaiseReadOnlyError;
Table State is dsSetKey.

Discussion

  • marsupilami79

    marsupilami79 - 2021-11-15

    Hello Hemmingway,

    how do you trigger that problem? LocateRecord is a part of TZAbstractRWDataSet.PSUpdateRecord. So it should only be called when updating data. If possible, please post a minimum working examplr that reproduces the problem.

    Best regards,

    Jan

     
    • hemmingway

      hemmingway - 2021-11-16

      Hello Jan,

      i have written a MySQL replacement for BDE TTable.
      The locate function for it requires LocateRecord in the same way as BDE:

      function TBDEDataSet.Locate(const KeyFields: string;
      const KeyValues: Variant; Options: TLocateOptions): Boolean;
      begin
      DoBeforeScroll;
      Result := LocateRecord(KeyFields, KeyValues, Options, True);
      if Result then
      begin
      Resync([rmExact, rmCenter]);
      DoAfterScroll;
      end;
      end;

      I have updated an old BDE project via text replace for .pas and .dfm
      files: TTable -> TMySQLTable.
      The locate function on the BDE version works with a readonly table. The
      MySQL version fails in TZAbstractRODataset.SetFieldData.

      Best regards, Bernhard

       

      Last edit: hemmingway 2021-11-16
      • marsupilami79

        marsupilami79 - 2021-11-16

        Hello Bernhard,

        sooo - I took a look at Delphi 7. LocateRecord is a protected method in TTable. It was not meant to be used. Unfortunately Borland decided to not document protected methods in the Delphi 7 help anymore. So I don't know the exact semantics of that method and I amnot going to install Delphi 6 just to take a look into that help ;)

        Anyway - for debugging this I need a working example (Create script, insert script, program) that demonstrates the problem. Everything else is like trying to look into a crystal ball.

        Best regards,

        Jan

         
  • hemmingway

    hemmingway - 2021-11-18

    Hello Jan,

    my component is started in 2005 with Delphi 7. Therefore the old behaviour. In the zip is a short part of this component. The attributes for tzconnection are empty.
    GetIndexField(0).AssignValue(Value) in my source causes the error.
    My version of ZAbstractRODataset.pas is attached. I think, there is no risk.

    Best regards, Bernhard

     

    Last edit: hemmingway 2021-11-18
    • marsupilami79

      marsupilami79 - 2021-11-19

      Hello Bernhard,

      I had to compile without your version of ZAbstractRODataset.pas because it seems to be from an aged version of Zeos. It simply doesn't fit anymore.

      But then - for me the root cause is what you already posted here:

      GetIndexField(0).AssignValue(Value) in my source causes the error.

      It doesn't make sense to call AssignValue on a readonly dataset since AssignValue tries to modify the data.

      On a deeper level: Why does LocateRecord - which I assume should locate a record - call SetKeyFields, which seems to be made to change the key field values? Does it make sense for a method that is meant to locate data to change data in reality?

      Best regards,

      Jan

       
  • hemmingway

    hemmingway - 2021-11-19

    Hello Jan,

    in BDE I found

    procedure TTable.FindNearest(const KeyValues: array of const);
    begin
    CheckBrowseMode;
    SetKeyFields(kiLookup, KeyValues);
    GotoNearest;
    end;

    So I used SetKeyFields in my LocateRecord function in the same way.
    Only the KeyFields are changed, not the real data.

    Best regards, Bernhard

     

Log in to post a comment.