diff options
author | lacak <lacak@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-02-12 12:24:47 +0000 |
---|---|---|
committer | lacak <lacak@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-02-12 12:24:47 +0000 |
commit | 083b2f4bd1596886efdc353ec6b2c8dce66ebcbf (patch) | |
tree | ba04ce5394cd6dae0e823950bff839a672127f1f /packages | |
parent | 17ce65dd3aceef9b45735adedd82f3191a14d125 (diff) | |
download | fpc-083b2f4bd1596886efdc353ec6b2c8dce66ebcbf.tar.gz |
fcl-db: bufdataset: small reprocessing
- adapt method ProcessFieldsToCompareStruct - initialise DBCompareStruct in one place all fields. Used by BuildIndex and Locate.
- add new method BufferOffset - returns offset of buffer data from begining of memory record = ( sizeof(TBufRecLinkItem) * FMaxIndexesCount )
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@23598 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages')
-rw-r--r-- | packages/fcl-db/src/base/bufdataset.pas | 137 |
1 files changed, 70 insertions, 67 deletions
diff --git a/packages/fcl-db/src/base/bufdataset.pas b/packages/fcl-db/src/base/bufdataset.pas index 2b5a6ed844..aef5b07b8f 100644 --- a/packages/fcl-db/src/base/bufdataset.pas +++ b/packages/fcl-db/src/base/bufdataset.pas @@ -433,7 +433,10 @@ type FUpdateBlobBuffers: array of PBlobBuffer; procedure FetchAll; + procedure ProcessFieldsToCompareStruct(const AFields, ADescFields, ACInsFields: TList; + const AIndexOptions: TIndexOptions; const ALocateOptions: TLocateOptions; out ACompareStruct: TDBCompareStruct); procedure BuildIndex(var AIndex : TBufIndex); + function BufferOffset: integer; function GetIndexDefs : TIndexDefs; function GetCurrentBuffer: TRecordBuffer; procedure CalcRecordSize; @@ -446,7 +449,6 @@ type function GetRecordUpdateBuffer(const ABookmark : TBufBookmark; IncludePrior : boolean = false; AFindNext : boolean = false) : boolean; function GetRecordUpdateBufferCached(const ABookmark : TBufBookmark; IncludePrior : boolean = false) : boolean; function GetActiveRecordUpdateBuffer : boolean; - procedure ProcessFieldCompareStruct(AField: TField; var ACompareRec : TDBCompareRec); procedure SetIndexFieldNames(const AValue: String); procedure SetIndexName(AValue: String); procedure SetMaxIndexesCount(const AValue: Integer); @@ -887,9 +889,7 @@ var PCurRecLinkItem : PBufRecLinkItem; IndexFields : TList; DescIndexFields : TList; CInsIndexFields : TList; - FieldsAmount : Integer; - FieldNr : integer; - AField : TField; + Index0, DblLinkIndex : TDoubleLinkedBufIndex; @@ -923,24 +923,11 @@ begin CInsIndexFields := TList.Create; try GetFieldList(IndexFields,FieldsName); - FieldsAmount:=IndexFields.Count; GetFieldList(DescIndexFields,DescFields); GetFieldList(CInsIndexFields,CaseinsFields); - if FieldsAmount=0 then + if IndexFields.Count=0 then DatabaseError(SNoIndexFieldNameGiven); - SetLength(DBCompareStruct,FieldsAmount); - for FieldNr:=0 to FieldsAmount-1 do - begin - AField := TField(IndexFields[FieldNr]); - ProcessFieldCompareStruct(AField,DBCompareStruct[FieldNr]); - - DBCompareStruct[FieldNr].Desc := (DescIndexFields.IndexOf(AField)>-1) or (ixDescending in Options); - if (CInsIndexFields.IndexOf(AField)>-1) then - DBCompareStruct[FieldNr].Options := [loCaseInsensitive] - else - DBCompareStruct[FieldNr].Options := []; - - end; + ProcessFieldsToCompareStruct(IndexFields, DescIndexFields, CInsIndexFields, Options, [], DBCompareStruct); finally CInsIndexFields.Free; DescIndexFields.Free; @@ -1089,10 +1076,16 @@ begin Result:=not (UniDirectional or ReadOnly); end; +function TCustomBufDataset.BufferOffset: integer; +begin + // Returns the offset of data buffer in bufdataset record + Result := sizeof(TBufRecLinkItem) * FMaxIndexesCount; +end; + function TCustomBufDataset.IntAllocRecordBuffer: TRecordBuffer; begin // Note: Only the internal buffers of TDataset provide bookmark information - result := AllocMem(FRecordSize+sizeof(TBufRecLinkItem)*FMaxIndexesCount); + result := AllocMem(FRecordSize+BufferOffset); end; function TCustomBufDataset.AllocRecordBuffer: TRecordBuffer; @@ -1237,11 +1230,6 @@ begin SetToLastRecord; end; -function TDoubleLinkedBufIndex.GetCurrentRecord: TRecordBuffer; -begin - Result := TRecordBuffer(FCurrentRecBuf); -end; - function TDoubleLinkedBufIndex.GetBookmarkSize: integer; begin Result:=sizeof(TBufBookmark); @@ -1249,7 +1237,12 @@ end; function TDoubleLinkedBufIndex.GetCurrentBuffer: Pointer; begin - Result := pointer(FCurrentRecBuf)+(sizeof(TBufRecLinkItem)*FDataset.MaxIndexesCount); + Result := pointer(FCurrentRecBuf) + FDataset.BufferOffset; +end; + +function TDoubleLinkedBufIndex.GetCurrentRecord: TRecordBuffer; +begin + Result := TRecordBuffer(FCurrentRecBuf); end; function TDoubleLinkedBufIndex.GetIsInitialized: boolean; @@ -1259,7 +1252,7 @@ end; function TDoubleLinkedBufIndex.GetSpareBuffer: TRecordBuffer; begin - Result := pointer(FLastRecBuf)+(sizeof(TBufRecLinkItem)*FDataset.MaxIndexesCount); + Result := pointer(FLastRecBuf) + FDataset.BufferOffset; end; function TDoubleLinkedBufIndex.GetSpareRecord: TRecordBuffer; @@ -1598,34 +1591,53 @@ begin result := GetRecordUpdateBufferCached(ABookmark); end; -procedure TCustomBufDataset.ProcessFieldCompareStruct(AField: TField; var ACompareRec : TDBCompareRec); -begin - case AField.DataType of - ftString, ftFixedChar : ACompareRec.Comparefunc := @DBCompareText; - ftWideString, ftFixedWideChar: ACompareRec.Comparefunc := @DBCompareWideText; - ftSmallint : ACompareRec.Comparefunc := @DBCompareSmallInt; - ftInteger, ftBCD, ftAutoInc : ACompareRec.Comparefunc := - @DBCompareInt; - ftWord : ACompareRec.Comparefunc := @DBCompareWord; - ftBoolean : ACompareRec.Comparefunc := @DBCompareByte; - ftFloat, ftCurrency : ACompareRec.Comparefunc := @DBCompareDouble; - ftDateTime, ftDate, ftTime : ACompareRec.Comparefunc := - @DBCompareDouble; - ftLargeint : ACompareRec.Comparefunc := @DBCompareLargeInt; - ftFmtBCD : ACompareRec.Comparefunc := @DBCompareBCD; - else - DatabaseErrorFmt(SErrIndexBasedOnInvField, [AField.FieldName,Fieldtypenames[AField.DataType]]); - end; +procedure TCustomBufDataset.ProcessFieldsToCompareStruct(const AFields, ADescFields, ACInsFields: TList; + const AIndexOptions: TIndexOptions; const ALocateOptions: TLocateOptions; out ACompareStruct: TDBCompareStruct); +var i: integer; + AField: TField; + ACompareRec: TDBCompareRec; +begin + SetLength(ACompareStruct, AFields.Count); + for i:=0 to high(ACompareStruct) do + begin + AField := TField(AFields[i]); + + case AField.DataType of + ftString, ftFixedChar : ACompareRec.Comparefunc := @DBCompareText; + ftWideString, ftFixedWideChar: ACompareRec.Comparefunc := @DBCompareWideText; + ftSmallint : ACompareRec.Comparefunc := @DBCompareSmallInt; + ftInteger, ftBCD, ftAutoInc : ACompareRec.Comparefunc := + @DBCompareInt; + ftWord : ACompareRec.Comparefunc := @DBCompareWord; + ftBoolean : ACompareRec.Comparefunc := @DBCompareByte; + ftFloat, ftCurrency : ACompareRec.Comparefunc := @DBCompareDouble; + ftDateTime, ftDate, ftTime : ACompareRec.Comparefunc := + @DBCompareDouble; + ftLargeint : ACompareRec.Comparefunc := @DBCompareLargeInt; + ftFmtBCD : ACompareRec.Comparefunc := @DBCompareBCD; + else + DatabaseErrorFmt(SErrIndexBasedOnInvField, [AField.FieldName,Fieldtypenames[AField.DataType]]); + end; + + ACompareRec.Off1:=BufferOffset + FFieldBufPositions[AField.FieldNo-1]; + ACompareRec.Off2:=ACompareRec.Off1; - ACompareRec.Off1:=sizeof(TBufRecLinkItem)*FMaxIndexesCount+ - FFieldBufPositions[AField.FieldNo-1]; - ACompareRec.Off2:=ACompareRec.Off1; + ACompareRec.FieldInd1:=AField.FieldNo-1; + ACompareRec.FieldInd2:=ACompareRec.FieldInd1; - ACompareRec.FieldInd1:=AField.FieldNo-1; - ACompareRec.FieldInd2:=ACompareRec.FieldInd1; + ACompareRec.NullBOff1:=BufferOffset; + ACompareRec.NullBOff2:=ACompareRec.NullBOff1; - ACompareRec.NullBOff1:=sizeof(TBufRecLinkItem)*MaxIndexesCount; - ACompareRec.NullBOff2:=ACompareRec.NullBOff1; + ACompareRec.Desc := ixDescending in AIndexOptions; + if assigned(ADescFields) then + ACompareRec.Desc := ACompareRec.Desc or (ADescFields.IndexOf(AField)>-1); + + ACompareRec.Options := ALocateOptions; + if assigned(ACInsFields) and (ACInsFields.IndexOf(AField)>-1) then + ACompareRec.Options := ACompareRec.Options + [loCaseInsensitive]; + + ACompareStruct[i] := ACompareRec; + end; end; procedure TCustomBufDataset.InitDefaultIndexes; @@ -3084,11 +3096,9 @@ Function TCustomBufDataset.Locate(const KeyFields: string; const KeyValues: Vari var CurrLinkItem : PBufRecLinkItem; bm : TBufBookmark; SearchFields : TList; - FieldsAmount : Integer; DBCompareStruct : TDBCompareStruct; - FieldNr : Integer; StoreDSState : TDataSetState; - FilterBuffer : TRecordBuffer; + FilterBuffer : TRecordBuffer; FiltAcceptable : boolean; begin @@ -3101,15 +3111,8 @@ begin SearchFields := TList.Create; try GetFieldList(SearchFields,KeyFields); - FieldsAmount:=SearchFields.Count; - if FieldsAmount=0 then exit; - - SetLength(DBCompareStruct,FieldsAmount); - for FieldNr:=0 to FieldsAmount-1 do - begin - ProcessFieldCompareStruct(TField(SearchFields[FieldNr]),DBCompareStruct[FieldNr]); - DBCompareStruct[FieldNr].Options:=options; - end; + if SearchFields.Count=0 then exit; + ProcessFieldsToCompareStruct(SearchFields, nil, nil, [], Options, DBCompareStruct); finally SearchFields.Free; end; @@ -3118,18 +3121,18 @@ begin StoreDSState:=SetTempState(dsFilter); FFilterBuffer:=FCurrentIndex.SpareBuffer; SetFieldValues(KeyFields,KeyValues); - CurrLinkItem := (FCurrentIndex as TDoubleLinkedBufIndex).FFirstRecBuf; FilterBuffer:=IntAllocRecordBuffer; - move((FCurrentIndex as TDoubleLinkedBufIndex).FLastRecBuf^,FilterBuffer^,FRecordSize+sizeof(TBufRecLinkItem)*FMaxIndexesCount); + move(FCurrentIndex.SpareRecord^, FilterBuffer^, FRecordSize+BufferOffset); // Iterate through the records until a match is found + CurrLinkItem := (FCurrentIndex as TDoubleLinkedBufIndex).FFirstRecBuf; while (CurrLinkItem <> (FCurrentIndex as TDoubleLinkedBufIndex).FLastRecBuf) do begin if (IndexCompareRecords(FilterBuffer,CurrLinkItem,DBCompareStruct) = 0) then begin if Filtered then begin - FFilterBuffer:=pointer(CurrLinkItem)+(sizeof(TBufRecLinkItem)*MaxIndexesCount); + FFilterBuffer:=pointer(CurrLinkItem)+BufferOffset; // The dataset state is still dsFilter at this point, so we don't have to set it. DoFilterRecord(FiltAcceptable); if FiltAcceptable then |