Bläddra i källkod

fcl-db: base: when copying character data use MaxLen up to Size (not DataSize), because buffer size is = DataSize, o we can copy max. DataSize-1 which is Size.
+ better test TestInsertLargeStrFields

git-svn-id: trunk@27717 -

lacak 11 år sedan
förälder
incheckning
54c09051a0
2 ändrade filer med 33 tillägg och 21 borttagningar
  1. 4 4
      packages/fcl-db/src/base/fields.inc
  2. 29 17
      packages/fcl-db/tests/testfieldtypes.pas

+ 4 - 4
packages/fcl-db/src/base/fields.inc

@@ -1190,9 +1190,9 @@ begin
     else
       // The data is copied into the buffer, since some TDataset descendents copy
       // the whole buffer-length in SetData. (See bug 8477)
-      Buf := AValue;
-    // If length(AValue) > DataSize the buffer isn't terminated properly
-    Buf[DataSize-1] := #0;
+      StrPLCopy(PChar(Buf), AValue, Size);
+    // If length(AValue) > Size the buffer isn't terminated properly ?
+    Buf[Size] := #0;
     SetData(@Buf);
     end
   else
@@ -1201,7 +1201,7 @@ begin
     if FTransliterate then
       DataSet.Translate(@AValue[1],@DynBuf[0],True)
     else
-      StrPLCopy(PChar(DynBuf), AValue, DataSize);
+      StrPLCopy(PChar(DynBuf), AValue, Size);
     SetData(@DynBuf[0]);
     end
 end;

+ 29 - 17
packages/fcl-db/tests/testfieldtypes.pas

@@ -931,40 +931,52 @@ begin
   with TSQLDBConnector(DBConnector).Query do
     begin
     Open;
-    AssertEquals(s,fields[0].AsString);
-    close;
+    AssertEquals(s,Fields[0].AsString);
+    Close;
     end;
 end;
 
 procedure TTestFieldTypes.TestInsertLargeStrFields;
 // See also: TestStringLargerThen8192
-const
-  FieldValue1='test1';
 var
-  FieldValue2: string;
+  FieldValues: array [1..4] of string;
+  i,l1,l2: integer;
 begin
-  FieldValue2:=StringOfChar('t', 16000);
+  FieldValues[1] := 'test1';                  // string length < 8192 (dsMaxStringSize)
+  FieldValues[2] := StringOfChar('a', 8192);  // string length = 8192 (dsMaxStringSize)
+  FieldValues[3] := StringOfChar('b', 16000); // string length > 8192 (dsMaxStringSize)
+  FieldValues[4] := StringOfChar('c', 17000); // string length > Field.Size
+
   with TSQLDBConnector(DBConnector) do
     begin
-    Connection.ExecuteDirect('create table FPDEV2 (  ' +
-                              '  ID INT NOT NULL ,   ' +
-                              '  NAME VARCHAR(16000),' +
-                              '  PRIMARY KEY (ID)    ' +
-                              ')                     ');
+    Connection.ExecuteDirect( 'create table FPDEV2 (' +
+                              '  ID INT NOT NULL , ' +
+                              '  F1 VARCHAR(8192), ' +
+                              '  F2 VARCHAR(16000),' +
+                              'primary key (ID) )');
     // Firebird/Interbase need a commit after a DDL statement. Not necessary for the other connections
     TSQLDBConnector(DBConnector).CommitDDL;
 
     query.sql.Text:='select * from FPDEV2';
     Query.Open;
-    Query.InsertRecord([1,FieldValue1]); // string length <= 8192 (dsMaxStringSize)
-    Query.InsertRecord([2,FieldValue2]); // string length >  8192 (dsMaxStringSize)
+    for i:=1 to high(FieldValues) do
+      Query.InsertRecord([i, FieldValues[i], FieldValues[i]]);
     Query.ApplyUpdates;
     Query.Close;
     Query.Open;
-    AssertEquals(FieldValue1, Query.FieldByName('NAME').AsString);
-    Query.Next;
-    AssertEquals(length(FieldValue2), length(Query.FieldByName('NAME').AsString));
-    AssertEquals(FieldValue2, Query.FieldByName('NAME').AsString);
+    for i:=1 to high(FieldValues) do
+      begin
+      l1:=length(FieldValues[i]);
+      if l1 > 8192  then l1 := 8192;
+      l2:=length(FieldValues[i]);
+      if l2 > 16000 then l2 := 16000;
+
+      AssertEquals(l1, length(Query.FieldByName('F1').AsString));
+      AssertEquals(l2, length(Query.FieldByName('F2').AsString));
+      AssertEquals(copy(FieldValues[i],1,l1), Query.FieldByName('F1').AsString);
+      AssertEquals(copy(FieldValues[i],1,l2), Query.FieldByName('F2').AsString);
+      Query.Next;
+      end;
     Query.Close;
     end;
 end;