mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-19 12:09:22 +02:00
* The bookmarkdata in a delete-update buffer now points to the old, deleted, record which is not deleted immediately anymore. Because else GetUpdateBuffer can not find the update-buffer from a deleted record
* Delete-update buffers now has an extra bookmark (NextBookmarkData) to store the next record in the dataset * Thus re-linking update buffers of records that are going to be deleted, is not necessary anymore * GetRecordUpdateBuffer now looks for update-buffers linked to BookmarkData, and for those linked to NextBookmarkdata only when asked * The commented-out resync in ApplyUpdates is replaced by a call to GetRecord. The goal is to synchronise the ActiveBuffer of TDataset with the CurrentBuffer of the TBufDataset. git-svn-id: trunk@12365 -
This commit is contained in:
parent
47ba5b19ec
commit
97ef7c31c7
@ -73,13 +73,13 @@ type
|
|||||||
- Is -1 if the update has canceled out. For example: a appended record has been deleted again
|
- Is -1 if the update has canceled out. For example: a appended record has been deleted again
|
||||||
- If UpdateKind is ukInsert it contains a bookmark to the new created record
|
- If UpdateKind is ukInsert it contains a bookmark to the new created record
|
||||||
- If UpdateKind is ukModify it contains a bookmark to the record with the new data
|
- If UpdateKind is ukModify it contains a bookmark to the record with the new data
|
||||||
- If UpdateKind is ukDelete it contains a bookmark to the record just after the deleted record
|
- If UpdateKind is ukDelete it contains a bookmark to the deleted record (ie: the record is still there)
|
||||||
}
|
}
|
||||||
BookmarkData : TBufBookmark;
|
BookmarkData : TBufBookmark;
|
||||||
{ DelBookMarkData:
|
{ NextBookMarkData:
|
||||||
- If UpdateKind is ukDelete it contains a bookmark to the deleted record, before it got deleted
|
- If UpdateKind is ukDelete it contains a bookmark to the record just after the deleted record
|
||||||
}
|
}
|
||||||
DelBookmarkData : TBufBookmark;
|
NextBookmarkData : TBufBookmark;
|
||||||
{ OldValuesBuffer:
|
{ OldValuesBuffer:
|
||||||
- If UpdateKind is ukModify it contains a record-buffer which contains the old data
|
- If UpdateKind is ukModify it contains a record-buffer which contains the old data
|
||||||
- If UpdateKind is ukDelete it contains a record-buffer with the data of the deleted record
|
- If UpdateKind is ukDelete it contains a record-buffer with the data of the deleted record
|
||||||
@ -386,8 +386,8 @@ type
|
|||||||
function GetIndexName: String;
|
function GetIndexName: String;
|
||||||
function LoadBuffer(Buffer : PChar): TGetResult;
|
function LoadBuffer(Buffer : PChar): TGetResult;
|
||||||
function GetFieldSize(FieldDef : TFieldDef) : longint;
|
function GetFieldSize(FieldDef : TFieldDef) : longint;
|
||||||
function GetRecordUpdateBuffer(const ABookmark : TBufBookmark; IncludeDeleted : boolean = false; AFindNext : boolean = false) : boolean;
|
function GetRecordUpdateBuffer(const ABookmark : TBufBookmark; IncludePrior : boolean = false; AFindNext : boolean = false) : boolean;
|
||||||
function GetRecordUpdateBufferCached(const ABookmark : TBufBookmark; IncludeDeleted : boolean = false) : boolean;
|
function GetRecordUpdateBufferCached(const ABookmark : TBufBookmark; IncludePrior : boolean = false) : boolean;
|
||||||
function GetActiveRecordUpdateBuffer : boolean;
|
function GetActiveRecordUpdateBuffer : boolean;
|
||||||
procedure ProcessFieldCompareStruct(AField: TField; var ACompareRec : TDBCompareRec);
|
procedure ProcessFieldCompareStruct(AField: TField; var ACompareRec : TDBCompareRec);
|
||||||
procedure SetIndexFieldNames(const AValue: String);
|
procedure SetIndexFieldNames(const AValue: String);
|
||||||
@ -1473,7 +1473,7 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBufDataset.GetRecordUpdateBuffer(const ABookmark : TBufBookmark; IncludeDeleted : boolean = false; AFindNext : boolean = false): boolean;
|
function TBufDataset.GetRecordUpdateBuffer(const ABookmark : TBufBookmark; IncludePrior : boolean = false; AFindNext : boolean = false): boolean;
|
||||||
|
|
||||||
var x : integer;
|
var x : integer;
|
||||||
StartBuf : integer;
|
StartBuf : integer;
|
||||||
@ -1485,8 +1485,8 @@ begin
|
|||||||
StartBuf := 0;
|
StartBuf := 0;
|
||||||
Result := False;
|
Result := False;
|
||||||
for x := StartBuf to high(FUpdateBuffer) do
|
for x := StartBuf to high(FUpdateBuffer) do
|
||||||
if FCurrentIndex.CompareBookmarks(@FUpdateBuffer[x].BookmarkData,@ABookmark) and
|
if FCurrentIndex.CompareBookmarks(@FUpdateBuffer[x].BookmarkData,@ABookmark) or
|
||||||
((FUpdateBuffer[x].UpdateKind<>ukDelete) or IncludeDeleted) then // The Bookmarkdata of a deleted record does not contain the deleted record, but the record thereafter
|
(IncludePrior and (FUpdateBuffer[x].UpdateKind=ukDelete) and FCurrentIndex.CompareBookmarks(@FUpdateBuffer[x].NextBookmarkData,@ABookmark)) then
|
||||||
begin
|
begin
|
||||||
FCurrentUpdateBuffer := x;
|
FCurrentUpdateBuffer := x;
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -1495,15 +1495,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TBufDataset.GetRecordUpdateBufferCached(const ABookmark: TBufBookmark;
|
function TBufDataset.GetRecordUpdateBufferCached(const ABookmark: TBufBookmark;
|
||||||
IncludeDeleted: boolean): boolean;
|
IncludePrior: boolean): boolean;
|
||||||
begin
|
begin
|
||||||
// if the current update buffer complies, immediately return true
|
// if the current update buffer complies, immediately return true
|
||||||
if (FCurrentUpdateBuffer < length(FUpdateBuffer)) and
|
if (FCurrentUpdateBuffer < length(FUpdateBuffer)) and (
|
||||||
(FCurrentIndex.CompareBookmarks(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData,@ABookmark)) and
|
FCurrentIndex.CompareBookmarks(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData,@ABookmark) or
|
||||||
((FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind<>ukDelete) or IncludeDeleted) then
|
(IncludePrior and (FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind=ukDelete) and FCurrentIndex.CompareBookmarks(@FUpdateBuffer[FCurrentUpdateBuffer].NextBookmarkData,@ABookmark))) then
|
||||||
Result := True
|
Result := True
|
||||||
else
|
else
|
||||||
Result := GetRecordUpdateBuffer(ABookmark,IncludeDeleted);
|
Result := GetRecordUpdateBuffer(ABookmark,IncludePrior);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBufDataset.LoadBuffer(Buffer : PChar): TGetResult;
|
function TBufDataset.LoadBuffer(Buffer : PChar): TGetResult;
|
||||||
@ -1662,15 +1662,12 @@ end;
|
|||||||
procedure TBufDataset.InternalDelete;
|
procedure TBufDataset.InternalDelete;
|
||||||
var i : Integer;
|
var i : Integer;
|
||||||
StartInd : Integer;
|
StartInd : Integer;
|
||||||
RemRecBuf : Pchar;
|
|
||||||
RemRec : pointer;
|
RemRec : pointer;
|
||||||
RemRecBookmrk : TBufBookmark;
|
RemRecBookmrk : TBufBookmark;
|
||||||
TempUpdBuf: TRecUpdateBuffer;
|
|
||||||
begin
|
begin
|
||||||
InternalSetToRecord(ActiveBuffer);
|
InternalSetToRecord(ActiveBuffer);
|
||||||
// Remove the record from all active indexes
|
// Remove the record from all active indexes
|
||||||
FCurrentIndex.StoreCurrentRecIntoBookmark(@RemRecBookmrk);
|
FCurrentIndex.StoreCurrentRecIntoBookmark(@RemRecBookmrk);
|
||||||
RemRecBuf:=FCurrentIndex.GetCurrentRecord;
|
|
||||||
RemRec := FCurrentIndex.CurrentBuffer;
|
RemRec := FCurrentIndex.CurrentBuffer;
|
||||||
FIndexes[0].RemoveRecordFromIndex(RemRecBookmrk);
|
FIndexes[0].RemoveRecordFromIndex(RemRecBookmrk);
|
||||||
if FCurrentIndex=FIndexes[1] then StartInd := 1 else StartInd := 2;
|
if FCurrentIndex=FIndexes[1] then StartInd := 1 else StartInd := 2;
|
||||||
@ -1684,40 +1681,16 @@ begin
|
|||||||
|
|
||||||
FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := IntAllocRecordBuffer;
|
FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := IntAllocRecordBuffer;
|
||||||
move(RemRec^, FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize);
|
move(RemRec^, FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize);
|
||||||
FreeRecordBuffer(RemRecBuf);
|
|
||||||
end
|
end
|
||||||
else //with FIndexes[0] do
|
else //with FIndexes[0] do
|
||||||
begin
|
begin
|
||||||
FreeRecordBuffer(RemRecBuf);
|
|
||||||
if FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind <> ukModify then
|
if FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind <> ukModify then
|
||||||
FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := nil; //this 'disables' the updatebuffer
|
FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := nil; //this 'disables' the updatebuffer
|
||||||
end;
|
end;
|
||||||
FCurrentIndex.StoreCurrentRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData);
|
FCurrentIndex.StoreCurrentRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].NextBookmarkData);
|
||||||
FUpdateBuffer[FCurrentUpdateBuffer].DelBookmarkData := RemRecBookmrk;
|
FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := RemRecBookmrk;
|
||||||
FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukDelete;
|
FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukDelete;
|
||||||
|
|
||||||
// Search for update-buffers which are linked to the deleted record and re-link
|
|
||||||
// them to the current record.
|
|
||||||
if GetRecordUpdateBuffer(RemRecBookmrk,True,False) then
|
|
||||||
begin
|
|
||||||
repeat
|
|
||||||
if FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind = ukDelete then
|
|
||||||
begin
|
|
||||||
// If one of the update-buffers, linked to the deleted record, is a delete
|
|
||||||
// then disable the old update-buffer and create a new one. Such that the
|
|
||||||
// position of the records stays the samein case of a cancelupdates or
|
|
||||||
// something similar
|
|
||||||
TempUpdBuf := FUpdateBuffer[FCurrentUpdateBuffer];
|
|
||||||
move(FUpdateBuffer[FCurrentUpdateBuffer+1],FUpdateBuffer[FCurrentUpdateBuffer],((length(FUpdateBuffer)-FCurrentUpdateBuffer))*Sizeof(TRecUpdateBuffer));
|
|
||||||
dec(FCurrentUpdateBuffer);
|
|
||||||
FCurrentIndex.StoreCurrentRecIntoBookmark(@TempUpdBuf.BookmarkData);
|
|
||||||
FUpdateBuffer[length(FUpdateBuffer)-1] := TempUpdBuf;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
FCurrentIndex.StoreCurrentRecIntoBookmark(@FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData);
|
|
||||||
until not GetRecordUpdateBuffer(RemRecBookmrk,True,True)
|
|
||||||
end;
|
|
||||||
|
|
||||||
dec(FBRecordCount);
|
dec(FBRecordCount);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1735,6 +1708,7 @@ var StoreRecBM : TBufBookmark;
|
|||||||
TmpBuf : PChar;
|
TmpBuf : PChar;
|
||||||
StoreUpdBuf : integer;
|
StoreUpdBuf : integer;
|
||||||
Bm : TBufBookmark;
|
Bm : TBufBookmark;
|
||||||
|
x : Integer;
|
||||||
begin
|
begin
|
||||||
with AUpdBuffer do if assigned(BookmarkData.BookmarkData) then // this is used to exclude buffers which are already handled
|
with AUpdBuffer do if assigned(BookmarkData.BookmarkData) then // this is used to exclude buffers which are already handled
|
||||||
begin
|
begin
|
||||||
@ -1746,10 +1720,16 @@ var StoreRecBM : TBufBookmark;
|
|||||||
end
|
end
|
||||||
else if (UpdateKind = ukDelete) and (assigned(OldValuesBuffer)) then
|
else if (UpdateKind = ukDelete) and (assigned(OldValuesBuffer)) then
|
||||||
begin
|
begin
|
||||||
FCurrentIndex.GotoBookmark(@BookmarkData);
|
FCurrentIndex.GotoBookmark(@NextBookmarkData);
|
||||||
FCurrentIndex.InsertRecordBeforeCurrentRecord(IntAllocRecordBuffer);
|
FCurrentIndex.InsertRecordBeforeCurrentRecord(PChar(BookmarkData.BookmarkData));
|
||||||
FCurrentIndex.ScrollBackward;
|
FCurrentIndex.ScrollBackward;
|
||||||
move(pchar(OldValuesBuffer)^,pchar(FCurrentIndex.CurrentBuffer)^,FRecordSize);
|
move(pchar(OldValuesBuffer)^,pchar(FCurrentIndex.CurrentBuffer)^,FRecordSize);
|
||||||
|
|
||||||
|
{ for x := length(FUpdateBuffer)-1 downto 0 do
|
||||||
|
begin
|
||||||
|
if (FUpdateBuffer[x].UpdateKind=ukDelete) and FCurrentIndex.CompareBookmarks(@FUpdateBuffer[x].NextBookmarkData,@BookmarkData) then
|
||||||
|
CancelUpdBuffer(FUpdateBuffer[x]);
|
||||||
|
end;}
|
||||||
FreeRecordBuffer(OldValuesBuffer);
|
FreeRecordBuffer(OldValuesBuffer);
|
||||||
inc(FBRecordCount);
|
inc(FBRecordCount);
|
||||||
end
|
end
|
||||||
@ -1844,8 +1824,8 @@ begin
|
|||||||
if not ((FUpdateBuffer[r].UpdateKind=ukDelete) and not (assigned(FUpdateBuffer[r].OldValuesBuffer))) then
|
if not ((FUpdateBuffer[r].UpdateKind=ukDelete) and not (assigned(FUpdateBuffer[r].OldValuesBuffer))) then
|
||||||
begin
|
begin
|
||||||
FCurrentIndex.GotoBookmark(@FUpdateBuffer[r].BookmarkData);
|
FCurrentIndex.GotoBookmark(@FUpdateBuffer[r].BookmarkData);
|
||||||
// Joost: I do not see the use of this resync?
|
// Synchronise the Currentbuffer to the ActiveBuffer
|
||||||
//Resync([rmExact,rmCenter]);
|
GetRecord(ActiveBuffer,gmCurrent,True);
|
||||||
Response := rrApply;
|
Response := rrApply;
|
||||||
try
|
try
|
||||||
ApplyRecUpdate(FUpdateBuffer[r].UpdateKind);
|
ApplyRecUpdate(FUpdateBuffer[r].UpdateKind);
|
||||||
@ -1872,6 +1852,8 @@ begin
|
|||||||
if response in [rrApply, rrIgnore] then
|
if response in [rrApply, rrIgnore] then
|
||||||
begin
|
begin
|
||||||
FreeRecordBuffer(FUpdateBuffer[r].OldValuesBuffer);
|
FreeRecordBuffer(FUpdateBuffer[r].OldValuesBuffer);
|
||||||
|
if FUpdateBuffer[r].UpdateKind = ukDelete then
|
||||||
|
FreeRecordBuffer(PChar(FUpdateBuffer[r].BookmarkData.BookmarkData));
|
||||||
FUpdateBuffer[r].BookmarkData.BookmarkData := nil;
|
FUpdateBuffer[r].BookmarkData.BookmarkData := nil;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
@ -2309,9 +2291,6 @@ procedure TBufDataset.GetDatasetPacket(AWriter: TDataPacketReader);
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure HandleUpdateBuffersFromRecord(ARecBookmark : TBufBookmark; var ARowState: TRowState);
|
procedure HandleUpdateBuffersFromRecord(ARecBookmark : TBufBookmark; var ARowState: TRowState);
|
||||||
var
|
|
||||||
StoreUpdBuf : integer;
|
|
||||||
ADumRowstate : TRowState;
|
|
||||||
begin
|
begin
|
||||||
if GetRecordUpdateBuffer(ARecBookmark,True) then
|
if GetRecordUpdateBuffer(ARecBookmark,True) then
|
||||||
begin
|
begin
|
||||||
@ -2330,7 +2309,6 @@ var ScrollResult : TGetResult;
|
|||||||
ABookMark : PBufBookmark;
|
ABookMark : PBufBookmark;
|
||||||
ATBookmark : TBufBookmark;
|
ATBookmark : TBufBookmark;
|
||||||
RowState : TRowState;
|
RowState : TRowState;
|
||||||
EntryNr : integer;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
FDatasetReader := AWriter;
|
FDatasetReader := AWriter;
|
||||||
|
Loading…
Reference in New Issue
Block a user