浏览代码

fcl-db:
* Fixes tests for UniDirectional datasets
* Calculated fields are supported by UniDirectional datasets
* Lookup fields return always null for UniDirectional datasets in Delphi
* First is valid for UniDirectional datasets (in TDataSet.First closes/opens dataset if not at Bof)

git-svn-id: trunk@23307 -

lacak 12 年之前
父节点
当前提交
c5e8af10a4
共有 3 个文件被更改,包括 68 次插入41 次删除
  1. 4 5
      packages/fcl-db/src/base/bufdataset.pas
  2. 5 4
      packages/fcl-db/src/base/dataset.inc
  3. 59 32
      packages/fcl-db/tests/testdbbasics.pas

+ 4 - 5
packages/fcl-db/src/base/bufdataset.pas

@@ -1233,11 +1233,9 @@ end;
 procedure TCustomBufDataset.InternalFirst;
 begin
   with FCurrentIndex do
-    begin
-// if FCurrentRecBuf = FLastRecBuf then the dataset is just opened and empty
-// in which case InternalFirst should do nothing (bug 7211)
+    // if FCurrentRecBuf = FLastRecBuf then the dataset is just opened and empty
+    // in which case InternalFirst should do nothing (bug 7211)
     SetToFirstRecord;
-    end;
 end;
 
 procedure TCustomBufDataset.InternalLast;
@@ -3609,7 +3607,8 @@ end;
 
 procedure TUniDirectionalBufIndex.SetToFirstRecord;
 begin
-  DatabaseError(SUniDirectional);
+  // for UniDirectional datasets should be [Internal]First valid method call
+  // do nothing
 end;
 
 procedure TUniDirectionalBufIndex.SetToLastRecord;

+ 5 - 4
packages/fcl-db/src/base/dataset.inc

@@ -139,15 +139,16 @@ var
   OldState: TDatasetState;
 begin
   FCalcBuffer := Buffer; 
-  if not IsUniDirectional and (FState <> dsInternalCalc) then
+  if FState <> dsInternalCalc then
   begin
     OldState := FState;
     FState := dsCalcFields;
     try
       ClearCalcFields(FCalcBuffer);
-      for i := 0 to FFieldList.Count - 1 do
-        if FFieldList[i].FieldKind = fkLookup then
-          FFieldList[i].CalcLookupValue;
+      if not IsUniDirectional then
+        for i := 0 to FFieldList.Count - 1 do
+          if FFieldList[i].FieldKind = fkLookup then
+            FFieldList[i].CalcLookupValue;
     finally
       DoOnCalcFields;
       FState := OldState;

+ 59 - 32
packages/fcl-db/tests/testdbbasics.pas

@@ -430,7 +430,10 @@ begin
       open;
       DataEvents := '';
       Resync([rmExact]);
-      CheckEquals('deDataSetChange:0;DataSetChanged;',DataEvents);
+      if IsUniDirectional then
+        CheckEquals('',DataEvents)
+      else
+        CheckEquals('deDataSetChange:0;DataSetChanged;',DataEvents);
       DataEvents := '';
       next;
       CheckEquals('deCheckBrowseMode:0;DataEvent;deDataSetScroll:0;DataSetScrolled:1;DataSetChanged;',DataEvents);
@@ -716,17 +719,28 @@ begin
 
     lds.Open;
     Open;
-    CheckTrue(FieldByName('ID').CanModify);
+    if IsUniDirectional then
+      // The CanModify property is always False for UniDirectional datasets
+      CheckFalse(FieldByName('ID').CanModify)
+    else
+      CheckTrue(FieldByName('ID').CanModify);
     CheckFalse(FieldByName('LookupFld').CanModify);
     CheckFalse(FieldByName('ID').ReadOnly);
     CheckFalse(FieldByName('LookupFld').ReadOnly);
 
     CheckEquals(1,FieldByName('ID').AsInteger);
-    CheckEquals('TestName1',FieldByName('LookupFld').AsString);
+    if IsUniDirectional then
+      // Lookup fields are not supported by UniDirectional datasets
+      CheckTrue(FieldByName('LookupFld').IsNull)
+    else
+      CheckEquals('TestName1',FieldByName('LookupFld').AsString);
     Next;
     Next;
     CheckEquals(3,FieldByName('ID').AsInteger);
-    CheckEquals('TestName3',FieldByName('LookupFld').AsString);
+    if IsUniDirectional then
+      CheckTrue(FieldByName('LookupFld').IsNull)
+    else
+      CheckEquals('TestName3',FieldByName('LookupFld').AsString);
 
     Close;
     lds.Close;
@@ -971,32 +985,38 @@ begin
   with DBConnector.GetNDataset(true,11) do
     begin
     open;
+    // First and Next methods are supported by UniDirectional datasets
     first;
-    edit;
-    FieldValues['id']:=5;
-    post;
-    CheckEquals('TestName1',FieldByName('name').AsString);
-    CheckEquals(5,FieldByName('id').AsInteger);
-    edit;
-    FieldValues['name']:='FieldValuesTestName';
-    post;
-    CheckEquals('FieldValuesTestName',FieldByName('name').AsString);
-    CheckEquals(5,FieldByName('id').AsInteger);
-    edit;
-    FieldValues['id;name']:= VarArrayOf([243,'ValuesTestName']);
-    post;
-    CheckEquals('ValuesTestName',FieldByName('name').AsString);
-    CheckEquals(243,FieldByName('id').AsInteger);
-    
-    PassException:=false;
-    try
+    if IsUniDirectional then
+      CheckException(Edit, EDatabaseError)
+    else
+      begin
       edit;
-      FieldValues['id;name;fake']:= VarArrayOf([243,'ValuesTestName',4]);
-    except
-      on E: EDatabaseError do PassException := True;
-    end;
-    post;
-    CheckTrue(PassException);
+      FieldValues['id']:=5;
+      post;
+      CheckEquals('TestName1',FieldByName('name').AsString);
+      CheckEquals(5,FieldByName('id').AsInteger);
+      edit;
+      FieldValues['name']:='FieldValuesTestName';
+      post;
+      CheckEquals('FieldValuesTestName',FieldByName('name').AsString);
+      CheckEquals(5,FieldByName('id').AsInteger);
+      edit;
+      FieldValues['id;name']:= VarArrayOf([243,'ValuesTestName']);
+      post;
+      CheckEquals('ValuesTestName',FieldByName('name').AsString);
+      CheckEquals(243,FieldByName('id').AsInteger);
+    
+      PassException:=false;
+      try
+        edit;
+        FieldValues['id;name;fake']:= VarArrayOf([243,'ValuesTestName',4]);
+      except
+        on E: EDatabaseError do PassException := True;
+      end;
+      post;
+      CheckTrue(PassException);
+      end;
     end;
 end;
 
@@ -2188,6 +2208,7 @@ begin
   else
     dataset.fieldbyname('CALCFLD').AsInteger := 1;
   end;
+  CheckTrue(DataSet.State=dsCalcFields, 'State');
 end;
 
 procedure TTestDBBasics.TestCalculatedField;
@@ -2221,10 +2242,16 @@ begin
     CheckEquals(true,FieldByName('CALCFLD').isnull);
     next;
     CheckEquals(1234,FieldByName('CALCFLD').AsInteger);
-    edit;
-    FieldByName('ID').AsInteger := 10;
-    post;
-    CheckEquals(true,FieldByName('CALCFLD').isnull);
+    if IsUniDirectional then
+      // The CanModify property is always False, so attempts to put the dataset into edit mode always fail
+      CheckException(Edit, EDatabaseError)
+    else
+      begin
+      Edit;
+      FieldByName('ID').AsInteger := 10;
+      Post;
+      CheckEquals(true,FieldByName('CALCFLD').isnull);
+      end;
     close;
     AFld1.Free;
     AFld2.Free;