Skip to content

Commit

Permalink
ArrayField
Browse files Browse the repository at this point in the history
  • Loading branch information
echatav committed Sep 12, 2024
1 parent 6b790f2 commit e8b97a9
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
1 change: 0 additions & 1 deletion squeal-postgresql/src/Squeal/PostgreSQL/Session.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import Control.Monad (MonadPlus(..))
import Control.Monad.Base (MonadBase(..))
import Control.Monad.Fix (MonadFix(..))
import Control.Monad.Catch
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Morph
import Control.Monad.Reader
import Control.Monad.Trans.Control (MonadBaseControl(..), MonadTransControl(..))
Expand Down
37 changes: 37 additions & 0 deletions squeal-postgresql/src/Squeal/PostgreSQL/Session/Decode.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module Squeal.PostgreSQL.Session.Decode
, genericProductRow
, appendRows
, consRow
, ArrayField (..)
-- * Decoding Classes
, FromValue (..)
, FromField (..)
Expand Down Expand Up @@ -533,6 +534,42 @@ instance {-# OVERLAPPABLE #-} IsLabel fld (MaybeT (DecodeRow row) y)
fromLabel = MaybeT . decodeRow $ \(_ SOP.:* bs) ->
runDecodeRow (runMaybeT (fromLabel @fld)) bs

{- | Utility for decoding array fields in a `DecodeRow`,
accessed via overloaded labels.
-}
newtype ArrayField row y = ArrayField
{ runArrayField
:: StateT Strict.ByteString (Except Strict.Text) y
-> DecodeRow row [y]
}
instance {-# OVERLAPPING #-}
( KnownSymbol fld
, PG y ~ ty
, arr ~ 'NotNull ('PGvararray ('NotNull ty))
) => IsLabel fld (ArrayField (fld ::: arr ': row) y) where
fromLabel = ArrayField $ \yval ->
decodeRow $ \(SOP.K bytesMaybe SOP.:* _) -> do
let
flderr = mconcat
[ "field name: "
, "\"", fromString (symbolVal (SOP.Proxy @fld)), "\"; "
]
yarr
= devalue
. array
. dimensionArray replicateM
. valueArray
. revalue
$ yval
case bytesMaybe of
Nothing -> Left (flderr <> "encountered unexpected NULL")
Just bytes -> runExcept (evalStateT yarr bytes)
instance {-# OVERLAPPABLE #-} IsLabel fld (ArrayField row y)
=> IsLabel fld (ArrayField (field ': row) y) where
fromLabel = ArrayField $ \yval ->
decodeRow $ \(_ SOP.:* bytess) ->
runDecodeRow (runArrayField (fromLabel @fld) yval) bytess

-- | A `GenericRow` constraint to ensure that a Haskell type
-- is a record type,
-- has a `RowPG`,
Expand Down

0 comments on commit e8b97a9

Please sign in to comment.