@@ -138,6 +138,7 @@ Person {name = Just "Faisal", age = Just 24}
138138 , FlexibleInstances
139139 , GADTs
140140 , LambdaCase
141+ , OverloadedStrings
141142 , MultiParamTypeClasses
142143 , ScopedTypeVariables
143144 , TypeApplications
@@ -159,7 +160,6 @@ module Squeal.PostgreSQL.Binary
159160 , Only (..)
160161 ) where
161162
162−import BinaryParser
163163import ByteString.StrictBuilder
164164import Data.Aeson hiding (Null)
165165import Data.Int
@@ -270,6 +270,7 @@ instance
270270 toParam =
271271 let
272272
273+ -- encoders :: NP (Maybe :.: P) fields -> NP (K (Maybe Encoding.Encoding)) xs
273274 encoders = htrans (Proxy @ToAliasedParam) toAliasedParam
274275
275276 composite
@@ -304,17 +305,17 @@ instance
304305 hcfoldMap (Proxy @HasAliasedOid) each fields
305306
306307 in
307− composite . encoders . unMaybes . unZ . unSOP . from
308+ composite . encoders . toRecord
308309
309−class HasAliasedOid (field :: (Symbol, PGType)) where aliasedOid :: Word32
310−instance HasOid ty => HasAliasedOid (alias ::: ty) where aliasedOid = oid @ty
310+class HasAliasedOid (field :: (Symbol, NullityType)) where
311+ aliasedOid :: Word32
312+instance HasOid ty => HasAliasedOid (alias ::: nullity ty) where
313+ aliasedOid = oid @ty
311314
312−class ToAliasedParam (x :: Type) (field :: (Symbol, PGType)) where
313− toAliasedParam :: Maybe x -> K (Maybe Encoding.Encoding) field
314−instance ToParam x ty => ToAliasedParam x (alias ::: ty) where
315− toAliasedParam = \case
316− Nothing -> K Nothing
317− Just x -> K . Just . unK $ toParam @x @ty x
315+class ToAliasedParam (x :: (Symbol, Type)) (field :: (Symbol, NullityType)) where
316+ toAliasedParam :: P x -> K (Maybe Encoding.Encoding) field
317+instance ToColumnParam x ty => ToAliasedParam (alias ::: x) (alias ::: ty) where
318+ toAliasedParam (P x) = K . unK $ toColumnParam @x @ty x
318319
319320-- | A `ToColumnParam` constraint lifts the `ToParam` encoding
320321-- of a `Type` to a `NullityType`, encoding `Maybe`s to `Null`s. You should
@@ -328,11 +329,11 @@ class ToColumnParam (x :: Type) (ty :: NullityType) where
328329 --
329330 -- >>> toColumnParam @(Maybe Int16) @('Null 'PGint2) Nothing
330331 -- K Nothing
331− toColumnParam :: x -> K (Maybe Strict.ByteString) ty
332+ toColumnParam :: x -> K (Maybe Encoding.Encoding) ty
332333instance ToParam x pg => ToColumnParam x ('NotNull pg) where
333− toColumnParam = K . Just . Encoding.encodingBytes . unK . toParam @x @pg
334+ toColumnParam = K . Just . unK . toParam @x @pg
334335instance ToParam x pg => ToColumnParam (Maybe x) ('Null pg) where
335− toColumnParam = K . fmap (Encoding.encodingBytes . unK . toParam @x @pg)
336+ toColumnParam = K . fmap (unK . toParam @x @pg)
336337
337338-- | A `ToParams` constraint generically sequences the encodings of `Type`s
338339-- of the fields of a tuple or record to a row of `ColumnType`s. You should
@@ -348,7 +349,7 @@ class SListI tys => ToParams (x :: Type) (tys :: [NullityType]) where
348349 -- >>> instance Generic Tuple
349350 -- >>> toParams @Tuple @Params (Tuple False (Just 0))
350351 -- K (Just "\NUL") :* K (Just "\NUL\NUL") :* Nil
351− toParams :: x -> NP (K (Maybe Strict.ByteString)) tys
352+ toParams :: x -> NP (K (Maybe Encoding.Encoding)) tys
352353instance (SListI tys, IsProductType x xs, AllZip ToColumnParam xs tys)
353354 => ToParams x tys where
354355 toParams
@@ -433,21 +434,21 @@ instance
433434 . Strict.unpack
434435
435436instance
436− ( SListI fields
437− , IsRecord y ys
438− , AllZip FromAliasedValue fields ys
437+ ( FromRow fields y
439438 ) => FromValue ('PGcomposite fields) y where
440− fromValue =
439+ fromValue p =
441440 let
442− decoders
443− :: forall pgs zs proxy
444− . AllZip FromAliasedValue pgs zs
445− => proxy ('PGcomposite pgs)
446− -> NP Decoding.Value zs
447− decoders _ = htrans (Proxy @FromAliasedValue) fromAliasedValue
448− (hpure Proxy :: NP Proxy pgs)
449−
450− composite fields = do
441+ composite
442+ :: proxy ('PGcomposite pgs)
443+ -> Strict.ByteString
444+ -> NP (K (Maybe Strict.ByteString)) pgs
445+ composite = undefined
446+
447+ -- composite
448+ -- :: SListI zs
449+ -- => NP ((->) (Maybe Strict.ByteString) :.: Either Strict.Text :.: P) zs
450+ -- -> Decoding.Value (NP P zs)
451+ -- composite fields = do
451452 -- <number of fields: 4 bytes>
452453 -- [for each field]
453454 -- <OID of field's type: sizeof(Oid) bytes>
@@ -458,26 +459,28 @@ instance
458459 -- <value: <length> bytes>
459460 -- [end if]
460461 -- [end for]
461− unitOfSize 4
462− let
463− each field = do
464− unitOfSize 4
465− len <- sized 4 Decoding.int
466− if len == -1 then return Nothing else Just <$> sized len field
467− htraverse' each fields
462+ -- unitOfSize 4
463+ -- let
464+ -- each
465+ -- :: ((->) (Maybe Strict.ByteString) :.: Either Strict.Text :.: P) z
466+ -- -> Decoding.Value (P z)
467+ -- each = undefined
468+ -- each (Comp field) = _
469+ -- unitOfSize 4
470+ -- len <- sized 4 Decoding.int
471+ -- if len == -1
472+ -- then return (P (field Nothing))
473+ -- else sized len (fn _)
474+ -- htraverse' each fields
468475
469− in fmap (to . SOP . Z . maybes) . composite . decoders
470−
471−class FromAliasedValue (pg :: (Symbol,PGType)) (y :: Type) where
472− fromAliasedValue :: proxy pg -> Decoding.Value y
473−instance FromValue pg y => FromAliasedValue (alias ::: pg) y where
474− fromAliasedValue _ = fromValue (Proxy @pg)
476+ in
477+ Decoding.fn (fromRow @fields @y . composite p)
475478
476479-- | A `FromColumnValue` constraint lifts the `FromValue` parser
477480-- to a decoding of a @(Symbol, NullityType)@ to a `Type`,
478481-- decoding `Null`s to `Maybe`s. You should not define instances for
479482-- `FromColumnValue`, just use the provided instances.
480−class FromColumnValue (colty :: (Symbol,NullityType)) (y :: Type) where
483+class FromColumnValue (pg :: (Symbol, NullityType)) (y :: (Symbol, Type)) where
481484 -- | >>> :set -XTypeOperators -XOverloadedStrings
482485 -- >>> newtype Id = Id { getId :: Int16 } deriving Show
483486 -- >>> instance FromValue 'PGint2 Id where fromValue = fmap Id . fromValue
@@ -486,33 +489,28 @@ class FromColumnValue (colty :: (Symbol,NullityType)) (y :: Type) where
486489 --
487490 -- >>> fromColumnValue @("col" ::: 'Null 'PGint2) @(Maybe Id) (K (Just "\NUL\SOH"))
488491 -- Just (Id {getId = 1})
489− fromColumnValue :: K (Maybe Strict.ByteString) colty -> y
492+ fromColumnValue
493+ :: K (Maybe Strict.ByteString) pg
494+ -> (Either Strict.Text :.: P) y
490495instance FromValue pg y
491− => FromColumnValue (column ::: ('NotNull pg)) y where
492− fromColumnValue = \case
493− K Nothing -> error "fromColumnValue: saw NULL when expecting NOT NULL"
494− K (Just bs) ->
495− let
496− errOrValue =
497− Decoding.valueParser (fromValue @pg @y Proxy) bs
498− err str = error $ "fromColumnValue: " ++ Strict.unpack str
499− in
500− either err id errOrValue
496+ => FromColumnValue (column ::: ('NotNull pg)) (column ::: y) where
497+ fromColumnValue = Comp . \case
498+ K Nothing -> Left "fromColumnValue: saw NULL when expecting NOT NULL"
499+ K (Just bytestring) -> P <$>
500+ Decoding.valueParser (fromValue @pg @y Proxy) bytestring
501501instance FromValue pg y
502− => FromColumnValue (column ::: ('Null pg)) (Maybe y) where
503− fromColumnValue (K nullOrBytes)
504− = either err id
505− . Decoding.valueParser (fromValue @pg @y Proxy)
506− <$> nullOrBytes
507− where
508− err str = error $ "fromColumnValue: " ++ Strict.unpack str
502+ => FromColumnValue (column ::: 'Null pg) (column ::: Maybe y) where
503+ fromColumnValue = Comp . \case
504+ K Nothing -> Right $ P Nothing
505+ K (Just bytestring) -> P . Just <$>
506+ Decoding.valueParser (fromValue @pg @y Proxy) bytestring
509507
510508-- | A `FromRow` constraint generically sequences the parsings of the columns
511509-- of a `RelationType` into the fields of a record `Type` provided they have
512510-- the same field names. You should not define instances of `FromRow`.
513511-- Instead define `Generic` and `HasDatatypeInfo` instances which in turn
514512-- provide `FromRow` instances.
515−class SListI results => FromRow (results :: RelationType) y where
513+class SListI result => FromRow (result :: RelationType) y where
516514 -- | >>> :set -XOverloadedStrings
517515 -- >>> import Data.Text
518516 -- >>> newtype UserId = UserId { getUserId :: Int16 } deriving Show
@@ -523,14 +521,16 @@ class SListI results => FromRow (results :: RelationType) y where
523521 -- >>> type User = '["userId" ::: 'NotNull 'PGint2, "userName" ::: 'Null 'PGtext]
524522 -- >>> fromRow @User @UserRow (K (Just "\NUL\SOH") :* K (Just "bloodninja") :* Nil)
525523 -- UserRow {userId = UserId {getUserId = 1}, userName = Just "bloodninja"}
526− fromRow :: NP (K (Maybe Strict.ByteString)) results -> y
524+ fromRow :: NP (K (Maybe Strict.ByteString)) result -> Either Strict.Text y
527525instance
528− ( SListI results
526+ ( SListI result
529527 , IsRecord y ys
530− , AllZip FromColumnValue results ys
531− ) => FromRow results y where
528+ , AllZip FromColumnValue result ys
529+ ) => FromRow result y where
532530 fromRow
533− = to . SOP . Z . htrans (Proxy @FromColumnValue) (I . fromColumnValue)
531+ = fmap fromRecord
532+ . hsequence'
533+ . htrans (Proxy @FromColumnValue) fromColumnValue
534534
535535-- | `Only` is a 1-tuple type, useful for encoding a single parameter with
536536-- `toParams` or decoding a single value with `fromRow`.