Browse Source

fcl-db: memds: when FieldDefs are changed set TableIsCreated to false to signal, that CreteTable should be called.
+ Add test unit for TMemDataset to allow test specific properties/methods of TMemDataset
+ Add this unit to test frameworks

git-svn-id: trunk@26025 -

lacak 11 years ago
parent
commit
aa147703d5

+ 1 - 0
.gitattributes

@@ -2217,6 +2217,7 @@ packages/fcl-db/tests/testjsondataset.pp svneol=native#text/plain
 packages/fcl-db/tests/testleaks.sh svneol=native#text/plain
 packages/fcl-db/tests/testspecifictbufdataset.pas svneol=native#text/plain
 packages/fcl-db/tests/testspecifictdbf.pas svneol=native#text/plain
+packages/fcl-db/tests/testspecifictmemdataset.pas svneol=native#text/pascal
 packages/fcl-db/tests/testsqldb.pas svneol=native#text/pascal
 packages/fcl-db/tests/testsqlfiles.lpi svneol=native#text/plain
 packages/fcl-db/tests/testsqlfiles.lpr svneol=native#text/plain

+ 9 - 7
packages/fcl-db/src/memds/memds.pp

@@ -488,6 +488,7 @@ begin
     B:=ReadInteger(F)<>0;
     TFieldDef.Create(FieldDefs,FN,ft,FS,B,I);
     end;
+  FTableIsCreated:=False;
 end;
 
 procedure TMemDataset.InternalFirst;
@@ -880,17 +881,18 @@ begin
     begin
     Close;
     FieldDefs.Clear;
+    FTableIsCreated:=False;
     end;
 end;
 
 procedure TMemDataset.calcrecordlayout;
 var
-  i,count : integer;
+  i,Count : integer;
 begin
- Count := fielddefs.count;
+ Count := FieldDefs.Count;
  // Avoid mem-leak if CreateTable is called twice
- FreeMem(ffieldoffsets);
- Freemem(ffieldsizes);
+ FreeMem(FFieldOffsets);
+ Freemem(FFieldSizes);
  {$IFDEF FPC}
  FFieldOffsets:=getmem(Count*sizeof(integer));
  FFieldSizes:=getmem(Count*sizeof(integer));
@@ -904,8 +906,8 @@ begin
 {$ENDIF}
  for i:= 0 to Count-1 do
    begin
-   GetIntegerPointer(ffieldoffsets, i)^ := FRecSize;
-   GetIntegerPointer(ffieldsizes,   i)^ := MDSGetbufferSize(i+1);
+   GetIntegerPointer(FFieldOffsets, i)^ := FRecSize;
+   GetIntegerPointer(FFieldSizes,   i)^ := MDSGetbufferSize(i+1);
    FRecSize:= FRecSize+GetIntegerPointer(FFieldSizes, i)^;
    end;
  FRecInfoOffset:=FRecSize;
@@ -975,7 +977,7 @@ Var
 
 begin
   Clear(True);
-  // NOT from fielddefs. The data may not be available in buffers !!
+  // NOT from FieldDefs. The data may not be available in buffers !!
   For I:=0 to Dataset.FieldCount-1 do
     begin
     F:=Dataset.Fields[I];

+ 2 - 1
packages/fcl-db/tests/dbtestframework.pas

@@ -20,13 +20,14 @@ uses
   tcsdfdata,
 // Units wich contain the tests
   TestBasics,
+  TestDBBasics,
   TestFieldTypes,
   TestDatasources,
-  TestDBBasics,
   TestBufDatasetStreams,
   TestSQLDB,
   TestSpecificTBufDataset,
   TestSpecificTDBF,
+  TestSpecificTMemDataset,
   TestDBExport,
   consoletestrunner;
 

+ 3 - 2
packages/fcl-db/tests/dbtestframework_gui.lpr

@@ -26,14 +26,15 @@ uses
   SdfDSToolsUnit,
   tcsdfdata,
   // DB unittest
-  testbasics,
-  TestFieldTypes,
+  TestBasics,
   TestDBBasics,
+  TestFieldTypes,
   TestDatasources,
   TestBufDatasetStreams,
   TestSQLDB,
   TestSpecificTBufDataset,
   TestSpecificTDBF,
+  TestSpecificTMemDataset,
   TestDBExport;
 
 {$R *.res}

+ 115 - 0
packages/fcl-db/tests/testspecifictmemdataset.pas

@@ -0,0 +1,115 @@
+unit TestSpecificTMemDataSet;
+
+{
+  Unit tests which are specific to TMemDataset
+}
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils,
+  fpcunit, testregistry,
+  ToolsUnit;
+
+type
+
+  { TTestSpecificTMemDataset }
+
+  TTestSpecificTMemDataset = class(TDBBasicsTestCase)
+  private
+  protected
+  published
+    procedure TestClear;
+    procedure TestFileName;
+    procedure TestCopyFromDataset;
+  end;
+
+implementation
+
+uses
+  MemDS, db;
+
+const
+  Test_FileName='test.dat';
+
+{ TTestSpecificTMemDataset }
+
+procedure TTestSpecificTMemDataset.TestClear;
+const
+  testValuesCount=3;
+var
+  i: integer;
+begin
+  with DBConnector.GetNDataset(10) as TMemDataset do
+  begin
+    Open;
+    Clear;
+    // test after FieldDefs are Cleared, if internal structures are updated properly
+    // create other FieldDefs
+    FieldDefs.Add('Fs', ftString, 20);
+    FieldDefs.Add('Fi', ftInteger);
+    FieldDefs.Add('Fi2', ftInteger);
+    // use only Open without CreateTable
+    Open;
+    CheckTrue(IsEmpty);
+    CheckEquals(0, DataSize);
+    // add some data
+    for i:=1 to testValuesCount do
+      AppendRecord([TestStringValues[i], TestIntValues[i], TestIntValues[i]]);
+    // check data
+    CheckEquals(testValuesCount, RecordCount);
+    First;
+    for i:=1 to testValuesCount do
+    begin
+      CheckEquals(TestStringValues[i], FieldByName('Fs').AsString);
+      CheckEquals(TestIntValues[i], FieldByName('Fi2').AsInteger);
+      Next;
+    end;
+    CheckTrue(Eof);
+  end;
+end;
+
+procedure TTestSpecificTMemDataset.TestFileName;
+var memds1, memds2: TMemDataset;
+begin
+  memds1:=DBConnector.GetFieldDataset as TMemDataset;
+  memds2:=DBConnector.GetNDataset(0) as TMemDataset;
+
+  memds1.Open;
+  memds1.SaveToFile(Test_FileName);
+  memds1.Close;
+  memds1.Clear;
+
+  memds1.FileName:=Test_FileName;
+  memds1.Open;
+  CheckFieldDatasetValues(memds1);
+
+  // try read same file into different dataset, testing if FieldDefs are updated properly
+  memds2.FileName:=Test_FileName;
+  memds2.Open;
+  CheckFieldDatasetValues(memds2);
+  DeleteFile(memds2.FileName);
+end;
+
+procedure TTestSpecificTMemDataset.TestCopyFromDataset;
+var memds1, memds2: TMemDataset;
+begin
+  memds1:=DBConnector.GetFieldDataset as TMemDataset;
+  memds2:=DBConnector.GetNDataset(0) as TMemDataset;
+
+  memds1.Open;
+  memds2.CopyFromDataset(memds1);
+  CheckFieldDatasetValues(memds2);
+end;
+
+
+initialization
+
+  if uppercase(dbconnectorname)='MEMDS' then
+    begin
+    RegisterTestDecorator(TDBBasicsTestSetup, TTestSpecificTMemDataset);
+    end;
+
+end.

+ 36 - 0
packages/fcl-db/tests/toolsunit.pas

@@ -99,6 +99,8 @@ type
     protected
       procedure SetUp; override;
       procedure TearDown; override;
+      procedure CheckFieldDatasetValues(ADataSet: TDataSet);
+      procedure CheckNDatasetValues(ADataSet: TDataSet; n: integer);
   end;
 
 
@@ -392,6 +394,40 @@ begin
   inherited TearDown;
 end;
 
+procedure TDBBasicsTestCase.CheckFieldDatasetValues(ADataSet: TDataSet);
+var i: integer;
+begin
+  with ADataSet do
+  begin
+    First;
+    for i := 0 to testValuesCount-1 do
+    begin
+      CheckEquals(i, FieldByName('ID').AsInteger, 'ID');
+      CheckEquals(testStringValues[i], FieldByName('FSTRING').AsString, 'FSTRING');
+      CheckEquals(testIntValues[i], FieldByName('FINTEGER').AsInteger, 'FINTEGER');
+      CheckEquals(testLargeIntValues[i], FieldByName('FLARGEINT').AsLargeInt, 'FLARGEINT');
+      Next;
+    end;
+    CheckTrue(Eof, 'Eof');
+  end;
+end;
+
+procedure TDBBasicsTestCase.CheckNDatasetValues(ADataSet: TDataSet; n: integer);
+var i: integer;
+begin
+  with ADataSet do
+  begin
+    First;
+    for i := 1 to n do
+    begin
+      CheckEquals(i, FieldByName('ID').AsInteger, 'ID');
+      CheckEquals('TestName' + inttostr(i), FieldByName('NAME').AsString, 'NAME');
+      Next;
+    end;
+    CheckTrue(Eof, 'Eof');
+  end;
+end;
+
 
 procedure ReadIniFile;