2
0
Эх сурвалжийг харах

fcl-db: mysql: use new ftLongWord for INT UNSIGNED fields. Bug #37979

git-svn-id: trunk@47237 -
lacak 4 жил өмнө
parent
commit
78e7ea6fbf

+ 2 - 2
packages/fcl-db/src/base/xmldatapacketreader.pp

@@ -65,7 +65,7 @@ implementation
 uses xmlwrite, xmlread, base64;
 
 const
-  XMLFieldtypenames : Array [TFieldType] of String[16] =
+  XMLFieldTypeNames : Array [TFieldType] of String[16] =
     (
       'Unknown',
       'string',
@@ -109,7 +109,7 @@ const
       'bin.hex:WideText',   // ftWideMemo
       '',                   // ftOraTimeStamp
       '',                   // ftOraInterval
-      '',                   // ftLongWord
+      'i4',                 // ftLongWord
       '',                   // ftShortint
       '',                   // ftByte
       ''                    // ftExtended

+ 20 - 0
packages/fcl-db/src/sqldb/mysql/mysqlconn.inc

@@ -126,6 +126,7 @@ Type
     function InternalStrToDateTime(C: pchar; Len: integer): TDateTime;
     function InternalStrToFloat(C: pchar; Len: integer): Extended;
     function InternalStrToInt(C: pchar; Len: integer): integer;
+    function InternalStrToDWord(C: pchar; Len: integer): DWord;
     function InternalStrToInt64(C: pchar; Len: integer): Int64;
     function InternalStrToTime(C: pchar; Len: integer): TDateTime;
     function StrToMSecs(C: pchar; Len: integer): Word;
@@ -742,6 +743,8 @@ begin
       begin
       if AField^.flags and AUTO_INCREMENT_FLAG <> 0 then
         NewType := ftAutoInc
+      else if AField^.flags and UNSIGNED_FLAG <> 0 then
+        NewType := ftLongWord
       else
         NewType := ftInteger;
       end;
@@ -926,6 +929,17 @@ begin
   Result:=StrToInt(S);
 end;
 
+function TConnectionName.InternalStrToDWord(C: pchar; Len: integer): DWord;
+Var
+  S : String;
+begin
+  Result := 0;
+  if (Len=0) or (C=Nil) then
+    exit;
+  SetString(S,C,Len);
+  Result:=StrToDWord(S);
+end;
+
 function TConnectionName.InternalStrToInt64(C: pchar; Len: integer): Int64;
 
 Var
@@ -1112,6 +1126,7 @@ var
   VL: LargeInt;
   VS: Smallint;
   VW: Word;
+  VO: LongWord;
   VF: Double;
   VC: Currency;
   VD: TDateTime;
@@ -1153,6 +1168,11 @@ begin
       VL := InternalStrToInt64(Source, Len);
       Move(VL, Dest^, SizeOf(LargeInt));
       end;
+    ftLongWord:
+      begin
+      VO := InternalStrToDWord(Source, Len);
+      Move(VO, Dest^, SizeOf(LongWord));
+      end;
     ftFloat:
       begin
       VF := InternalStrToFloat(Source, Len);

+ 1 - 1
packages/fcl-db/tests/bufdatasettoolsunit.pas

@@ -186,7 +186,7 @@ begin
       FieldByName('FWIDESTRING').AsString := testStringValues[i];
       FieldByName('FFIXEDWIDECHAR').AsString := PadRight(testStringValues[i], 10);
       FieldByName('FWIDEMEMO').AsString := testStringValues[i];
-      FieldByName('FLONGWORD').AsLongWord := testWordValues[i];
+      FieldByName('FLONGWORD').AsLongWord := testLongWordValues[i];
       FieldByName('FSHORTINT').AsInteger := testShortIntValues[i];
       FieldByName('FBYTE').AsInteger := testByteValues[i];
       Post;

+ 1 - 0
packages/fcl-db/tests/sqldbtoolsunit.pas

@@ -316,6 +316,7 @@ begin
       FieldtypeDefinitions[ftBytes]    := 'BINARY(5)';
       FieldtypeDefinitions[ftVarBytes] := 'VARBINARY(10)';
       FieldtypeDefinitions[ftMemo]     := 'TEXT';
+      FieldtypeDefinitions[ftLongWord] := 'INT UNSIGNED';
       // Add into my.ini: sql-mode="...,PAD_CHAR_TO_FULL_LENGTH,ANSI_QUOTES" or set it explicitly by:
       // PAD_CHAR_TO_FULL_LENGTH to avoid trimming trailing spaces contrary to SQL standard (MySQL 5.1.20+)
       FConnection.ExecuteDirect('SET SESSION sql_mode=''STRICT_ALL_TABLES,PAD_CHAR_TO_FULL_LENGTH,ANSI_QUOTES''');

+ 8 - 0
packages/fcl-db/tests/testfieldtypes.pas

@@ -95,6 +95,7 @@ type
     procedure TestVarBytesParamQuery;
     procedure TestBooleanParamQuery;
     procedure TestBlobParamQuery;
+    procedure TestLongWordParamQuery;
 
     procedure TestSetBlobAsMemoParam;
     procedure TestSetBlobAsBlobParam;
@@ -1589,6 +1590,11 @@ begin
   TestXXParamQuery(ftBlob, FieldtypeDefinitions[ftBlob], testBlobValuesCount);
 end;
 
+procedure TTestFieldTypes.TestLongWordParamQuery;
+begin
+  TestXXParamQuery(ftLongWord, FieldtypeDefinitions[ftLongWord], testValuesCount);
+end;
+
 procedure TTestFieldTypes.TestStringParamQuery;
 begin
   TestXXParamQuery(ftString,'VARCHAR(10)',testValuesCount);
@@ -1649,6 +1655,7 @@ begin
         ftDateTime: Params.ParamByName('field1').AsDateTime := StrToDateTime(testValues[ADataType,i], DBConnector.FormatSettings);
         ftFMTBcd  : Params.ParamByName('field1').AsFMTBCD := StrToBCD(ParamValues[i], DBConnector.FormatSettings);
         ftBlob    : Params.ParamByName('field1').AsBlob := BytesOf(testBlobValues[i]);
+        ftLongWord: Params.ParamByName('field1').AsLongWord := testLongWordValues[i];
         ftBytes   : if cross then
                       Params.ParamByName('field1').Value := StringToByteArray(testBytesValues[i])
                     else
@@ -1691,6 +1698,7 @@ begin
         ftDateTime : AssertEquals(testValues[ADataType,i], DateTimeToStr(FieldByName('FIELD1').AsDateTime, DBConnector.FormatSettings));
         ftFMTBcd   : AssertEquals(ParamValues[i], BCDToStr(FieldByName('FIELD1').AsBCD, DBConnector.FormatSettings));
         ftBlob     : AssertEquals(testBlobValues[i], FieldByName('FIELD1').AsString);
+        ftLongWord : AssertEquals(testLongWordValues[i], FieldByName('FIELD1').AsLongWord);
         ftVarBytes,
         ftBytes    : AssertEquals(testBytesValues[i], shortstring(FieldByName('FIELD1').AsString));
       else

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

@@ -133,6 +133,7 @@ const
   testSmallIntValues : Array[0..testValuesCount-1] of smallint = (-maxSmallint,-maxSmallint+1,-256,-255,-128,-127,-1,0,1,127,128,255,256,maxSmallint,maxSmallint-1,100,110,120,130,150,-150,-132,234,231,42);
   testByteValues: Array[0..testValuesCount-1] of Byte = (1,2,3,4,5,6,7,8,0,1,127,128,255,0,0,0,0,0,0,0,0,0,0,0,0);
   testShortintValues: Array[0..testValuesCount-1] of ShortInt = (1,2,3,4,5,6,7,8,0,1,-128,-127,-64,64,126,127,0,0,0,0,0,0,0,0,0);
+  testLongWordValues : Array[0..testValuesCount-1] of Word = (1,2,3,4,5,6,7,8,0,1,$FF,$FFFF,$FFFFFF,$FFFFFFFF,0,0,0,0,0,0,0,0,0,0,0);
   testLargeIntValues : Array[0..testValuesCount-1] of LargeInt = (-$7fffffffffffffff,-$7ffffffffffffffe,-maxInt-1,-maxInt+1,-maxSmallint,-maxSmallint+1,-256,-255,-128,-127,-1,0,1,127,128,255,256,maxSmallint,maxSmallint-1,maxSmallint+1,MaxInt-1,MaxInt,$7fffffffffffffff-1,$7fffffffffffffff,235253244);
   testBooleanValues : Array[0..testValuesCount-1] of boolean = (true,false,false,true,true,false,false,true,false,true,true,true,false,false,false,false,true,true,true,true,false,true,true,false,false);
   testStringValues : Array[0..testValuesCount-1] of string = (
@@ -568,6 +569,7 @@ begin
     testValues[ftInteger,i] := IntToStr(testIntValues[i]);
     testValues[ftWord,i] := IntToStr(testWordValues[i]);
     testValues[ftLargeint,i] := IntToStr(testLargeIntValues[i]);
+    testValues[ftLongWord,i] := IntToStr(testLongWordValues[i]);
     testValues[ftCurrency,i] := CurrToStr(testCurrencyValues[i],FormatSettings);
     testValues[ftBCD,i] := CurrToStr(testCurrencyValues[i],FormatSettings);
     // For date '0001-01-01' other time-part like '00:00:00' causes "Invalid variant type cast", because of < MinDateTime constant