From a75c1e5dd3bcf973cb5ca98316fb9c5b595d5304 Mon Sep 17 00:00:00 2001 From: joost Date: Sat, 1 Apr 2006 16:03:41 +0000 Subject: [PATCH] + Replaced the array-based record-buffer for a linked-list buffer git-svn-id: trunk@3111 - --- fcl/db/bufdataset.inc | 497 +++++++++++++++--------------------------- fcl/db/db.pp | 40 ++-- 2 files changed, 189 insertions(+), 348 deletions(-) diff --git a/fcl/db/bufdataset.inc b/fcl/db/bufdataset.inc index 7736cc9910..a285b33a96 100644 --- a/fcl/db/bufdataset.inc +++ b/fcl/db/bufdataset.inc @@ -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; - - - diff --git a/fcl/db/db.pp b/fcl/db/db.pp index e3c783badc..f0721a2506 100644 --- a/fcl/db/db.pp +++ b/fcl/db/db.pp @@ -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;