+ Replaced the array-based record-buffer for a linked-list buffer

git-svn-id: trunk@3111 -
This commit is contained in:
joost 2006-04-01 16:03:41 +00:00
parent 3129dd042e
commit a75c1e5dd3
2 changed files with 189 additions and 348 deletions

View File

@ -18,7 +18,6 @@
---------------------------------------------------------------------}
constructor TBufDataset.Create(AOwner : TComponent);
begin
Inherited Create(AOwner);
SetLength(FUpdateBuffer,0);
@ -27,34 +26,28 @@ begin
end;
procedure TBufDataset.SetPacketRecords(aValue : integer);
begin
if aValue > 0 then FPacketRecords := aValue
else DatabaseError(SInvPacketRecordsValue);
end;
destructor TBufDataset.Destroy;
begin
inherited destroy;
end;
Function TBufDataset.GetCanModify: Boolean;
begin
Result:= False;
end;
function TBufDataset.intAllocRecordBuffer: PChar;
begin
// Only the internal buffers of TDataset provide bookmark information
result := AllocMem(FRecordsize);
result^ := #1; // this 'deletes' the record
// Note: Only the internal buffers of TDataset provide bookmark information
result := AllocMem(FRecordsize+sizeof(TBufRecLinkItem));
end;
function TBufDataset.AllocRecordBuffer: PChar;
begin
result := AllocMem(FRecordsize + sizeof(TBufBookmark));
result^ := #1; // this 'deletes' the record
@ -70,44 +63,44 @@ procedure TBufDataset.InternalOpen;
begin
CalcRecordSize;
FBRecordcount := 0;
FBDeletedRecords := 0;
FBBuffercount := 0;
FBCurrentrecord := -1;
// FBRecordcount := 0;
// FBDeletedRecords := 0;
FFirstRecBuf := pointer(IntAllocRecordBuffer);
FLastRecBuf := FFirstRecBuf;
FCurrentRecBuf := FLastRecBuf;
FOpen:=True;
FIsEOF := false;
FIsbOF := true;
end;
procedure TBufDataset.InternalClose;
var i : integer;
var pc : pchar;
begin
FOpen:=False;
CancelUpdates;
for i := 0 to FBRecordCount-1 do FreeRecordBuffer(FBBuffers[i]);
If FBBufferCount > 0 then ReAllocMem(FBBuffers,0);
FBRecordcount := 0;
FBBuffercount := 0;
FCurrentRecBuf := FFirstRecBuf;
while assigned(FCurrentRecBuf) do
begin
pc := pointer(FCurrentRecBuf);
FCurrentRecBuf := FCurrentRecBuf^.next;
FreeRecordBuffer(pc);
end;
SetLength(FFieldBufPositions,0);
FBCurrentrecord := -1;
FIsEOF := true;
FIsbOF := true;
end;
procedure TBufDataset.InternalFirst;
begin
FBCurrentRecord := -1;
FIsEOF := false;
FCurrentRecBuf := FFirstRecBuf;
end;
procedure TBufDataset.InternalLast;
begin
repeat
until getnextpacket < FPacketRecords;
FIsBOF := false;
FBCurrentRecord := FBRecordcount;
if FLastRecBuf <> FFirstRecBuf then
FCurrentRecBuf := FLastRecBuf;
end;
procedure unSetDeleted(NullMask : pbyte); //inline;
@ -145,140 +138,82 @@ end;
function TBufDataset.GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult;
var x : longint;
RecUpdBuf : PRecUpdateBuffer;
FieldUpdBuf : PFieldUpdateBuffer;
NullMask : pbyte;
begin
Result := grOK;
case GetMode of
gmPrior :
if FIsBOF then
result := grBOF
else if FBCurrentRecord <= 0 then
if not assigned(PBufRecLinkItem(FCurrentRecBuf)^.prior) then
begin
Result := grBOF;
FBCurrentRecord := -1;
end
else
begin
Dec(FBCurrentRecord);
FIsEof := false;
FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.prior;
end;
gmCurrent :
if (FBCurrentRecord < 0) or (FBCurrentRecord >= FBRecordCount) then
if FCurrentRecBuf = FLastRecBuf then
Result := grError;
gmNext :
if FIsEOF then
result := grEOF
else if FBCurrentRecord >= (FBRecordCount - 1) then
if FCurrentRecBuf = FLastRecBuf then // Dataset is empty (just opened)
begin
if getnextpacket = 0 then result := grEOF;
end
else if (PBufRecLinkItem(FCurrentRecBuf)^.next = FLastRecBuf) then
begin
if getnextpacket > 0 then
begin
Inc(FBCurrentRecord);
FIsBof := false;
FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.next;
end
else
begin
FIsEOF := true;
result:=grEOF;
end
end
else
begin
Inc(FBCurrentRecord);
FIsBof := false;
FCurrentRecBuf := PBufRecLinkItem(FCurrentRecBuf)^.next;
end;
end;
if Result = grOK then
begin
if GetDeleted(pbyte(FBBuffers[FBCurrentRecord])) then
begin
if getmode = gmCurrent then
if DoCheck then
begin
Result := grError;
DatabaseError(SDeletedRecord);
exit;
end
else
getmode := gmnext;
Result := GetRecord(Buffer,getmode,DoCheck);
exit
end;
with PBufBookmark(Buffer + RecordSize)^ do
begin
BookmarkData := FBCurrentRecord;
BookmarkData := FCurrentRecBuf;
BookmarkFlag := bfCurrent;
end;
move(FBBuffers[FBCurrentRecord]^,buffer^,RecordSize);
// Cached Updates:
If GetRecordUpdateBuffer(FBCurrentRecord,RecUpdBuf) then
begin
NullMask := pbyte(buffer);
inc(buffer,FNullmaskSize);
for x := 0 to FieldDefs.count-1 do
begin
if GetFieldUpdateBuffer(x,RecUpdBuf,FieldUpdBuf) then
If not FieldUpdBuf^.IsNull then
begin
unSetFieldIsNull(NullMask,x);
move(FieldUpdBuf^.NewValue^,buffer^,GetFieldSize(FieldDefs[x]));
end
else
SetFieldIsNull(NullMask,x);
Inc(Buffer, GetFieldSize(FieldDefs[x]));
end;
end;
move((pointer(FCurrentRecBuf)+sizeof(TBufRecLinkItem))^,buffer^,RecordSize);
end
else if (Result = grError) and doCheck then
DatabaseError('No record');
end;
function TBufDataset.GetRecordUpdateBuffer(rno : integer;var RecUpdBuf : PRecUpdateBuffer) : boolean;
function TBufDataset.GetRecordUpdateBuffer : boolean;
var r : integer;
var x : integer;
CurrBuff : PChar;
begin
Result := False;
for r := 0 to high(FUpdateBuffer) do
if (FUpdateBuffer[r].RecordNo = rno) and (@FUpdateBuffer[r] <> FEditBuf) then // Neglect the edit-buffer
GetBookmarkData(ActiveBuffer,@CurrBuff);
if (FCurrentUpdateBuffer >= length(FUpdateBuffer)) or (FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData <> CurrBuff) then
for x := 0 to high(FUpdateBuffer) do
if FUpdateBuffer[x].BookmarkData = CurrBuff then
begin
RecUpdBuf := @FUpdateBuffer[r];
Result := True;
Break;
end;
end;
function TBufDataset.GetFieldUpdateBuffer(fieldno : integer;RecUpdBuf : PRecUpdateBuffer;var FieldUpdBuf : pFieldUpdateBuffer) : boolean;
var f : integer;
begin
Result := False;
for f := 0 to High(RecUpdBuf^.FieldsUpdateBuffer) do
if RecUpdBuf^.FieldsUpdateBuffer[f].FieldNo = fieldno then
begin
FieldUpdBuf := @RecUpdBuf^.FieldsUpdateBuffer[f];
Result := True;
Break;
FCurrentUpdateBuffer := x;
break;
end;
Result := (FCurrentUpdateBuffer < length(FUpdateBuffer)) and (FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData = CurrBuff);
end;
procedure TBufDataset.InternalSetToRecord(Buffer: PChar);
begin
FBCurrentRecord := PBufBookmark(Buffer + RecordSize)^.BookmarkData;
FIsEOF := False;
FIsBOF := False;
FCurrentRecBuf := PBufBookmark(Buffer + RecordSize)^.BookmarkData;
end;
procedure TBufDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
begin
PBufBookmark(Buffer + RecordSize)^.BookmarkData := PInteger(Data)^;
PBufBookmark(Buffer + RecordSize)^.BookmarkData := pointer(Data^);
end;
procedure TBufDataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
@ -288,7 +223,7 @@ end;
procedure TBufDataset.GetBookmarkData(Buffer: PChar; Data: Pointer);
begin
PInteger(Data)^ := PBufBookmark(Buffer + RecordSize)^.BookmarkData;
pointer(Data^) := PBufBookmark(Buffer + RecordSize)^.BookmarkData;
end;
function TBufDataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
@ -298,35 +233,23 @@ end;
procedure TBufDataset.InternalGotoBookmark(ABookmark: Pointer);
begin
FBCurrentRecord := Plongint(ABookmark)^;
FIsEOF := False;
FIsBOF := False;
FCurrentRecBuf := ABookmark;
end;
function TBufDataset.getnextpacket : integer;
var i : integer;
b : boolean;
pb : pchar;
begin
i := 0;
if FBBufferCount < FBRecordCount+FPacketRecords then
for i := 0 to FPacketRecords-1 do
begin
FBBufferCount := FBBuffercount + FPacketRecords;
ReAllocMem(FBBuffers,FBBuffercount*SizeOf(PChar));
pb := pchar(pointer(FLastRecBuf)+sizeof(TBufRecLinkItem));
if (loadbuffer(pb)<>grOk) then break;
PBufRecLinkItem(FLastRecBuf)^.next := pointer(IntAllocRecordBuffer);
PBufRecLinkItem(PBufRecLinkItem(FLastRecBuf)^.next)^.prior := FLastRecBuf;
FLastRecBuf := PBufRecLinkItem(FLastRecBuf)^.next;
end;
repeat
FBBuffers[FBRecordCount+i] := intAllocRecordBuffer;
b := (loadbuffer(FBBuffers[FBRecordCount+i])<>grOk);
inc(i);
until (i = FPacketRecords) or b;
if b then
begin
dec(i);
FreeRecordBuffer(FBBuffers[FBRecordCount+i]);
end;
FBRecordCount := FBRecordCount + i;
result := i;
end;
@ -364,14 +287,12 @@ begin
NullMask := pointer(buffer);
fillchar(Nullmask^,FNullmaskSize,0);
inc(buffer,FNullmaskSize);
for x := 0 to FieldDefs.count-1 do
begin
if not LoadField(FieldDefs[x],buffer) then
SetFieldIsNull(NullMask,x);
inc(buffer,GetFieldSize(FieldDefs[x]));
end;
Result := grOK;
@ -385,9 +306,7 @@ end;
function TBufDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
var
x : longint;
CurrBuff : pchar;
var CurrBuff : pchar;
begin
Result := False;
@ -395,10 +314,13 @@ begin
begin
if state = dsOldValue then
begin
if FApplyingUpdates then
CurrBuff := FBBuffers[fbcurrentrecord] // This makes it possible for ApplyUpdates to get values from deleted records
else
CurrBuff := FBBuffers[GetRecNo];
if not GetRecordUpdateBuffer then
begin
// There is no old value available
result := false;
exit;
end;
currbuff := FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer+sizeof(TBufRecLinkItem);
end
else
begin
@ -429,11 +351,9 @@ begin
end;
procedure TBufDataset.SetFieldData(Field: TField; Buffer: Pointer);
var
x : longint;
CurrBuff : pointer;
NullMask : pbyte;
FieldUpdBuf : PFieldUpdateBuffer;
var CurrBuff : pointer;
NullMask : pbyte;
begin
if not (state in [dsEdit, dsInsert]) then
@ -446,122 +366,50 @@ begin
CurrBuff := ActiveBuffer;
NullMask := CurrBuff;
inc(Currbuff,FNullmaskSize);
for x := 0 to FieldDefs.count-1 do
inc(CurrBuff,FFieldBufPositions[Field.FieldNo-1]);
if assigned(buffer) then
begin
if (Field.FieldName = FieldDefs[x].Name) then
begin
if assigned(buffer) then
begin
Move(Buffer^, CurrBuff^, GetFieldSize(FieldDefs[x]));
unSetFieldIsNull(NullMask,x);
end
else
SetFieldIsNull(NullMask,x);
// cached updates
with FEditBuf^ do
begin
if not GetFieldUpdateBuffer(x,FEditBuf,FieldUpdBuf) then
begin
SetLength(FieldsUpdateBuffer,length(FieldsUpdateBuffer)+1);
FieldUpdBuf := @FieldsUpdateBuffer[high(FieldsUpdateBuffer)];
GetMem(FieldUpdBuf^.NewValue,GetFieldSize(FieldDefs[x]));
FieldUpdBuf^.FieldNo := x;
end;
if assigned(buffer) then
begin
Move(Buffer^, FieldUpdBuf^.NewValue^, GetFieldSize(FieldDefs[x]));
FieldUpdBuf^.IsNull := False;
end
else FieldUpdBuf^.IsNull := True;
end;
Break;
end
else Inc(CurrBuff, GetFieldSize(FieldDefs[x]));
end;
Move(Buffer^, CurrBuff^, GetFieldSize(FieldDefs[Field.FieldNo-1]));
unSetFieldIsNull(NullMask,Field.FieldNo-1);
end
else
SetFieldIsNull(NullMask,Field.FieldNo-1);
if not (State in [dsCalcFields, dsFilter, dsNewValue]) then
DataEvent(deFieldChange, Ptrint(Field));
end;
end;
procedure TBufDataset.InternalEdit;
begin
if not GetRecordUpdateBuffer(recno,FEditBuf) then
begin
If not assigned(FEditBuf) then
begin
SetLength(FUpdateBuffer,length(FUpdateBuffer)+1);
FEditBuf := @FUpdateBuffer[high(FUpdateBuffer)];
end;
FEditBuf^.UpdateKind := ukModify;
FEditBuf^.RecordNo := getrecno;
end;
end;
procedure TBufDataset.InternalInsert;
begin
if FBRecordCount > FBBufferCount-1 then
begin
inc(FBBufferCount);
ReAllocMem(FBBuffers,FBBuffercount*SizeOf(PChar));
end;
inc(FBRecordCount);
FBCurrentRecord := FBRecordCount -1;
FBBuffers[FBCurrentRecord] := intAllocRecordBuffer;
fillchar(FBBuffers[FBCurrentRecord]^,FNullmaskSize,255);
unSetDeleted(pbyte(FBBuffers[FBCurrentRecord]));
fillchar(ActiveBuffer^,FNullmaskSize,255);
unSetDeleted(pbyte(ActiveBuffer));
// cached updates:
If not assigned(FEditBuf) then
begin
SetLength(FUpdateBuffer,length(FUpdateBuffer)+1);
FEditBuf := @FUpdateBuffer[high(FUpdateBuffer)];
end;
FEditBuf^.RecordNo := FBCurrentRecord;
FEditBuf^.UpdateKind := ukInsert;
with PBufBookmark(ActiveBuffer + RecordSize)^ do
begin
BookmarkData := FBCurrentRecord;
BookmarkFlag := bfInserted;
end;
end;
procedure TBufDataset.InternalDelete;
var tel : integer;
var RecToDelete : PBufRecLinkItem;
begin
SetDeleted(pbyte(FBBuffers[FBCurrentRecord]));
GetBookmarkData(ActiveBuffer,@RecToDelete);
SetDeleted(pbyte(ActiveBuffer));
inc(FBDeletedRecords);
if GetRecordUpdateBuffer(recno,FEditBuf) and (FEditBuf^.UpdateKind = ukInsert) then
if RecToDelete <> FFirstRecBuf then RecToDelete^.prior^.next := RecToDelete^.next
else FFirstRecBuf := RecToDelete^.next;
RecToDelete^.next^.prior := RecToDelete^.prior;
FCurrentRecBuf := RecToDelete^.next;
if not GetRecordUpdateBuffer then
begin
if assigned(FEditBuf^.FieldsUpdateBuffer) then
for tel := 0 to high(FEditBuf^.FieldsUpdateBuffer) do
if not FEditBuf^.FieldsUpdateBuffer[tel].IsNull then
freemem(FEditBuf^.FieldsUpdateBuffer[tel].NewValue);
setlength(FEditBuf^.FieldsUpdateBuffer,0);
FEditBuf^.RecordNo := -1;
FCurrentUpdateBuffer := length(FUpdateBuffer);
SetLength(FUpdateBuffer,FCurrentUpdateBuffer+1);
FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := pchar(RecToDelete);
FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := RecToDelete;
end
else
begin
If not assigned(FEditBuf) then
begin
SetLength(FUpdateBuffer,length(FUpdateBuffer)+1);
FEditBuf := @FUpdateBuffer[high(FUpdateBuffer)];
end;
FEditBuf^.RecordNo := FBCurrentRecord;
FEditBuf^.UpdateKind := ukDelete;
FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer;
FreeRecordBuffer(pchar(RecToDelete));
end;
FEditBuf := nil;
FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukDelete;
end;
@ -573,10 +421,9 @@ end;
procedure TBufDataset.CancelUpdates;
var r,f : integer;
begin
for r := 0 to high(FUpdateBuffer) do
// To be implemented
{ for r := 0 to high(FUpdateBuffer) do
begin
if FUpdateBuffer[r].RecordNo > -1 then
if FUpdateBuffer[r].UpdateKind = ukDelete then
@ -594,72 +441,46 @@ begin
end;
SetLength(FUpdateBuffer,0);
if FOpen then Resync([]);
if FOpen then Resync([]);}
end;
procedure TBufDataset.ApplyUpdates;
var SaveBookmark : Integer;
r,i : Integer;
buffer : PChar;
x : integer;
FieldUpdBuf : PFieldUpdateBuffer;
NullMask : pbyte;
var SaveBookmark : pchar;
r : Integer;
FailedCount : integer;
begin
CheckBrowseMode;
// There is no bookmark available if the dataset is empty
if not IsEmpty then
SaveBookMark := GetRecNo;
GetBookmarkData(ActiveBuffer,@SaveBookmark);
r := 0;
FailedCount := 0;
while r < Length(FUpdateBuffer) do
begin
if (@FUpdateBuffer[r] <> FEditBuf) and // Neglect edit-buffer
(FUpdateBuffer[r].RecordNo <> -1) then // And the 'deleted' buffers
if assigned(FUpdateBuffer[r].BookmarkData) then
begin
FApplyingUpdates := true;
if FUpdateBuffer[r].UpdateKind = ukDelete then
InternalGotoBookmark(@(FUpdateBuffer[r].RecordNo))
else
begin
InternalGotoBookMark(@FUpdateBuffer[r].RecordNo);
Resync([rmExact,rmCenter]);
end;
InternalGotoBookmark(FUpdateBuffer[r].BookmarkData);
Resync([rmExact,rmCenter]);
if ApplyRecUpdate(FUpdateBuffer[r].UpdateKind) then
begin
buffer := FBBuffers[FUpdateBuffer[r].RecordNo];
NullMask := pbyte(buffer);
inc(buffer,FNullmaskSize);
for x := 0 to FieldDefs.count-1 do
begin
if GetFieldUpdateBuffer(x,@FUpdateBuffer[r],FieldUpdBuf) then
If not FieldUpdBuf^.IsNull then
begin
unSetFieldIsNull(NullMask,x);
move(FieldUpdBuf^.NewValue^,buffer^,GetFieldSize(FieldDefs[x]));
FreeMem(FieldUpdBuf^.NewValue);
end
else
SetFieldIsNull(NullMask,x);
Inc(Buffer, GetFieldSize(FieldDefs[x]));
end;
for i := r to high(FUpdateBuffer)-1 do
FUpdateBuffer[i] := FupdateBuffer[i+1];
dec(r);
SetLength(FUpdateBuffer,high(FUpdateBuffer));
end;
FApplyingUpdates := False;
FreeRecordBuffer(FUpdateBuffer[r].OldValuesBuffer);
FUpdateBuffer[r].BookmarkData := nil;
end
else
Inc(FailedCount);
end;
inc(r);
end;
if failedcount = 0 then
SetLength(FUpdateBuffer,0);
if not IsEmpty then
begin
InternalGotoBookMark(@SaveBookMark);
InternalGotoBookMark(SaveBookMark);
Resync([rmExact,rmCenter]);
end
else
@ -668,38 +489,67 @@ end;
procedure TBufDataset.InternalPost;
begin
if state in [dsEdit, dsInsert] then
begin
if Length(FUpdateBuffer[High(FUpdateBuffer)].FieldsUpdateBuffer) > 0 then
FEditBuf := nil;
end;
end;
procedure TBufDataset.InternalCancel;
var tel : integer;
Var tmpRecBuffer : PBufRecLinkItem;
CurrBuff : PChar;
begin
if state in [dsEdit, dsInsert] then
if state = dsInsert then
begin
if state = dsInsert then
if GetBookmarkFlag(ActiveBuffer) = bfEOF then
// Append
FCurrentRecBuf := FLastRecBuf
else
// The active buffer is the newly created TDataset record,
// from which the bookmark is set to the record where the new record should be
// inserted
GetBookmarkData(ActiveBuffer,@FCurrentRecBuf);
// Create the new record buffer
tmpRecBuffer := FCurrentRecBuf^.prior;
FCurrentRecBuf^.prior := pointer(IntAllocRecordBuffer);
FCurrentRecBuf^.prior^.next := FCurrentRecBuf;
FCurrentRecBuf := FCurrentRecBuf^.prior;
If assigned(tmpRecBuffer) then // if not, it's the first record
begin
SetDeleted(pbyte(FBBuffers[FBCurrentRecord]));
SetDeleted(pbyte(ActiveBuffer));
inc(FBDeletedRecords);
FCurrentRecBuf^.prior := tmpRecBuffer;
tmpRecBuffer^.next := FCurrentRecBuf
end
else
FFirstRecBuf := FCurrentRecBuf;
// Link the newly created record buffer to the newly created TDataset record
with PBufBookmark(ActiveBuffer + RecordSize)^ do
begin
BookmarkData := FCurrentRecBuf;
BookmarkFlag := bfInserted;
end;
FEditBuf^.RecordNo := -1;
end
else
GetBookmarkData(ActiveBuffer,@FCurrentRecBuf);
// clear the fieldbuffers
if assigned(FEditBuf^.FieldsUpdateBuffer) then
for tel := 0 to high(FEditBuf^.FieldsUpdateBuffer) do
if not FEditBuf^.FieldsUpdateBuffer[tel].IsNull then
freemem(FEditBuf^.FieldsUpdateBuffer[tel].NewValue);
setlength(FEditBuf^.FieldsUpdateBuffer,0);
if not GetRecordUpdateBuffer then
begin
FCurrentUpdateBuffer := length(FUpdateBuffer);
SetLength(FUpdateBuffer,FCurrentUpdateBuffer+1);
FUpdateBuffer[FCurrentUpdateBuffer].BookmarkData := FCurrentRecBuf;
if state = dsEdit then
begin
// Update the oldvalues-buffer
FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer := intAllocRecordBuffer;
move(FCurrentRecBuf^,FUpdateBuffer[FCurrentUpdateBuffer].OldValuesBuffer^,RecordSize+sizeof(TBufRecLinkItem));
FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukModify;
end
else
FUpdateBuffer[FCurrentUpdateBuffer].UpdateKind := ukInsert;
end;
end;
CurrBuff := pchar(FCurrentRecBuf);
inc(Currbuff,sizeof(TBufRecLinkItem));
move(ActiveBuffer^,CurrBuff^,RecordSize);
end;
procedure TBufDataset.CalcRecordSize;
@ -723,8 +573,12 @@ begin
end;
procedure TBufDataset.InternalInitRecord(Buffer: PChar);
begin
FillChar(Buffer^, FRecordSize, #0);
fillchar(Buffer^,FNullmaskSize,255);
unSetDeleted(pbyte(Buffer));
end;
procedure TBufDataset.SetRecNo(Value: Longint);
@ -736,7 +590,7 @@ end;
function TBufDataset.GetRecNo: Longint;
begin
GetBookmarkData(ActiveBuffer,@Result);
// GetBookmarkData(ActiveBuffer,@Result);
end;
function TBufDataset.IsCursorOpen: Boolean;
@ -748,7 +602,7 @@ end;
Function TBufDataset.GetRecordCount: Longint;
begin
Result := FBRecordCount-FBDeletedRecords;
// Result := FBRecordCount-FBDeletedRecords;
end;
Function TBufDataset.Locate(const KeyFields: string; const KeyValues: Variant; options: TLocateOptions) : boolean;
@ -768,7 +622,7 @@ var keyfield : TField; // Field to search in
begin
// For now it is only possible to search in one field at the same time
result := False;
{ result := False;
keyfield := FieldByName(keyfields);
CheckNull := VarIsNull(KeyValues);
@ -821,12 +675,9 @@ begin
if Result then
begin
bm.BookmarkData := i;
// bm.BookmarkData := i;
bm.BookmarkFlag := bfCurrent;
GotoBookmark(@bm);
end;
end;}
end;

View File

@ -1472,50 +1472,43 @@ type
PBufBookmark = ^TBufBookmark;
TBufBookmark = record
BookmarkData : integer;
BookmarkData : Pointer;
BookmarkFlag : TBookmarkFlag;
end;
PFieldUpdateBuffer = ^TFieldUpdateBuffer;
TFieldUpdateBuffer = record
FieldNo : integer;
NewValue : pointer;
IsNull : boolean;
PBufRecLinkItem = ^TBufRecLinkItem;
TBufRecLinkItem = record
prior : PBufRecLinkItem;
next : PBufRecLinkItem;
end;
TFieldsUpdateBuffer = array of TFieldUpdateBuffer;
PRecUpdateBuffer = ^TRecUpdateBuffer;
TRecUpdateBuffer = record
RecordNo : integer;
FieldsUpdateBuffer : TFieldsUpdateBuffer;
UpdateKind : TUpdateKind;
BookmarkData : pointer;
OldValuesBuffer : pchar;
end;
TRecordsUpdateBuffer = array of TRecUpdateBuffer;
TBufDataset = class(TDBDataSet)
private
FBBuffers : TBufferArray;
FBRecordCount : integer;
FBBufferCount : integer;
FBCurrentRecord : integer;
FIsEOF : boolean;
FIsBOF : boolean;
FCurrentRecBuf : PBufRecLinkItem;
FLastRecBuf : PBufRecLinkItem;
FFirstRecBuf : PBufRecLinkItem;
FPacketRecords : integer;
FRecordSize : Integer;
FNullmaskSize : byte;
FOpen : Boolean;
FUpdateBuffer : TRecordsUpdateBuffer;
FEditBuf : PRecUpdateBuffer;
FApplyingUpdates: boolean;
FBDeletedRecords: integer;
FCurrentUpdateBuffer : integer;
FFieldBufPositions : array of longint;
procedure CalcRecordSize;
function LoadBuffer(Buffer : PChar): TGetResult;
function GetFieldSize(FieldDef : TFieldDef) : longint;
function GetRecordUpdateBuffer(rno : integer;var RecUpdBuf : PRecUpdateBuffer) : boolean;
function GetFieldUpdateBuffer(fieldno : integer;RecUpdBuf : PRecUpdateBuffer;var FieldUpdBuf : pFieldUpdateBuffer) : boolean;
function GetRecordUpdateBuffer : boolean;
procedure SetPacketRecords(aValue : integer);
function IntAllocRecordBuffer: PChar;
protected
@ -1531,9 +1524,6 @@ type
function getnextpacket : integer;
function GetRecordSize: Word; override;
procedure InternalPost; override;
procedure InternalCancel; override;
procedure InternalEdit; override;
procedure InternalInsert; override;
procedure InternalDelete; override;
procedure InternalFirst; override;
procedure InternalLast; override;