Turn members of Oid module into constants

This commit is contained in:
Paul Brinkmeier 2024-04-11 15:55:19 +02:00
parent f8904ccc01
commit c2c6c6eec2
2 changed files with 44 additions and 44 deletions

View File

@ -41,6 +41,9 @@ import qualified Database.PostgreSQL.Opium.Oid as Oid
(\/) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
p \/ q = \x -> p x || q x
eq :: Eq a => a -> a -> Bool
eq = (==)
fromField :: FromField a => ByteString -> Either String a
fromField =
AP.parseOnly parseField
@ -52,13 +55,13 @@ class FromField a where
-- | See https://www.postgresql.org/docs/current/datatype-binary.html.
-- Accepts @bytea@.
instance FromField ByteString where
validOid Proxy = Oid.bytea
validOid Proxy = eq Oid.bytea
parseField = AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-character.html.
-- Accepts @text@, @character@ and @character varying@.
instance FromField Text where
validOid Proxy = Oid.text \/ Oid.character \/ Oid.characterVarying
validOid Proxy = eq Oid.text \/ eq Oid.character \/ eq Oid.characterVarying
parseField = Encoding.decodeUtf8 <$> AP.takeByteString
-- Accepts @text@, @character@ and @character varying@.
@ -98,22 +101,22 @@ readWord bs = case BS.length bs of
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
-- We assume that 'Int' has 64 bits. This is not guaranteed but reasonable enough.
instance FromField Int where
validOid Proxy = Oid.smallint \/ Oid.integer \/ Oid.bigint
validOid Proxy = eq Oid.smallint \/ eq Oid.integer \/ eq Oid.bigint
parseField = readInt =<< AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
instance FromField Integer where
validOid Proxy = Oid.smallint \/ Oid.integer \/ Oid.bigint
validOid Proxy = eq Oid.smallint \/ eq Oid.integer \/ eq Oid.bigint
parseField = readInt =<< AP.takeByteString
instance FromField Word where
validOid Proxy = Oid.smallint \/ Oid.integer \/ Oid.bigint
validOid Proxy = eq Oid.smallint \/ eq Oid.integer \/ eq Oid.bigint
parseField = readWord =<< AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
-- Accepts only @real@ fields, not @double precision@.
instance FromField Float where
validOid Proxy = Oid.real
validOid Proxy = eq Oid.real
-- Afaict there's no cleaner (@base@) way to access the underlying bits.
-- In C we'd do
--
@ -125,7 +128,7 @@ instance FromField Float where
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
-- Accepts only @double precision@ fields, not @real@.
instance FromField Double where
validOid Proxy = Oid.doublePrecision
validOid Proxy = eq Oid.doublePrecision
parseField = unsafeCoerce <$> readBigEndian @Word <$> AP.takeByteString
boolParser :: Parser Bool
@ -136,7 +139,7 @@ boolParser = AP.choice
-- | See https://www.postgresql.org/docs/current/datatype-boolean.html.
instance FromField Bool where
validOid Proxy = Oid.boolean
validOid Proxy = eq Oid.boolean
parseField = boolParser
postgresEpoch :: Day
@ -151,14 +154,14 @@ fromPostgresJulian x = addDays x postgresEpoch
-- In short, Postgres treats 1 BC as a leap year and doesn't have a year zero.
-- This means that working with negative dates will be different in Postgres and your application code.
instance FromField Day where
validOid Proxy = Oid.date
validOid Proxy = eq Oid.date
parseField = fromPostgresJulian . fromIntegral <$> readBigEndian @Int32 <$> AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-datetime.html.
-- Binary format: https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/date.c;h=ae0f24de2c3c54eb6d0405cdb212597c2407238e;hb=HEAD#l1542.
-- Accepts @time@.
instance FromField DiffTime where
validOid Proxy = Oid.time
validOid Proxy = eq Oid.time
parseField = microsecondsToDiffTime . fromIntegral <$> readBigEndian @Int <$> AP.takeByteString
where
microsecondsToDiffTime :: Integer -> DiffTime
@ -168,7 +171,7 @@ instance FromField DiffTime where
-- Binary format: https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/date.c;h=ae0f24de2c3c54eb6d0405cdb212597c2407238e;hb=HEAD#l1542.
-- Accepts @time@.
instance FromField TimeOfDay where
validOid Proxy = Oid.time
validOid Proxy = eq Oid.time
parseField = timeToTimeOfDay <$> parseField @DiffTime
fromPostgresTimestamp :: Int -> (Day, DiffTime)
@ -181,7 +184,7 @@ fromPostgresTimestamp ts = (day, time)
-- | See https://www.postgresql.org/docs/current/datatype-datetime.html.
-- Accepts @timestamp with timezone@.
instance FromField UTCTime where
validOid Proxy = Oid.timestampWithTimezone
validOid Proxy = eq Oid.timestampWithTimezone
parseField = toUTCTime . fromPostgresTimestamp <$> readBigEndian @Int <$> AP.takeByteString
where
toUTCTime (day, time) = UTCTime day time

View File

@ -2,65 +2,62 @@ module Database.PostgreSQL.Opium.Oid where
import Database.PostgreSQL.LibPQ (Oid (..))
eq :: Eq a => a -> a -> Bool
eq = (==)
-- raw byte string
bytea :: Oid -> Bool
bytea = eq $ Oid 17
bytea :: Oid
bytea = Oid 17
-- string types
text :: Oid -> Bool
text = eq $ Oid 25
text :: Oid
text = Oid 25
character :: Oid -> Bool
character = eq $ Oid 1042
character :: Oid
character = Oid 1042
characterVarying :: Oid -> Bool
characterVarying = eq $ Oid 1043
characterVarying :: Oid
characterVarying = Oid 1043
-- integer types
-- | 16-bit integer
smallint :: Oid -> Bool
smallint = eq $ Oid 21
smallint :: Oid
smallint = Oid 21
-- | 32-bit integer
integer :: Oid -> Bool
integer = eq $ Oid 23
integer :: Oid
integer = Oid 23
-- | 64-bit integer
bigint :: Oid -> Bool
bigint = eq $ Oid 20
bigint :: Oid
bigint = Oid 20
-- floating point types
-- | 32-bit IEEE float
real :: Oid -> Bool
real = eq $ Oid 700
real :: Oid
real = Oid 700
-- | 64-bit IEEE float
doublePrecision :: Oid -> Bool
doublePrecision = eq $ Oid 701
doublePrecision :: Oid
doublePrecision = Oid 701
-- | Boolean
boolean :: Oid -> Bool
boolean = eq $ Oid 16
-- | Oid
boolean :: Oid
boolean = Oid 16
-- | Single days/dates.
date :: Oid -> Bool
date = eq $ Oid 1082
date :: Oid
date = Oid 1082
-- | Time of day.
time :: Oid -> Bool
time = eq $ Oid 1083
time :: Oid
time = Oid 1083
-- | A point in time.
timestamp :: Oid -> Bool
timestamp = eq $ Oid 1114
timestamp :: Oid
timestamp = Oid 1114
-- | A point in time.
timestampWithTimezone :: Oid -> Bool
timestampWithTimezone = eq $ Oid 1184
timestampWithTimezone :: Oid
timestampWithTimezone = Oid 1184