11{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
2+ {-# OPTIONS_GHC -Wno-orphans #-}
23{-|
34Module: IHP.Hasql.FromRow
45Description: Typeclass for decoding hasql result rows
@@ -14,22 +15,12 @@ Also provides parser functions used by the generated decoders for custom Postgre
1415-}
1516module IHP.Hasql.FromRow
1617( FromRowHasql (.. )
17- , HasqlDecodeValue (.. )
1818, HasqlDecodeColumn (.. )
1919) where
2020
2121import Prelude
22- import Data.ByteString (ByteString )
23- import Data.Text (Text )
24- import Data.UUID (UUID )
25- import Data.Time.Clock (UTCTime , DiffTime )
26- import Data.Time.Calendar (Day )
27- import Data.Time.LocalTime (TimeOfDay )
2822import qualified Hasql.Decoders as Decoders
2923import qualified Hasql.Mapping.IsScalar as Mapping
30- import Data.Int (Int16 , Int32 , Int64 )
31- import Data.Scientific (Scientific )
32- import qualified Data.Aeson as Aeson
3324import qualified Database.PostgreSQL.Simple.Types as PG
3425import IHP.ModelSupport.Types (LabeledData (.. ), Id' (.. ), PrimaryKey )
3526
@@ -42,37 +33,24 @@ class FromRowHasql a where
4233 -- | Decoder for a single row
4334 hasqlRowDecoder :: Decoders. Row a
4435
45- -- | Typeclass mapping Haskell scalar types to hasql value decoders
46- class HasqlDecodeValue a where
47- hasqlDecodeValue :: Decoders. Value a
48-
49- instance HasqlDecodeValue Int16 where hasqlDecodeValue = Decoders. int2
50- instance HasqlDecodeValue Int32 where hasqlDecodeValue = Decoders. int4
51- instance HasqlDecodeValue Int64 where hasqlDecodeValue = Decoders. int8
52- instance HasqlDecodeValue Int where hasqlDecodeValue = fromIntegral <$> Decoders. int8
53- instance HasqlDecodeValue Bool where hasqlDecodeValue = Decoders. bool
54- instance HasqlDecodeValue Text where hasqlDecodeValue = Decoders. text
55- instance HasqlDecodeValue ByteString where hasqlDecodeValue = Decoders. bytea
56- instance HasqlDecodeValue UUID where hasqlDecodeValue = Decoders. uuid
57- instance HasqlDecodeValue UTCTime where hasqlDecodeValue = Decoders. timestamptz
58- instance HasqlDecodeValue Day where hasqlDecodeValue = Decoders. date
59- instance HasqlDecodeValue TimeOfDay where hasqlDecodeValue = Decoders. time
60- instance HasqlDecodeValue DiffTime where hasqlDecodeValue = Decoders. interval
61- instance HasqlDecodeValue Scientific where hasqlDecodeValue = Decoders. numeric
62- instance HasqlDecodeValue Double where hasqlDecodeValue = Decoders. float8
63- instance HasqlDecodeValue Float where hasqlDecodeValue = Decoders. float4
64- instance HasqlDecodeValue Aeson. Value where hasqlDecodeValue = Decoders. jsonb
65- instance Mapping. IsScalar (PrimaryKey table ) => HasqlDecodeValue (Id' table ) where hasqlDecodeValue = Id <$> Mapping. decoder
66-
67- -- | Typeclass for building column-level row decoders, handling nullable/non-nullable
36+ -- | Typeclass for building column-level row decoders, handling nullable/non-nullable.
37+ -- Uses 'Mapping.IsScalar' from hasql-mapping for value-level decoding.
6838class HasqlDecodeColumn a where
6939 hasqlColumnDecoder :: Decoders. Row a
7040
71- instance {-# OVERLAPPABLE #-} HasqlDecodeValue a => HasqlDecodeColumn a where
72- hasqlColumnDecoder = Decoders. column (Decoders. nonNullable hasqlDecodeValue )
41+ instance {-# OVERLAPPABLE #-} Mapping. IsScalar a => HasqlDecodeColumn a where
42+ hasqlColumnDecoder = Decoders. column (Decoders. nonNullable Mapping. decoder )
7343
74- instance {-# OVERLAPPING #-} HasqlDecodeValue a => HasqlDecodeColumn (Maybe a ) where
75- hasqlColumnDecoder = Decoders. column (Decoders. nullable hasqlDecodeValue)
44+ instance {-# OVERLAPPING #-} Mapping. IsScalar a => HasqlDecodeColumn (Maybe a ) where
45+ hasqlColumnDecoder = Decoders. column (Decoders. nullable Mapping. decoder)
46+
47+ -- | Decode 'Id' table' by decoding the primary key type and wrapping with 'Id'
48+ instance {-# OVERLAPPING #-} Mapping. IsScalar (PrimaryKey table ) => HasqlDecodeColumn (Id' table ) where
49+ hasqlColumnDecoder = Decoders. column (Decoders. nonNullable (Id <$> Mapping. decoder))
50+
51+ -- | Decode 'Maybe (Id' table)' for nullable foreign keys
52+ instance {-# OVERLAPPING #-} Mapping. IsScalar (PrimaryKey table ) => HasqlDecodeColumn (Maybe (Id' table )) where
53+ hasqlColumnDecoder = Decoders. column (Decoders. nullable (Id <$> Mapping. decoder))
7654
7755-- FromRowHasql instances for PG.Only and tuples (used by sqlQuery callers like fetchCount, fetchExists)
7856
0 commit comments