mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 11:29:20 +02:00
* Playing around with double-linked indexes, part II
git-svn-id: trunk@9166 -
This commit is contained in:
parent
4e507bd2ef
commit
03ea1bc4c3
@ -83,9 +83,16 @@ type
|
||||
|
||||
TBufDataset = class(TDBDataSet)
|
||||
private
|
||||
FIndexesCount : integer;
|
||||
FCurrentIndex : integer;
|
||||
|
||||
FCurrentRecBuf : PBufRecLinkItem;
|
||||
FLastRecBuf : PBufRecLinkItem;
|
||||
FFirstRecBuf : PBufRecLinkItem;
|
||||
|
||||
FLastRecBufs : array of PBufRecLinkItem;
|
||||
FFirstRecBufs : array of PBufRecLinkItem;
|
||||
|
||||
FFilterBuffer : pchar;
|
||||
FBRecordCount : integer;
|
||||
|
||||
@ -154,6 +161,8 @@ type
|
||||
procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField); virtual; abstract;
|
||||
|
||||
public
|
||||
procedure AddSecondIndex;
|
||||
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
function GetFieldData(Field: TField; Buffer: Pointer;
|
||||
NativeFormat: Boolean): Boolean; override;
|
||||
@ -185,6 +194,12 @@ uses variants, dbconst;
|
||||
constructor TBufDataset.Create(AOwner : TComponent);
|
||||
begin
|
||||
Inherited Create(AOwner);
|
||||
FIndexesCount:=2;
|
||||
FCurrentIndex:=0;
|
||||
|
||||
setlength(FFirstRecBufs,FIndexesCount);
|
||||
SetLength(FLastRecBufs,FIndexesCount);
|
||||
|
||||
SetLength(FUpdateBuffer,0);
|
||||
SetLength(FBlobBuffers,0);
|
||||
SetLength(FUpdateBlobBuffers,0);
|
||||
@ -212,7 +227,7 @@ end;
|
||||
function TBufDataset.intAllocRecordBuffer: PChar;
|
||||
begin
|
||||
// Note: Only the internal buffers of TDataset provide bookmark information
|
||||
result := AllocMem(FRecordsize+sizeof(TBufRecLinkItem));
|
||||
result := AllocMem(FRecordsize+sizeof(TBufRecLinkItem)*FIndexesCount);
|
||||
end;
|
||||
|
||||
function TBufDataset.AllocRecordBuffer: PChar;
|
||||
@ -335,13 +350,13 @@ begin
|
||||
Acceptable := True;
|
||||
case GetMode of
|
||||
gmPrior :
|
||||
if not assigned(PBufRecLinkItem(FCurrentRecBuf)^.prior) then
|
||||
if not assigned(FCurrentRecBuf[FCurrentIndex].prior) then
|
||||
begin
|
||||
Result := grBOF;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.prior;
|
||||
FCurrentRecBuf := FCurrentRecBuf[FCurrentIndex].prior;
|
||||
end;
|
||||
gmCurrent :
|
||||
if FCurrentRecBuf = FLastRecBuf then
|
||||
@ -352,11 +367,11 @@ begin
|
||||
if getnextpacket = 0 then result := grEOF;
|
||||
end
|
||||
else if FCurrentRecBuf = nil then FCurrentRecBuf := FFirstRecBuf
|
||||
else if (PBufRecLinkItem(FCurrentRecBuf)^.next = FLastRecBuf) then
|
||||
else if (FCurrentRecBuf[FCurrentIndex].next = FLastRecBuf) then
|
||||
begin
|
||||
if getnextpacket > 0 then
|
||||
begin
|
||||
FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.next;
|
||||
FCurrentRecBuf := FCurrentRecBuf[FCurrentIndex].next;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -365,7 +380,7 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.next;
|
||||
FCurrentRecBuf := FCurrentRecBuf[FCurrentIndex].next;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -377,7 +392,7 @@ begin
|
||||
BookmarkData := FCurrentRecBuf;
|
||||
BookmarkFlag := bfCurrent;
|
||||
end;
|
||||
move((pointer(FCurrentRecBuf)+sizeof(TBufRecLinkItem))^,buffer^,FRecordSize);
|
||||
move((pointer(FCurrentRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount)^,buffer^,FRecordSize);
|
||||
GetCalcFields(Buffer);
|
||||
|
||||
if Filtered then
|
||||
@ -459,13 +474,13 @@ begin
|
||||
exit;
|
||||
end;
|
||||
i := 0;
|
||||
pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem));
|
||||
pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount);
|
||||
while ((i < FPacketRecords) or (FPacketRecords = -1)) and (loadbuffer(pb) = grOk) do
|
||||
begin
|
||||
FLastRecBuf^.next := pointer(IntAllocRecordBuffer);
|
||||
FLastRecBuf^.next^.prior := FLastRecBuf;
|
||||
FLastRecBuf := FLastRecBuf^.next;
|
||||
pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem));
|
||||
pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount);
|
||||
inc(i);
|
||||
end;
|
||||
FBRecordCount := FBRecordCount + i;
|
||||
@ -568,7 +583,7 @@ begin
|
||||
result := false;
|
||||
exit;
|
||||
end;
|
||||
currbuff := FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer+sizeof(TBufRecLinkItem);
|
||||
currbuff := FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer+sizeof(TBufRecLinkItem)*FIndexesCount;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -624,7 +639,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
if state = dsFilter then // Set the value into the 'temporary' FLastRecBuf buffer for Locate and Lookup
|
||||
CurrBuff := pointer(FLastRecBuf) + sizeof(TBufRecLinkItem)
|
||||
CurrBuff := pointer(FLastRecBuf) + sizeof(TBufRecLinkItem)*FIndexesCount
|
||||
else
|
||||
CurrBuff := GetCurrentBuffer;
|
||||
If Field.Fieldno > 0 then // If = 0, then calculated field or something
|
||||
@ -715,7 +730,7 @@ begin
|
||||
begin
|
||||
if UpdateKind = ukModify then
|
||||
begin
|
||||
move(pchar(OldValuesBuffer+sizeof(TBufRecLinkItem))^,pchar(BookmarkData+sizeof(TBufRecLinkItem))^,FRecordSize);
|
||||
move(pchar(OldValuesBuffer+sizeof(TBufRecLinkItem)*FIndexesCount)^,pchar(BookmarkData+sizeof(TBufRecLinkItem)*FIndexesCount)^,FRecordSize);
|
||||
FreeRecordBuffer(OldValuesBuffer);
|
||||
end
|
||||
else if UpdateKind = ukDelete then
|
||||
@ -931,7 +946,7 @@ begin
|
||||
begin
|
||||
// Update the oldvalues-buffer
|
||||
FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := intAllocRecordBuffer;
|
||||
move(FCurrentRecBuf^,FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize+sizeof(TBufRecLinkItem));
|
||||
move(FCurrentRecBuf^,FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,FRecordSize+sizeof(TBufRecLinkItem)*FIndexesCount);
|
||||
FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukModify;
|
||||
end
|
||||
else
|
||||
@ -939,7 +954,7 @@ begin
|
||||
end;
|
||||
|
||||
CurrBuff := pchar(FCurrentRecBuf);
|
||||
inc(Currbuff,sizeof(TBufRecLinkItem));
|
||||
inc(Currbuff,sizeof(TBufRecLinkItem)*FIndexesCount);
|
||||
move(ActiveBuffer^,CurrBuff^,FRecordSize);
|
||||
end;
|
||||
|
||||
@ -1221,6 +1236,41 @@ begin
|
||||
Refresh;
|
||||
end;
|
||||
|
||||
procedure TBufDataset.AddSecondIndex;
|
||||
|
||||
var ALinkItem,
|
||||
ANewLinkItem : PBufRecLinkItem;
|
||||
|
||||
begin
|
||||
ALinkItem:=FLastRecBuf[0].prior;
|
||||
ANewLinkItem:=FLastRecBuf[0].prior;
|
||||
|
||||
FFirstRecBufs[1]:=ANewLinkItem;
|
||||
|
||||
while ALinkItem<>FFirstRecBuf do
|
||||
begin
|
||||
ANewLinkItem[1].next:=ALinkItem[0].prior;
|
||||
ANewLinkItem[1].prior:=ALinkItem[0].next;
|
||||
ALinkItem:=ALinkItem[0].prior;
|
||||
ANewLinkItem:=ANewLinkItem[1].next;
|
||||
end;
|
||||
|
||||
FLastRecBufs[1]:=FLastRecBuf;
|
||||
ANewLinkItem[1].next:=FLastRecBufs[1];
|
||||
FLastRecBufs[1][1].prior:=ANewLinkItem;
|
||||
FFirstRecBufs[1][1].prior:=nil;
|
||||
FLastRecBufs[1][1].next:=nil;
|
||||
|
||||
// Stel in op tweede index:
|
||||
FCurrentIndex:=1;
|
||||
FLastRecBuf:=FLastRecBufs[FCurrentIndex];
|
||||
FFirstRecBuf:=FFirstRecBufs[FCurrentIndex];
|
||||
FCurrentRecBuf:=FFirstRecBuf;
|
||||
|
||||
Resync([rmExact,rmCenter]);
|
||||
end;
|
||||
|
||||
|
||||
procedure TBufDataset.ParseFilter(const AFilter: string);
|
||||
begin
|
||||
// parser created?
|
||||
@ -1303,7 +1353,7 @@ begin
|
||||
FieldBufPos := FFieldBufPositions[keyfield.FieldNo-1];
|
||||
VBLength := keyfield.DataSize;
|
||||
ValueBuffer := AllocMem(VBLength);
|
||||
currbuff := pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)+FieldBufPos;
|
||||
currbuff := pointer(FLastRecBuf)+sizeof(TBufRecLinkItem)*FIndexesCount+FieldBufPos;
|
||||
move(currbuff^,ValueBuffer^,VBLength);
|
||||
end;
|
||||
|
||||
@ -1312,7 +1362,7 @@ begin
|
||||
if CheckNull then
|
||||
begin
|
||||
repeat
|
||||
currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem);
|
||||
currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem)*FIndexesCount;
|
||||
if GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
|
||||
begin
|
||||
result := True;
|
||||
@ -1325,7 +1375,7 @@ begin
|
||||
else if keyfield.DataType = ftString then
|
||||
begin
|
||||
repeat
|
||||
currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem);
|
||||
currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem)*FIndexesCount;
|
||||
if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
|
||||
begin
|
||||
inc(CurrBuff,FieldBufPos);
|
||||
@ -1342,7 +1392,7 @@ begin
|
||||
else
|
||||
begin
|
||||
repeat
|
||||
currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem);
|
||||
currbuff := pointer(CurrLinkItem)+sizeof(TBufRecLinkItem)*FIndexesCount;
|
||||
if not GetFieldIsnull(pbyte(CurrBuff),keyfield.Fieldno-1) then
|
||||
begin
|
||||
inc(CurrBuff,FieldBufPos);
|
||||
|
Loading…
Reference in New Issue
Block a user