2
0
Эх сурвалжийг харах

Merged revisions 11134,11136,11139-11141,11146-11147,11152-11154,11157,11159,11163-11164,11166-11167,11170,11173,11176,11178,11181-11182,11184-11185,11187-11189,11195-11196,11206-11209,11214-11215,11223,11225,11227,11232,11235,11239-11240,11249-11256,11258,11260,11263-11265,11269-11271,11274,11276 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r11134 | joost | 2008-05-31 00:23:52 +0200 (Sat, 31 May 2008) | 1 line

* Force 4-byte alignment of fields in record-buffers hwn necessary
........
r11163 | joost | 2008-06-02 00:05:15 +0200 (Mon, 02 Jun 2008) | 1 line

* Patch from Paul Ishenin to implement TField.AsBCD
........
r11164 | joost | 2008-06-02 00:26:57 +0200 (Mon, 02 Jun 2008) | 1 line

* Use Align function to align fields in record-buffer
........
r11176 | joost | 2008-06-02 22:31:09 +0200 (Mon, 02 Jun 2008) | 1 line

* Check the alignment in GetFieldSize instead of CalcRecordSize
........
r11263 | joost | 2008-06-22 23:59:12 +0200 (Sun, 22 Jun 2008) | 5 lines

* Added support for ftDateTime fields
* Call CreateTable on open when this is not done yet (bug 10958)
* Check if the dataset is inactive on CreateTable
* Opening a closed dataset is possible again
* Implemented BookmarkValid + test (bug 8511)
........
r11269 | joost | 2008-06-23 23:39:54 +0200 (Mon, 23 Jun 2008) | 1 line

* Fixed overflow for large records (bug10003)
........
r11270 | joost | 2008-06-24 00:15:21 +0200 (Tue, 24 Jun 2008) | 1 line

* Only align data when needed
........
r11274 | joost | 2008-06-24 23:36:48 +0200 (Tue, 24 Jun 2008) | 1 line

* Do not add a terminating zero, since the terminating zeros are not stored in the buffer at all
........
r11276 | joost | 2008-06-25 00:06:13 +0200 (Wed, 25 Jun 2008) | 2 lines

* Align field-data when needed (bug 10957)
* Fix for bookmark property
........

git-svn-id: branches/rc_2_2_2@11286 -

joost 17 жил өмнө
parent
commit
aa9d9ef13b

+ 6 - 1
packages/fcl-db/src/base/bufdataset.pas

@@ -1196,7 +1196,9 @@ begin
       ftWideMemo : result := sizeof(TBufBlobField)
   else Result := 10
   end;
-
+{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT}
+  result:=Align(result,4);
+{$ENDIF}
 end;
 
 function TBufDataset.LoadBuffer(Buffer : PChar): TGetResult;
@@ -1807,6 +1809,9 @@ var x : longint;
 
 begin
   FNullmaskSize := 1+((FieldDefs.count-1) div 8);
+{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT}
+  FNullmaskSize:=Align(FNullmaskSize,4);
+{$ENDIF}
   FRecordSize := FNullmaskSize;
   SetLength(FFieldBufPositions,FieldDefs.count);
   for x := 0 to FieldDefs.count-1 do

+ 5 - 2
packages/fcl-db/src/base/db.pas

@@ -22,7 +22,7 @@ unit db;
 
 interface
 
-uses Classes,Sysutils,Variants;
+uses Classes,Sysutils,Variants,FmtBCD;
 
 const
 
@@ -319,6 +319,7 @@ type
     procedure Change; virtual;
     procedure DataChanged;
     procedure FreeBuffers; virtual;
+    function GetAsBCD: TBCD; virtual;
     function GetAsBoolean: Boolean; virtual;
     function GetAsCurrency: Currency; virtual;
     function GetAsLargeInt: LargeInt; virtual;
@@ -344,6 +345,7 @@ type
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
     procedure PropertyChanged(LayoutAffected: Boolean);
     procedure ReadState(Reader: TReader); override;
+    procedure SetAsBCD(const AValue: TBCD); virtual;
     procedure SetAsBoolean(AValue: Boolean); virtual;
     procedure SetAsCurrency(AValue: Currency); virtual;
     procedure SetAsDateTime(AValue: TDateTime); virtual;
@@ -377,6 +379,7 @@ type
     procedure SetData(Buffer: Pointer; NativeFormat : Boolean); overload;
     procedure SetFieldType(AValue: TFieldType); virtual;
     procedure Validate(Buffer: Pointer);
+    property AsBCD: TBCD read GetAsBCD write SetAsBCD;
     property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean;
     property AsCurrency: Currency read GetAsCurrency write SetAsCurrency;
     property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;
@@ -1937,7 +1940,7 @@ function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : boole
 
 implementation
 
-uses dbconst,typinfo, fmtbcd;
+uses dbconst,typinfo;
 
 { ---------------------------------------------------------------------
     Auxiliary functions

+ 35 - 6
packages/fcl-db/src/memds/memds.pp

@@ -45,6 +45,8 @@ type
     BookmarkFlag: TBookmarkFlag;
   end;
 
+  { TMemDataset }
+
   TMemDataset=class(TDataSet)
   private
     FOpenStream : TStream;
@@ -57,6 +59,7 @@ type
     FRecBufferSize: integer;
     FCurrRecNo: integer;
     FIsOpen: boolean;
+    FTableIsCreated: boolean;
     FFilterBuffer: PChar;
     ffieldoffsets: PInteger;
     ffieldsizes: PInteger;
@@ -115,6 +118,7 @@ type
   public
     constructor Create(AOwner:tComponent); override;
     destructor Destroy; override;
+    function BookmarkValid(ABookmark: TBookmark): Boolean; override;
     procedure CreateTable;
 
     Function  DataSize : Integer;
@@ -251,15 +255,28 @@ begin
   FRecBufferSize:=0;
   FRecInfoOffset:=0;
   FCurrRecNo:=-1;
+  BookmarkSize := sizeof(TMTRecInfo);
   FIsOpen:=False;
 end;
 
 Destructor TMemDataset.Destroy;
 begin
   FStream.Free;
+  FreeMem(FFieldOffsets);
+  FreeMem(FFieldSizes);
   inherited Destroy;
 end;
 
+function TMemDataset.BookmarkValid(ABookmark: TBookmark): Boolean;
+var
+  ReqBookmark: integer;
+begin
+  Result := False;
+  if ABookMark=nil then exit;
+  ReqBookmark:=PInteger(ABookmark)^;
+  Result := (ReqBookmark>=0) and (ReqBookmark<FRecCount);
+end;
+
 function TMemDataset.MDSGetRecordOffset(ARecNo: integer): longint;
 begin
   Result:=FRecSize*ARecNo
@@ -287,12 +304,16 @@ begin
   ftFloat:    result:=SizeOf(Double);
   ftLargeInt: result:=SizeOf(int64);
   ftSmallInt: result:=SizeOf(SmallInt);
-  ftInteger:  result:=SizeOf(Integer);
-  ftDate:     result:=SizeOf(TDateTime);
-  ftTime:     result:=SizeOf(TDateTime);
+  ftInteger:  result:=SizeOf(longint);
+  ftDateTime,
+    ftTime,
+    ftDate:   result:=SizeOf(TDateTime);
  else
   RaiseError(SErrFieldTypeNotSupported,[FieldDefs.Items[FieldNo-1].Name]);
  end;
+{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT}
+ Result:=Align(Result,4);
+{$ENDIF}
 end;
 
 function TMemDataset.MDSGetActiveBuffer(var Buffer: PChar): Boolean;
@@ -456,6 +477,7 @@ procedure TMemDataset.InternalOpen;
 
 
 begin
+  if not FTableIsCreated then CreateTable;
   If (FFileName<>'') then
     FOpenStream:=TFileStream.Create(FFileName,fmOpenRead);
   Try
@@ -610,8 +632,6 @@ begin
  if DefaultFields then begin
   DestroyFields;
  end;
- FreeMem(FFieldOffsets);
- FreeMem(FFieldSizes);
 end;
 
 procedure TMemDataset.InternalPost;
@@ -819,10 +839,17 @@ var
   i,count : integer;
 begin
  Count := fielddefs.count;
+ // Avoid mem-leak if CreateTable is called twice
+ FreeMem(ffieldoffsets);
+ Freemem(ffieldsizes);
+
  FFieldOffsets:=getmem(Count*sizeof(integer));
  FFieldSizes:=getmem(Count*sizeof(integer));
  FRecSize:= (Count+7) div 8; //null mask
- for i:= 0 to Count-1 do 
+{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT}
+ FRecSize:=Align(FRecSize,4);
+{$ENDIF}
+ for i:= 0 to Count-1 do
    begin
    ffieldoffsets[i] := frecsize;
    ffieldsizes[i] := MDSGetbufferSize(i+1);
@@ -833,6 +860,7 @@ end;
 procedure TMemDataset.CreateTable;
 
 begin
+  CheckInactive;
   FStream.Clear;
   FRecCount:=0;
   FCurrRecNo:=-1;
@@ -841,6 +869,7 @@ begin
   FRecInfoOffset:=FRecSize;
   FRecSize:=FRecSize+SizeRecInfo;
   FRecBufferSize:=FRecSize;
+  FTableIsCreated:=True;
 end;
 
 procedure TMemDataset.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean);

+ 2 - 3
packages/fcl-db/src/sdf/sdfdata.pp

@@ -162,8 +162,8 @@ type
     FRecBufSize         :Integer;
     FRecordSize         :Integer;
     FLastBookmark       :PtrInt;
-    FRecInfoOfs         :Word;
-    FBookmarkOfs        :Word;
+    FRecInfoOfs         :Integer;
+    FBookmarkOfs        :Integer;
     FSaveChanges        :Boolean;
   protected
     function AllocRecordBuffer: PChar; override;
@@ -675,7 +675,6 @@ begin
       if p > Field.Size then
         p := Field.Size;
       Move(Buffer^, RecBuf[0], p);
-      ActiveBuffer[RecordSize-1] := #0;
     end;
   end
   else // fkCalculated, fkLookup

+ 38 - 1
packages/fcl-db/tests/testdbbasics.pas

@@ -30,7 +30,8 @@ type
     procedure TestCancelUpdDelete1;
     procedure TestCancelUpdDelete2;
     procedure TestBookmarks;
-    
+    procedure TestBookmarkValid;
+
     procedure TestLocate;
 
     procedure TestFirst;
@@ -566,6 +567,42 @@ begin
     end;
 end;
 
+procedure TTestDBBasics.TestBookmarkValid;
+var BM1,BM2,BM3,BM4,BM5 : TBookmark;
+begin
+  with DBConnector.GetNDataset(true,14) do
+    begin
+    BM1 := Nil;
+    AssertFalse(BookmarkValid(BM1));
+    open;
+    BM1:=GetBookmark; // id=1, BOF
+    AssertTrue(BookmarkValid(BM1));
+    next;next;
+    BM2:=GetBookmark; // id=3
+    AssertTrue(BookmarkValid(BM2));
+    next;next;next;
+    BM3:=GetBookmark; // id=6
+    AssertTrue(BookmarkValid(BM3));
+    next;next;next;next;next;next;next;next;
+    BM4:=GetBookmark; // id=14
+    AssertTrue(BookmarkValid(BM4));
+    next;
+    BM5:=GetBookmark; // id=14, EOF
+    AssertTrue(BookmarkValid(BM5));
+
+    AssertTrue(BookmarkValid(BM4));
+    AssertTrue(BookmarkValid(BM3));
+    AssertTrue(BookmarkValid(BM2));
+    AssertTrue(BookmarkValid(BM1));
+    GotoBookmark(BM2);
+    AssertTrue(BookmarkValid(BM5));
+    AssertTrue(BookmarkValid(BM4));
+    AssertTrue(BookmarkValid(BM3));
+    AssertTrue(BookmarkValid(BM2));
+    AssertTrue(BookmarkValid(BM1));
+    end;
+end;
+
 procedure TTestDBBasics.TestLocate;
 begin
   with DBConnector.GetNDataset(true,13) do