1{-# language DataKinds #-}
2{-# language FlexibleContexts #-}
3{-# language FlexibleInstances #-}
4{-# language InstanceSigs #-}
5{-# language MultiParamTypeClasses #-}
6{-# language NamedFieldPuns #-}
7{-# language ScopedTypeVariables #-}
8{-# language StandaloneKindSignatures #-}
9{-# language TypeFamilies #-}
11module Rel8.Schema.Context.Nullify
12 ( Nullifiable( ConstrainTag, encodeTag, decodeTag, nullifier, unnullifier )
13 , HNullifiable( HConstrainTag, hencodeTag, hdecodeTag, hnullifier, hunnullifier )
19import Data.Kind ( Constraint, Type )
20import GHC.TypeLits ( KnownSymbol )
21import Prelude hiding ( null )
24import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
32import Rel8.Expr ( Expr, Col(..) )
33import Rel8.Expr.Bool ( boolExpr )
34import Rel8.Expr.Null ( nullify, unsafeUnnullify )
35import Rel8.Expr.Opaleye ( fromPrimExpr, toPrimExpr )
36import Rel8.Kind.Necessity ( Necessity( Required ) )
37import Rel8.Schema.Context ( Interpretation )
38import qualified Rel8.Schema.Kind as K
39import Rel8.Schema.Name ( Name( Name ), Col(..) )
40import Rel8.Schema.Null ( Nullify, Nullity( Null, NotNull ), Sql )
41import Rel8.Schema.Dict ( Dict( Dict ) )
42import Rel8.Schema.Spec ( Spec( Spec ), SSpec(..) )
43import Rel8.Schema.Spec.ConstrainDBType ( ConstrainDBType )
44import qualified Rel8.Schema.Spec.ConstrainDBType as ConstrainDBType
45import Rel8.Table.Tag ( Tag(..), Taggable, fromAggregate, fromExpr, fromName )
48type Nullifiable :: K.Context -> Constraint
49class Interpretation context => Nullifiable context where
50 type ConstrainTag context :: Type -> Constraint
51 type ConstrainTag _context = DefaultConstrainTag
54 ( Sql (ConstrainTag context) a
59 -> Col context ('Spec labels 'Required a)
62 ( Sql (ConstrainTag context) a
66 => Col context ('Spec labels 'Required a)
71 -> (Expr a -> Expr Bool)
72 -> SSpec ('Spec labels necessity x)
73 -> Col context ('Spec labels necessity x)
74 -> Col context ('Spec labels necessity (Nullify x))
77 => SSpec ('Spec labels necessity x)
78 -> Col context ('Spec labels necessity (Nullify x))
79 -> Col context ('Spec labels necessity x)
82instance Nullifiable Aggregate where
83 encodeTag Tag {aggregator, expr} =
84 Aggregation $ unsafeMakeAggregate toPrimExpr fromPrimExpr aggregator expr
86 decodeTag (Aggregation aggregate) = fromAggregate aggregate
88 nullifier Tag {expr} test SSpec {nullity} (Aggregation aggregate) =
90 mapInputs (toPrimExpr . runTag nullity condition . fromPrimExpr) $
91 runTag nullity condition <$> aggregate
95 unnullifier SSpec {nullity} (Aggregation aggregate) =
96 Aggregation $ unnull nullity <$> aggregate
98 {-# INLINABLE encodeTag #-}
99 {-# INLINABLE decodeTag #-}
100 {-# INLINABLE nullifier #-}
101 {-# INLINABLE unnullifier #-}
104instance Nullifiable Expr where
105 encodeTag Tag {expr} = DB expr
106 decodeTag (DB a) = fromExpr a
107 nullifier Tag {expr} test SSpec {nullity} (DB a) =
108 DB $ runTag nullity (test expr) a
109 unnullifier SSpec {nullity} (DB a) = DB $ unnull nullity a
111 {-# INLINABLE encodeTag #-}
112 {-# INLINABLE decodeTag #-}
113 {-# INLINABLE nullifier #-}
114 {-# INLINABLE unnullifier #-}
117instance Nullifiable Name where
118 encodeTag Tag {name = Name name} = NameCol name
119 decodeTag (NameCol name) = fromName (Name name)
120 nullifier _ _ _ (NameCol name) = NameCol name
121 unnullifier _ (NameCol name) = NameCol name
123 {-# INLINABLE encodeTag #-}
124 {-# INLINABLE decodeTag #-}
125 {-# INLINABLE nullifier #-}
126 {-# INLINABLE unnullifier #-}
129runTag :: Nullity a -> Expr Bool -> Expr a -> Expr (Nullify a)
130runTag nullity tag a = case nullity of
131 Null -> boolExpr null a tag
132 NotNull -> boolExpr null (nullify a) tag
134 null = fromPrimExpr $ Opaleye.ConstExpr Opaleye.NullLit
137unnull :: Nullity a -> Expr (Nullify a) -> Expr a
138unnull nullity a = case nullity of
140 NotNull -> unsafeUnnullify a
143type HNullifiable :: K.HContext -> Constraint
144class HNullifiable context where
145 type HConstrainTag context :: Type -> Constraint
146 type HConstrainTag _context = DefaultConstrainTag
148 hencodeTag :: (Sql (HConstrainTag context) a, KnownSymbol label, Taggable a)
150 -> context ('Spec labels 'Required a)
152 hdecodeTag :: (Sql (HConstrainTag context) a, KnownSymbol label, Taggable a)
153 => context ('Spec labels 'Required a)
158 -> (Expr a -> Expr Bool)
159 -> SSpec ('Spec labels necessity x)
160 -> context ('Spec labels necessity x)
161 -> context ('Spec labels necessity (Nullify x))
164 => SSpec ('Spec labels necessity x)
165 -> context ('Spec labels necessity (Nullify x))
166 -> context ('Spec labels necessity x)
169instance Nullifiable context => HNullifiable (Col context) where
170 type HConstrainTag (Col context) = ConstrainTag context
171 hencodeTag = encodeTag
172 hdecodeTag = decodeTag
173 hnullifier = nullifier
174 hunnullifier = unnullifier
177instance HNullifiable (Dict (ConstrainDBType constraint)) where
178 type HConstrainTag (Dict (ConstrainDBType constraint)) = constraint
182 hnullifier _ _ = ConstrainDBType.nullifier
183 hunnullifier = ConstrainDBType.unnullifier
186type DefaultConstrainTag :: Type -> Constraint
187class DefaultConstrainTag a
188instance DefaultConstrainTag 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