1. A report "Can''t read Buffer.Incorrect RecordNo" appeared on adding a new record to the database. An exception arose on trying to refresh an empty dataset.
function TRecordsCache.OldBuffer(RecordNo:integer): PChar;
begin
 if SaveChangeLog then
 begin
  if RecordNo<=FRecordCount then
   ReadRecordBuffer(RecordNo,FOldBuffer,True)
  else
   ClearOldBuffer
 end
 else
 begin
   if FOldBufRecordNumber<>RecordNo then
    if RecordNo<=FRecordCount then
     SaveOldBuffer(RecordNo)
    else
     ClearOldBuffer
 end;
 Result:=FOldBuffer
end;

procedure TRecordsCache.SaveOldBuffer(RecordNo: integer);
begin
 if SaveChangeLog then
   SaveToChangeLog(RecordNo)
 else
 begin
  if RecordNo<=FRecordCount then
   ReadRecord(RecordNo,FOldBuffer)
  else
   ClearOldBuffer;
  FOldBufRecordNumber:=RecordNo;
 end;
end;
2. Incorrect FullRefresh occurred with CacheModelKind=cmkLimitedBufferSize
unit FIBDataSet;

function TFIBCustomDataSet.RefreshAround(BaseQuery: TFIBQuery;var  
BaseRecNum:integer;
IgnoreEmptyBaseQuery:boolean = True;ReopenBaseQuery:boolean = True
):boolean;

procedure ExecCurSelect( aCurSelect:TFIBQuery; SourceObject:ISQLObject);
begin
     aCurSelect.Close;
     AssignSQLObjectParams(aCurSelect,[SourceObject]);
     aCurSelect.Params.AssignValues(FQSelect.Params);
     aCurSelect.ExecQuery;
end;

function FetchAround(aCurSelect:TFIBQuery; RecordsLimit:integer;  
Arrow:smallint;
   FromRecNum:integer =-1
):boolean;
var
   i:integer;
begin
     if FromRecNum=-1 then
      FCurrentRecord:=BaseRecNum
     else
      FCurrentRecord:=FromRecNum;
     i:=RecordsLimit;
     Result := False;
     while  (i>0) and (aCurSelect.Next<>nil)  do
     begin
       Result := True;
       Inc(FCurrentRecord,Arrow);
       FetchRecordToCache(aCurSelect, FCurrentRecord);
       if Arrow<0 then
       begin
        vPartition^.BeginPartRecordNo:=FCurrentRecord;
        if vPartition^.EndPartRecordNo=-1 then
         vPartition^.EndPartRecordNo:=vPartition^.BeginPartRecordNo
       end
       else
       begin
        vPartition^.EndPartRecordNo  :=FCurrentRecord;
        if vPartition^.BeginPartRecordNo=-1 then
         vPartition^.BeginPartRecordNo:=vPartition^.EndPartRecordNo;
       end;
       Dec(i);
     end;
     if aCurSelect.Eof then
      if Arrow<0 then
       vPartition^.IncludeBof:=True
      else
       vPartition^.IncludeEof:=True;
end;

var
    RecordSource  :ISQLObject;
    EmptyDataSet  :boolean;
    NotFetchedCount:integer;
begin
with BaseQuery do
begin
   if ReopenBaseQuery then
   begin
    Close;
    Params.AssignValues(FQSelect.Params);
    ExecQuery;
    Next;
    Result:=not Eof;
   end
   else
    Result :=RecordCount>0;

end;

EmptyDataSet :=True;

if Result or (not IgnoreEmptyBaseQuery) then
begin
     if BaseRecNum<(FCacheModelOptions.FBufferChunks div 2) then
      BaseRecNum:=FCacheModelOptions.FBufferChunks div 2;

     if Result then
     begin
       EmptyDataSet     :=False;
       FetchRecordToCache(BaseQuery, BaseRecNum);
       vPartition^.BeginPartRecordNo:=BaseRecNum;
       vPartition^.EndPartRecordNo  :=BaseRecNum;
       RecordSource:=BaseQuery
     end
     else
     begin
      RecordSource:=Self;
     end;

     vPartition^.IncludeBof:=False;
     vPartition^.IncludeEof:=False;

     ExecCurSelect(FQSelectDescPart,RecordSource);
     ExecCurSelect(FQSelectPart,RecordSource);
     if not Result then
     begin
      vPartition^.BeginPartRecordNo:=-1;
      vPartition^.EndPartRecordNo  :=-1;
     end;

     if FetchAround(FQSelectDescPart,FCacheModelOptions.FBufferChunks div  
2,-1) then
      EmptyDataSet:=False;

     if not Result then
      Dec(BaseRecNum);

     NotFetchedCount:=FCacheModelOptions.FBufferChunks-(vPartition^.EndPartRecordNo-vPartition^.BeginPartRecordNo+2);
     if FetchAround(FQSelectPart,NotFetchedCount,1) then
      EmptyDataSet:=False;

     NotFetchedCount:=FCacheModelOptions.FBufferChunks-(vPartition^.EndPartRecordNo-vPartition^.BeginPartRecordNo+2);
     if NotFetchedCount>0 then
      FetchAround(FQSelectDescPart,NotFetchedCount,-1,vPartition^.BeginPartRecordNo);

     FQSelectDescPart.Close;

     if  Result then
      FCurrentRecord:=BaseRecNum
     else
     if EmptyDataSet then
      FCurrentRecord:=-1
     else
      FCurrentRecord:=BaseRecNum+1;
     FQCurrentSelect:=FQSelectPart ;

     BaseQuery.Close;
end;
end;
3. Local sorting and the CloneCurRecord method did not work.
unit FIBDataSet;

procedure GetInspectRecBuffer;
var
   dsState:TDataSetState;
begin
    dsState:=State;
    Allocated:=
     (dsState<>dsCalcFields) and (Field.FieldKind in  
[fkLookUp,fkCalculated]);
    if Allocated then
    begin
     Buff :=AllocRecordBuffer;
     ReadRecordCache(vInspectRecno, Buff, State=dsOldValue);
     if (Field.FieldKind in [fkLookUp,fkCalculated])  then
     try
      SetTempState(dsCalcFields);
      CalculateFields(Buff);
     finally
      RestoreState(dsState);
     end
    end
    else
    begin
     Allocated:=(dsState in [dsOldValue,dsFilter]) or
      (vTypeDispositionField=dfRRecNumber);
     if Allocated then
     begin
      Buff :=AllocRecordBuffer;
      ReadRecordCache(vInspectRecno, Buff, State=dsOldValue)
     end
     else
      Buff:=GetActiveBuf;
    end;
end;
4. On saving a dataset to the repository the query dialog always opened with an empty string.
unit RegFIBPlusEditors;

procedure TFIBGenSQlEd.SaveDataSetInfo;
var
  vDescription:string;
begin
  with Component as TpFibDataSet do
    if DataSet_ID = 0 then ShowMessage(Name + SCompEditDataSet_ID)
    else
      if DataBase = nil then ShowMessage(SDataBaseNotAssigned)
      else
      begin
        if not ExistDRepositaryTable(TFIBDataset(Component).DataBase) then
        begin
          if
            MessageDlg(SCompEditInfoTableNotExist, mtConfirmation, [mbOK, mbCancel], 0
            ) <> mrOk
            then Exit;
          CreateDRepositaryTable(TFibDataSet(Component).DataBase);
        end;
        vDescription:=TpFibDataSet(Component).Description;
        if not InputQuery(SCompEditSaveDataSetProperty, SCompEditDataSetDesc, vDescription) then
         Exit;
        SaveFIBDataSetInfo(TpFibDataSet(Component),vDescription);
        TpFibDataSet(Component).Description:=vDescription;
      end;
end;
5. When creating the SQL statements at design time, FibPlus 6 invoked an error in the Refreh SQL Query.
unit fraDSSQLEdit;

procedure TfDSSQLEdit.cmbTablesChange(Sender: TObject);
begin
with cmbTables do
  if ItemIndex>-1 then
  begin
   FUpdTableSynonym:=
    FormatIdentifier(FDatabase.SQLDialect,AliasForTable(SelectSQLEdit.SQLText,cmbTables.Text))    +'.';
   if FUpdTableSynonym[1]='@' then FUpdTableSynonym:='';     
  end
  else
   FUpdTableSynonym:='';

  LstKeyFields.Clear;  LstUpdFields.Clear;
  btnGetFieldsClick(btnGetFields);   
end;
6. On trying to connect to the database in design-time FIBPlus used the client library gds32.dll, though the LibraryName property had fbclient.dll.
unit pFIBDBEdit;

procedure TDBEditForm.TestBClick(Sender: TObject);
var TempDB : TFIBDatabase;
begin
  TestB.Enabled := false;
  TempDB := TFIBDatabase.Create(nil);
  try
    if LocalC.Checked then
      TempDB.DBName := DBNameE.Text
    else
      case ProtocolC.ItemIndex of
        0: TempDB.DBName := Format('\\%s\%s', [ServerE.Text, DBNameE.Text]);
        1: TempDB.DBName := Format('%s@%s', [ServerE.Text, DBNameE.Text]);
        2: TempDB.DBName := Format('%s:%s', [ServerE.Text, DBNameE.Text]);
      end;
    TempDB.DBParams.Assign(ParamsM.Lines);
    TempDB.UseLoginPrompt := UseLoginC.Checked;
/////////////
    TempDB.LibraryName    := aDatabase.LibraryName;
////^^^^^^^^^ to add

    TempDB.SQLDialect :=  DialectC.ItemIndex + 1;
    TempDB.Connected := True;
    ShowMessage(SDBEditSuccessConnection);
  finally
    TempDB.Free;
    TestB.Enabled := true;
  end;
end;
6. If Select uses macro, refresh did not work.
function TFIBCustomDataSet.InternalRefreshRow(Qry: TFIBQuery; Buff:Pointer):boolean;
var
  iCurScreenState: Integer;
begin
  ChangeScreenCursor(iCurScreenState);
  Result:=False;
  try
    if Buff=nil then
     Exit;
    if not EmptyStrings(Qry.SQL)  and (Active) then
    begin
     if not FCachedUpdates and (CacheModelOptions.CacheModelKind=cmkStandard) then
      SaveOldBuffer(Buff);
     if  not (Qry.Open  or Qry.ProcExecuted) then
     begin
      SetQueryParams(Qry, Buff);
      PrepareQuery(skRefresh);
      if (poStartTransaction in Options) and
        not Qry.Transaction.InTransaction
      then
       Qry.Transaction.StartTransaction;
      Qry.ExecQuery;
     end;
     if Qry.Open then
      with PRecordData(Buff)^ do
      try
        if (Qry.SQLType = SQLExecProcedure) or  (Qry.Next <> nil) then
        begin
          FetchCurrentRecordToBuffer(Qry,PRecordData(Buff)^.rdRecordNumber,Buff);
          Result:=True;
        end
        else
        if poRefreshDeletedRecord in Options then
        begin
          if (CacheModelOptions.CacheModelKind=cmkStandard) then
          begin
           CacheDelete;
           DoAfterRefresh;
          end;
        end;
      finally
        Qry.Close;
      end;
    end
    else
    if RecordCount>0 then
      FIBError(feCannotRefresh, [CmpFullName(Self)]);
  finally
   RestoreScreenCursor(iCurScreenState);
  end;
end;

Preview text: Use these hot fixes for FIBPlus 6.0 if you would not like to wait for FIBPlus 6.0 Service Pack
Prices in Euro:

235 (1 copy)
1250 (unlimited)

Volume discounts are available...

Navigation



In the 30 years in the IT industry from development to IT Manager, I have
rarely used third party components but I would not be without your product. >>

John Hart ,Tradewinds Software Pty Ltd
FOR CUSTOMERS
Download full versions and updates in your Personal Area