1{-# language DataKinds #-}
2{-# language FlexibleContexts #-}
3{-# language FlexibleInstances #-}
4{-# language InstanceSigs #-}
5{-# language LambdaCase #-}
6{-# language MultiParamTypeClasses #-}
7{-# language NamedFieldPuns #-}
8{-# language ScopedTypeVariables #-}
9{-# language StandaloneKindSignatures #-}
10{-# language TypeApplications #-}
11{-# language TypeFamilies #-}
13module Rel8.Schema.Context.Nullify
14 ( Nullifiable( ConstrainTag, encodeTag, decodeTag, nullifier, unnullifier )
15 , HNullifiable( HConstrainTag, hencodeTag, hdecodeTag, hnullifier, hunnullifier )
21import Data.Kind ( Constraint, Type )
22import GHC.TypeLits ( KnownSymbol )
23import Prelude hiding ( null )
26import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye
34import Rel8.Expr ( Expr, Col(..) )
35import Rel8.Expr.Bool ( boolExpr )
36import Rel8.Expr.Null ( nullify, unsafeUnnullify )
37import Rel8.Expr.Opaleye ( fromPrimExpr, toPrimExpr )
38import Rel8.Kind.Necessity ( Necessity( Required ) )
39import Rel8.Schema.Context ( Interpretation )
40import qualified Rel8.Schema.Kind as K
41import Rel8.Schema.Name ( Name( Name ), Col(..) )
42import Rel8.Schema.Nullability
44 , Nullability( Nullable, NonNullable )
47import Rel8.Schema.Dict ( Dict( Dict ) )
48import Rel8.Schema.Spec ( Spec( Spec ), SSpec(..) )
49import Rel8.Schema.Spec.ConstrainDBType
51 , dbTypeDict, dbTypeNullability, fromNullabilityDict
53import Rel8.Table.Tag ( Tag(..), Taggable, fromAggregate, fromExpr, fromName )
56type Nullifiable :: K.Context -> Constraint
57class Interpretation context => Nullifiable context where
58 type ConstrainTag context :: Type -> Constraint
59 type ConstrainTag _context = DefaultConstrainTag
62 ( Sql (ConstrainTag context) a
67 -> Col context ('Spec labels 'Required a)
70 ( Sql (ConstrainTag context) a
74 => Col context ('Spec labels 'Required a)
79 -> (Expr a -> Expr Bool)
80 -> SSpec ('Spec labels necessity x)
81 -> Col context ('Spec labels necessity x)
82 -> Col context ('Spec labels necessity (Nullify x))
85 => SSpec ('Spec labels necessity x)
86 -> Col context ('Spec labels necessity (Nullify x))
87 -> Col context ('Spec labels necessity x)
90instance Nullifiable Aggregate where
91 encodeTag Tag {aggregator, expr} =
92 Aggregation $ unsafeMakeAggregate toPrimExpr fromPrimExpr aggregator expr
94 decodeTag (Aggregation aggregate) = fromAggregate aggregate
96 nullifier Tag {expr} test SSpec {nullability} (Aggregation aggregate) =
98 mapInputs (toPrimExpr . runTag nullability condition . fromPrimExpr) $
99 runTag nullability condition <$> aggregate
101 condition = test expr
103 unnullifier SSpec {nullability} (Aggregation aggregate) =
104 Aggregation $ unnull nullability <$> aggregate
106 {-# INLINABLE encodeTag #-}
107 {-# INLINABLE decodeTag #-}
108 {-# INLINABLE nullifier #-}
109 {-# INLINABLE unnullifier #-}
112instance Nullifiable Expr where
113 encodeTag Tag {expr} = DB expr
114 decodeTag (DB a) = fromExpr a
115 nullifier Tag {expr} test SSpec {nullability} (DB a) =
116 DB $ runTag nullability (test expr) a
117 unnullifier SSpec {nullability} (DB a) = DB $ unnull nullability a
119 {-# INLINABLE encodeTag #-}
120 {-# INLINABLE decodeTag #-}
121 {-# INLINABLE nullifier #-}
122 {-# INLINABLE unnullifier #-}
125instance Nullifiable Name where
126 encodeTag Tag {name = Name name} = NameCol name
127 decodeTag (NameCol name) = fromName (Name name)
128 nullifier _ _ _ (NameCol name) = NameCol name
129 unnullifier _ (NameCol name) = NameCol name
131 {-# INLINABLE encodeTag #-}
132 {-# INLINABLE decodeTag #-}
133 {-# INLINABLE nullifier #-}
134 {-# INLINABLE unnullifier #-}
137runTag :: Nullability a -> Expr Bool -> Expr a -> Expr (Nullify a)
138runTag nullability tag a = case nullability of
139 Nullable -> boolExpr null a tag
140 NonNullable -> boolExpr null (nullify a) tag
142 null = fromPrimExpr $ Opaleye.ConstExpr Opaleye.NullLit
145unnull :: Nullability a -> Expr (Nullify a) -> Expr a
146unnull nullability a = case nullability of
148 NonNullable -> unsafeUnnullify a
151type HNullifiable :: K.HContext -> Constraint
152class HNullifiable context where
153 type HConstrainTag context :: Type -> Constraint
154 type HConstrainTag _context = DefaultConstrainTag
156 hencodeTag :: (Sql (HConstrainTag context) a, KnownSymbol label, Taggable a)
158 -> context ('Spec labels 'Required a)
160 hdecodeTag :: (Sql (HConstrainTag context) a, KnownSymbol label, Taggable a)
161 => context ('Spec labels 'Required a)
166 -> (Expr a -> Expr Bool)
167 -> SSpec ('Spec labels necessity x)
168 -> context ('Spec labels necessity x)
169 -> context ('Spec labels necessity (Nullify x))
172 => SSpec ('Spec labels necessity x)
173 -> context ('Spec labels necessity (Nullify x))
174 -> context ('Spec labels necessity x)
177instance Nullifiable context => HNullifiable (Col context) where
178 type HConstrainTag (Col context) = ConstrainTag context
179 hencodeTag = encodeTag
180 hdecodeTag = decodeTag
181 hnullifier = nullifier
182 hunnullifier = unnullifier
185instance HNullifiable (Dict (ConstrainDBType constraint)) where
186 type HConstrainTag (Dict (ConstrainDBType constraint)) = constraint
191 hnullifier _ _ SSpec {} dict = case dbTypeDict dict of
192 Dict -> case dbTypeNullability dict of
196 hunnullifier SSpec {nullability} dict = case dbTypeDict dict of
197 Dict -> case nullability of
199 NonNullable -> case dbTypeNullability dict of
200 Nullable -> fromNullabilityDict nullability Dict
203type DefaultConstrainTag :: Type -> Constraint
204class DefaultConstrainTag a
205instance 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