on 93168af help sign in
rel8/src/Rel8/Type/Array.hs
63 lines 1.8 kB history raw
1{-# language GADTs #-}
2{-# language NamedFieldPuns #-}
3{-# language OverloadedStrings #-}
5module Rel8.Type.Array
6 ( array
7 , listTypeInformation
8 , nonEmptyTypeInformation
9 )
10where
12-- base
13import Data.Foldable ( toList )
14import Data.List.NonEmpty ( NonEmpty, nonEmpty )
15import Prelude hiding ( null, repeat, zipWith )
17-- hasql
18import qualified Hasql.Decoders as Hasql
20-- opaleye
21import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
23-- rel8
24import Rel8.Schema.Nullability ( Nullability( Nullable, NonNullable ) )
25import Rel8.Type.Information ( TypeInformation(..), parseTypeInformation )
28array :: Foldable f
29 => TypeInformation a -> f Opaleye.PrimExpr -> Opaleye.PrimExpr
30array TypeInformation {typeName} =
31 Opaleye.UnExpr (Opaleye.UnOpOther "ROW") .
32 Opaleye.CastExpr (typeName <> "[]") .
33 Opaleye.ArrayExpr . toList
36listTypeInformation :: ()
37 => Nullability a ma
38 -> TypeInformation a
39 -> TypeInformation [ma]
40listTypeInformation nullability info = TypeInformation
41 { decode = row $ case nullability of
42 Nullable -> Hasql.listArray (Hasql.nullable decode)
43 NonNullable -> Hasql.listArray (Hasql.nonNullable decode)
44 , encode = case nullability of
45 Nullable -> array info . fmap (maybe null encode)
46 NonNullable -> array info . fmap encode
47 , typeName = "record"
48 }
49 where
50 TypeInformation {encode, decode} = info
51 row = Hasql.composite . Hasql.field . Hasql.nonNullable
52 null = Opaleye.ConstExpr Opaleye.NullLit
55nonEmptyTypeInformation :: ()
56 => Nullability a ma
57 -> TypeInformation a
58 -> TypeInformation (NonEmpty ma)
59nonEmptyTypeInformation nullability =
60 parseTypeInformation parse toList . listTypeInformation nullability
61 where
62 parse = maybe (Left message) Right . nonEmpty
63 message = "failed to decode NonEmptyList: got empty list"