|
From: Micha N. <md...@us...> - 2004-08-23 18:03:25
|
Update of /cvsroot/tdbf/tdbf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11674 Modified Files: dbf.pas dbf_common.pas dbf_cursor.pas dbf_dbffile.pas dbf_idxcur.pas dbf_idxfile.pas history.txt Log Message: - fixed: getting recno in oncalcfields event (rep by lutz) - fixed: AV when checking empty binary fields Index: history.txt =================================================================== RCS file: /cvsroot/tdbf/tdbf/history.txt,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** history.txt 20 Aug 2004 19:20:15 -0000 1.65 --- history.txt 23 Aug 2004 18:03:11 -0000 1.66 *************** *** 54,57 **** --- 54,59 ---- - fixed: datetime issues with fieldtype '@' and delphi 4 and lower (nobody uses those fieldtypes? they have been horribly broken, and maybe still are) + - fixed: getting recno in oncalcfields event (rep by lutz) + - fixed: AV when checking empty binary fields Index: dbf_dbffile.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/dbf_dbffile.pas,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dbf_dbffile.pas 23 Aug 2004 08:12:32 -0000 1.3 --- dbf_dbffile.pas 23 Aug 2004 18:03:11 -0000 1.4 *************** *** 150,156 **** function GetSequentialRecNo: Integer; override; procedure SetSequentialRecNo(RecNo: Integer); override; - - procedure GotoBookmark(Bookmark: rBookmarkData); override; - function GetBookMark: rBookmarkData; override; end; --- 150,153 ---- *************** *** 1364,1368 **** begin Result := PDWord(Src)^ <> 0; ! if Result then begin PInteger(Dst)^ := SwapInt(PInteger(Src)^); --- 1361,1365 ---- begin Result := PDWord(Src)^ <> 0; ! if Result and (Dst <> nil) then begin PInteger(Dst)^ := SwapInt(PInteger(Src)^); *************** *** 1372,1376 **** end else begin Result := true; ! PInteger(Dst)^ := PInteger(Src)^; end; end; --- 1369,1374 ---- end else begin Result := true; ! if Dst <> nil then ! PInteger(Dst)^ := PInteger(Src)^; end; end; *************** *** 1379,1383 **** {$ifdef SUPPORT_INT64} Result := (PInt64(Src)^ <> 0); ! if Result then begin SwapInt64(Src, Dst); --- 1377,1381 ---- {$ifdef SUPPORT_INT64} Result := (PInt64(Src)^ <> 0); ! if Result and (Dst <> nil) then begin SwapInt64(Src, Dst); *************** *** 1392,1396 **** begin Result := (PInteger(Src)^ <> 0) and (PInteger(PChar(Src)+4)^ <> 0); ! if Result then begin SwapInt64(Src, Dst); --- 1390,1394 ---- begin Result := (PInteger(Src)^ <> 0) and (PInteger(PChar(Src)+4)^ <> 0); ! if Result and (Dst <> nil) then begin SwapInt64(Src, Dst); *************** *** 1406,1410 **** // all binary zeroes -> empty datetime Result := (PInteger(Src)^ <> 0) or (PInteger(PChar(Src)+4)^ <> 0); ! if Result then begin timeStamp.Date := PInteger(Src)^ - 1721425; --- 1404,1408 ---- // all binary zeroes -> empty datetime Result := (PInteger(Src)^ <> 0) or (PInteger(PChar(Src)+4)^ <> 0); ! if Result and (Dst <> nil) then begin timeStamp.Date := PInteger(Src)^ - 1721425; *************** *** 1418,1430 **** {$ifdef SUPPORT_INT64} Result := true; ! SwapInt64(Src, Dst); ! case DataType of ! ftCurrency: ! begin ! PDouble(Dst)^ := PInt64(Src)^ / 10000.0; ! end; ! ftBCD: ! begin ! PCurrency(Dst)^ := PCurrency(Src)^; end; end; --- 1416,1431 ---- {$ifdef SUPPORT_INT64} Result := true; ! if Dst <> nil then ! begin ! SwapInt64(Src, Dst); ! case DataType of ! ftCurrency: ! begin ! PDouble(Dst)^ := PInt64(Src)^ / 10000.0; ! end; ! ftBCD: ! begin ! PCurrency(Dst)^ := PCurrency(Src)^; ! end; end; end; *************** *** 2399,2407 **** end; - procedure TDbfCursor.GotoBookmark(Bookmark: rBookmarkData); - begin - FPhysicalRecNo := Bookmark{.RecNo}; - end; - // codepage enumeration procedure var --- 2400,2403 ---- *************** *** 2419,2428 **** end; - function TDbfCursor.GetBookMark: rBookmarkData; {override;} - begin - // Result.IndexBookmark := -1; - Result{.RecNo} := FPhysicalRecNo; - end; - //==================================================================== // TDbfGlobals --- 2415,2418 ---- Index: dbf.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/dbf.pas,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** dbf.pas 23 Aug 2004 08:12:32 -0000 1.4 --- dbf.pas 23 Aug 2004 18:03:11 -0000 1.5 *************** *** 25,32 **** //==================================================================== ! pDbfRecord = ^rDbfRecordHeader; ! rDbfRecordHeader = record ! BookmarkData: rBookmarkData; BookmarkFlag: TBookmarkFlag; DeletedFlag: Char; end; --- 25,38 ---- //==================================================================== ! pBookmarkData = ^TBookmarkData; ! TBookmarkData = record ! PhysicalRecNo: Integer; ! end; ! ! pDbfRecord = ^TDbfRecordHeader; ! TDbfRecordHeader = record ! BookmarkData: TBookmarkData; BookmarkFlag: TBookmarkFlag; + SequentialRecNo: Integer; DeletedFlag: Char; end; *************** *** 593,597 **** DbfGlobals := TDbfGlobals.Create; ! BookmarkSize := sizeof(rBookmarkData); FIndexDefs := TDbfIndexDefs.Create(Self); FMasterLink := TDbfMasterLink.Create(Self); --- 599,603 ---- DbfGlobals := TDbfGlobals.Create; ! BookmarkSize := sizeof(TBookmarkData); FIndexDefs := TDbfIndexDefs.Create(Self); FMasterLink := TDbfMasterLink.Create(Self); *************** *** 639,643 **** function TDbf.AllocRecordBuffer: PChar; {override virtual abstract from TDataset} begin ! GetMem(Result, SizeOf(rDbfRecordHeader)+FDbfFile.RecordSize+CalcFieldsSize+1); end; --- 645,649 ---- function TDbf.AllocRecordBuffer: PChar; {override virtual abstract from TDataset} begin ! GetMem(Result, SizeOf(TDbfRecordHeader)+FDbfFile.RecordSize+CalcFieldsSize+1); end; *************** *** 648,664 **** procedure TDbf.GetBookmarkData(Buffer: PChar; Data: Pointer); {override virtual abstract from TDataset} - var - pRecord: pDbfRecord; begin ! pRecord := pDbfRecord(Buffer); ! pBookMarkData(Data)^ := pRecord.BookMarkData; end; function TDbf.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; {override virtual abstract from TDataset} - var - pRecord: pDbfRecord; begin ! pRecord := pDbfRecord(Buffer); ! Result := pRecord.BookMarkFlag; end; --- 654,664 ---- procedure TDbf.GetBookmarkData(Buffer: PChar; Data: Pointer); {override virtual abstract from TDataset} begin ! pBookmarkData(Data)^ := pDbfRecord(Buffer)^.BookmarkData; end; function TDbf.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; {override virtual abstract from TDataset} begin ! Result := pDbfRecord(Buffer)^.BookmarkFlag; end; *************** *** 775,784 **** Result := grOK; case GetMode of - gmCurrent : - begin - //if pRecord.BookmarkData.RecNo=FPhysicalRecNo then begin - // exit; // try to fasten a bit... - //end; - end; gmNext : begin --- 775,778 ---- *************** *** 830,844 **** if (Result = grOK) and not FFindRecordFilter then begin ! ClearCalcFields(Buffer); //run automatically ! try ! GetCalcFields(Buffer); ! finally ! pRecord.BookmarkData := FCursor.GetBookMark; ! pRecord.BookmarkFlag := bfCurrent; ! end; ! if (pRecord.BookMarkData <= 0) then ! pRecord.BookmarkData := FCursor.GetBookMark; end else begin ! pRecord.BookmarkData := -1; end; end; --- 824,833 ---- if (Result = grOK) and not FFindRecordFilter then begin ! pRecord.BookmarkData.PhysicalRecNo := FCursor.PhysicalRecNo; ! pRecord.BookmarkFlag := bfCurrent; ! pRecord.SequentialRecNo := FCursor.SequentialRecNo; ! GetCalcFields(Buffer); end else begin ! pRecord.BookmarkData.PhysicalRecNo := -1; end; end; *************** *** 955,963 **** procedure TDbf.InternalGotoBookmark(Bookmark: Pointer); {override virtual abstract from TDataset} - var - RecInfo: rBookmarkData; begin ! RecInfo := rBookmarkData(Bookmark^); ! FCursor.GotoBookmark(RecInfo); end; --- 944,960 ---- procedure TDbf.InternalGotoBookmark(Bookmark: Pointer); {override virtual abstract from TDataset} begin ! with PBookmarkData(Bookmark)^ do ! begin ! if (PhysicalRecNo = 0) then begin ! First; ! end else ! if (PhysicalRecNo = MaxInt) then begin ! Last; ! end else begin ! if FCursor.PhysicalRecNo <> PhysicalRecNo then ! FCursor.PhysicalRecNo := PhysicalRecNo; ! end; ! end; end; *************** *** 1069,1074 **** begin pRecord := pDbfRecord(Buffer); ! pRecord.BookmarkData{.IndexBookmark} := 0; pRecord.BookmarkFlag := bfCurrent; // Init Record with zero and set autoinc field with next value FDbfFile.InitRecord(@pRecord.DeletedFlag); --- 1066,1072 ---- begin pRecord := pDbfRecord(Buffer); ! pRecord.BookmarkData.PhysicalRecNo := 0; pRecord.BookmarkFlag := bfCurrent; + pRecord.SequentialRecNo := 0; // Init Record with zero and set autoinc field with next value FDbfFile.InitRecord(@pRecord.DeletedFlag); *************** *** 1916,1924 **** begin pRecord := pDbfRecord(Buffer); ! if pRecord.BookMarkFlag = bfInserted then begin // do what ??? end else begin ! FCursor.GotoBookmark(pRecord.BookmarkData); end; end; --- 1914,1922 ---- begin pRecord := pDbfRecord(Buffer); ! if pRecord.BookmarkFlag = bfInserted then begin // do what ??? end else begin ! FCursor.SequentialRecNo := pRecord.SequentialRecNo; end; end; *************** *** 1936,1952 **** procedure TDbf.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); {override virtual abstract from TDataset} - var - pRecord: pDbfRecord; begin ! pRecord := pDbfRecord(Buffer); ! pRecord.BookMarkFlag := Value; end; procedure TDbf.SetBookmarkData(Buffer: PChar; Data: Pointer); {override virtual abstract from TDataset} - var - pRecord: pDbfRecord; begin ! pRecord := pDbfRecord(Buffer); ! pRecord.BookMarkData := pBookMarkData(Data)^; end; --- 1934,1944 ---- procedure TDbf.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); {override virtual abstract from TDataset} begin ! pDbfRecord(Buffer)^.BookmarkFlag := Value; end; procedure TDbf.SetBookmarkData(Buffer: PChar; Data: Pointer); {override virtual abstract from TDataset} begin ! pDbfRecord(Buffer)^.BookmarkData := pBookmarkData(Data)^; end; *************** *** 2028,2040 **** // it doesn't have to be perfectly accurate, but fast. function TDbf.GetRecNo: Integer; {override virtual} begin ! UpdateCursorPos; ! Result := FCursor.SequentialRecNo; end; ! procedure TDbf.SetRecNo(Value: Integer); {override virual} begin FCursor.SequentialRecNo := Value; Resync([]); end; --- 2020,2043 ---- // it doesn't have to be perfectly accurate, but fast. function TDbf.GetRecNo: Integer; {override virtual} + var + pBuffer: pointer; begin ! if State = dsCalcFields then ! pBuffer := CalcBuffer ! else ! pBuffer := ActiveBuffer; ! Result := pDbfRecord(pBuffer)^.SequentialRecNo; end; ! procedure TDbf.SetRecNo(Value: Integer); {override virtual} begin + CheckBrowseMode; + if Value = RecNo then + exit; + + DoBeforeScroll; FCursor.SequentialRecNo := Value; Resync([]); + DoAfterScroll; end; *************** *** 2397,2406 **** function TDbf.GetPhysicalRecNo: Integer; begin // check if active, test state: if inserting, then -1 if (FCursor <> nil) and (State <> dsInsert) then begin ! UpdateCursorPos; ! Result := FCursor.PhysicalRecNo; end else Result := -1; --- 2400,2414 ---- function TDbf.GetPhysicalRecNo: Integer; + var + pBuffer: pointer; begin // check if active, test state: if inserting, then -1 if (FCursor <> nil) and (State <> dsInsert) then begin ! if State = dsCalcFields then ! pBuffer := CalcBuffer ! else ! pBuffer := ActiveBuffer; ! Result := pDbfRecord(pBuffer)^.BookmarkData.PhysicalRecNo; end else Result := -1; *************** *** 2409,2422 **** procedure TDbf.SetPhysicalRecNo(const NewRecNo: Integer); begin ! // active? ! if FCursor <> nil then ! begin ! // editing? ! CheckBrowseMode; ! // set recno ! FCursor.PhysicalRecNo := NewRecNo; ! // refresh data controls ! Resync([]); ! end; end; --- 2417,2426 ---- procedure TDbf.SetPhysicalRecNo(const NewRecNo: Integer); begin ! // editing? ! CheckBrowseMode; ! DoBeforeScroll; ! FCursor.PhysicalRecNo := NewRecNo; ! Resync([]); ! DoAfterScroll; end; Index: dbf_idxcur.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/dbf_idxcur.pas,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** dbf_idxcur.pas 23 Aug 2004 08:12:32 -0000 1.2 --- dbf_idxcur.pas 23 Aug 2004 18:03:11 -0000 1.3 *************** *** 37,43 **** procedure Last; override; - procedure GotoBookmark(Bookmark: rBookmarkData); override; - function GetBookMark: rBookmarkData; override; - procedure Insert(RecNo: Integer; Buffer: PChar); procedure Update(RecNo: Integer; PrevBuffer, NewBuffer: PChar); --- 37,40 ---- *************** *** 130,143 **** end; - procedure TIndexCursor.GotoBookmark(Bookmark: rBookmarkData); - begin - TIndexFile(PagedFile).GotoBookMark(Bookmark); - end; - - function TIndexCursor.GetBookMark: rBookmarkData; - begin - Result := TIndexFile(PagedFile).GetBookmark; - end; - {$ifdef SUPPORT_VARIANTS} --- 127,130 ---- Index: dbf_common.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/dbf_common.pas,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** dbf_common.pas 23 Aug 2004 08:12:32 -0000 1.3 --- dbf_common.pas 23 Aug 2004 18:03:11 -0000 1.4 *************** *** 28,33 **** TDbfFieldType = char; - PBookMarkData = ^rBookMarkData; - rBookmarkData = Integer; TXBaseVersion = (xUnknown, xClipper, xBaseIII, xBaseIV, xBaseV, xFoxPro, xBaseVII); --- 28,31 ---- Index: dbf_cursor.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/dbf_cursor.pas,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** dbf_cursor.pas 23 Aug 2004 08:12:32 -0000 1.2 --- dbf_cursor.pas 23 Aug 2004 18:03:11 -0000 1.3 *************** *** 36,42 **** 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; --- 36,39 ---- Index: dbf_idxfile.pas =================================================================== RCS file: /cvsroot/tdbf/tdbf/dbf_idxfile.pas,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** dbf_idxfile.pas 23 Aug 2004 08:12:32 -0000 1.2 --- dbf_idxfile.pas 23 Aug 2004 18:03:11 -0000 1.3 *************** *** 157,161 **** procedure UpdateWeight; procedure Flush; - procedure DisableRange; property Key: PChar read GetKeyData; --- 157,160 ---- *************** *** 273,277 **** function CalcTagOffset(AIndex: Integer): Pointer; ! function FindKey(const Insert: Boolean): Integer; procedure InsertKey(Buffer: PChar); procedure DeleteKey(Buffer: PChar); --- 272,276 ---- function CalcTagOffset(AIndex: Integer): Pointer; ! function FindKey(Insert: boolean): Integer; procedure InsertKey(Buffer: PChar); procedure DeleteKey(Buffer: PChar); *************** *** 280,283 **** --- 279,283 ---- procedure UpdateCurrent(PrevBuffer, NewBuffer: PChar); procedure ReadIndexes; + procedure Resync(Relative: boolean); procedure ResyncRoot; procedure ResyncTree; *************** *** 352,358 **** function Prev: Boolean; - function GetBookMark: rBookmarkData; - function GotoBookmark(IndexBookmark: rBookmarkData): Boolean; - procedure SetRange(LowRange, HighRange: PChar); procedure CancelRange; --- 352,355 ---- *************** *** 1230,1242 **** end; - procedure TIndexPage.DisableRange; - begin - // update low / high index range - FLowIndex := 0; - FHighIndex := GetNumEntries; - if FLowerPage = nil then - dec(FHighIndex); - end; - function TMdxPage.GetIsInnerNode: Boolean; begin --- 1227,1230 ---- *************** *** 2923,2927 **** // assumes: FUserKey is an OEM key var - TempPage: TIndexPage; SearchKey: array[0..100] of Char; OemKey: PChar; --- 2911,2914 ---- *************** *** 2938,2941 **** --- 2925,2930 ---- TranslateToANSI(OemKey, FUserKey); end; + // temporarily remove range to find correct location of key + ResetRange; // find this record as closely as possible // if result = 0 then key already exists *************** *** 2960,2968 **** // check range, disabled by insert ! TempPage := FRoot; ! repeat ! TempPage.UpdateBounds(TempPage.LowerPage <> nil); ! TempPage := TempPage.LowerPage; ! until TempPage = nil; end; end; --- 2949,2953 ---- // check range, disabled by insert ! ResyncRange; end; end; *************** *** 3035,3038 **** --- 3020,3025 ---- // delete selected entry FLeaf.Delete; + // range may be changed + ResyncRange; end; end; *************** *** 3191,3195 **** end; ! function TIndexFile.FindKey(const Insert: Boolean): Integer; // // if you set Insert = true, you need to re-enable range after insert!! --- 3178,3182 ---- end; ! function TIndexFile.FindKey(Insert: boolean): Integer; // // if you set Insert = true, you need to re-enable range after insert!! *************** *** 3215,3228 **** searchRecNo := -2; end; - // disable range to prepare for insert - if Insert then - begin - // start from root - TempPage := FRoot; - repeat - TempPage.DisableRange; - TempPage := TempPage.LowerPage; - until TempPage = nil; - end; // start from root TempPage := FRoot; --- 3202,3205 ---- *************** *** 3327,3344 **** end; - function TIndexFile.GotoBookmark(IndexBookmark: rBookmarkData): Boolean; - begin - if (IndexBookmark{.RecNo} = 0) then begin - First; - end else if (IndexBookmark{.RecNo} = MAXINT) then begin - Last; - end else begin - if (FLeaf.GetRecNo <> IndexBookmark{.RecNo}) then - PhysicalRecNo := IndexBookmark{.RecNo}; - end; - - Result := true; - end; - procedure TIndexFile.SetLocaleID(const NewID: LCID); {$ifdef WIN32} --- 3304,3307 ---- *************** *** 3390,3404 **** end; - function TIndexFile.GetBookMark: rBookmarkData; - begin - // get physical recno - Result := FLeaf.GetRecNo; - end; - procedure TIndexFile.First; begin // resync tree ! if NeedLocks then ! ResyncRoot; // search first node FRoot.RecurFirst; --- 3353,3360 ---- end; procedure TIndexFile.First; begin // resync tree ! Resync(false); // search first node FRoot.RecurFirst; *************** *** 3410,3415 **** begin // resync tree ! if NeedLocks then ! ResyncRoot; // search last node FRoot.RecurLast; --- 3366,3370 ---- begin // resync tree ! Resync(false); // search last node FRoot.RecurLast; *************** *** 3427,3431 **** // disable current range if any ! CancelRange; // search lower bound Result := SearchKey(FLowBuffer, stGreaterEqual); --- 3382,3386 ---- // disable current range if any ! ResetRange; // search lower bound Result := SearchKey(FLowBuffer, stGreaterEqual); *************** *** 3458,3461 **** --- 3413,3428 ---- end; + procedure TIndexFile.Resync(Relative: boolean); + begin + if NeedLocks then + begin + if not Relative then + ResyncRoot; + ResyncRange; + if Relative then + ResyncTree; + end; + end; + procedure TIndexFile.ResyncTree; begin *************** *** 3483,3487 **** end; end; - ResyncRange; end; --- 3450,3453 ---- *************** *** 3491,3496 **** begin // resync in-mem tree with tree on disk ! if NeedLocks then ! ResyncTree; // save current recno, find different next! curRecNo := FLeaf.PhysicalRecNo; --- 3457,3461 ---- begin // resync in-mem tree with tree on disk ! Resync(true); // save current recno, find different next! curRecNo := FLeaf.PhysicalRecNo; *************** *** 3506,3511 **** begin // resync in-mem tree with tree on disk ! if NeedLocks then ! ResyncTree; // save current recno, find different prev! curRecNo := FLeaf.PhysicalRecNo; --- 3471,3475 ---- begin // resync in-mem tree with tree on disk ! Resync(true); // save current recno, find different prev! curRecNo := FLeaf.PhysicalRecNo; |