Browse Source

* Patch from Lacak2 for initial Pg interval support.

git-svn-id: trunk@20370 -
marco 13 years ago
parent
commit
b31c15fbcc
1 changed files with 69 additions and 9 deletions
  1. 69 9
      packages/fcl-db/src/sqldb/postgres/pqconnection.pp

+ 69 - 9
packages/fcl-db/src/sqldb/postgres/pqconnection.pp

@@ -115,6 +115,8 @@ const Oid_Bool     = 16;
       Oid_Money    = 790;
       Oid_Money    = 790;
       Oid_Float8   = 701;
       Oid_Float8   = 701;
       Oid_Unknown  = 705;
       Oid_Unknown  = 705;
+      Oid_MacAddr  = 829;
+      Oid_Inet     = 869;
       Oid_bpchar   = 1042;
       Oid_bpchar   = 1042;
       Oid_varchar  = 1043;
       Oid_varchar  = 1043;
       oid_date      = 1082;
       oid_date      = 1082;
@@ -122,6 +124,7 @@ const Oid_Bool     = 16;
       Oid_timeTZ    = 1266;
       Oid_timeTZ    = 1266;
       Oid_timestamp = 1114;
       Oid_timestamp = 1114;
       Oid_timestampTZ = 1184;
       Oid_timestampTZ = 1184;
+      Oid_interval  = 1186;
       oid_numeric   = 1700;
       oid_numeric   = 1700;
       Oid_uuid      = 2950;
       Oid_uuid      = 2950;
 
 
@@ -416,6 +419,7 @@ begin
     Oid_TimeStamp,
     Oid_TimeStamp,
     Oid_TimeStampTZ        : Result := ftDateTime;
     Oid_TimeStampTZ        : Result := ftDateTime;
     Oid_Date               : Result := ftDate;
     Oid_Date               : Result := ftDate;
+    Oid_Interval,
     Oid_Time,
     Oid_Time,
     Oid_TimeTZ             : Result := ftTime;
     Oid_TimeTZ             : Result := ftTime;
     Oid_Bool               : Result := ftBoolean;
     Oid_Bool               : Result := ftBoolean;
@@ -442,6 +446,14 @@ begin
                              Result := ftGuid;
                              Result := ftGuid;
                              Size := 38;
                              Size := 38;
                              end;
                              end;
+    Oid_MacAddr            : begin
+                             Result := ftFixedChar;
+                             Size := 17;
+                             end;
+    Oid_Inet               : begin
+                             Result := ftString;
+                             Size := 39;
+                             end;
     Oid_Unknown            : Result := ftUnknown;
     Oid_Unknown            : Result := ftUnknown;
   else
   else
     Result := ftUnknown;
     Result := ftUnknown;
@@ -729,6 +741,7 @@ end;
 function TPQConnection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 function TPQConnection.LoadField(cursor : TSQLCursor;FieldDef : TfieldDef;buffer : pointer; out CreateBlob : boolean) : boolean;
 
 
 const NBASE=10000;
 const NBASE=10000;
+      DAYS_PER_MONTH=30;
 
 
 type TNumericRecord = record
 type TNumericRecord = record
        Digits : SmallInt;
        Digits : SmallInt;
@@ -736,6 +749,21 @@ type TNumericRecord = record
        Sign   : SmallInt;
        Sign   : SmallInt;
        Scale  : Smallint;
        Scale  : Smallint;
      end;
      end;
+     TIntervalRec = packed record
+       time  : int64;
+       day   : longint;
+       month : longint;
+     end;
+     TMacAddrRec = packed record
+       a, b, c, d, e, f: byte;
+     end;
+     TInetRec = packed record
+       family : byte;
+       bits   : byte;
+       is_cidr: byte;
+       nb     : byte;
+       ipaddr : array[1..16] of byte;
+     end;
 
 
 var
 var
   x,i,j         : integer;
   x,i,j         : integer;
@@ -747,6 +775,8 @@ var
   NumericRecord : ^TNumericRecord;
   NumericRecord : ^TNumericRecord;
   guid          : TGUID;
   guid          : TGUID;
   bcd           : TBCD;
   bcd           : TBCD;
+  macaddr       : ^TMacAddrRec;
+  inet          : ^TInetRec;
 
 
 begin
 begin
   Createblob := False;
   Createblob := False;
@@ -784,9 +814,32 @@ begin
           end;
           end;
         ftString, ftFixedChar :
         ftString, ftFixedChar :
           begin
           begin
-          li := pqgetlength(res,curtuple,x);
-          if li > dsMaxStringSize then li := dsMaxStringSize;
-          Move(CurrBuff^, Buffer^, li);
+          case PQftype(res, x) of
+            Oid_MacAddr:
+            begin
+              macaddr := Pointer(CurrBuff);
+              li := FormatBuf(Buffer^, FieldDef.Size, '%.2x:%.2x:%.2x:%.2x:%.2x:%.2x', 29,
+                    [macaddr^.a,macaddr^.b,macaddr^.c,macaddr^.d,macaddr^.e,macaddr^.f]);
+            end;
+            Oid_Inet:
+            begin
+              inet := Pointer(CurrBuff);
+              if inet^.nb = 4 then
+                li := FormatBuf(Buffer^, FieldDef.Size, '%d.%d.%d.%d', 11,
+                      [inet^.ipaddr[1],inet^.ipaddr[2],inet^.ipaddr[3],inet^.ipaddr[4]])
+              else if inet^.nb = 16 then
+                li := FormatBuf(Buffer^, FieldDef.Size, '%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x:%x%.2x', 55,
+                      [inet^.ipaddr[1],inet^.ipaddr[2],inet^.ipaddr[3],inet^.ipaddr[4],inet^.ipaddr[5],inet^.ipaddr[6],inet^.ipaddr[7],inet^.ipaddr[8],inet^.ipaddr[9],inet^.ipaddr[10],inet^.ipaddr[11],inet^.ipaddr[12],inet^.ipaddr[13],inet^.ipaddr[14],inet^.ipaddr[15],inet^.ipaddr[16]])
+              else
+                li := 0;
+            end
+            else
+            begin
+              li := pqgetlength(res,curtuple,x);
+              if li > dsMaxStringSize then li := dsMaxStringSize;
+              Move(CurrBuff^, Buffer^, li);
+            end;
+          end;
           pchar(Buffer + li)^ := #0;
           pchar(Buffer + li)^ := #0;
           end;
           end;
         ftBlob, ftMemo :
         ftBlob, ftMemo :
@@ -798,15 +851,22 @@ begin
           end;
           end;
         ftDateTime, ftTime :
         ftDateTime, ftTime :
           begin
           begin
-          pint64(buffer)^ := BEtoN(pint64(CurrBuff)^);
           dbl := pointer(buffer);
           dbl := pointer(buffer);
-          if FIntegerDatetimes then dbl^ := pint64(buffer)^/1000000;
-          if FieldDef.DataType = ftDateTime then
-            dbl^ := dbl^ + 3.1558464E+009; // postgres counts seconds elapsed since 1-1-2000
-          dbl^ := dbl^ / 86400;
+          if FIntegerDatetimes then
+            dbl^ := BEtoN(pint64(CurrBuff)^) / 1000000
+          else
+            pint64(dbl)^ := BEtoN(pint64(CurrBuff)^);
+          case PQftype(res, x) of
+            Oid_Timestamp, Oid_TimestampTZ:
+              dbl^ := dbl^ + 3.1558464E+009; // postgres counts seconds elapsed since 1-1-2000
+            Oid_Interval:
+              dbl^ := dbl^ + BEtoN(plongint(CurrBuff+ 8)^) * SecsPerDay
+                           + BEtoN(plongint(CurrBuff+12)^) * SecsPerDay * DAYS_PER_MONTH;
+          end;
+          dbl^ := dbl^ / SecsPerDay;
           // Now convert the mathematically-correct datetime to the
           // Now convert the mathematically-correct datetime to the
           // illogical windows/delphi/fpc TDateTime:
           // illogical windows/delphi/fpc TDateTime:
-          if (dbl^ <= 0) and (frac(dbl^)<0) then
+          if (dbl^ <= 0) and (frac(dbl^) < 0) then
             dbl^ := trunc(dbl^)-2-frac(dbl^);
             dbl^ := trunc(dbl^)-2-frac(dbl^);
           end;
           end;
         ftBCD, ftFmtBCD:
         ftBCD, ftFmtBCD: