@@ -25,6 +25,7 @@ Binary encoding and decoding between Haskell and PostgreSQL types.
25 , ScopedTypeVariables
25 , ScopedTypeVariables
26 , TypeApplications
26 , TypeApplications
27 , TypeFamilies
27 , TypeFamilies
28+ , TypeFamilyDependencies
28 , TypeInType
29 , TypeInType
29 , TypeOperators
30 , TypeOperators
30 , UndecidableInstances
31 , UndecidableInstances
@@ -43,6 +44,7 @@ module Squeal.PostgreSQL.Binary
43 , Only (..)
44 , Only (..)
46import Data.Aeson hiding (Null)
48import Data.Aeson hiding (Null)
47import Data.Int
49import Data.Int
48import Data.Kind
50import Data.Kind
@@ -202,6 +204,63 @@ instance FromValue pg y => FromValue ('PGfixarray n pg) (Vector (Maybe y)) where
202 (Decoding.dimensionArray Vector.replicateM
204 (Decoding.dimensionArray Vector.replicateM
203 (Decoding.nullableValueArray (fromValue (Proxy @pg))))
205 (Decoding.nullableValueArray (fromValue (Proxy @pg))))
207+class IsMaybes (xs :: [Type]) where
208+ type family Maybes xs = (mxs :: [Type]) | mxs -> xs
209+ maybes :: NP Maybe xs -> NP I (Maybes xs)
211+instance IsMaybes '[] where
212+ type Maybes '[] = '[]
215+instance IsMaybes xs => IsMaybes (x ': xs) where
216+ type Maybes (x ': xs) = Maybe x ': Maybes xs
217+ maybes (x :* xs) = I x :* maybes xs
219+class FromAliasedValue (pg :: (Symbol,PGType)) (y :: Type) where
220+ fromAliasedValue :: proxy pg -> Decoding.Value y
221+instance FromValue pg y => FromAliasedValue (alias ::: pg) y where
222+ fromAliasedValue _ = fromValue (Proxy @pg)
227+ , IsProductType y (Maybes ys)
228+ , AllZip FromAliasedValue fields ys
229+ , SameFields (DatatypeInfoOf y) fields
230+ ) => FromValue ('PGcomposite fields) y where
231+ fromValue = fmap (to . SOP . Z . maybes) . composite . decoders
234+ :: forall pgs ys proxy
235+ . AllZip FromAliasedValue pgs ys
236+ => proxy ('PGcomposite pgs)
237+ -> NP Decoding.Value ys
238+decoders _ = htrans (Proxy @FromAliasedValue) fromAliasedValue
239+ (hpure Proxy :: NP Proxy pgs)
243+ => NP Decoding.Value ys
244+ -> Decoding.Value (NP Maybe ys)
245+composite decoders = do
247+-- <OID of field's type: sizeof(Oid) bytes>
248+-- [if value is NULL]
251+-- <length of value: 4 bytes>
252+-- <value: <length> bytes>
255+-- <number of fields: 4 bytes>
260+ len <- sized 4 Decoding.int
261+ if len == -1 then return Nothing else Just <$> sized len decoder
262+ htraverse' each decoders
205-- | A `FromColumnValue` constraint lifts the `FromValue` parser
264-- | A `FromColumnValue` constraint lifts the `FromValue` parser
206-- to a decoding of a @(Symbol, ColumnType)@ to a `Type`,
265-- to a decoding of a @(Symbol, ColumnType)@ to a `Type`,
207-- decoding `Null`s to `Maybe`s. You should not define instances for
266-- decoding `Null`s to `Maybe`s. You should not define instances for