Add FromField Integer

This commit is contained in:
Paul Brinkmeier 2023-09-17 05:25:04 +02:00
parent dc4a302311
commit e307ee73d8
3 changed files with 32 additions and 8 deletions

View File

@ -67,3 +67,5 @@ getScoreByAge conn = do
- [ ] Implement JSON decoding - [ ] Implement JSON decoding
- [ ] Implement `ByteString` decoding (`bytea`) - [ ] Implement `ByteString` decoding (`bytea`)
- Can we make the fromField instance choose whether it wants binary or text? - Can we make the fromField instance choose whether it wants binary or text?
- [ ] Implement (anonymous) composite types
- It seems that in order to decode these, we'd need to use binary mode. In order to avoid writing everything twice it would be wise to move the whole `FromField` machinery to decoding from binary first

View File

@ -41,22 +41,28 @@ class FromField a where
-- | See https://www.postgresql.org/docs/current/datatype-character.html. -- | See https://www.postgresql.org/docs/current/datatype-character.html.
instance FromField Text where instance FromField Text where
validOid _ = Oid.text \/ Oid.character \/ Oid.characterVarying validOid Proxy = Oid.text \/ Oid.character \/ Oid.characterVarying
parseField = takeText parseField = takeText
-- | See https://www.postgresql.org/docs/current/datatype-character.html. -- | See https://www.postgresql.org/docs/current/datatype-character.html.
instance FromField String where instance FromField String where
validOid _ = validOid @Text Proxy validOid Proxy = validOid @Text Proxy
parseField = Text.unpack <$> parseField parseField = Text.unpack <$> parseField
-- | See https://www.postgresql.org/docs/current/datatype-character.html. -- | See https://www.postgresql.org/docs/current/datatype-character.html.
-- This instance accepts all character types but fails to decode fields that are not exactly one character. -- This instance accepts all character types but fails to decode fields that are not exactly one character.
instance FromField Char where instance FromField Char where
validOid _ = validOid @Text Proxy validOid Proxy = validOid @Text Proxy
parseField = anyChar parseField = anyChar
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
instance FromField Int where instance FromField Int where
validOid _ = Oid.smallint \/ Oid.integer \/ Oid.bigint validOid Proxy = Oid.smallint \/ Oid.integer \/ Oid.bigint
parseField = signed decimal
-- | See https://www.postgresql.org/docs/current/datatype-numeric.html.
instance FromField Integer where
validOid Proxy = Oid.smallint \/ Oid.integer \/ Oid.bigint
parseField = signed decimal parseField = signed decimal
doubleParser :: Parser Double doubleParser :: Parser Double
@ -70,11 +76,11 @@ doubleParser = choice
infinity = 1 / 0 infinity = 1 / 0
instance FromField Float where instance FromField Float where
validOid _ = Oid.real validOid Proxy = Oid.real
parseField = fmap double2Float doubleParser parseField = fmap double2Float doubleParser
instance FromField Double where instance FromField Double where
validOid _ = Oid.real \/ Oid.doublePrecision validOid Proxy = Oid.real \/ Oid.doublePrecision
parseField = doubleParser parseField = doubleParser
boolParser :: Parser Bool boolParser :: Parser Bool
@ -85,5 +91,5 @@ boolParser = 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 _ = Oid.boolean validOid Proxy = Oid.boolean
parseField = boolParser parseField = boolParser

View File

@ -18,6 +18,12 @@ newtype AnInt = AnInt
instance FromRow AnInt where instance FromRow AnInt where
newtype AnInteger = AnInteger
{ integer :: Integer
} deriving (Eq, Generic, Show)
instance FromRow AnInteger where
newtype AText = AText newtype AText = AText
{ text :: Text { text :: Text
} deriving (Eq, Generic, Show) } deriving (Eq, Generic, Show)
@ -72,7 +78,17 @@ spec = do
shouldFetch conn "SELECT 42::INTEGER AS int" [AnInt 42] shouldFetch conn "SELECT 42::INTEGER AS int" [AnInt 42]
it "Decodes bigint" $ \conn -> do it "Decodes bigint" $ \conn -> do
shouldFetch conn "SELECT 42::BIGINT AS int" [AnInt 42] shouldFetch conn "SELECT pow(2, 48)::BIGINT AS int" [AnInt $ (2 :: Int) ^ (48 :: Int)]
describe "FromField Integer" $ do
it "Decodes smallint" $ \conn -> do
shouldFetch conn "SELECT 42::SMALLINT AS integer" [AnInteger 42]
it "Decodes integer" $ \conn -> do
shouldFetch conn "SELECT pow(2, 20)::INTEGER AS integer" [AnInteger $ (2 :: Integer) ^ (20 :: Integer)]
it "Decodes bigint" $ \conn -> do
shouldFetch conn "SELECT pow(2, 48)::BIGINT AS integer" [AnInteger $ (2 :: Integer) ^ (48 :: Integer)]
describe "FromField Text" $ do describe "FromField Text" $ do
it "Decodes text" $ \conn -> do it "Decodes text" $ \conn -> do