RTC Forums

Subscription => Support => Topic started by: manoi on August 11, 2017, 06:32:46 AM



Title: RTCMemDataSet Locate Method
Post by: manoi on August 11, 2017, 06:32:46 AM
Hi,

I've use TRTCMemDataset in mobile application (freepascal) and use it as TClientDataset replacement and it work very well but I need the locate function to work from RTCMemDataset.

Do you have any suggestion ?


Title: Re: RTCMemDataSet Locate Method
Post by: D.Tkalcec (RTC) on August 11, 2017, 07:28:24 AM
Sorry, but the TRtcMemDataSet component is deprecated and I have no plans to extend it with new features. If you need anything that is NOT already implemented in the TRtcMemDataSet component and you can NOT port your project to a later Delphi version to use the TRtcClientDataSet component (which is based on TClientDataSet), you could try some other in-memory DataSet component for FreePascal to see if it better suits your needs, or ... you could write your own version of a "TRtcMemDataSet" component and implement the missing function(s) yourself.

Best Regards,
Danijel Tkalcec


Title: Re: RTCMemDataSet Locate Method
Post by: manoi on August 12, 2017, 04:05:21 AM
OK. I've modify routine from JvDBUtils.DataSetLocateThrough

Code:
function DataSetLocateThrough(DataSet: TDataSet; const KeyFields: string;
  const KeyValues: Variant; Options: TLocateOptions): Boolean;
var
  FieldCount: Integer;
  Fields: TList;
  OldRecNo: Integer;

  function CompareField(Field: TField; Value: Variant): Boolean;
  var
    S: string;
  begin

    if Field.DataType = ftString then
    begin
      if Value = Null then
        Result := Field.IsNull
      else
      begin
        S := Field.AsString;
        if loPartialKey in Options then
          Delete(S, Length(Value) + 1, MaxInt);
        if loCaseInsensitive in Options then
          Result := AnsiCompareText(S, Value) = 0
        else
          Result := AnsiCompareStr(S, Value) = 0;
      end;
    end
    else
    begin
      Result := (Field.Value = Value);
    end;
  end;

  function CompareRecord: Boolean;
  var
    I: Integer;
  begin
    if FieldCount = 1 then
      Result := CompareField(TField(Fields.First), KeyValues[0])
    else
    begin
      Result := True;
      for I := 0 to FieldCount - 1 do
        Result := Result and CompareField(TField(Fields[I]), KeyValues[I]);
    end;
  end;

begin



  Result := False;
  OldRecNo:=0;
  with DataSet do
  begin
    CheckBrowseMode;
    if Bof and Eof then
      Exit;
  end;
  Fields := TList.Create;
  try
    DataSet.GetFieldList(Fields, KeyFields);


    FieldCount := Fields.Count;
    Result := CompareRecord;
    if Result then
      Exit;
    DataSet.DisableControls;
    try
      OldRecNo := DataSet.Recno;
      try
        with DataSet do
        begin
          First;
          while not EOF do
          begin
            Result := CompareRecord;
            if Result then
              Break;
            Next;
          end;
        end;
      finally
        if not Result and (OldRecNo>0) then
          DataSet.RecNo := OldRecNo;
      end;
    finally
      DataSet.EnableControls;
    end;
  finally
    Fields.Free;
  end;
end;



and modify TRtcBaseDataSet.Locate to

Code:
function TRtcBaseDataSet.Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions): Boolean;
begin
  CheckBiDirectional;
  Result := DataSetLocateThrough(Self, KeyFields, KeyValues, Options);
  // ??
end;

Now it work.


Title: Re: RTCMemDataSet Locate Method
Post by: D.Tkalcec (RTC) on August 12, 2017, 07:49:59 AM
Ok. Thank you for your feedback.

Best Regards,
Danijel Tkalcec