/Database/HDBC/PostgreSQL/PTypeConv.hsc

http://github.com/hdbc/hdbc-postgresql · Unknown · 85 lines · 71 code · 14 blank · 0 comment · 0 complexity · edd3916ba6e8fa686ea0bd36b026aa17 MD5 · raw file

  1. -- -*- mode: haskell; -*-
  2. module Database.HDBC.PostgreSQL.PTypeConv where
  3. import Database.HDBC.ColTypes
  4. import Data.Word
  5. #include "pgtypes.h"
  6. #include <libpq-fe.h>
  7. colDescForPGAttr :: #{type Oid} -> Int -> String -> Bool -> SqlColDesc
  8. colDescForPGAttr atttypeid attlen formattedtype attnotnull =
  9. let
  10. coltype = oidToColType atttypeid
  11. size = if attlen == -1 then maybeExtractFirstParenthesizedNumber formattedtype
  12. else Just attlen
  13. decDigs = if coltype == SqlNumericT then maybeExtractSecondParenthesizedNumber formattedtype
  14. else Nothing
  15. in
  16. SqlColDesc { colType = coltype,
  17. colSize = size,
  18. colOctetLength = Nothing, -- not available in postgres
  19. colDecDigits = decDigs,
  20. colNullable = Just attnotnull }
  21. where
  22. maybeExtractFirstParenthesizedNumber s = case extractParenthesizedInts s of n:_ -> Just n; _ -> Nothing
  23. maybeExtractSecondParenthesizedNumber s = case extractParenthesizedInts s of _:n2:_ -> Just n2; _ -> Nothing
  24. extractParenthesizedInts :: String -> [Int]
  25. extractParenthesizedInts s =
  26. case takeWhile (/=')') $ dropWhile (/='(') s of
  27. '(':textBetweenParens ->
  28. case map fst $ reads $ "[" ++ textBetweenParens ++ "]" of
  29. l:_ -> l
  30. [] -> []
  31. _ -> []
  32. oidToColDef :: #{type Oid} -> SqlColDesc
  33. oidToColDef oid =
  34. SqlColDesc {colType = (oidToColType oid),
  35. colSize = Nothing,
  36. colOctetLength = Nothing,
  37. colDecDigits = Nothing,
  38. colNullable = Nothing}
  39. oidToColType :: #{type Oid} -> SqlTypeId
  40. oidToColType oid =
  41. case oid of
  42. #{const PG_TYPE_CHAR} -> SqlCharT
  43. #{const PG_TYPE_CHAR2} -> SqlCharT
  44. #{const PG_TYPE_CHAR4} -> SqlCharT
  45. #{const PG_TYPE_CHAR8} -> SqlCharT
  46. #{const PG_TYPE_NAME} -> SqlVarCharT
  47. #{const PG_TYPE_BPCHAR} -> SqlCharT
  48. #{const PG_TYPE_VARCHAR} -> SqlVarCharT
  49. #{const PG_TYPE_TEXT} -> SqlVarCharT
  50. #{const PG_TYPE_XML} -> SqlVarCharT
  51. #{const PG_TYPE_BYTEA} -> SqlVarBinaryT
  52. #{const PG_TYPE_INT2} -> SqlSmallIntT
  53. #{const PG_TYPE_OID} -> SqlIntegerT
  54. #{const PG_TYPE_XID} -> SqlIntegerT
  55. #{const PG_TYPE_INT4} -> SqlBigIntT
  56. #{const PG_TYPE_INT8} -> SqlBigIntT
  57. #{const PG_TYPE_NUMERIC} -> SqlNumericT
  58. #{const PG_TYPE_FLOAT4} -> SqlRealT
  59. #{const PG_TYPE_FLOAT8} -> SqlFloatT
  60. #{const PG_TYPE_DATE} -> SqlDateT
  61. #{const PG_TYPE_ABSTIME} -> SqlTimestampWithZoneT
  62. #{const PG_TYPE_DATETIME} -> SqlTimestampWithZoneT
  63. #{const PG_TYPE_TIMESTAMP_NO_TMZONE} -> SqlTimestampT
  64. #{const PG_TYPE_TIMESTAMP} -> SqlTimestampT
  65. #{const PG_TYPE_TIME} -> SqlTimeT
  66. #{const PG_TYPE_TIME_WITH_TMZONE} -> SqlTimeWithZoneT
  67. #{const PG_TYPE_TINTERVAL} -> SqlIntervalT SqlIntervalMonthT -- SqlIntervalMonthT chosen arbitrarily in these two. PG allows any parts
  68. #{const PG_TYPE_RELTIME} -> SqlIntervalT SqlIntervalMonthT -- of an interval (microsecond to millennium) to be specified together.
  69. 1186 -> SqlIntervalT SqlIntervalMonthT
  70. #{const PG_TYPE_BOOL} -> SqlBitT
  71. x -> SqlUnknownT (show x)