hasql-th-0.4.1: src/library/Hasql/TH/Extraction/Exp.hs
module Hasql.TH.Extraction.Exp where
import qualified Hasql.Decoders as Decoders
import qualified Hasql.Encoders as Encoders
import qualified Hasql.TH.Construction.Exp as Exp
import qualified Hasql.TH.Extraction.InputTypeList as InputTypeList
import qualified Hasql.TH.Extraction.OutputTypeList as OutputTypeList
import qualified Hasql.TH.Extraction.PrimitiveType as PrimitiveType
import Hasql.TH.Prelude
import Language.Haskell.TH
import qualified PostgresqlSyntax.Ast as Ast
import qualified PostgresqlSyntax.Rendering as Rendering
undecodedStatement :: (Exp -> Exp) -> Ast.PreparableStmt -> Either Text Exp
undecodedStatement _decoderProj _ast =
let _sql = (Exp.byteString . Rendering.toByteString . Rendering.preparableStmt) _ast
in do
_encoder <- paramsEncoder _ast
_rowDecoder <- rowDecoder _ast
return (Exp.statement _sql _encoder (_decoderProj _rowDecoder))
foldStatement :: Ast.PreparableStmt -> Either Text Exp
foldStatement _ast =
let _sql = (Exp.byteString . Rendering.toByteString . Rendering.preparableStmt) _ast
in do
_encoder <- paramsEncoder _ast
_rowDecoder <- rowDecoder _ast
return (Exp.foldStatement _sql _encoder _rowDecoder)
paramsEncoder :: Ast.PreparableStmt -> Either Text Exp
paramsEncoder a = do
b <- InputTypeList.preparableStmt a
c <- traverse paramEncoder b
return (Exp.contrazip c)
rowDecoder :: Ast.PreparableStmt -> Either Text Exp
rowDecoder a = do
b <- OutputTypeList.preparableStmt a
c <- traverse columnDecoder b
return (Exp.cozip c)
paramEncoder :: Ast.Typename -> Either Text Exp
paramEncoder =
byTypename
(\a b -> valueEncoder a & fmap (Exp.unidimensionalParamEncoder b))
(\a b c d -> valueEncoder a & fmap (Exp.multidimensionalParamEncoder b c d))
columnDecoder :: Ast.Typename -> Either Text Exp
columnDecoder =
byTypename
(\a b -> valueDecoder a & fmap (Exp.unidimensionalColumnDecoder b))
(\a b c d -> valueDecoder a & fmap (Exp.multidimensionalColumnDecoder b c d))
byTypename :: (PrimitiveType.PrimitiveType -> Bool -> Either Text Exp) -> (PrimitiveType.PrimitiveType -> Bool -> Int -> Bool -> Either Text Exp) -> Ast.Typename -> Either Text Exp
byTypename unidimensional multidimensional (Ast.Typename a b c d) =
if a
then Left "SETOF is not supported"
else do
e <- PrimitiveType.simpleTypename b
case d of
Nothing -> unidimensional e c
Just (f, g) -> case f of
Ast.BoundsTypenameArrayDimensions h -> multidimensional e c (length h) g
Ast.ExplicitTypenameArrayDimensions _ -> multidimensional e c 1 g
valueEncoder :: PrimitiveType.PrimitiveType -> Either Text Exp
valueEncoder =
Right . VarE . \case
PrimitiveType.BoolPrimitiveType -> 'Encoders.bool
PrimitiveType.Int2PrimitiveType -> 'Encoders.int2
PrimitiveType.Int4PrimitiveType -> 'Encoders.int4
PrimitiveType.Int8PrimitiveType -> 'Encoders.int8
PrimitiveType.Float4PrimitiveType -> 'Encoders.float4
PrimitiveType.Float8PrimitiveType -> 'Encoders.float8
PrimitiveType.NumericPrimitiveType -> 'Encoders.numeric
PrimitiveType.CharPrimitiveType -> 'Encoders.char
PrimitiveType.TextPrimitiveType -> 'Encoders.text
PrimitiveType.ByteaPrimitiveType -> 'Encoders.bytea
PrimitiveType.DatePrimitiveType -> 'Encoders.date
PrimitiveType.TimestampPrimitiveType -> 'Encoders.timestamp
PrimitiveType.TimestamptzPrimitiveType -> 'Encoders.timestamptz
PrimitiveType.TimePrimitiveType -> 'Encoders.time
PrimitiveType.TimetzPrimitiveType -> 'Encoders.timetz
PrimitiveType.IntervalPrimitiveType -> 'Encoders.interval
PrimitiveType.UuidPrimitiveType -> 'Encoders.uuid
PrimitiveType.InetPrimitiveType -> 'Encoders.inet
PrimitiveType.JsonPrimitiveType -> 'Encoders.json
PrimitiveType.JsonbPrimitiveType -> 'Encoders.jsonb
valueDecoder :: PrimitiveType.PrimitiveType -> Either Text Exp
valueDecoder =
Right . VarE . \case
PrimitiveType.BoolPrimitiveType -> 'Decoders.bool
PrimitiveType.Int2PrimitiveType -> 'Decoders.int2
PrimitiveType.Int4PrimitiveType -> 'Decoders.int4
PrimitiveType.Int8PrimitiveType -> 'Decoders.int8
PrimitiveType.Float4PrimitiveType -> 'Decoders.float4
PrimitiveType.Float8PrimitiveType -> 'Decoders.float8
PrimitiveType.NumericPrimitiveType -> 'Decoders.numeric
PrimitiveType.CharPrimitiveType -> 'Decoders.char
PrimitiveType.TextPrimitiveType -> 'Decoders.text
PrimitiveType.ByteaPrimitiveType -> 'Decoders.bytea
PrimitiveType.DatePrimitiveType -> 'Decoders.date
PrimitiveType.TimestampPrimitiveType -> 'Decoders.timestamp
PrimitiveType.TimestamptzPrimitiveType -> 'Decoders.timestamptz
PrimitiveType.TimePrimitiveType -> 'Decoders.time
PrimitiveType.TimetzPrimitiveType -> 'Decoders.timetz
PrimitiveType.IntervalPrimitiveType -> 'Decoders.interval
PrimitiveType.UuidPrimitiveType -> 'Decoders.uuid
PrimitiveType.InetPrimitiveType -> 'Decoders.inet
PrimitiveType.JsonPrimitiveType -> 'Decoders.json
PrimitiveType.JsonbPrimitiveType -> 'Decoders.jsonb