{-# LANGUAGE
ConstraintKinds
, DataKinds
, DeriveFunctor
, DeriveFoldable
, DeriveGeneric
, DeriveTraversable
, FlexibleContexts
, GADTs
, RankNTypes
#-}
module Squeal.PostgreSQL.Session.Statement
( Statement (..)
, query
, manipulation
, GenericParams
, GenericRow
) where
import Data.Functor.Contravariant
import Data.Profunctor (Profunctor (..))
import qualified Generics.SOP as SOP
import qualified Generics.SOP.Record as SOP
import Squeal.PostgreSQL.Manipulation
import Squeal.PostgreSQL.Session.Decode
import Squeal.PostgreSQL.Session.Encode
import Squeal.PostgreSQL.Session.Oid
import Squeal.PostgreSQL.Query
import Squeal.PostgreSQL.Render
data Statement db x y where
Manipulation
:: (SOP.All (OidOfNull db) params, SOP.SListI row)
=> EncodeParams db params x
-> DecodeRow row y
-> Manipulation '[] db params row
-> Statement db x y
Query
:: (SOP.All (OidOfNull db) params, SOP.SListI row)
=> EncodeParams db params x
-> DecodeRow row y
-> Query '[] '[] db params row
-> Statement db x y
instance Profunctor (Statement db) where
lmap f (Manipulation encode decode q) =
Manipulation (contramap f encode) decode q
lmap f (Query encode decode q) =
Query (contramap f encode) decode q
rmap f (Manipulation encode decode q) =
Manipulation encode (fmap f decode) q
rmap f (Query encode decode q) =
Query encode (fmap f decode) q
dimap f g (Manipulation encode decode q) =
Manipulation (contramap f encode) (fmap g decode) q
dimap f g (Query encode decode q) =
Query (contramap f encode) (fmap g decode) q
instance Functor (Statement db x) where fmap = rmap
instance RenderSQL (Statement db x y) where
renderSQL (Manipulation _ _ q) = renderSQL q
renderSQL (Query _ _ q) = renderSQL q
type GenericParams db params x xs =
( SOP.All (OidOfNull db) params
, SOP.IsProductType x xs
, SOP.AllZip (ToParam db) params xs )
type GenericRow row y ys =
( SOP.IsRecord y ys
, SOP.AllZip FromField row ys )
query ::
( GenericParams db params x xs
, GenericRow row y ys
) => Query '[] '[] db params row
-> Statement db x y
query = Query genericParams genericRow
manipulation ::
( GenericParams db params x xs
, GenericRow row y ys
) => Manipulation '[] db params row
-> Statement db x y
manipulation = Manipulation genericParams genericRow