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 (\/) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
p \/ q = \x -> p x || q x p \/ q = \x -> p x || q x
eq :: Eq a => a -> a -> Bool
eq = (==)
fromField :: FromField a => ByteString -> Either String a fromField :: FromField a => ByteString -> Either String a
fromField = fromField =
AP.parseOnly parseField AP.parseOnly parseField
@ -52,13 +55,13 @@ class FromField a where
-- | See https://www.postgresql.org/docs/current/datatype-binary.html. -- | See https://www.postgresql.org/docs/current/datatype-binary.html.
-- Accepts @bytea@. -- Accepts @bytea@.
instance FromField ByteString where instance FromField ByteString where
validOid Proxy = Oid.bytea validOid Proxy = eq Oid.bytea
parseField = AP.takeByteString parseField = AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-character.html. -- | See https://www.postgresql.org/docs/current/datatype-character.html.
-- Accepts @text@, @character@ and @character varying@. -- Accepts @text@, @character@ and @character varying@.
instance FromField Text where 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 parseField = Encoding.decodeUtf8 <$> AP.takeByteString
-- Accepts @text@, @character@ and @character varying@. -- 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. -- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
-- We assume that 'Int' has 64 bits. This is not guaranteed but reasonable enough. -- We assume that 'Int' has 64 bits. This is not guaranteed but reasonable enough.
instance FromField Int where 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 parseField = readInt =<< AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html. -- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
instance FromField Integer where 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 parseField = readInt =<< AP.takeByteString
instance FromField Word where 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 parseField = readWord =<< AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html. -- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
-- Accepts only @real@ fields, not @double precision@. -- Accepts only @real@ fields, not @double precision@.
instance FromField Float where 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. -- Afaict there's no cleaner (@base@) way to access the underlying bits.
-- In C we'd do -- In C we'd do
-- --
@ -125,7 +128,7 @@ instance FromField Float where
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html. -- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
-- Accepts only @double precision@ fields, not @real@. -- Accepts only @double precision@ fields, not @real@.
instance FromField Double where instance FromField Double where
validOid Proxy = Oid.doublePrecision validOid Proxy = eq Oid.doublePrecision
parseField = unsafeCoerce <$> readBigEndian @Word <$> AP.takeByteString parseField = unsafeCoerce <$> readBigEndian @Word <$> AP.takeByteString
boolParser :: Parser Bool boolParser :: Parser Bool
@ -136,7 +139,7 @@ boolParser = AP.choice
-- | See https://www.postgresql.org/docs/current/datatype-boolean.html. -- | See https://www.postgresql.org/docs/current/datatype-boolean.html.
instance FromField Bool where instance FromField Bool where
validOid Proxy = Oid.boolean validOid Proxy = eq Oid.boolean
parseField = boolParser parseField = boolParser
postgresEpoch :: Day 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. -- 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. -- This means that working with negative dates will be different in Postgres and your application code.
instance FromField Day where instance FromField Day where
validOid Proxy = Oid.date validOid Proxy = eq Oid.date
parseField = fromPostgresJulian . fromIntegral <$> readBigEndian @Int32 <$> AP.takeByteString parseField = fromPostgresJulian . fromIntegral <$> readBigEndian @Int32 <$> AP.takeByteString
-- | See https://www.postgresql.org/docs/current/datatype-datetime.html. -- | 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. -- 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@. -- Accepts @time@.
instance FromField DiffTime where instance FromField DiffTime where
validOid Proxy = Oid.time validOid Proxy = eq Oid.time
parseField = microsecondsToDiffTime . fromIntegral <$> readBigEndian @Int <$> AP.takeByteString parseField = microsecondsToDiffTime . fromIntegral <$> readBigEndian @Int <$> AP.takeByteString
where where
microsecondsToDiffTime :: Integer -> DiffTime 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. -- 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@. -- Accepts @time@.
instance FromField TimeOfDay where instance FromField TimeOfDay where
validOid Proxy = Oid.time validOid Proxy = eq Oid.time
parseField = timeToTimeOfDay <$> parseField @DiffTime parseField = timeToTimeOfDay <$> parseField @DiffTime
fromPostgresTimestamp :: Int -> (Day, DiffTime) fromPostgresTimestamp :: Int -> (Day, DiffTime)
@ -181,7 +184,7 @@ fromPostgresTimestamp ts = (day, time)
-- | See https://www.postgresql.org/docs/current/datatype-datetime.html. -- | See https://www.postgresql.org/docs/current/datatype-datetime.html.
-- Accepts @timestamp with timezone@. -- Accepts @timestamp with timezone@.
instance FromField UTCTime where instance FromField UTCTime where
validOid Proxy = Oid.timestampWithTimezone validOid Proxy = eq Oid.timestampWithTimezone
parseField = toUTCTime . fromPostgresTimestamp <$> readBigEndian @Int <$> AP.takeByteString parseField = toUTCTime . fromPostgresTimestamp <$> readBigEndian @Int <$> AP.takeByteString
where where
toUTCTime (day, time) = UTCTime day time toUTCTime (day, time) = UTCTime day time

View File

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