Browse Source

* 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)

git-svn-id: trunk@11263 -

joost 17 years ago
parent
commit
545c6b0d64
2 changed files with 65 additions and 6 deletions
  1. 27 5
      packages/fcl-db/src/memds/memds.pp
  2. 38 1
      packages/fcl-db/tests/testdbbasics.pas

+ 27 - 5
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;
@@ -257,9 +261,21 @@ 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,9 +303,10 @@ 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;
@@ -456,6 +473,7 @@ procedure TMemDataset.InternalOpen;
 
 
 begin
+  if not FTableIsCreated then CreateTable;
   If (FFileName<>'') then
     FOpenStream:=TFileStream.Create(FFileName,fmOpenRead);
   Try
@@ -610,8 +628,6 @@ begin
  if DefaultFields then begin
   DestroyFields;
  end;
- FreeMem(FFieldOffsets);
- FreeMem(FFieldSizes);
 end;
 
 procedure TMemDataset.InternalPost;
@@ -819,6 +835,10 @@ 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
@@ -833,6 +853,7 @@ end;
 procedure TMemDataset.CreateTable;
 
 begin
+  CheckInactive;
   FStream.Clear;
   FRecCount:=0;
   FCurrRecNo:=-1;
@@ -841,6 +862,7 @@ begin
   FRecInfoOffset:=FRecSize;
   FRecSize:=FRecSize+SizeRecInfo;
   FRecBufferSize:=FRecSize;
+  FTableIsCreated:=True;
 end;
 
 procedure TMemDataset.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean);

+ 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