2
0
Эх сурвалжийг харах

* Refactored indexes: TBufIndex is now a class instead of a record. All index-related code (such as for scrolling) should eventually be placed into this class. This is not done yet completely, but a start is made.
* From now on, FLastRecBuf.Next of the dl-list is linked to the first record. This way it is possible to move the cursur to the first record by setting the current record to the last record in the list. With this trick several corner-case checks which were necessary on every scroll-action on the dataset have become obsolete and are removed.

git-svn-id: trunk@11382 -

joost 17 жил өмнө
parent
commit
d647fff9f1

+ 210 - 96
packages/fcl-db/src/base/bufdataset.pas

@@ -115,8 +115,16 @@ type
                   end;
                   end;
   TDBCompareStruct = array of TDBCompareRec;
   TDBCompareStruct = array of TDBCompareRec;
 
 
-  PBufIndex = ^TBufIndex;
-  TBufIndex = record
+  { TBufIndex }
+
+  TBufIndex = class(TObject)
+  private
+    FStoredRecBuf  : PBufRecLinkItem;
+    FCurrentRecBuf  : PBufRecLinkItem;
+    function GetCurrentRecord: PChar;
+    function GetIsInitialized: boolean;
+    function GetSpareRecord: PChar;
+  public
     Name            : String;
     Name            : String;
     Fields          : TField;
     Fields          : TField;
     FieldsName      : String;
     FieldsName      : String;
@@ -133,6 +141,23 @@ type
     FFirstRecBuf    : PBufRecLinkItem;
     FFirstRecBuf    : PBufRecLinkItem;
 {$ENDIF ARRAYBUF}
 {$ENDIF ARRAYBUF}
     IndNr           : integer;
     IndNr           : integer;
+    FNeedScroll     : Boolean;
+    function ScrollBackward : TGetResult;
+    function ScrollForward : TGetResult;
+    function GetCurrent : TGetResult;
+    function ScrollFirst : TGetResult;
+
+    procedure StoreCurrentRecord;
+    procedure RestoreCurrentRecord;
+
+    function CanScrollForward : Boolean;
+    procedure DoScrollForward;
+    
+    procedure InitialiseSpareRecord(const ASpareRecord : PChar);
+    procedure ReleaseSpareRecord;
+    property SpareRecord : PChar read GetSpareRecord;
+    property CurrentRecord : PChar read GetCurrentRecord;
+    property IsInitialized : boolean read GetIsInitialized;
   end;
   end;
 
 
   TBufDataset = class(TDBDataSet)
   TBufDataset = class(TDBDataSet)
@@ -146,8 +171,7 @@ type
 {$ENDIF ARRAYBUF}
 {$ENDIF ARRAYBUF}
 
 
     FIndexesCount   : integer;
     FIndexesCount   : integer;
-    FCurrentIndex   : PBufIndex;
-    FCurrentRecBuf  : PBufRecLinkItem;
+    FCurrentIndex   : TBufIndex;
 
 
     FFilterBuffer   : pchar;
     FFilterBuffer   : pchar;
     FBRecordCount   : integer;
     FBRecordCount   : integer;
@@ -378,8 +402,8 @@ begin
 {$ENDIF}
 {$ENDIF}
   FIndexesCount:=0;
   FIndexesCount:=0;
   InternalAddIndex('DEFAULT_ORDER','',[],'','');
   InternalAddIndex('DEFAULT_ORDER','',[],'','');
+  FCurrentIndex:=FIndexes[0];
   InternalAddIndex('','',[],'','');
   InternalAddIndex('','',[],'','');
-  FCurrentIndex:=@FIndexes[0];
 
 
   FIndexDefs := TIndexDefs.Create(Self);
   FIndexDefs := TIndexDefs.Create(Self);
 
 
@@ -495,7 +519,7 @@ begin
 
 
 // Set FirstRecBuf and FCurrentRecBuf
 // Set FirstRecBuf and FCurrentRecBuf
   AIndex.FFirstRecBuf:=FIndexes[0].FFirstRecBuf;
   AIndex.FFirstRecBuf:=FIndexes[0].FFirstRecBuf;
-  FCurrentRecBuf:=AIndex.FFirstRecBuf;
+  FCurrentIndex.FCurrentRecBuf:=AIndex.FFirstRecBuf;
 // Link in the FLastRecBuf that belongs to this index
 // Link in the FLastRecBuf that belongs to this index
   PCurRecLinkItem[AIndex.IndNr].next:=AIndex.FLastRecBuf;
   PCurRecLinkItem[AIndex.IndNr].next:=AIndex.FLastRecBuf;
   AIndex.FLastRecBuf[AIndex.IndNr].prior:=PCurRecLinkItem;
   AIndex.FLastRecBuf[AIndex.IndNr].prior:=PCurRecLinkItem;
@@ -590,7 +614,7 @@ begin
   k:=k*2;
   k:=k*2;
 
 
   until MergeAmount = 1;
   until MergeAmount = 1;
-  AIndex.FLastRecBuf[AIndex.IndNr].next:=nil;
+  AIndex.FLastRecBuf[AIndex.IndNr].next:=AIndex.FFirstRecBuf;
   AIndex.FLastRecBuf[AIndex.IndNr].prior:=l;
   AIndex.FLastRecBuf[AIndex.IndNr].prior:=l;
 
 
 {$ENDIF}
 {$ENDIF}
@@ -662,10 +686,8 @@ begin
 {$IFNDEF ARRAYBUF}
 {$IFNDEF ARRAYBUF}
   for IndexNr:=0 to FIndexesCount-1 do with FIndexes[IndexNr] do
   for IndexNr:=0 to FIndexesCount-1 do with FIndexes[IndexNr] do
     begin
     begin
-    FFirstRecBuf := pointer(IntAllocRecordBuffer);
-    FLastRecBuf := FFirstRecBuf;
+    InitialiseSpareRecord(IntAllocRecordBuffer);
     end;
     end;
-  FCurrentRecBuf := FCurrentIndex^. FLastRecBuf;
 {$ELSE}
 {$ELSE}
   for IndexNr:=0 to FIndexesCount-1 do with FIndexes[IndexNr] do
   for IndexNr:=0 to FIndexesCount-1 do with FIndexes[IndexNr] do
     begin
     begin
@@ -692,36 +714,37 @@ end;
 procedure TBufDataset.InternalClose;
 procedure TBufDataset.InternalClose;
 
 
 var r  : integer;
 var r  : integer;
+    iGetResult : TGetResult;
 {$IFNDEF ARRAYBUF}
 {$IFNDEF ARRAYBUF}
     pc : pchar;
     pc : pchar;
 {$ENDIF}
 {$ENDIF}
 
 
 begin
 begin
   FOpen:=False;
   FOpen:=False;
-  with FIndexes[0] do
+  with FIndexes[0] do if IsInitialized then
     begin
     begin
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
     for r := 0 to FLastRecInd-1 do FreeRecordBuffer(FRecordArray[r]);
     for r := 0 to FLastRecInd-1 do FreeRecordBuffer(FRecordArray[r]);
 {$ELSE}
 {$ELSE}
-    FCurrentRecBuf := FFirstRecBuf;
-    while assigned(FCurrentRecBuf) do
+    iGetResult:=ScrollFirst;
+    while iGetResult = grOK do
       begin
       begin
       pc := pointer(FCurrentRecBuf);
       pc := pointer(FCurrentRecBuf);
-      FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
+      iGetResult:=ScrollForward;
       FreeRecordBuffer(pc);
       FreeRecordBuffer(pc);
       end;
       end;
-    FFirstRecBuf:=nil;
 {$ENDIF}
 {$ENDIF}
     end;
     end;
 
 
-  for r := 1 to FIndexesCount-1 do with FIndexes[r] do
+  for r := 0 to FIndexesCount-1 do with FIndexes[r] do if IsInitialized then
     begin
     begin
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
     FreeRecordBuffer(FRecordArray[FLastRecInd]);
     FreeRecordBuffer(FRecordArray[FLastRecInd]);
     SetLength(FRecordArray,FInitialBuffers);
     SetLength(FRecordArray,FInitialBuffers);
 {$ELSE}
 {$ELSE}
-    FreeRecordBuffer(pointer(FLastRecBuf));
-    FFirstRecBuf:= nil;
+    pc := SpareRecord;
+    ReleaseSpareRecord;
+    FreeRecordBuffer(pc);
 {$ENDIF}
 {$ENDIF}
     end;
     end;
 
 
@@ -754,22 +777,24 @@ end;
 
 
 procedure TBufDataset.InternalFirst;
 procedure TBufDataset.InternalFirst;
 begin
 begin
+  with FCurrentIndex do
+{$IFDEF ARRAYBUF}
 // if FCurrentRecBuf = FLastRecBuf then the dataset is just opened and empty
 // if FCurrentRecBuf = FLastRecBuf then the dataset is just opened and empty
 // in which case InternalFirst should do nothing (bug 7211)
 // in which case InternalFirst should do nothing (bug 7211)
-  with FCurrentIndex^ do
-{$IFDEF ARRAYBUF}
     if FCurrentRecInd <> FLastRecInd then
     if FCurrentRecInd <> FLastRecInd then
       FCurrentRecInd := -1;
       FCurrentRecInd := -1;
 {$ELSE}
 {$ELSE}
-    if FCurrentRecBuf <> FLastRecBuf then
-      FCurrentRecBuf := nil;
+    begin
+    FLastRecBuf[IndNr].next:=FFirstRecBuf;
+    FCurrentRecBuf := FLastRecBuf;
+    end;
 {$ENDIF}
 {$ENDIF}
 end;
 end;
 
 
 procedure TBufDataset.InternalLast;
 procedure TBufDataset.InternalLast;
 begin
 begin
   FetchAll;
   FetchAll;
-  with FCurrentIndex^ do
+  with FCurrentIndex do
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
     if FLastRecInd <> 0 then FCurrentRecInd := FLastRecInd;
     if FLastRecInd <> 0 then FCurrentRecInd := FLastRecInd;
 {$ELSE}
 {$ELSE}
@@ -792,6 +817,102 @@ begin
   result := ord(NullMask[x div 8]) and (1 shl (x mod 8)) > 0
   result := ord(NullMask[x div 8]) and (1 shl (x mod 8)) > 0
 end;
 end;
 
 
+function TBufIndex.GetCurrentRecord: PChar;
+begin
+  Result := pchar(FCurrentRecBuf);
+end;
+
+function TBufIndex.GetIsInitialized: boolean;
+begin
+  Result := (FFirstRecBuf<>nil);
+end;
+
+function TBufIndex.GetSpareRecord: PChar;
+begin
+  Result := pchar(FLastRecBuf);
+end;
+
+function TBufIndex.ScrollBackward: TGetResult;
+begin
+  if not assigned(FCurrentRecBuf[IndNr].prior) then
+    begin
+    Result := grBOF;
+    end
+  else
+    begin
+    Result := grOK;
+    FCurrentRecBuf := FCurrentRecBuf[IndNr].prior;
+    end;
+end;
+
+function TBufIndex.ScrollForward: TGetResult;
+begin
+  if (FCurrentRecBuf = FLastRecBuf) or // just opened
+     (FCurrentRecBuf[IndNr].next = FLastRecBuf) then
+    result := grEOF
+  else
+    begin
+    FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
+    Result := grOK;
+    end;
+end;
+
+function TBufIndex.GetCurrent: TGetResult;
+begin
+  if FFirstRecBuf = FLastRecBuf then
+    Result := grError
+  else
+    begin
+    Result := grOK;
+    if FCurrentRecBuf = FLastRecBuf then
+      FCurrentRecBuf:=FLastRecBuf[IndNr].prior;
+    end;
+end;
+
+function TBufIndex.ScrollFirst: TGetResult;
+begin
+  FCurrentRecBuf:=FFirstRecBuf;
+  if (FCurrentRecBuf = FLastRecBuf) or // just opened
+     (FCurrentRecBuf[IndNr].next = FLastRecBuf) then
+    result := grEOF;
+end;
+
+procedure TBufIndex.StoreCurrentRecord;
+begin
+  FStoredRecBuf:=FCurrentRecBuf;
+end;
+
+procedure TBufIndex.RestoreCurrentRecord;
+begin
+  FCurrentRecBuf:=FStoredRecBuf;
+end;
+
+procedure TBufIndex.DoScrollForward;
+begin
+  FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
+end;
+
+function TBufIndex.CanScrollForward: Boolean;
+begin
+  if (FCurrentRecBuf[IndNr].next = FLastRecBuf) then
+    Result := False
+  else
+    Result := True;
+end;
+
+procedure TBufIndex.InitialiseSpareRecord(const ASpareRecord : PChar);
+begin
+  FFirstRecBuf := pointer(ASpareRecord);
+  FLastRecBuf := FFirstRecBuf;
+  FLastRecBuf[IndNr].next:=FLastRecBuf;
+  FCurrentRecBuf := FLastRecBuf;
+end;
+
+procedure TBufIndex.ReleaseSpareRecord;
+begin
+  FFirstRecBuf:= nil;
+end;
+
 function TBufDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult;
 function TBufDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult;
 
 
 var Acceptable : Boolean;
 var Acceptable : Boolean;
@@ -800,36 +921,31 @@ var Acceptable : Boolean;
 
 
 begin
 begin
   Result := grOK;
   Result := grOK;
-  with FCurrentIndex^ do
+  with FCurrentIndex do
     begin
     begin
     repeat
     repeat
     Acceptable := True;
     Acceptable := True;
     case GetMode of
     case GetMode of
-      gmPrior :
+      gmPrior : Result := ScrollBackward;
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
         if FCurrentRecInd=0 then
         if FCurrentRecInd=0 then
           Result := grBOF
           Result := grBOF
         else
         else
           Dec(FCurrentRecInd);
           Dec(FCurrentRecInd);
-{$ELSE}
-        if not assigned(FCurrentRecBuf[IndNr].prior) then
-          begin
-          Result := grBOF;
-          end
-        else
-          begin
-          FCurrentRecBuf := FCurrentRecBuf[IndNr].prior;
-          end;
 {$ENDIF}
 {$ENDIF}
-      gmCurrent :
+      gmCurrent : Result := GetCurrent;
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
         if FCurrentRecInd = FLastRecInd then
         if FCurrentRecInd = FLastRecInd then
           Result := grError;
           Result := grError;
-{$ELSE}
-        if FCurrentRecBuf = FLastRecBuf then
-          Result := grError;
 {$ENDIF}
 {$ENDIF}
-      gmNext :
+      gmNext : begin
+               if not CanScrollForward and (getnextpacket = 0) then result := grEOF
+               else
+                 begin
+                 result := grOK;
+                 DoScrollForward;
+                 end;
+               end;
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
         if FCurrentRecInd = FLastRecInd then // Dataset is empty (just opened)
         if FCurrentRecInd = FLastRecInd then // Dataset is empty (just opened)
           begin
           begin
@@ -851,27 +967,6 @@ begin
           begin
           begin
           inc(FCurrentRecInd);
           inc(FCurrentRecInd);
           end;
           end;
-{$ELSE}
-        if FCurrentRecBuf = FLastRecBuf then // Dataset is empty (just opened)
-          begin
-          if getnextpacket = 0 then result := grEOF;
-          end
-        else if FCurrentRecBuf = nil then FCurrentRecBuf := FFirstRecBuf
-        else if (FCurrentRecBuf[IndNr].next = FLastRecBuf) then
-          begin
-          if getnextpacket > 0 then
-            begin
-            FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
-            end
-          else
-            begin
-            result:=grEOF;
-            end
-          end
-        else
-          begin
-          FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
-          end;
 {$ENDIF}
 {$ENDIF}
     end;
     end;
 
 
@@ -981,7 +1076,7 @@ begin
   if AValue<>'' then
   if AValue<>'' then
     begin
     begin
     FIndexes[1].FieldsName:=AValue;
     FIndexes[1].FieldsName:=AValue;
-    FCurrentIndex:=@FIndexes[1];
+    FCurrentIndex:=FIndexes[1];
     if active then
     if active then
       begin
       begin
       BuildIndex(FIndexes[1]);
       BuildIndex(FIndexes[1]);
@@ -999,7 +1094,8 @@ begin
   for i := 0 to FIndexesCount-1 do
   for i := 0 to FIndexesCount-1 do
     if SameText(FIndexes[i].Name,AValue) then
     if SameText(FIndexes[i].Name,AValue) then
       begin
       begin
-      FCurrentIndex:=@FIndexes[i];
+      FIndexes[i].FCurrentRecBuf:=FCurrentIndex.FCurrentRecBuf;
+      FCurrentIndex:=FIndexes[i];
       if active then Resync([rmCenter]);
       if active then Resync([rmCenter]);
       exit;
       exit;
       end;
       end;
@@ -1021,7 +1117,7 @@ begin
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
   FCurrentIndex^.FCurrentRecInd:=GetRecordFromBookmark(PBufBookmark(Buffer + FRecordSize)^);
   FCurrentIndex^.FCurrentRecInd:=GetRecordFromBookmark(PBufBookmark(Buffer + FRecordSize)^);
 {$ELSE}
 {$ELSE}
-  FCurrentRecBuf := PBufBookmark(Buffer + FRecordSize)^.BookmarkData;
+  FCurrentIndex.FCurrentRecBuf := PBufBookmark(Buffer + FRecordSize)^.BookmarkData;
 {$ENDIF}
 {$ENDIF}
 end;
 end;
 
 
@@ -1060,7 +1156,7 @@ begin
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
   FCurrentIndex^.FCurrentRecInd:=GetRecordFromBookmark(PBufBookmark(ABookmark)^);
   FCurrentIndex^.FCurrentRecInd:=GetRecordFromBookmark(PBufBookmark(ABookmark)^);
 {$ELSE}
 {$ELSE}
-  FCurrentRecBuf := pointer(ABookmark^);
+  FCurrentIndex.FCurrentRecBuf := pointer(ABookmark^);
 {$ENDIF}
 {$ENDIF}
 end;
 end;
 
 
@@ -1121,6 +1217,7 @@ function TBufDataset.getnextpacket : integer;
 
 
 var i : integer;
 var i : integer;
     pb : pchar;
     pb : pchar;
+    CursOnFirstRec : boolean;
 
 
 begin
 begin
   if FAllPacketsFetched then
   if FAllPacketsFetched then
@@ -1128,6 +1225,11 @@ begin
     result := 0;
     result := 0;
     exit;
     exit;
     end;
     end;
+  with FCurrentIndex do if FCurrentRecBuf = FLastRecBuf then
+    CursOnFirstRec := True
+  else
+    CursOnFirstRec := False;
+
   i := 0;
   i := 0;
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
   with FCurrentIndex^ do
   with FCurrentIndex^ do
@@ -1160,6 +1262,13 @@ begin
 {$ENDIF}
 {$ENDIF}
     inc(i);
     inc(i);
     end;
     end;
+  with FIndexes[0] do
+    FLastRecBuf^.next:=FFirstRecBuf;
+
+  with FCurrentIndex do
+    begin
+    if CursOnFirstRec then FCurrentRecBuf:=FLastRecBuf;
+    end;
   FBRecordCount := FBRecordCount + i;
   FBRecordCount := FBRecordCount + i;
   result := i;
   result := i;
 end;
 end;
@@ -1218,7 +1327,7 @@ begin
       if not ((x=1) and (FIndexes[1].FieldsName='')) then
       if not ((x=1) and (FIndexes[1].FieldsName='')) then
         begin
         begin
         BuildIndex(FIndexes[x]);
         BuildIndex(FIndexes[x]);
-        FCurrentRecBuf:=FCurrentIndex^.FFirstRecBuf;
+        FCurrentIndex.FCurrentRecBuf:=FCurrentIndex.FFirstRecBuf;
         end;
         end;
       end;
       end;
     Exit;
     Exit;
@@ -1327,7 +1436,7 @@ begin
     exit;
     exit;
     end;
     end;
   if state = dsFilter then  // Set the value into the 'temporary' FLastRecBuf buffer for Locate and Lookup
   if state = dsFilter then  // Set the value into the 'temporary' FLastRecBuf buffer for Locate and Lookup
-    with FCurrentIndex^ do
+    with FCurrentIndex do
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
       CurrBuff := FRecordArray[FLastRecInd]
       CurrBuff := FRecordArray[FLastRecInd]
 {$ELSE}
 {$ELSE}
@@ -1370,10 +1479,10 @@ begin
   InternalSetToRecord(ActiveBuffer);
   InternalSetToRecord(ActiveBuffer);
 {$IFNDEF ARRAYBUF}
 {$IFNDEF ARRAYBUF}
   // Remove the record from all active indexes
   // Remove the record from all active indexes
-  RemoveRecordFromIndex(FCurrentRecBuf,FIndexes[0]);
-  if FCurrentIndex=@FIndexes[1] then StartInd := 1 else StartInd := 2;
+  RemoveRecordFromIndex(FCurrentIndex.FCurrentRecBuf,FIndexes[0]);
+  if FCurrentIndex=FIndexes[1] then StartInd := 1 else StartInd := 2;
   for i := StartInd to FIndexesCount-1 do
   for i := StartInd to FIndexesCount-1 do
-    RemoveRecordFromIndex(FCurrentRecBuf,FIndexes[i]);
+    RemoveRecordFromIndex(FCurrentIndex.FCurrentRecBuf,FIndexes[i]);
 {$ENDIF}
 {$ENDIF}
 
 
   if not GetRecordUpdateBuffer then
   if not GetRecordUpdateBuffer then
@@ -1391,14 +1500,14 @@ begin
       FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := pchar(FCurrentRecBuf);
       FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := pchar(FCurrentRecBuf);
       FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := FCurrentRecBuf;
       FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := FCurrentRecBuf;
 
 
-      with FCurrentIndex^ do
+      with FCurrentIndex do
         FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
         FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
 {$ENDIF}
 {$ENDIF}
       end;
       end;
     end
     end
   else with FIndexes[0] do
   else with FIndexes[0] do
     begin
     begin
-    with FCurrentIndex^ do
+    with FCurrentIndex do
       FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
       FCurrentRecBuf := FCurrentRecBuf[IndNr].next;
     if FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind = ukModify then
     if FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind = ukModify then
       begin
       begin
@@ -1490,7 +1599,7 @@ begin
           if assigned(PBufRecLinkItem(BookmarkData)^.prior) then  // or else it was the first record
           if assigned(PBufRecLinkItem(BookmarkData)^.prior) then  // or else it was the first record
             PBufRecLinkItem(BookmarkData)^.prior^.next := BookmarkData
             PBufRecLinkItem(BookmarkData)^.prior^.next := BookmarkData
           else
           else
-            FCurrentIndex^.FFirstRecBuf := BookmarkData;
+            FCurrentIndex.FFirstRecBuf := BookmarkData;
           PBufRecLinkItem(BookmarkData)^.next^.prior := BookmarkData;
           PBufRecLinkItem(BookmarkData)^.next^.prior := BookmarkData;
 {$ENDIF}
 {$ENDIF}
           inc(FBRecordCount);
           inc(FBRecordCount);
@@ -1506,10 +1615,10 @@ begin
           if assigned(PBufRecLinkItem(BookmarkData)^.prior) then // or else it was the first record
           if assigned(PBufRecLinkItem(BookmarkData)^.prior) then // or else it was the first record
             PBufRecLinkItem(BookmarkData)^.prior^.next := PBufRecLinkItem(BookmarkData)^.next
             PBufRecLinkItem(BookmarkData)^.prior^.next := PBufRecLinkItem(BookmarkData)^.next
           else
           else
-            FCurrentIndex^.FFirstRecBuf := PBufRecLinkItem(BookmarkData)^.next;
+            FCurrentIndex.FFirstRecBuf := PBufRecLinkItem(BookmarkData)^.next;
           PBufRecLinkItem(BookmarkData)^.next^.prior := PBufRecLinkItem(BookmarkData)^.prior;
           PBufRecLinkItem(BookmarkData)^.next^.prior := PBufRecLinkItem(BookmarkData)^.prior;
           // resync won't work if the currentbuffer is freed...
           // resync won't work if the currentbuffer is freed...
-          with FCurrentIndex^ do
+          with FCurrentIndex do
           if FCurrentRecBuf = BookmarkData then FCurrentRecBuf := FCurrentRecBuf^.next;
           if FCurrentRecBuf = BookmarkData then FCurrentRecBuf := FCurrentRecBuf^.next;
           FreeRecordBuffer(BookmarkData);
           FreeRecordBuffer(BookmarkData);
 {$ENDIF}
 {$ENDIF}
@@ -1550,7 +1659,7 @@ begin
 {$ELSE}
 {$ELSE}
   CheckBrowseMode;
   CheckBrowseMode;
 
 
-  StoreRecBuf := FCurrentRecBuf;
+  StoreRecBuf := FCurrentIndex.FCurrentRecBuf;
 
 
   r := 0;
   r := 0;
   FailedCount := 0;
   FailedCount := 0;
@@ -1562,7 +1671,8 @@ begin
       if assigned(FUpdateBuffer[r].BookmarkData) then
       if assigned(FUpdateBuffer[r].BookmarkData) then
         begin
         begin
         InternalGotoBookmark(@FUpdateBuffer[r].BookmarkData);
         InternalGotoBookmark(@FUpdateBuffer[r].BookmarkData);
-        Resync([rmExact,rmCenter]);
+        // Joost: I do not see the use of this resync?
+        //Resync([rmExact,rmCenter]);
         Response := rrApply;
         Response := rrApply;
         try
         try
           ApplyRecUpdate(FUpdateBuffer[r].UpdateKind);
           ApplyRecUpdate(FUpdateBuffer[r].UpdateKind);
@@ -1619,7 +1729,7 @@ begin
       SetLength(FUpdateBlobBuffers,0);
       SetLength(FUpdateBlobBuffers,0);
       end;
       end;
 
 
-    FCurrentRecBuf := StoreRecBuf;
+    FCurrentIndex.FCurrentRecBuf := StoreRecBuf;
     Resync([]);
     Resync([]);
     EnableControls;
     EnableControls;
   end;
   end;
@@ -1696,7 +1806,7 @@ begin
       AddRecordToIndex(PBufRecLinkItem(IntAllocRecordBuffer),FCurrentRecBuf,FIndexes[0]);
       AddRecordToIndex(PBufRecLinkItem(IntAllocRecordBuffer),FCurrentRecBuf,FIndexes[0]);
       FCurrentRecBuf := FCurrentRecBuf[IndNr].prior;
       FCurrentRecBuf := FCurrentRecBuf[IndNr].prior;
       // Add the record to the other indexes
       // Add the record to the other indexes
-      for i := 1 to FIndexesCount-1 do if ((i>1) or (@FIndexes[i]=FCurrentIndex)) then
+      for i := 1 to FIndexesCount-1 do if ((i>1) or (FIndexes[i]=FCurrentIndex)) then
         begin
         begin
         AddRecordToIndex(FCurrentRecBuf,FIndexes[i].FLastRecBuf,FIndexes[i]);
         AddRecordToIndex(FCurrentRecBuf,FIndexes[i].FLastRecBuf,FIndexes[i]);
         end;
         end;
@@ -1710,7 +1820,7 @@ begin
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
       BookmarkData := FCurrentIndex^.FCurrentRecInd;
       BookmarkData := FCurrentIndex^.FCurrentRecInd;
 {$ELSE}
 {$ELSE}
-      BookmarkData := FCurrentRecBuf;
+      BookmarkData := FCurrentIndex.FCurrentRecBuf;
 {$ENDIF}
 {$ENDIF}
       BookmarkFlag := bfInserted;
       BookmarkFlag := bfInserted;
       end;
       end;
@@ -1732,14 +1842,14 @@ begin
       FUpdateBuffer[FCurrentUpdateBuffer].Bookmark.BookMarkBuf := FRecordArray[FCurrentRecInd];
       FUpdateBuffer[FCurrentUpdateBuffer].Bookmark.BookMarkBuf := FRecordArray[FCurrentRecInd];
       end;
       end;
 {$ELSE}
 {$ELSE}
-    FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := FCurrentRecBuf;
+    FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := FCurrentIndex.FCurrentRecBuf;
 {$ENDIF}
 {$ENDIF}
 
 
     if state = dsEdit then
     if state = dsEdit then
       begin
       begin
       // Update the oldvalues-buffer
       // Update the oldvalues-buffer
       FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := intAllocRecordBuffer;
       FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := intAllocRecordBuffer;
-      with FCurrentIndex^ do
+      with FCurrentIndex do
 {$IFDEF ARRAYBUF}
 {$IFDEF ARRAYBUF}
         move(FRecordArray[FCurrentRecInd]^,FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize);
         move(FRecordArray[FCurrentRecInd]^,FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize);
 {$ELSE}
 {$ELSE}
@@ -1755,14 +1865,14 @@ begin
   with FIndexes[0] do
   with FIndexes[0] do
     move(ActiveBuffer^,FRecordArray[FCurrentRecInd]^,FRecordSize);
     move(ActiveBuffer^,FRecordArray[FCurrentRecInd]^,FRecordSize);
 {$ELSE}
 {$ELSE}
-    CurrBuff := pchar(FCurrentRecBuf);
+    CurrBuff := pchar(FCurrentIndex.FCurrentRecBuf);
 
 
   tmpRecBuffer:=PBufRecLinkItem(CurrBuff);
   tmpRecBuffer:=PBufRecLinkItem(CurrBuff);
   inc(Currbuff,sizeof(TBufRecLinkItem)*FMaxIndexesCount);
   inc(Currbuff,sizeof(TBufRecLinkItem)*FMaxIndexesCount);
   move(ActiveBuffer^,CurrBuff^,FRecordSize);
   move(ActiveBuffer^,CurrBuff^,FRecordSize);
   CurrBuff:=pchar(tmpRecBuffer);
   CurrBuff:=pchar(tmpRecBuffer);
 
 
-  if FCurrentIndex=@FIndexes[1] then StartInd := 1 else StartInd := 2;
+  if FCurrentIndex=FIndexes[1] then StartInd := 1 else StartInd := 2;
   for i := StartInd to FIndexesCount-1 do
   for i := StartInd to FIndexesCount-1 do
     begin
     begin
     IndNr:=FIndexes[i].IndNr;
     IndNr:=FIndexes[i].IndNr;
@@ -1823,15 +1933,15 @@ end;
 
 
 function TBufDataset.GetIndexFieldNames: String;
 function TBufDataset.GetIndexFieldNames: String;
 begin
 begin
-  if FCurrentIndex<>@FIndexes[1] then
+  if FCurrentIndex<>FIndexes[1] then
     result := ''
     result := ''
   else
   else
-    result := FCurrentIndex^.FieldsName;
+    result := FCurrentIndex.FieldsName;
 end;
 end;
 
 
 function TBufDataset.GetIndexName: String;
 function TBufDataset.GetIndexName: String;
 begin
 begin
-  result := FCurrentIndex^.Name;
+  result := FCurrentIndex.Name;
 end;
 end;
 
 
 function TBufDataset.GetRecordSize : Word;
 function TBufDataset.GetRecordSize : Word;
@@ -1881,7 +1991,7 @@ begin
   ABookMark.BookmarkData:=Value-1;
   ABookMark.BookmarkData:=Value-1;
   GotoBookmark(@ABookMark);
   GotoBookmark(@ABookMark);
 {$ELSE}
 {$ELSE}
-  TmpRecBuffer := FCurrentIndex^.FFirstRecBuf;
+  TmpRecBuffer := FCurrentIndex.FFirstRecBuf;
   for recnr := 1 to value-1 do
   for recnr := 1 to value-1 do
     TmpRecBuffer := TmpRecBuffer^.next;
     TmpRecBuffer := TmpRecBuffer^.next;
   GotoBookmark(@TmpRecBuffer);
   GotoBookmark(@TmpRecBuffer);
@@ -1909,7 +2019,7 @@ begin
     inc(recnr);
     inc(recnr);
 {$ELSE}
 {$ELSE}
     GetBookmarkData(abuf,@SearchRecBuffer);
     GetBookmarkData(abuf,@SearchRecBuffer);
-    TmpRecBuffer := FCurrentIndex^.FFirstRecBuf;
+    TmpRecBuffer := FCurrentIndex.FFirstRecBuf;
     recnr := 1;
     recnr := 1;
     while TmpRecBuffer <> SearchRecBuffer do
     while TmpRecBuffer <> SearchRecBuffer do
       begin
       begin
@@ -2098,12 +2208,13 @@ var StoreIndNr : Integer;
 begin
 begin
   if Active then FetchAll;
   if Active then FetchAll;
   if FIndexesCount>0 then
   if FIndexesCount>0 then
-    StoreIndNr:=FCurrentIndex^.IndNr
+    StoreIndNr:=FCurrentIndex.IndNr
   else
   else
     StoreIndNr:=0;
     StoreIndNr:=0;
   inc(FIndexesCount);
   inc(FIndexesCount);
-  setlength(FIndexes,FIndexesCount); // This invalidates the currentindex!
-  FCurrentIndex:=@FIndexes[StoreIndNr];
+  setlength(FIndexes,FIndexesCount); // This invalidates the currentindex! -> not anymore
+  FCurrentIndex:=FIndexes[StoreIndNr];
+  FIndexes[FIndexesCount-1] := TBufIndex.Create;
   InitialiseIndex(FIndexes[FIndexesCount-1]);
   InitialiseIndex(FIndexes[FIndexesCount-1]);
   with FIndexes[FIndexesCount-1] do
   with FIndexes[FIndexesCount-1] do
     begin
     begin
@@ -2122,7 +2233,7 @@ begin
     begin
     begin
     FIndexes[FIndexesCount-1].FFirstRecBuf := pointer(IntAllocRecordBuffer);
     FIndexes[FIndexesCount-1].FFirstRecBuf := pointer(IntAllocRecordBuffer);
     FIndexes[FIndexesCount-1].FLastRecBuf := FIndexes[FIndexesCount-1].FFirstRecBuf;
     FIndexes[FIndexesCount-1].FLastRecBuf := FIndexes[FIndexesCount-1].FFirstRecBuf;
-    FCurrentRecBuf := FIndexes[FIndexesCount-1].FLastRecBuf;
+    FCurrentIndex.FCurrentRecBuf := FIndexes[FIndexesCount-1].FLastRecBuf;
     BuildIndex(FIndexes[FIndexesCount-1]);
     BuildIndex(FIndexes[FIndexesCount-1]);
     end
     end
 {$IFNDEF ARRAYBUF}
 {$IFNDEF ARRAYBUF}
@@ -2211,7 +2322,10 @@ begin
   if ARecord <> AIndex.FFirstRecBuf then
   if ARecord <> AIndex.FFirstRecBuf then
     ARecord[IndNr].prior[IndNr].next := ARecord[IndNr].next
     ARecord[IndNr].prior[IndNr].next := ARecord[IndNr].next
   else
   else
+    begin
     AIndex.FFirstRecBuf := ARecord[IndNr].next;
     AIndex.FFirstRecBuf := ARecord[IndNr].next;
+    AIndex.FLastRecBuf[IndNr].next := AIndex.FFirstRecBuf;
+    end;
   ARecord[IndNr].next[IndNr].prior := ARecord[IndNr].prior;
   ARecord[IndNr].next[IndNr].prior := ARecord[IndNr].prior;
 end;
 end;
 
 
@@ -2300,13 +2414,13 @@ begin
   StoreDSState:=State;
   StoreDSState:=State;
   SetTempState(dsFilter);
   SetTempState(dsFilter);
   SetFieldValues(keyfields,KeyValues);
   SetFieldValues(keyfields,KeyValues);
-  CurrLinkItem := FCurrentIndex^.FFirstRecBuf;
+  CurrLinkItem := FCurrentIndex.FFirstRecBuf;
   FilterBuffer:=IntAllocRecordBuffer;
   FilterBuffer:=IntAllocRecordBuffer;
-  move(FCurrentIndex^.FLastRecBuf^,FilterBuffer^,FRecordsize+sizeof(TBufRecLinkItem)*FMaxIndexesCount);
+  move(FCurrentIndex.FLastRecBuf^,FilterBuffer^,FRecordsize+sizeof(TBufRecLinkItem)*FMaxIndexesCount);
   SetTempState(StoreDSState);
   SetTempState(StoreDSState);
 
 
   // Iterate through the records until a match is found
   // Iterate through the records until a match is found
-  while (CurrLinkItem <> FCurrentIndex^.FLastRecBuf) do
+  while (CurrLinkItem <> FCurrentIndex.FLastRecBuf) do
     begin
     begin
     if (IndexCompareRecords(FilterBuffer,CurrLinkItem,DBCompareStruct) = 0) then
     if (IndexCompareRecords(FilterBuffer,CurrLinkItem,DBCompareStruct) = 0) then
       begin
       begin
@@ -2314,7 +2428,7 @@ begin
       break;
       break;
       end;
       end;
     CurrLinkItem := CurrLinkItem^.next;
     CurrLinkItem := CurrLinkItem^.next;
-    if CurrLinkItem = FCurrentIndex^.FLastRecBuf then
+    if CurrLinkItem = FCurrentIndex.FLastRecBuf then
       getnextpacket;
       getnextpacket;
     end;
     end;