Browse Source

fcl-db/dbase:
* Foxpro: memo pointer 10 chars=>4 bytes, should make files compatible with (V)FoxPro
* Started support for FoxPro P(picture), Visual FoxPro 9 W(blob),V(varchar),Q(varbinary) field types.

git-svn-id: trunk@24216 -

reiniero 12 years ago
parent
commit
bceb3b28d4
2 changed files with 79 additions and 39 deletions
  1. 75 38
      packages/fcl-db/src/dbase/dbf_fields.pas
  2. 4 1
      packages/fcl-db/src/dbase/readme.txt

+ 75 - 38
packages/fcl-db/src/dbase/dbf_fields.pas

@@ -335,18 +335,21 @@ end;
 procedure TDbfFieldDef.NativeToVCL;
 procedure TDbfFieldDef.NativeToVCL;
 begin
 begin
   case FNativeFieldType of
   case FNativeFieldType of
-    '+' :
+    '+' : //dbase7+ autoinc
       if DbfVersion = xBaseVII then
       if DbfVersion = xBaseVII then
         FFieldType := ftAutoInc;
         FFieldType := ftAutoInc;
-    'I' : FFieldType := ftInteger;
-    'O' : FFieldType := ftFloat;
-    '@', 'T':
-          FFieldType := ftDateTime;
-    'C',
-    #$91  {Russian 'C'}
-        : FFieldType := ftString;
-    'L' : FFieldType := ftBoolean;
-    'F', 'N':
+    'I' : //integer
+      FFieldType := ftInteger;
+    'O' : //double, 8 bytes?
+      FFieldType := ftFloat;
+    '@', 'T' {Foxpro? datetime}:
+      FFieldType := ftDateTime;
+    'C', //character
+    #$91  {Russian 'C'}:
+      FFieldType := ftString;
+    'L' : //logical
+      FFieldType := ftBoolean;
+    'F', 'N': //float/numeric
       begin
       begin
         if (FPrecision = 0) then
         if (FPrecision = 0) then
         begin
         begin
@@ -365,28 +368,37 @@ begin
           FFieldType := ftFloat;
           FFieldType := ftFloat;
         end;
         end;
       end;
       end;
-    'D' : FFieldType := ftDate;
-    'M' : FFieldType := ftMemo;
-    'B' : 
+    'D' : //date
+      FFieldType := ftDate;
+    'M' : //memo
+      FFieldType := ftMemo;
+    'B' : //binary or float
       if (DbfVersion = xFoxPro) or (DbfVersion=xVisualFoxPro) then
       if (DbfVersion = xFoxPro) or (DbfVersion=xVisualFoxPro) then
         FFieldType := ftFloat
         FFieldType := ftFloat
       else
       else
         FFieldType := ftBlob;
         FFieldType := ftBlob;
-    'G' : FFieldType := ftDBaseOle;
-    'Y' :
+    'G' : //general
+      FFieldType := ftDBaseOle;
+    'Y' : //currency
       if DbfGlobals.CurrencyAsBCD then
       if DbfGlobals.CurrencyAsBCD then
         FFieldType := ftBCD
         FFieldType := ftBCD
       else
       else
         FFieldType := ftCurrency;
         FFieldType := ftCurrency;
-    '0' : FFieldType := ftBytes; { Visual FoxPro ``_NullFlags'' }
-    {
-    To do: add support for Visual Foxpro types
-    http://msdn.microsoft.com/en-US/library/ww305zh2%28v=vs.80%29.aspx
-    P Picture (perhaps also in FoxPro)
-    V Varchar/varchar binary (perhaps also in FoxPro) 1 byte up to 255 bytes (or perhaps 254)
-    W Blob (perhaps also in FoxPro), 4 bytes in a table; stored in .fpt
-    Q Varbinary (perhaps also in Foxpro)
-    }
+    '0' : //zero, not the letter O
+      FFieldType := ftBytes;
+    'P' : //picture
+      if (DBFversion in [xFoxPro,xVisualFoxPro]) then
+        FFieldType := ftBlob; {Picture, but probably not compatible with ftGraphic storage}
+    'V' : //VFP 9 Varchar; character with length indication
+      if (DbfVersion = xVisualFoxPro) then
+        FFieldType := ftString;
+      //todo: verify if 'V' for other systems exists. DBF "Varifields"?
+    'W' : //BLOB
+      if (DBFVersion = xVisualFoxPro) then
+        FFieldType := ftBlob;
+    'Q' : //varbinary
+      if (DBFVersion = xVisualFoxPro) then
+        FFieldType := ftBytes;
   else
   else
     FNativeFieldType := #0;
     FNativeFieldType := #0;
     FFieldType := ftUnknown;
     FFieldType := ftUnknown;
@@ -397,7 +409,8 @@ procedure TDbfFieldDef.VCLToNative;
 begin
 begin
   FNativeFieldType := #0;
   FNativeFieldType := #0;
   case FFieldType of
   case FFieldType of
-    ftAutoInc  : FNativeFieldType  := '+';
+    ftAutoInc  :
+      FNativeFieldType  := '+'; //todo: verify: xbasev/7 only? also (V)foxpro?
     ftDateTime :
     ftDateTime :
       if DbfVersion = xBaseVII then
       if DbfVersion = xBaseVII then
         FNativeFieldType := '@'
         FNativeFieldType := '@'
@@ -410,23 +423,46 @@ begin
     ftFixedChar,
     ftFixedChar,
     ftWideString,
     ftWideString,
 {$endif}
 {$endif}
-    ftString   : FNativeFieldType  := 'C';
-    ftBoolean  : FNativeFieldType  := 'L';
+    ftString   :
+      FNativeFieldType := 'C'; // VFP9: could have used V but this works, too.
+    ftBoolean  :
+      FNativeFieldType := 'L'; //logical
     ftFloat, ftSmallInt, ftWord
     ftFloat, ftSmallInt, ftWord
 {$ifdef SUPPORT_INT64}
 {$ifdef SUPPORT_INT64}
       , ftLargeInt
       , ftLargeInt
 {$endif}
 {$endif}
                : FNativeFieldType := 'N';
                : FNativeFieldType := 'N';
-    ftDate     : FNativeFieldType := 'D';
-    ftMemo     : FNativeFieldType := 'M';
-    ftBlob     : FNativeFieldType := 'B';
-    ftDBaseOle : FNativeFieldType := 'G';
+    ftDate     :
+      FNativeFieldType := 'D'; //date
+    ftMemo     :
+      FNativeFieldType := 'M'; //memo
+    ftBlob     :
+      case DBFVersion of
+        xFoxPro:
+          FNativeFieldType := 'P'; //picture
+        xVisualFoxPro:
+          FNativeFieldType := 'W'; //blob
+        xBaseIII,xBaseIV:
+          FNativeFieldType := 'M'; //memo; best we can do
+        xBaseV,xBaseVII:
+          FNativeFieldType := 'B'; //binary
+      else
+        FNativeFieldType := 'M'; //fallback
+      end;
+    ftDBaseOle :
+      FNativeFieldType := 'G'; //general
+      //todo: verify if this is dbaseV/7 specific
+    ftGraphic  :
+      // Let's store this as a BLOB even though FoxPro has P(icture).
+      // P is apparently not recommended
+      FNativeFieldType := 'B'; //BLOB
     ftInteger  :
     ftInteger  :
+      //todo: verify FoxPro I=4 byte little endian integer
       if DbfVersion = xBaseVII then
       if DbfVersion = xBaseVII then
-        FNativeFieldType := 'I'
+        FNativeFieldType := 'I' //integer
       else
       else
-        FNativeFieldType := 'N';
-    ftBCD, ftCurrency: 
+        FNativeFieldType := 'N'; //numeric
+    ftBCD, ftCurrency:
       if (DbfVersion = xFoxPro) or (DBFVersion = xVisualFoxPro) then
       if (DbfVersion = xFoxPro) or (DBFVersion = xVisualFoxPro) then
         FNativeFieldType := 'Y';
         FNativeFieldType := 'Y';
   end;
   end;
@@ -481,9 +517,10 @@ begin
 end;
 end;
 
 
 procedure TDbfFieldDef.CheckSizePrecision;
 procedure TDbfFieldDef.CheckSizePrecision;
+// FSize means size in the database, not any VCL field size
 begin
 begin
   case FNativeFieldType of
   case FNativeFieldType of
-    'C': // Character
+    'C','V','Q': // Character, Visual FoxPro varchar,Visual FoxPro varbinary
       begin
       begin
         if FSize < 0 then
         if FSize < 0 then
           FSize := 0;
           FSize := 0;
@@ -530,14 +567,14 @@ begin
           FPrecision := 0;
           FPrecision := 0;
         end;
         end;
       end;
       end;
-    'M','G': // Memo, general
+    'M','G','P','W': // Memo, general, FoxPro picture, Visual FoxPro blob
       begin
       begin
-        if (DbfVersion = xFoxPro) or (DbfVersion = xVisualFoxPro) then
+        if (DbfVersion = xVisualFoxPro) then
         begin
         begin
           if (FSize <> 4) and (FSize <> 10) then
           if (FSize <> 4) and (FSize <> 10) then
             FSize := 4;
             FSize := 4;
         end else
         end else
-          FSize := 10;
+          FSize := 10; //Dbase, includes FoxPro
         FPrecision := 0;
         FPrecision := 0;
       end;
       end;
     '+','I': // Autoincrement, integer
     '+','I': // Autoincrement, integer

+ 4 - 1
packages/fcl-db/src/dbase/readme.txt

@@ -25,7 +25,10 @@ http://msdn.microsoft.com/en-us/library/d863bcf2%28v=vs.80%29.aspx
 especially this for table structure:
 especially this for table structure:
 http://msdn.microsoft.com/en-US/library/st4a0s68%28v=vs.80%29.aspx
 http://msdn.microsoft.com/en-US/library/st4a0s68%28v=vs.80%29.aspx
 note however that the file type/magic number at offset 0 is incorrect.
 note however that the file type/magic number at offset 0 is incorrect.
-A community member amended these. See bottom of page
+A community member amended these with correct numbers. See bottom of page
+
+Visual FoxPro 9 data types
+http://msdn.microsoft.com/en-US/library/ww305zh2%28v=vs.80%29.aspx
 
 
 Visual FoxPro 9 specific changes:
 Visual FoxPro 9 specific changes:
 http://foxcentral.net/microsoft/WhatsNewInVFP9_Chapter09.htm
 http://foxcentral.net/microsoft/WhatsNewInVFP9_Chapter09.htm