Skip to content

Commit c87390c

Browse files
committed
derive foreign key from the table #37
1 parent bb02cd1 commit c87390c

3 files changed

Lines changed: 40 additions & 16 deletions

File tree

src/Opaleye/Internal/Schema.hs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,25 @@ import Opaleye.PGTypes
1717
import Data.Profunctor (Profunctor, dimap, lmap)
1818
import Data.Profunctor.Product as PP
1919

20+
import Data.Monoid
21+
2022
import qualified Data.Profunctor.Product.Default as D
2123

2224
class PGType a where
2325
data SchemaOptions a
24-
pgTypeName :: a -> String
25-
pgTypeOptions :: SchemaOptions a -> String
26+
pgColumnDefinition :: SchemaOptions a -> String
27+
defaultOptions :: SchemaOptions a
2628

2729
instance PGType PGInt8 where
28-
data SchemaOptions PGInt8 = NoIntOptions | Autogenerated
29-
pgTypeName = const "numeric"
30-
pgTypeOptions _ = "SERIAL"
30+
data SchemaOptions PGInt8 = NoIntOptions
31+
pgColumnDefinition _ = "SERIAL"
32+
defaultOptions = NoIntOptions
3133

3234
instance PGType PGText where
33-
data SchemaOptions PGText = NoOptions
34-
pgTypeName = const "varchar"
35-
pgTypeOptions _ = "(256)"
35+
data SchemaOptions PGText = Length Int | Unspecified
36+
pgColumnDefinition (Length x) = "varchar (" <> show x <> ")"
37+
pgColumnDefinition _ = "text"
38+
defaultOptions = Unspecified
3639

3740
data TableSchema = TableSchema String [UntypedColumn]
3841

@@ -54,8 +57,27 @@ tableSchema (discardSchema -> (tableName, (IT.TableProperties _ (View tableColum
5457
extractor d = ([d], ())
5558
(columns, ()) = pm extractor tableColumns
5659

60+
data ForeignKey = ForeignKey [String] [String]
61+
62+
foreignKey ::
63+
forall from from' to to' fk.
64+
(D.Default SchemaMaker fk fk) =>
65+
IT.Table from' from -> (from -> fk) -> IT.Table to' to -> (to -> fk) -> ForeignKey
66+
foreignKey tableFrom selectSubsetFrom tableTo selectSubsetTo = let
67+
extractor (unUntypedColumn -> TM.TableColumn name' _) = ([name'], ())
68+
(snd . discardSchema -> (IT.TableProperties _ (View tableColsFrom))) = tableFrom
69+
(snd . discardSchema -> (IT.TableProperties _ (View tableColsTo))) = tableTo
70+
keyFrom = selectSubsetFrom tableColsFrom
71+
keyTo = selectSubsetTo tableColsTo
72+
s1 :: SchemaMaker fk fk
73+
s1 = D.def
74+
(SchemaMaker (PM.PackMap pm)) = s1
75+
(columnsFrom, ()) = pm extractor keyFrom
76+
(columnsTo, ()) = pm extractor keyTo
77+
in ForeignKey columnsFrom columnsTo
78+
5779
columnSchemaMaker :: SchemaMaker (TM.TableColumn any) b
58-
columnSchemaMaker = SchemaMaker (PM.PackMap (\f (TM.TableColumn x y z) -> f (UntypedColumn (TM.TableColumn x y z))))
80+
columnSchemaMaker = SchemaMaker (PM.PackMap (\f (TM.TableColumn x y) -> f (UntypedColumn (TM.TableColumn x y))))
5981

6082
instance D.Default SchemaMaker (TM.TableColumn a) (Column a) where
6183
def = columnSchemaMaker

src/Opaleye/Internal/TableMaker.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ newtype ColumnMaker columns columns' =
2828

2929
data TableColumn a = TableColumn {
3030
name :: String ,
31-
pgType :: String ,
32-
options :: String }
31+
columnDefinition :: String }
3332

3433
newtype TableProjector columns columns' = TableProjector (columns -> I.Identity columns')
3534

@@ -55,7 +54,7 @@ column = ColumnMaker
5554
-> fmap IC.Column (f s)))
5655

5756
tableProjector :: TableProjector (TableColumn a) (IC.Column a)
58-
tableProjector = TableProjector (\(TableColumn name' _ _) -> (I.Identity . IC.Column . HPQ.BaseTableAttrExpr) name')
57+
tableProjector = TableProjector (\(TableColumn name' _) -> (I.Identity . IC.Column . HPQ.BaseTableAttrExpr) name')
5958

6059
instance Default ViewColumnMaker String (C.Column a) where
6160
def = tableColumn

src/Opaleye/Table.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,22 @@ queryTable :: (D.Default TM.ColumnMaker columns columns, D.Default TM.TableProje
4343
Table a tableColumns -> Q.Query columns
4444
queryTable = queryTableExplicit D.def D.def
4545

46+
required' :: S.PGType a => S.SchemaOptions a -> String -> TableProperties (Column a) (TM.TableColumn a)
47+
required' schemaOptions columnName = T.TableProperties
48+
(T.required columnName)
49+
(View (TM.TableColumn columnName (S.pgColumnDefinition schemaOptions) ))
50+
4651
-- | 'required' is for columns which are not 'optional'. You must
4752
-- provide them on writes.
4853
required :: S.PGType a => String -> TableProperties (Column a) (TM.TableColumn a)
49-
required columnName = T.TableProperties
50-
(T.required columnName)
51-
(View (TM.TableColumn columnName "" ""))
54+
required = required' S.defaultOptions
5255

5356
-- | 'optional' is for columns that you can omit on writes, such as
5457
-- columns which have defaults or which are SERIAL.
5558
optional :: S.PGType a => String -> TableProperties (Maybe (Column a)) (TM.TableColumn a)
5659
optional columnName = T.TableProperties
5760
(T.optional columnName)
58-
(View (TM.TableColumn columnName "" ""))
61+
(View (TM.TableColumn columnName ""))
5962

6063
-- * Explicit versions
6164

0 commit comments

Comments
 (0)