Implement date -> Day decoding

This commit is contained in:
Paul Brinkmeier 2023-09-23 11:11:29 +02:00
parent 4d21e67130
commit 126b8ee6e9
6 changed files with 32 additions and 0 deletions

View File

@ -63,6 +63,7 @@ getScoreByAge conn = do
- [x] Implement `Float` and `Double` decoding
- [x] Clean up and document column table stuff
- [x] Decode `LibPQ.Binary`
- [x] Implement `date -> Day` decoding
- [ ] Implement `fetch` (`fetch_` but with parameter passing)
- [ ] Implement `UTCTime` and zoned time decoding
- [ ] Implement JSON decoding

View File

@ -20,6 +20,7 @@
hspec
postgresql-libpq
text
time
transformers
vector
]))

View File

@ -11,7 +11,9 @@ import Data.Attoparsec.ByteString (Parser)
import Data.Bits (Bits (..))
import Data.ByteString (ByteString)
import Data.Functor (($>))
import Data.Int (Int32)
import Data.Proxy (Proxy (..))
import Data.Time (Day (..))
import Data.Text (Text)
import Data.Word (Word32, Word64)
import Database.PostgreSQL.LibPQ (Oid)
@ -107,3 +109,11 @@ boolParser = AP.choice
instance FromField Bool where
validOid Proxy = Oid.boolean
parseField = boolParser
-- | See https://www.postgresql.org/docs/current/datatype-datetime.html.
-- Relevant as well: https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/datetime.c;h=267dfd37b2e8b9bc63797c69b9ca2e45e6bfde61;hb=HEAD#l267.
instance FromField Day where
validOid Proxy = Oid.date
parseField = fromJulianDay . fromIntegral <$> intParser @Int32
where
fromJulianDay x = ModifiedJulianDay $ x + 51544

View File

@ -48,3 +48,7 @@ doublePrecision = eq $ Oid 701
-- | Boolean
boolean :: Oid -> Bool
boolean = eq $ Oid 16
-- | Single days/dates.
date :: Oid -> Bool
date = eq $ Oid 1082

View File

@ -79,6 +79,7 @@ library
containers,
postgresql-libpq,
text,
time,
transformers,
vector
@ -122,4 +123,5 @@ test-suite opium-test
bytestring,
hspec,
postgresql-libpq,
time,
text

View File

@ -4,6 +4,7 @@
module Database.PostgreSQL.Opium.FromFieldSpec (spec) where
import Data.ByteString (ByteString)
import Data.Time (Day (..), fromGregorian)
import Data.Text (Text)
import Database.PostgreSQL.LibPQ (Connection)
import Database.PostgreSQL.Opium (FromRow)
@ -72,6 +73,12 @@ newtype ABool = ABool
instance FromRow ABool where
newtype ADay = ADay
{ day :: Day
} deriving (Eq, Generic, Show)
instance FromRow ADay where
shouldFetch :: (Eq a, FromRow a, Show a) => Connection -> ByteString -> [a] -> IO ()
shouldFetch conn query expectedRows = do
actualRows <- Opium.fetch_ conn query
@ -200,3 +207,10 @@ spec = do
shouldFetch conn "SELECT 'no'::boolean AS bool" [ABool False]
shouldFetch conn "SELECT 'off'::boolean AS bool" [ABool False]
shouldFetch conn "SELECT 0::boolean AS bool" [ABool False]
describe "FromField Day" $ do
it "Decodes date" $ \conn -> do
shouldFetch conn "SELECT date '1970-01-01' AS day" [ADay $ fromGregorian 1970 1 1]
shouldFetch conn "SELECT date '2023-09-23' AS day" [ADay $ fromGregorian 2023 9 23]
-- Example from postgres doc page
shouldFetch conn "SELECT date 'J2451187' AS day" [ADay $ fromGregorian 1999 1 8]