* Implemented descending indexes, for those too lazy to use last-prior-prior ;)

* TBufDataset.AddIndex has got the new parameters options,descfields and caseinsfields

git-svn-id: trunk@10654 -
This commit is contained in:
joost 2008-04-13 16:51:11 +00:00
parent 0aacad124c
commit 97f2a80d0d
2 changed files with 87 additions and 22 deletions

View File

@ -110,6 +110,7 @@ type
TDBCompareRec = record TDBCompareRec = record
Comparefunc : TCompareFunc; Comparefunc : TCompareFunc;
Off1,Off2 : PtrInt; Off1,Off2 : PtrInt;
Desc : Boolean;
end; end;
TDBCompareStruct = array of TDBCompareRec; TDBCompareStruct = array of TDBCompareRec;
@ -120,6 +121,7 @@ type
FieldsName : String; FieldsName : String;
CaseinsFields : String; CaseinsFields : String;
DescFields : String; DescFields : String;
Options : TIndexOptions;
DBCompareStruct : TDBCompareStruct; DBCompareStruct : TDBCompareStruct;
{$IFDEF ARRAYBUF} {$IFDEF ARRAYBUF}
FCurrentRecInd : integer; FCurrentRecInd : integer;
@ -217,7 +219,8 @@ type
procedure InternalClose; override; procedure InternalClose; override;
function getnextpacket : integer; function getnextpacket : integer;
function GetRecordSize: Word; override; function GetRecordSize: Word; override;
procedure InternalAddIndex(const AName, AFields : string); virtual; procedure InternalAddIndex(const AName, AFields : string; AOptions : TIndexOptions; const ADescFields: string;
const ACaseInsFields: string); virtual;
procedure InternalPost; override; procedure InternalPost; override;
procedure InternalCancel; Override; procedure InternalCancel; Override;
procedure InternalDelete; override; procedure InternalDelete; override;
@ -255,7 +258,8 @@ type
function Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean; override; function Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean; override;
function UpdateStatus: TUpdateStatus; override; function UpdateStatus: TUpdateStatus; override;
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override; function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override;
procedure AddIndex(const AName, AFields : string); virtual; procedure AddIndex(const AName, AFields : string; AOptions : TIndexOptions; const ADescFields: string = '';
const ACaseInsFields: string = ''); virtual;
property ChangeCount : Integer read GetChangeCount; property ChangeCount : Integer read GetChangeCount;
{$IFNDEF ARRAYBUF} {$IFNDEF ARRAYBUF}
property MaxIndexesCount : Integer read FMaxIndexesCount write SetMaxIndexesCount; property MaxIndexesCount : Integer read FMaxIndexesCount write SetMaxIndexesCount;
@ -354,7 +358,12 @@ begin
for IndexFieldNr:=0 to length(ADBCompareRecs)-1 do with ADBCompareRecs[IndexFieldNr] do for IndexFieldNr:=0 to length(ADBCompareRecs)-1 do with ADBCompareRecs[IndexFieldNr] do
begin begin
Result := Comparefunc(Rec1+Off1,Rec2+Off2,[]); Result := Comparefunc(Rec1+Off1,Rec2+Off2,[]);
if Result <> 0 then break; if Result <> 0 then
begin
if Desc then
Result := -Result;
break;
end;
end; end;
end; end;
@ -372,8 +381,8 @@ begin
FMaxIndexesCount:=2; FMaxIndexesCount:=2;
{$ENDIF} {$ENDIF}
FIndexesCount:=0; FIndexesCount:=0;
InternalAddIndex('DEFAULT_ORDER',''); InternalAddIndex('DEFAULT_ORDER','',[],'','');
InternalAddIndex('',''); InternalAddIndex('','',[],'','');
FCurrentIndex:=@FIndexes[0]; FCurrentIndex:=@FIndexes[0];
FIndexDefs := TIndexDefs.Create(Self); FIndexDefs := TIndexDefs.Create(Self);
@ -412,7 +421,8 @@ var PCurRecLinkItem : PBufRecLinkItem;
MergeAmount : integer; MergeAmount : integer;
PlaceQRec : boolean; PlaceQRec : boolean;
IndexFields : TStrings; IndexFields : TList;
DescIndexFields : TList;
FieldsAmount : Integer; FieldsAmount : Integer;
FieldNr : integer; FieldNr : integer;
AField : TField; AField : TField;
@ -439,17 +449,18 @@ begin
// Build the DBCompareStructure // Build the DBCompareStructure
with AIndex do with AIndex do
begin begin
IndexFields := TStringList.Create; IndexFields := TList.Create;
DescIndexFields := TList.Create;
try try
FieldsAmount:=ExtractStrings([','],[' '],pchar(FieldsName),IndexFields); GetFieldList(IndexFields,FieldsName);
FieldsAmount:=IndexFields.Count;
GetFieldList(DescIndexFields,DescFields);
if FieldsAmount=0 then if FieldsAmount=0 then
DatabaseError(SNoIndexFieldNameGiven); DatabaseError(SNoIndexFieldNameGiven);
SetLength(DBCompareStruct,FieldsAmount); SetLength(DBCompareStruct,FieldsAmount);
for FieldNr:=0 to FieldsAmount-1 do for FieldNr:=0 to FieldsAmount-1 do
begin begin
AField := FindField(IndexFields[FieldNr]); AField := TField(IndexFields[FieldNr]);
if not assigned(AField) then
DatabaseErrorFmt(SErrIndexBasedOnUnkField,[IndexFields[FieldNr]]);
case AField.DataType of case AField.DataType of
ftString : DBCompareStruct[FieldNr].Comparefunc := @DBCompareText; ftString : DBCompareStruct[FieldNr].Comparefunc := @DBCompareText;
@ -464,11 +475,14 @@ begin
DatabaseErrorFmt(SErrIndexBasedOnInvField,[AField.FieldName]); DatabaseErrorFmt(SErrIndexBasedOnInvField,[AField.FieldName]);
end; end;
DBCompareStruct[FieldNr].Desc := (DescIndexFields.IndexOf(AField)>-1);
DBCompareStruct[FieldNr].Off1:=sizeof(TBufRecLinkItem)*FMaxIndexesCount+FFieldBufPositions[AField.FieldNo-1]; DBCompareStruct[FieldNr].Off1:=sizeof(TBufRecLinkItem)*FMaxIndexesCount+FFieldBufPositions[AField.FieldNo-1];
DBCompareStruct[FieldNr].Off2:=DBCompareStruct[FieldNr].Off1; DBCompareStruct[FieldNr].Off2:=DBCompareStruct[FieldNr].Off1;
end; end;
finally finally
DescIndexFields.Free;
IndexFields.Free; IndexFields.Free;
end; end;
end; end;
@ -609,6 +623,7 @@ begin
Fields := FIndexes[i].FieldsName; Fields := FIndexes[i].FieldsName;
DescFields:= FIndexes[i].DescFields; DescFields:= FIndexes[i].DescFields;
CaseInsFields:=FIndexes[i].CaseinsFields; CaseInsFields:=FIndexes[i].CaseinsFields;
Options:=FIndexes[i].Options;
end; end;
end; end;
@ -2076,7 +2091,8 @@ begin
end; end;
end; end;
procedure TBufDataset.AddIndex(const AName, AFields: string); procedure TBufDataset.AddIndex(const AName, AFields : string; AOptions : TIndexOptions; const ADescFields: string = '';
const ACaseInsFields: string = '');
begin begin
if AFields='' then DatabaseError(SNoIndexFieldNameGiven); if AFields='' then DatabaseError(SNoIndexFieldNameGiven);
@ -2088,10 +2104,11 @@ begin
// If not all packets are fetched, you can not sort properly. // If not all packets are fetched, you can not sort properly.
if not active then if not active then
FPacketRecords:=-1; FPacketRecords:=-1;
InternalAddIndex(AName,AFields); InternalAddIndex(AName,AFields,AOptions,ADescFields,ACaseInsFields);
end; end;
procedure TBufDataset.InternalAddIndex(const AName, AFields: string); procedure TBufDataset.InternalAddIndex(const AName, AFields : string; AOptions : TIndexOptions; const ADescFields: string;
const ACaseInsFields: string);
var StoreIndNr : Integer; var StoreIndNr : Integer;
begin begin
if Active then FetchAll; if Active then FetchAll;
@ -2107,6 +2124,9 @@ begin
begin begin
Name:=AName; Name:=AName;
FieldsName:=AFields; FieldsName:=AFields;
DescFields:=ADescFields;
CaseinsFields:=ACaseInsFields;
Options:=AOptions;
IndNr:=FIndexesCount-1; IndNr:=FIndexesCount-1;
end; end;

View File

@ -42,6 +42,7 @@ type
procedure TestGetFieldValues; procedure TestGetFieldValues;
procedure TestAddIndex; procedure TestAddIndex;
procedure TestAddDescIndex;
procedure TestInactSwitchIndex; procedure TestInactSwitchIndex;
procedure TestAddIndexInteger; procedure TestAddIndexInteger;
@ -886,7 +887,7 @@ begin
if not ActiveDS then if not ActiveDS then
begin begin
AddIndex('testindex','F'+FieldTypeNames[AfieldType]); AddIndex('testindex','F'+FieldTypeNames[AfieldType],[]);
IndexName:='testindex'; IndexName:='testindex';
end end
else else
@ -905,7 +906,7 @@ begin
begin begin
if not assigned(ds.FindField('F'+FieldTypeNames[AfieldType])) then if not assigned(ds.FindField('F'+FieldTypeNames[AfieldType])) then
Ignore('Fields of the type ' + FieldTypeNames[AfieldType] + ' are not supported by this type of dataset'); Ignore('Fields of the type ' + FieldTypeNames[AfieldType] + ' are not supported by this type of dataset');
AddIndex('testindex','F'+FieldTypeNames[AfieldType]); AddIndex('testindex','F'+FieldTypeNames[AfieldType],[]);
IndexName:='testindex'; IndexName:='testindex';
First; First;
end; end;
@ -978,7 +979,7 @@ begin
begin begin
AFieldType:=ftString; AFieldType:=ftString;
AddIndex('testindex','F'+FieldTypeNames[AfieldType]); AddIndex('testindex','F'+FieldTypeNames[AfieldType],[]);
FList := TStringList.Create; FList := TStringList.Create;
FList.Sorted:=true; FList.Sorted:=true;
FList.CaseSensitive:=True; FList.CaseSensitive:=True;
@ -1011,6 +1012,50 @@ begin
end; end;
end; end;
procedure TTestDBBasics.TestAddDescIndex;
var ds : TBufDataset;
AFieldType : TFieldType;
FList : TStringList;
i : integer;
begin
ds := DBConnector.GetFieldDataset as TBufDataset;
with ds do
begin
AFieldType:=ftString;
AddIndex('testindex','F'+FieldTypeNames[AfieldType],[],'F'+FieldTypeNames[AfieldType]);
FList := TStringList.Create;
FList.Sorted:=true;
FList.CaseSensitive:=True;
FList.Duplicates:=dupAccept;
open;
while not eof do
begin
flist.Add(FieldByName('F'+FieldTypeNames[AfieldType]).AsString);
Next;
end;
IndexName:='testindex';
first;
i:=FList.Count-1;
while not eof do
begin
AssertEquals(flist[i],FieldByName('F'+FieldTypeNames[AfieldType]).AsString);
dec(i);
Next;
end;
while not bof do
begin
inc(i);
AssertEquals(flist[i],FieldByName('F'+FieldTypeNames[AfieldType]).AsString);
Prior;
end;
end;
end;
procedure TTestDBBasics.TestInactSwitchIndex; procedure TTestDBBasics.TestInactSwitchIndex;
// Test if the default-index is properly build when the active index is not // Test if the default-index is properly build when the active index is not
// the default-index while opening then dataset // the default-index while opening then dataset
@ -1023,7 +1068,7 @@ begin
begin begin
AFieldType:=ftString; AFieldType:=ftString;
AddIndex('testindex','F'+FieldTypeNames[AfieldType]); AddIndex('testindex','F'+FieldTypeNames[AfieldType],[]);
IndexName:='testindex'; IndexName:='testindex';
open; open;
IndexName:=''; // This should set the default index (default_order) IndexName:=''; // This should set the default index (default_order)
@ -1066,7 +1111,7 @@ begin
FieldByName('name').asstring := 'aA'; FieldByName('name').asstring := 'aA';
post; post;
AddIndex('test','name'); AddIndex('test','name',[]);
first; first;
ds.IndexName:='test'; ds.IndexName:='test';
@ -1163,7 +1208,7 @@ begin
with ds do with ds do
begin begin
AFieldType:=ftString; AFieldType:=ftString;
AddIndex('testindex','F'+FieldTypeNames[AfieldType]); AddIndex('testindex','F'+FieldTypeNames[AfieldType],[]);
open; open;
for i := 0 to (testValuesCount div 3) do for i := 0 to (testValuesCount div 3) do
@ -1208,7 +1253,7 @@ begin
with ds do with ds do
begin begin
AddIndex('testindex','F'+FieldTypeNames[ftString]+', F'+FieldTypeNames[ftInteger]); AddIndex('testindex','F'+FieldTypeNames[ftString]+', F'+FieldTypeNames[ftInteger],[]);
FList := TStringList.Create; FList := TStringList.Create;
FList.Sorted:=true; FList.Sorted:=true;
FList.CaseSensitive:=True; FList.CaseSensitive:=True;
@ -1258,7 +1303,7 @@ begin
with ds do with ds do
begin begin
AFieldType:=ftString; AFieldType:=ftString;
AddIndex('testindex','F'+FieldTypeNames[AfieldType]); AddIndex('testindex','F'+FieldTypeNames[AfieldType],[]);
IndexName:='testindex'; IndexName:='testindex';
open; open;
OldStringValue:=FieldByName('F'+FieldTypeNames[AfieldType]).AsString; OldStringValue:=FieldByName('F'+FieldTypeNames[AfieldType]).AsString;