Browse Source

* fcl-db/tests: test memorybacked dbf equals filebased dbf. Use memory dbfs because of speed.

git-svn-id: trunk@24125 -
reiniero 12 years ago
parent
commit
d54af2322f
2 changed files with 74 additions and 14 deletions
  1. 13 13
      packages/fcl-db/tests/dbftoolsunit.pas
  2. 61 1
      packages/fcl-db/tests/testspecifictdbf.pas

+ 13 - 13
packages/fcl-db/tests/dbftoolsunit.pas

@@ -10,7 +10,7 @@ Because of this, we use file-backed dbfs instead of memory backed dbfs
 {$ENDIF}
 
 // If defined, do not delete the dbf files when done but print out location to stdout:
-{.$DEFINE KEEPDBFFILES}
+{$DEFINE KEEPDBFFILES}
 
 interface
 
@@ -48,6 +48,7 @@ type
   // DBF descendant that saves to a temp file and removes file when closed
   TDBFAutoClean = class(TDBF)
   private
+    FBackingStream: TMemoryStream;
     FCreatedBy: string;
   public
     // Keeps track of which function created the dataset, useful for troubleshooting
@@ -84,15 +85,13 @@ begin
 end;
 
 constructor TDBFAutoClean.Create;
-var
-  DBFFileName: string;
-  TableLevelProvided: integer;
 begin
-  DBFFileName := GetTempFileName;
-  FilePathFull := ExtractFilePath(DBFFileName);
-  TableName := ExtractFileName(DBFFileName);
-  TableLevelProvided := UserRequestedTableLevel;
-  TableLevel := TableLevelProvided;
+  FBackingStream:=TMemoryStream.Create;
+  // Create a unique name:
+  TableName := FormatDateTime('hhnnssz',Now())+'/'+inttostr(random(32767));
+  TableLevel := UserRequestedTableLevel;
+  Storage:=stoMemory;
+  UserStream:=FBackingStream;
   CreateTable; //write out header to disk
 end;
 
@@ -106,13 +105,14 @@ destructor TDBFAutoClean.Destroy;
 var
   FileName: string;
 begin
-  FileName := AbsolutePath + TableName;
-  inherited Destroy;
   {$IFDEF KEEPDBFFILES}
+  Close;
+  FileName := GetTempFileName;
+  FBackingStream.SaveToFile(FileName);
   writeln('TDBFAutoClean: file created by ',CreatedBy,' left file: ',FileName);
-  {$ELSE}
-  deletefile(FileName);
   {$ENDIF}
+  inherited Destroy;
+  FBackingStream.Free;
 end;
 
 

+ 61 - 1
packages/fcl-db/tests/testspecifictdbf.pas

@@ -1,7 +1,7 @@
 unit testspecifictdbf;
 
 {
-  Unit tests which are specific to the tdbf dbase units.
+  Unit tests which are specific to the tdbf dbase/foxpro units.
 }
 
 {$IFDEF FPC}
@@ -32,6 +32,8 @@ type
   published
     // Verifies that requested tablelevel is delivered:
     procedure TestTableLevel;
+    // Verifies that writing to memory and writing to disk results in the same data
+    procedure TestMemoryDBFEqualsDiskDBF;
     // Create fields using indexdefs:
     procedure TestCreateDatasetFromFielddefs;
     // Specifying fields from field objects
@@ -109,6 +111,64 @@ begin
   ds.free;
 end;
 
+procedure TTestSpecificTDBF.TestMemoryDBFEqualsDiskDBF;
+var
+  dsfile: TDBF;
+  dsmem: TDBF;
+  backingstream: TMemoryStream;
+  FileName: string;
+  i: integer;
+  thefile: TMemoryStream;
+begin
+  backingstream:=TMemoryStream.Create;
+  thefile:=TMemoryStream.Create;
+  dsmem:=TDBF.Create(nil);
+  dsfile:=TDBF.Create(nil);
+  FileName:=GetTempFileName;
+  dsfile.FilePathFull:=ExtractFilePath(FileName);
+  dsfile.TableName:=ExtractFileName(FileName);
+  dsmem.TableName:=ExtractFileName(FileName);
+  dsmem.Storage:=stoMemory;
+  dsmem.UserStream:=backingstream;
+
+  // A small number of fields but should be enough
+  dsfile.FieldDefs.Add('ID',ftInteger);
+  dsmem.FieldDefs.Add('ID',ftInteger);
+  dsfile.FieldDefs.Add('NAME',ftString,50);
+  dsmem.FieldDefs.Add('NAME',ftString,50);
+  dsfile.CreateTable;
+  dsmem.CreateTable;
+  dsfile.Open;
+  dsmem.Open;
+  // Some sample data
+  for i := 1 to 101 do
+  begin
+    dsfile.Append;
+    dsmem.Append;
+    dsfile.FieldByName('ID').AsInteger := i;
+    dsmem.FieldByName('ID').AsInteger := i;
+    dsfile.FieldByName('NAME').AsString := 'TestName' + inttostr(i);
+    dsmem.FieldByName('NAME').AsString := 'TestName' + inttostr(i);
+    dsfile.Post;
+    dsmem.Post;
+  end;
+
+  // By closing, we update the number of records in the header
+  dsfile.close;
+  dsmem.close;
+  dsfile.free;
+
+  // Keep dsmem; load file into stream:
+  thefile.LoadfromFile(FileName);
+  deletefile(FileName);
+
+  CheckEquals(backingstream.size,thefile.size,'Memory backed dbf should have same size as file-backed dbf');
+  // Now compare stream contents - thereby comparing the file with backingstream
+  CheckEquals(true,comparemem(thefile.Memory,backingstream.Memory,thefile.size),'Memory backed dbf data should be the same as file-backed dbf');
+  backingstream.free;
+  thefile.free;
+end;
+
 procedure TTestSpecificTDBF.TestCreateDatasetFromFielddefs;
 var
   ds : TDBF;