1{-# language DataKinds #-}
2{-# language DisambiguateRecordFields #-}
3{-# language FlexibleContexts #-}
4{-# language FlexibleInstances #-}
5{-# language FunctionalDependencies #-}
6{-# language StandaloneKindSignatures #-}
7{-# language TypeFamilies #-}
8{-# language UndecidableInstances #-}
11 ( Table (Columns, Context)
12 , toColumns, fromColumns
18import Data.Functor.Identity ( Identity( Identity ) )
19import Data.Kind ( Constraint, Type )
23import Rel8.Aggregate ( Aggregate )
24import Rel8.Expr ( Expr )
25import Rel8.Opaque ( Opaque, Opaque1 )
26import Rel8.Schema.Context ( Col(..), Insertion(..), Name(..) )
27import Rel8.Schema.Context.Label ( Labelable, labeler, unlabeler )
28import Rel8.Schema.HTable ( HTable, hfield, hspecs, htabulate, htabulateA )
29import Rel8.Schema.HTable.Identity ( HIdentity(..) )
30import Rel8.Schema.HTable.Label ( HLabel, hlabel, hunlabel )
31import Rel8.Schema.HTable.Pair ( HPair(..) )
32import Rel8.Schema.HTable.Quartet ( HQuartet(..) )
33import Rel8.Schema.HTable.Quintet ( HQuintet(..) )
34import Rel8.Schema.HTable.Trio ( HTrio(..) )
35import Rel8.Schema.HTable.Type ( HType( HType ) )
36import qualified Rel8.Schema.Kind as K
37import Rel8.Schema.Nullability ( Sql )
38import Rel8.Schema.Spec ( SSpec( SSpec ), KnownSpec )
39import Rel8.Type ( DBType )
42-- | @Table@s are one of the foundational elements of Rel8, and describe data
43-- types that have a finite number of columns. Each of these columns contains
44-- data under a shared context, and contexts describe how to interpret the
45-- metadata about a column to a particular Haskell type. In Rel8, we have
46-- contexts for expressions (the 'Expr' context), aggregations (the 'Aggregate'
47-- context), insert values (the 'Insert' contex), among others.
49-- In typical usage of Rel8 you don't need to derive instances of 'Table'
50-- yourself, as anything that's an instance of 'Rel8able' is always a 'Table'.
51type Table :: K.Context -> Type -> Constraint
52class (HTable (Columns a), context ~ Context a) => Table context a | a -> context where
53 -- | The 'HTable' functor that describes the schema of this table.
54 type Columns a :: K.HTable
56 -- | The common context that all columns use as an interpretation.
57 type Context a :: K.Context
59 toColumns :: a -> Columns a (Col (Context a))
60 fromColumns :: Columns a (Col (Context a)) -> a
63-- | Any 'HTable' is also a 'Table'.
64instance HTable t => Table context (t (Col context)) where
65 type Columns (t (Col context)) = t
66 type Context (t (Col context)) = context
72-- | Any context is trivially a table.
73instance KnownSpec spec => Table context (Col context spec) where
74 type Columns (Col context spec) = HIdentity spec
75 type Context (Col context spec) = context
78 fromColumns = unHIdentity
81instance Table Expr a => Table Aggregate (Aggregate a) where
82 type Columns (Aggregate a) = Columns a
83 type Context (Aggregate a) = Aggregate
85 toColumns a = htabulate $ \field -> case hfield hspecs field of
86 SSpec {} -> Aggregation $ unDB . (`hfield` field) . toColumns <$> a
87 fromColumns as = fmap fromColumns $ htabulateA $ \field ->
88 case hfield as field of
89 Aggregation a -> DB <$> a
92instance Sql DBType a => Table Expr (Expr a) where
93 type Columns (Expr a) = HType a
94 type Context (Expr a) = Expr
96 toColumns a = HType (DB a)
97 fromColumns (HType (DB a)) = a
100instance Sql DBType a => Table Identity (Identity a) where
101 type Columns (Identity a) = HType a
102 type Context (Identity a) = Identity
104 toColumns (Identity a) = HType (Result a)
105 fromColumns (HType (Result a)) = Identity a
108instance Sql DBType a => Table Insertion (Insertion a) where
109 type Columns (Insertion a) = HType a
110 type Context (Insertion a) = Insertion
112 toColumns (Insertion a) = HType (RequiredInsert a)
113 fromColumns (HType (RequiredInsert a)) = Insertion a
116instance Sql DBType a => Table Name (Name a) where
117 type Columns (Name a) = HType a
118 type Context (Name a) = Name
120 toColumns (Name a) = HType (NameCol a)
121 fromColumns (HType (NameCol a)) = Name a
125 ( Table context a, Table context b
130 type Columns (a, b) =
132 (HLabel "fst" (Columns a))
133 (HLabel "snd" (Columns b))
134 type Context (a, b) = Context a
136 toColumns (a, b) = HPair
137 { hfst = hlabel labeler $ toColumns a
138 , hsnd = hlabel labeler $ toColumns b
140 fromColumns (HPair a b) =
141 ( fromColumns $ hunlabel unlabeler a
142 , fromColumns $ hunlabel unlabeler b
147 ( Table context a, Table context b, Table context c
149 ) => Table context (a, b, c)
151 type Columns (a, b, c) =
153 (HLabel "fst" (Columns a))
154 (HLabel "snd" (Columns b))
155 (HLabel "trd" (Columns c))
156 type Context (a, b, c) = Context a
158 toColumns (a, b, c) = HTrio
159 { hfst = hlabel labeler $ toColumns a
160 , hsnd = hlabel labeler $ toColumns b
161 , htrd = hlabel labeler $ toColumns c
163 fromColumns (HTrio a b c) =
164 ( fromColumns $ hunlabel unlabeler a
165 , fromColumns $ hunlabel unlabeler b
166 , fromColumns $ hunlabel unlabeler c
171 ( Table context a, Table context b, Table context c, Table context d
173 ) => Table context (a, b, c, d)
175 type Columns (a, b, c, d) =
177 (HLabel "fst" (Columns a))
178 (HLabel "snd" (Columns b))
179 (HLabel "trd" (Columns c))
180 (HLabel "frt" (Columns d))
181 type Context (a, b, c, d) = Context a
183 toColumns (a, b, c, d) = HQuartet
184 { hfst = hlabel labeler $ toColumns a
185 , hsnd = hlabel labeler $ toColumns b
186 , htrd = hlabel labeler $ toColumns c
187 , hfrt = hlabel labeler $ toColumns d
189 fromColumns (HQuartet a b c d) =
190 ( fromColumns $ hunlabel unlabeler a
191 , fromColumns $ hunlabel unlabeler b
192 , fromColumns $ hunlabel unlabeler c
193 , fromColumns $ hunlabel unlabeler d
198 ( Table context a, Table context b, Table context c, Table context d
201 ) => Table context (a, b, c, d, e)
203 type Columns (a, b, c, d, e) =
205 (HLabel "fst" (Columns a))
206 (HLabel "snd" (Columns b))
207 (HLabel "trd" (Columns c))
208 (HLabel "frt" (Columns d))
209 (HLabel "fft" (Columns e))
210 type Context (a, b, c, d, e) = Context a
212 toColumns (a, b, c, d, e) = HQuintet
213 { hfst = hlabel labeler $ toColumns a
214 , hsnd = hlabel labeler $ toColumns b
215 , htrd = hlabel labeler $ toColumns c
216 , hfrt = hlabel labeler $ toColumns d
217 , hfft = hlabel labeler $ toColumns e
219 fromColumns (HQuintet a b c d e) =
220 ( fromColumns $ hunlabel unlabeler a
221 , fromColumns $ hunlabel unlabeler b
222 , fromColumns $ hunlabel unlabeler c
223 , fromColumns $ hunlabel unlabeler d
224 , fromColumns $ hunlabel unlabeler e
228instance Table Expr Opaque where
229 type Columns Opaque = HType Opaque
230 type Context Opaque = Expr
232 fromColumns = error "opaque"
233 toColumns = error "opaque"
236instance Table context (Opaque1 context a) where
237 type Columns (Opaque1 context a) = HType Opaque
238 type Context (Opaque1 context a) = context
240 fromColumns = error "opaque"
241 toColumns = error "opaque"
244type Congruent :: Type -> Type -> Constraint
245class Columns a ~ Columns b => Congruent a b
246instance Columns a ~ Columns b => Congruent a b
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