hasql-th-0.4.0.21: library/Hasql/TH/Extraction/PlaceholderTypeMap.hs
{-# OPTIONS_GHC -Wno-missing-signatures #-}
module Hasql.TH.Extraction.PlaceholderTypeMap where
import qualified Data.IntMap.Strict as IntMap
import Hasql.TH.Extraction.ChildExprList (ChildExpr (..))
import qualified Hasql.TH.Extraction.ChildExprList as ChildExprList
import Hasql.TH.Prelude hiding (union)
import PostgresqlSyntax.Ast
preparableStmt :: PreparableStmt -> Either Text (IntMap Typename)
preparableStmt = childExprList . ChildExprList.preparableStmt
childExprList :: [ChildExpr] -> Either Text (IntMap Typename)
childExprList = foldM union IntMap.empty <=< traverse childExpr
union :: IntMap Typename -> IntMap Typename -> Either Text (IntMap Typename)
union a b = IntMap.mergeWithKey merge (fmap Right) (fmap Right) a b & sequence
where
merge index a b =
if a == b
then Just (Right a)
else Just (Left ("Placeholder $" <> (fromString . show) index <> " has conflicting type annotations"))
childExpr :: ChildExpr -> Either Text (IntMap Typename)
childExpr = \case
AChildExpr a -> aExpr a
BChildExpr a -> bExpr a
CChildExpr a -> cExpr a
aExpr = \case
CExprAExpr a -> cExpr a
TypecastAExpr a b -> castedAExpr b a
a -> childExprList (ChildExprList.aChildExpr a)
bExpr = \case
CExprBExpr a -> cExpr a
TypecastBExpr a b -> castedBExpr b a
a -> childExprList (ChildExprList.bChildExpr a)
cExpr = \case
ParamCExpr a _ -> Left ("Placeholder $" <> (fromString . show) a <> " misses an explicit typecast")
a -> childExprList (ChildExprList.cChildExpr a)
castedAExpr a = \case
CExprAExpr b -> castedCExpr a b
TypecastAExpr b c -> castedAExpr c b
b -> aExpr b
castedBExpr a = \case
CExprBExpr b -> castedCExpr a b
TypecastBExpr b c -> castedBExpr c b
b -> bExpr b
castedCExpr a = \case
ParamCExpr b _ -> Right (IntMap.singleton b a)
InParensCExpr b _ -> castedAExpr a b
b -> cExpr b