1{-# language DataKinds #-}
2{-# language EmptyCase #-}
3{-# language FlexibleContexts #-}
5{-# language LambdaCase #-}
6{-# language NamedFieldPuns #-}
7{-# language StandaloneKindSignatures #-}
9module Rel8.Schema.Context.Nullify
10 ( Nullifiability(..), NonNullifiability(..), nullifiableOrNot, absurd
11 , Nullifiable, nullifiability
12 , guarder, nullifier, unnullifier
18import Data.Bool ( bool )
19import Data.Functor.Identity ( Identity( Identity ) )
20import Data.Kind ( Constraint, Type )
21import Data.Monoid ( getFirst )
22import Prelude hiding ( null )
25import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
28import Rel8.Aggregate ( Aggregate( Aggregate ), foldInputs, mapInputs )
29import Rel8.Expr ( Expr )
30import Rel8.Expr.Bool ( boolExpr )
31import Rel8.Expr.Null ( nullify, unsafeUnnullify )
32import Rel8.Expr.Opaleye ( fromPrimExpr, toPrimExpr )
33import Rel8.Kind.Context ( SContext(..) )
34import Rel8.Schema.Field ( Field )
35import qualified Rel8.Schema.Kind as K
36import Rel8.Schema.Name ( Name( Name ) )
37import Rel8.Schema.Null ( Nullify, Nullity( Null, NotNull ) )
38import Rel8.Schema.Result ( Result )
39import Rel8.Schema.Spec ( Spec(..) )
42type Nullifiability :: K.Context -> Type
43data Nullifiability context where
44 NAggregate :: Nullifiability Aggregate
45 NExpr :: Nullifiability Expr
46 NName :: Nullifiability Name
49type Nullifiable :: K.Context -> Constraint
50class Nullifiable context where
51 nullifiability :: Nullifiability context
54instance Nullifiable Aggregate where
55 nullifiability = NAggregate
58instance Nullifiable Expr where
59 nullifiability = NExpr
62instance Nullifiable Name where
63 nullifiability = NName
66type NonNullifiability :: K.Context -> Type
67data NonNullifiability context where
68 NField :: NonNullifiability (Field table)
69 NResult :: NonNullifiability Result
74 -> Either (NonNullifiability context) (Nullifiability context)
75nullifiableOrNot = \case
76 SAggregate -> Right NAggregate
80 SResult -> Left NResult
83absurd :: Nullifiability context -> NonNullifiability context -> a
94 -> (Expr tag -> Expr Bool)
98 SAggregate -> \tag _ isNonNull (Aggregate a) ->
100 mtag = foldInputs (\_ -> pure . fromPrimExpr) tag
101 run = maybe id (sguard . isNonNull) (getFirst mtag)
103 mapInputs (toPrimExpr . run . fromPrimExpr) $
106 SExpr -> \tag _ isNonNull a -> sguard (isNonNull tag) a
107 SField -> \_ _ _ field -> field
108 SName -> \_ _ _ name -> name
109 SResult -> \(Identity tag) isNonNull _ (Identity a) ->
110 Identity (bool Nothing a (isNonNull tag))
114 => Nullifiability context
117 -> context (Nullify a)
119 NAggregate -> \Spec {nullity} (Aggregate a) ->
120 Aggregate $ snullify nullity <$> a
121 NExpr -> \Spec {nullity} a -> snullify nullity a
122 NName -> \_ (Name a) -> Name a
126 => Nullifiability context
128 -> context (Nullify a)
131 NAggregate -> \Spec {nullity} (Aggregate a) ->
132 Aggregate $ sunnullify nullity <$> a
133 NExpr -> \Spec {nullity} a -> sunnullify nullity a
134 NName -> \_ (Name a) -> Name a
137sguard :: Expr Bool -> Expr (Maybe a) -> Expr (Maybe a)
138sguard condition a = boolExpr null a condition
140 null = fromPrimExpr $ Opaleye.ConstExpr Opaleye.NullLit
143snullify :: Nullity a -> Expr a -> Expr (Nullify a)
144snullify nullity a = case nullity of
149sunnullify :: Nullity a -> Expr (Nullify a) -> Expr a
150sunnullify nullity a = case nullity of
152 NotNull -> unsafeUnnullify a
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list