|
From: Micha N. <md...@us...> - 2004-08-18 19:16:45
|
Update of /cvsroot/tdbf/tdbf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19925 Modified Files: Dbf.pas Dbf_Common.inc Dbf_Cursor.pas Dbf_DbfFile.pas Dbf_IdxCur.pas Dbf_IdxFile.pas history.txt Log Message: added: multi-user and insert aware ranges (req by ralf) Index: Dbf_Common.inc =================================================================== RCS file: /cvsroot/tdbf/tdbf/Dbf_Common.inc,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Dbf_Common.inc 31 Jul 2004 17:26:54 -0000 1.11 --- Dbf_Common.inc 18 Aug 2004 19:16:22 -0000 1.12 *************** *** 175,178 **** --- 175,179 ---- {$define SUPPORT_FIELDTYPES_V4} {$define SUPPORT_UINT32_CARDINAL} + {$define SUPPORT_REINTRODUCE} // FPC 1.0.x exceptions: no 0/0 support Index: history.txt =================================================================== RCS file: /cvsroot/tdbf/tdbf/history.txt,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** history.txt 18 Aug 2004 14:21:32 -0000 1.60 --- history.txt 18 Aug 2004 19:16:26 -0000 1.61 *************** *** 15,20 **** - Multi-user support - not tested well... - - ranges are not fully multi-user 'aware' (yet) because range is cached - -> race conditions can occur - use FIXED LENGTH index expressions: an expression which will always return a string which is the same length. When returning a float you don't have to --- 15,18 ---- *************** *** 50,53 **** --- 48,52 ---- - fixed: use correct dbf version when creating table to decide field types - fixed: kylix compilation + - added: multi-user and insert aware ranges (req by ralf) Index: Dbf_DbfFile.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/Dbf_DbfFile.pas,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** Dbf_DbfFile.pas 18 Aug 2004 13:49:59 -0000 1.56 --- Dbf_DbfFile.pas 18 Aug 2004 19:16:22 -0000 1.57 *************** *** 152,157 **** procedure GotoBookmark(Bookmark: rBookmarkData); override; - procedure Insert(RecNo: Integer; Buffer: PChar); override; - procedure Update(RecNo: Integer; PrevBuffer,NewBuffer: PChar); override; function GetBookMark: rBookmarkData; override; end; --- 152,155 ---- *************** *** 2397,2409 **** end; - procedure TDbfCursor.Insert(RecNo: Integer; Buffer: PChar); {override;} - begin - FPhysicalRecNo := TDbfFile(PagedFile).RecordCount; - end; - - procedure TDbfCursor.Update(RecNo: Integer; PrevBuffer,NewBuffer: PChar); {override;} - begin - end; - // codepage enumeration procedure var --- 2395,2398 ---- Index: Dbf.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/Dbf.pas,v retrieving revision 1.80 retrieving revision 1.81 diff -C2 -d -r1.80 -r1.81 *** Dbf.pas 18 Aug 2004 13:49:59 -0000 1.80 --- Dbf.pas 18 Aug 2004 19:16:21 -0000 1.81 *************** *** 2286,2290 **** // try to delete index FDbfFile.DeleteIndex(lIndexFileName); - // raise EDbfError.CreateFmt(STRING_INDEX_NOT_EXIST, [AIndexName]); // refresh index defs --- 2286,2289 ---- *************** *** 2470,2515 **** // disable current range if any ! TIndexCursor(FCursor).CancelRange; ! // refresh ! Refresh; end; procedure TDbf.SetRangeBuffer(LowRange: PChar; HighRange: PChar); - var - Result: Boolean; begin if FIndexFile = nil then exit; ! // disable current range if any ! TIndexCursor(FCursor).CancelRange; ! // search lower bound ! Result := TIndexCursor(FCursor).SearchKey(LowRange, stGreaterEqual); ! if not Result then ! begin ! // not found? -> make empty range ! FCursor.Last; ! end; ! // set lower bound ! TIndexCursor(FCursor).SetBracketLow; ! // search upper bound ! Result := TIndexCursor(FCursor).SearchKey(HighRange, stGreater); ! // if result true, then need to get previous item <=> ! // last of equal/lower than key ! if Result then ! begin ! Result := FCursor.Prev; ! if not Result then ! begin ! // cannot go prev -> empty range ! FCursor.First; ! end; ! end else begin ! // not found -> EOF found, go EOF, then to last record ! FCursor.Last; ! FCursor.Prev; ! end; ! // set upper bound ! TIndexCursor(FCursor).SetBracketHigh; // go to first in this range if Active then --- 2469,2483 ---- // disable current range if any ! FIndexFile.CancelRange; ! // reretrieve previous and next records ! Resync([]); end; procedure TDbf.SetRangeBuffer(LowRange: PChar; HighRange: PChar); begin if FIndexFile = nil then exit; ! FIndexFile.SetRange(LowRange, HighRange); // go to first in this range if Active then *************** *** 2550,2555 **** procedure TDbf.ExtractKey(KeyBuffer: PChar); begin ! if FCursor is TIndexCursor then ! StrCopy(TIndexCursor(FCursor).IndexFile.ExtractKeyFromBuffer(GetCurrentBuffer), KeyBuffer) else KeyBuffer[0] := #0; --- 2518,2523 ---- procedure TDbf.ExtractKey(KeyBuffer: PChar); begin ! if FIndexFile <> nil then ! StrCopy(FIndexFile.ExtractKeyFromBuffer(GetCurrentBuffer), KeyBuffer) else KeyBuffer[0] := #0; *************** *** 2618,2622 **** CheckBrowseMode; ! Result := TIndexCursor(FCursor).SearchKey(Buffer, SearchType); { if found, then retrieve new current record } if Result then --- 2586,2590 ---- CheckBrowseMode; ! Result := FIndexFile.SearchKey(Buffer, SearchType); { if found, then retrieve new current record } if Result then Index: Dbf_IdxCur.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/Dbf_IdxCur.pas,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Dbf_IdxCur.pas 28 Jul 2004 08:14:31 -0000 1.11 --- Dbf_IdxCur.pas 18 Aug 2004 19:16:24 -0000 1.12 *************** *** 42,56 **** function GetBookMark: rBookmarkData; override; ! procedure Insert(RecNo: Integer; Buffer: PChar); override; ! procedure Update(RecNo: Integer; PrevBuffer, NewBuffer: PChar); override; {$ifdef SUPPORT_VARIANTS} ! procedure VariantToBuffer(Key: Variant; ABuffer: PChar); { override; } {$endif} ! function CheckUserKey(Key: PChar; StringBuf: PChar): PChar; { override; } ! function SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; { override; } ! procedure CancelRange; { override; } ! procedure SetBracketLow; { override;} ! procedure SetBracketHigh; { override; } property IndexFile: TIndexFile read FIndexFile; --- 42,52 ---- function GetBookMark: rBookmarkData; override; ! procedure Insert(RecNo: Integer; Buffer: PChar); ! procedure Update(RecNo: Integer; PrevBuffer, NewBuffer: PChar); {$ifdef SUPPORT_VARIANTS} ! procedure VariantToBuffer(Key: Variant; ABuffer: PChar); {$endif} ! function CheckUserKey(Key: PChar; StringBuf: PChar): PChar; property IndexFile: TIndexFile read FIndexFile; *************** *** 146,164 **** end; - procedure TIndexCursor.SetBracketLow; - begin - TIndexFile(PagedFile).SetBracketLow; - end; - - procedure TIndexCursor.SetBracketHigh; - begin - TIndexFile(PagedFile).SetBracketHigh; - end; - - procedure TIndexCursor.CancelRange; - begin - TIndexFile(PagedFile).CancelRange; - end; - {$ifdef SUPPORT_VARIANTS} --- 142,145 ---- *************** *** 212,250 **** end; - function TIndexCursor.SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; - var - findres, currRecNo: Integer; - begin - // save current position - currRecNo := TIndexFile(PagedFile).SequentialRecNo; - // search, these are always from the root: no need for first - findres := TIndexFile(PagedFile).Find(-2, Key); - // test result - case SearchType of - stEqual: - Result := findres = 0; - stGreaterEqual: - Result := findres <= 0; - stGreater: - begin - if findres = 0 then - begin - // find next record that is greater - // NOTE: MatchKey assumes key to search for is already specified - // in FUserKey, it is because we have called Find - repeat - Result := TIndexFile(PagedFile).Next; - until not Result or (TIndexFile(PagedFile).MatchKey(Key) <> 0); - end else - Result := findres < 0; - end; - else - Result := false; - end; - // search failed -> restore previous position - if not Result then - TIndexFile(PagedFile).SequentialRecNo := currRecNo; - end; - end. --- 193,196 ---- Index: Dbf_Cursor.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/Dbf_Cursor.pas,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Dbf_Cursor.pas 21 Jun 2004 16:22:33 -0000 1.6 --- Dbf_Cursor.pas 18 Aug 2004 19:16:22 -0000 1.7 *************** *** 1,70 **** ! unit Dbf_Cursor; ! ! interface ! ! {$I Dbf_Common.inc} ! ! uses ! SysUtils, ! Classes, ! Dbf_PgFile, ! Dbf_Common; ! ! type ! ! //==================================================================== ! TVirtualCursor = class(TObject) ! private ! FFile: TPagedFile; ! ! protected ! function GetPhysicalRecno: Integer; virtual; abstract; ! function GetSequentialRecno: Integer; virtual; abstract; ! function GetSequentialRecordCount: Integer; virtual; abstract; ! procedure SetPhysicalRecno(Recno: Integer); virtual; abstract; ! procedure SetSequentialRecno(Recno: Integer); virtual; abstract; ! ! public ! constructor Create(pFile: TPagedFile); ! destructor Destroy; override; ! ! function RecordSize: Integer; ! ! function Next: Boolean; virtual; abstract; ! function Prev: Boolean; virtual; abstract; ! procedure First; virtual; abstract; ! procedure Last; virtual; abstract; ! ! function GetBookMark: rBookmarkData; virtual; abstract; ! procedure GotoBookmark(Bookmark: rBookmarkData); virtual; abstract; ! ! procedure Insert(Recno: Integer; Buffer: PChar); virtual; abstract; ! procedure Update(Recno: Integer; PrevBuffer,NewBuffer: PChar); virtual; abstract; ! ! property PagedFile: TPagedFile read FFile; ! property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; ! property SequentialRecNo: Integer read GetSequentialRecNo write SetSequentialRecNo; ! property SequentialRecordCount: Integer read GetSequentialRecordCount; ! end; ! ! implementation ! ! constructor TVirtualCursor.Create(pFile: TPagedFile); ! begin ! FFile := pFile; ! end; ! ! destructor TVirtualCursor.Destroy; {override;} ! begin ! end; ! ! function TVirtualCursor.RecordSize : Integer; ! begin ! if FFile = nil then ! Result := 0 ! else ! Result := FFile.RecordSize; ! end; ! ! end. ! --- 1,67 ---- ! unit Dbf_Cursor; ! ! interface ! ! {$I Dbf_Common.inc} ! ! uses ! SysUtils, ! Classes, ! Dbf_PgFile, ! Dbf_Common; ! ! type ! ! //==================================================================== ! TVirtualCursor = class(TObject) ! private ! FFile: TPagedFile; ! ! protected ! function GetPhysicalRecno: Integer; virtual; abstract; ! function GetSequentialRecno: Integer; virtual; abstract; ! function GetSequentialRecordCount: Integer; virtual; abstract; ! procedure SetPhysicalRecno(Recno: Integer); virtual; abstract; ! procedure SetSequentialRecno(Recno: Integer); virtual; abstract; ! ! public ! constructor Create(pFile: TPagedFile); ! destructor Destroy; override; ! ! function RecordSize: Integer; ! ! function Next: Boolean; virtual; abstract; ! function Prev: Boolean; virtual; abstract; ! procedure First; virtual; abstract; ! procedure Last; virtual; abstract; ! ! function GetBookMark: rBookmarkData; virtual; abstract; ! procedure GotoBookmark(Bookmark: rBookmarkData); virtual; abstract; ! ! property PagedFile: TPagedFile read FFile; ! property PhysicalRecNo: Integer read GetPhysicalRecNo write SetPhysicalRecNo; ! property SequentialRecNo: Integer read GetSequentialRecNo write SetSequentialRecNo; ! property SequentialRecordCount: Integer read GetSequentialRecordCount; ! end; ! ! implementation ! ! constructor TVirtualCursor.Create(pFile: TPagedFile); ! begin ! FFile := pFile; ! end; ! ! destructor TVirtualCursor.Destroy; {override;} ! begin ! end; ! ! function TVirtualCursor.RecordSize : Integer; ! begin ! if FFile = nil then ! Result := 0 ! else ! Result := FFile.RecordSize; ! end; ! ! end. ! Index: Dbf_IdxFile.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/Dbf_IdxFile.pas,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** Dbf_IdxFile.pas 18 Aug 2004 13:49:59 -0000 1.63 --- Dbf_IdxFile.pas 18 Aug 2004 19:16:24 -0000 1.64 *************** *** 241,244 **** --- 241,246 ---- FHeaderLocked: Integer; // used to remember which header page we have locked FKeyBuffer: array[0..100] of Char; + FLowBuffer: array[0..100] of Char; + FHighBuffer: array[0..100] of Char; FEntryBof: Pointer; FEntryEof: Pointer; *************** *** 246,249 **** --- 248,252 ---- FCanEdit: Boolean; FOpened: Boolean; + FRangeActive: Boolean; FUpdateMode: TIndexUpdateMode; FUserKey: PChar; // find / insert key *************** *** 279,282 **** --- 282,289 ---- procedure ResyncRoot; procedure ResyncTree; + procedure ResyncRange; + procedure ResetRange; + procedure SetBracketLow; + procedure SetBracketHigh; procedure TranslateToANSI(Src, Dest: PChar); *************** *** 331,334 **** --- 338,342 ---- procedure CreateIndex(FieldDesc, TagName: string; Options: TIndexOptions); function ExtractKeyFromBuffer(Buffer: PChar): PChar; + function SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; function Find(RecNo: Integer; Buffer: PChar): Integer; function IndexOf(const AIndexName: string): Integer; *************** *** 347,352 **** function GotoBookmark(IndexBookmark: rBookmarkData): Boolean; ! procedure SetBracketLow; ! procedure SetBracketHigh; procedure CancelRange; function MatchKey(UserKey: PChar): Integer; --- 355,359 ---- function GotoBookmark(IndexBookmark: rBookmarkData): Boolean; ! procedure SetRange(LowRange, HighRange: PChar); procedure CancelRange; function MatchKey(UserKey: PChar): Integer; *************** *** 1705,1708 **** --- 1712,1716 ---- // clear variables FOpened := false; + FRangeActive := false; FUpdateMode := umCurrent; FModifyMode := mmNormal; *************** *** 3140,3143 **** --- 3148,3186 ---- end; + function TIndexFile.SearchKey(Key: PChar; SearchType: TSearchKeyType): Boolean; + var + findres, currRecNo: Integer; + begin + // save current position + currRecNo := SequentialRecNo; + // search, these are always from the root: no need for first + findres := Find(-2, Key); + // test result + case SearchType of + stEqual: + Result := findres = 0; + stGreaterEqual: + Result := findres <= 0; + stGreater: + begin + if findres = 0 then + begin + // find next record that is greater + // NOTE: MatchKey assumes key to search for is already specified + // in FUserKey, it is because we have called Find + repeat + Result := Next; + until not Result or (MatchKey(Key) <> 0); + end else + Result := findres < 0; + end; + else + Result := false; + end; + // search failed -> restore previous position + if not Result then + SequentialRecNo := currRecNo; + end; + function TIndexFile.Find(RecNo: Integer; Buffer: PChar): Integer; begin *************** *** 3260,3263 **** --- 3303,3314 ---- end; + procedure TIndexFile.SetRange(LowRange, HighRange: PChar); + begin + Move(LowRange^, FLowBuffer[0], KeyLen); + Move(HighRange^, FHighBuffer[0], KeyLen); + FRangeActive := true; + ResyncRange; + end; + procedure TIndexFile.RecordDeleted(RecNo: Integer; Buffer: PChar); begin *************** *** 3368,3371 **** --- 3419,3461 ---- end; + procedure TIndexFile.ResyncRange; + var + Result: Boolean; + begin + if not FRangeActive then + exit; + + // disable current range if any + CancelRange; + // search lower bound + Result := SearchKey(FLowBuffer, stGreaterEqual); + if not Result then + begin + // not found? -> make empty range + Last; + end; + // set lower bound + SetBracketLow; + // search upper bound + SearchKey(FHighBuffer, stGreater); + // if result true, then need to get previous item <=> + // last of equal/lower than key + if Result then + begin + Result := Prev; + if not Result then + begin + // cannot go prev -> empty range + First; + end; + end else begin + // not found -> EOF found, go EOF, then to last record + Last; + Prev; + end; + // set upper bound + SetBracketHigh; + end; + procedure TIndexFile.ResyncTree; begin *************** *** 3393,3396 **** --- 3483,3487 ---- end; end; + ResyncRange; end; *************** *** 3530,3533 **** --- 3621,3630 ---- procedure TIndexFile.CancelRange; + begin + FRangeActive := false; + ResetRange; + end; + + procedure TIndexFile.ResetRange; var TempPage: TIndexPage; |