@@ -105,17 +105,38 @@ module Squeal.PostgreSQL.Schema
105 , SchemumType (..)
105 , SchemumType (..)
106 , SchemaType
106 , SchemaType
114+ , ConstructorNamesOf
120+ , RecordFieldTypesOf
110import Control.DeepSeq
124import Control.DeepSeq
111−import Data.ByteString
125+import Data.Aeson (Value)
126+import Data.ByteString (ByteString)
112import Data.Kind
128import Data.Kind
113import Data.Monoid hiding (All)
129import Data.Monoid hiding (All)
130+import Data.Scientific
114import Data.String
131import Data.String
132+import Data.Text (Text)
115import Data.Word
134import Data.Word
116import Data.Type.Bool
135import Data.Type.Bool
136+import Data.UUID.Types (UUID)
117import GHC.OverloadedLabels
137import GHC.OverloadedLabels
118import GHC.TypeLits
138import GHC.TypeLits
139+import Network.IP.Addr
120import qualified GHC.Generics as GHC
141import qualified GHC.Generics as GHC
121import qualified Generics.SOP as SOP
142import qualified Generics.SOP as SOP
@@ -653,3 +674,79 @@ type family LabelsOf (conss :: [Type.ConstructorInfo]) :: [Symbol] where
654type family DatatypeLabels (info :: Type.DatatypeInfo) :: [Symbol] where
675type family DatatypeLabels (info :: Type.DatatypeInfo) :: [Symbol] where
655 DatatypeLabels ('Type.ADT _module _datatype constructors) = LabelsOf constructors
676 DatatypeLabels ('Type.ADT _module _datatype constructors) = LabelsOf constructors
678+type family PG (hask :: Type) = (pg :: PGType) | pg -> hask where
683+ PG Scientific = 'PGnumeric
684+ PG Float = 'PGfloat4
685+ PG Double = 'PGfloat8
687+ PG ByteString = 'PGbytea
688+ PG LocalTime = 'PGtimestamp
689+ PG UTCTime = 'PGtimestamptz
691+ PG TimeOfDay = 'PGtime
692+ PG (TimeOfDay, TimeZone) = 'PGtimetz
693+ PG DiffTime = 'PGinterval
695+ PG (NetAddr IP) = 'PGinet
698+type family PGenumWith (hask :: Type) :: PGType where
700+ 'PGenum (ConstructorNamesOf (ConstructorsOf (SOP.DatatypeInfoOf hask)))
702+type family PGcompositeWith (hask :: Type) :: PGType where
703+ PGcompositeWith hask =
705+ (FieldNamesOf (FieldsOf (SOP.DatatypeInfoOf hask)))
706+ (RecordFieldTypesOf (SOP.Code hask)))
708+type family ConstructorsOf (datatype :: Type.DatatypeInfo)
709+ :: [Type.ConstructorInfo] where
710+ ConstructorsOf ('Type.ADT _module _datatype constructors) =
712+ ConstructorsOf ('Type.Newtype _module _datatype constructor) =
715+type family ConstructorNameOf (constructors :: Type.ConstructorInfo)
716+ :: Type.ConstructorName where
717+ ConstructorNameOf ('Type.Constructor name) = name
718+ ConstructorNameOf ('Type.Infix name _assoc _fix) = name
719+ ConstructorNameOf ('Type.Record name _fields) = name
721+type family ConstructorNamesOf (constructors :: [Type.ConstructorInfo])
722+ :: [Type.ConstructorName] where
723+ ConstructorNamesOf '[] = '[]
724+ ConstructorNamesOf (constructor ': constructors) =
725+ ConstructorNameOf constructor ': ConstructorNamesOf constructors
727+type family FieldsOf (constructor :: Type.DatatypeInfo)
728+ :: [Type.FieldInfo] where
729+ FieldsOf ('Type.ADT _module _datatype '[ 'Type.Record _name fields]) =
732+type family FieldNameOf (field :: Type.FieldInfo) :: Type.FieldName where
733+ FieldNameOf ('Type.FieldInfo name) = name
735+type family FieldNamesOf (fields :: [Type.FieldInfo])
736+ :: [Type.FieldName] where
737+ FieldNamesOf '[] = '[]
738+ FieldNamesOf (field ': fields) = FieldNameOf field ': FieldNamesOf fields
740+type family FieldTypeOf (maybe :: Type) where
741+ FieldTypeOf (Maybe hask) = PG hask
743+type family FieldTypesOf (fields :: [Type]) where
744+ FieldTypesOf '[] = '[]
745+ FieldTypesOf (field ': fields) = FieldTypeOf field ': FieldTypesOf fields
747+type family RecordFieldTypesOf (code :: [[Type]]) where
748+ RecordFieldTypesOf '[fields] = FieldTypesOf fields
750+type family Zip xs ys where
752+ Zip (x ': xs) (y ': ys) = '(x,y) ': Zip xs ys