refactor: remove colFK from Column

This commit is contained in:
steve-chavez
2021-04-30 10:06:07 -05:00
committed by Steve Chavez
parent 6670a3214b
commit 0f6a13191c
4 changed files with 32 additions and 42 deletions
+2 -18
View File
@@ -51,7 +51,6 @@ import PostgREST.DbStructure.Proc (PgArg (..), PgType (..),
ProcVolatility (..), ProcVolatility (..),
ProcsMap, RetType (..)) ProcsMap, RetType (..))
import PostgREST.DbStructure.Relationship (Cardinality (..), import PostgREST.DbStructure.Relationship (Cardinality (..),
ForeignKey (..),
Junction (..), Junction (..),
PrimaryKey (..), PrimaryKey (..),
Relationship (..)) Relationship (..))
@@ -98,12 +97,11 @@ getDbStructure schemas extraSearchPath pgVer prepared = do
procs <- HT.statement schemas $ allProcs prepared procs <- HT.statement schemas $ allProcs prepared
let rels = addO2MRels . addM2MRels $ addViewM2ORels srcCols m2oRels let rels = addO2MRels . addM2MRels $ addViewM2ORels srcCols m2oRels
cols' = addForeignKeys rels cols
keys' = addViewPrimaryKeys srcCols keys keys' = addViewPrimaryKeys srcCols keys
return $ removeInternal schemas $ DbStructure { return $ removeInternal schemas $ DbStructure {
dbTables = tabs dbTables = tabs
, dbColumns = cols' , dbColumns = cols
, dbRelationships = rels , dbRelationships = rels
, dbPrimaryKeys = keys' , dbPrimaryKeys = keys'
, dbProcs = procs , dbProcs = procs
@@ -379,20 +377,6 @@ accessibleTables =
) )
order by relname |] order by relname |]
addForeignKeys :: [Relationship] -> [Column] -> [Column]
addForeignKeys rels = map addFk
where
addFk col = col { colFK = fk col }
fk col = find (lookupFn col) rels >>= relToFk col
lookupFn :: Column -> Relationship -> Bool
lookupFn c rel = case rel of
Relationship{relColumns=cs, relCardinality=M2O _} -> c `elem` cs
_ -> False
relToFk col Relationship{relColumns=cols, relForeignColumns=colsF} = do
pos <- L.elemIndex col cols
colF <- atMay colsF pos
return $ ForeignKey colF
{- {-
Adds Views M2O Relationships based on SourceColumns found, the logic is as follows: Adds Views M2O Relationships based on SourceColumns found, the logic is as follows:
@@ -675,7 +659,7 @@ columnFromRow :: [Table] ->
-> Maybe Column -> Maybe Column
columnFromRow tabs (s, t, n, desc, nul, typ, l, d, e) = buildColumn <$> table columnFromRow tabs (s, t, n, desc, nul, typ, l, d, e) = buildColumn <$> table
where where
buildColumn tbl = Column tbl n desc nul typ l d (parseEnum e) Nothing buildColumn tbl = Column tbl n desc nul typ l d (parseEnum e)
table = find (\tbl -> tableSchema tbl == s && tableName tbl == t) tabs table = find (\tbl -> tableSchema tbl == s && tableName tbl == t) tabs
parseEnum :: Maybe Text -> [Text] parseEnum :: Maybe Text -> [Text]
parseEnum = maybe [] (split (==',')) parseEnum = maybe [] (split (==','))
+1 -3
View File
@@ -3,7 +3,6 @@
module PostgREST.DbStructure.Relationship module PostgREST.DbStructure.Relationship
( Cardinality(..) ( Cardinality(..)
, ForeignKey(..)
, PrimaryKey(..) , PrimaryKey(..)
, Relationship(..) , Relationship(..)
, Junction(..) , Junction(..)
@@ -12,8 +11,7 @@ module PostgREST.DbStructure.Relationship
import qualified Data.Aeson as JSON import qualified Data.Aeson as JSON
import PostgREST.DbStructure.Table (Column (..), ForeignKey (..), import PostgREST.DbStructure.Table (Column (..), Table (..))
Table (..))
import Protolude import Protolude
-6
View File
@@ -3,7 +3,6 @@
module PostgREST.DbStructure.Table module PostgREST.DbStructure.Table
( Column(..) ( Column(..)
, ForeignKey(..)
, Table(..) , Table(..)
, tableQi , tableQi
) where ) where
@@ -34,10 +33,6 @@ instance Eq Table where
tableQi :: Table -> QualifiedIdentifier tableQi :: Table -> QualifiedIdentifier
tableQi Table{tableSchema=s, tableName=n} = QualifiedIdentifier s n tableQi Table{tableSchema=s, tableName=n} = QualifiedIdentifier s n
newtype ForeignKey = ForeignKey
{ fkCol :: Column }
deriving (Eq, Ord, Generic, JSON.ToJSON)
data Column = Column data Column = Column
{ colTable :: Table { colTable :: Table
, colName :: FieldName , colName :: FieldName
@@ -47,7 +42,6 @@ data Column = Column
, colMaxLen :: Maybe Int32 , colMaxLen :: Maybe Int32
, colDefault :: Maybe Text , colDefault :: Maybe Text
, colEnum :: [Text] , colEnum :: [Text]
, colFK :: Maybe ForeignKey
} }
deriving (Ord, Generic, JSON.ToJSON) deriving (Ord, Generic, JSON.ToJSON)
+29 -15
View File
@@ -2,6 +2,8 @@
Module : PostgREST.OpenAPI Module : PostgREST.OpenAPI
Description : Generates the OpenAPI output Description : Generates the OpenAPI output
-} -}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE RecordWildCards #-}
module PostgREST.OpenAPI (encode) where module PostgREST.OpenAPI (encode) where
@@ -27,10 +29,10 @@ import PostgREST.DbStructure (DbStructure (..),
tableCols, tablePKCols) tableCols, tablePKCols)
import PostgREST.DbStructure.Proc (PgArg (..), import PostgREST.DbStructure.Proc (PgArg (..),
ProcDescription (..)) ProcDescription (..))
import PostgREST.DbStructure.Relationship (PrimaryKey (..)) import PostgREST.DbStructure.Relationship (Cardinality (..),
import PostgREST.DbStructure.Table (Column (..), PrimaryKey (..),
ForeignKey (..), Relationship (..))
Table (..)) import PostgREST.DbStructure.Table (Column (..), Table (..))
import PostgREST.Version (docsVersion, prettyVersion) import PostgREST.Version (docsVersion, prettyVersion)
import PostgREST.ContentType import PostgREST.ContentType
@@ -42,6 +44,7 @@ encode :: AppConfig -> DbStructure -> [Table] -> Maybe Text -> HashMap.HashMap k
encode conf dbStructure tables schemaDescription procs = encode conf dbStructure tables schemaDescription procs =
JSON.encode $ JSON.encode $
postgrestSpec postgrestSpec
(dbRelationships dbStructure)
(concat $ HashMap.elems procs) (concat $ HashMap.elems procs)
(openApiTableInfo dbStructure <$> tables) (openApiTableInfo dbStructure <$> tables)
(proxyUri conf) (proxyUri conf)
@@ -64,27 +67,38 @@ toSwaggerType "real" = SwaggerNumber
toSwaggerType "double precision" = SwaggerNumber toSwaggerType "double precision" = SwaggerNumber
toSwaggerType _ = SwaggerString toSwaggerType _ = SwaggerString
makeTableDef :: [PrimaryKey] -> (Table, [Column], [Text]) -> (Text, Schema) makeTableDef :: [Relationship] -> [PrimaryKey] -> (Table, [Column], [Text]) -> (Text, Schema)
makeTableDef pks (t, cs, _) = makeTableDef rels pks (t, cs, _) =
let tn = tableName t in let tn = tableName t in
(tn, (mempty :: Schema) (tn, (mempty :: Schema)
& description .~ tableDescription t & description .~ tableDescription t
& type_ ?~ SwaggerObject & type_ ?~ SwaggerObject
& properties .~ fromList (fmap (makeProperty pks) cs) & properties .~ fromList (fmap (makeProperty rels pks) cs)
& required .~ fmap colName (filter (not . colNullable) cs)) & required .~ fmap colName (filter (not . colNullable) cs))
makeProperty :: [PrimaryKey] -> Column -> (Text, Referenced Schema) makeProperty :: [Relationship] -> [PrimaryKey] -> Column -> (Text, Referenced Schema)
makeProperty pks c = (colName c, Inline s) makeProperty rels pks c = (colName c, Inline s)
where where
e = if null $ colEnum c then Nothing else JSON.decode $ JSON.encode $ colEnum c e = if null $ colEnum c then Nothing else JSON.decode $ JSON.encode $ colEnum c
fk ForeignKey{fkCol=Column{colTable=Table{tableName=a}, colName=b}} = fk :: Maybe Text
T.intercalate "" ["This is a Foreign Key to `", a, ".", b, "`.<fk table='", a, "' column='", b, "'/>"] fk =
let
-- Finds the relationship that has a single column foreign key
rel = find (\case
Relationship{relColumns, relCardinality=M2O _} -> [c] == relColumns
_ -> False
) rels
fCol = colName <$> (headMay =<< (relForeignColumns <$> rel))
fTbl = tableName . relForeignTable <$> rel
fTblCol = (,) <$> fTbl <*> fCol
in
(\(a, b) -> T.intercalate "" ["This is a Foreign Key to `", a, ".", b, "`.<fk table='", a, "' column='", b, "'/>"]) <$> fTblCol
pk :: Bool pk :: Bool
pk = any (\p -> pkTable p == colTable c && pkName p == colName c) pks pk = any (\p -> pkTable p == colTable c && pkName p == colName c) pks
n = catMaybes n = catMaybes
[ Just "Note:" [ Just "Note:"
, if pk then Just "This is a Primary Key.<pk/>" else Nothing , if pk then Just "This is a Primary Key.<pk/>" else Nothing
, fk <$> colFK c , fk
] ]
d = d =
if length n > 1 then if length n > 1 then
@@ -294,8 +308,8 @@ escapeHostName "*6" = "0.0.0.0"
escapeHostName "!6" = "0.0.0.0" escapeHostName "!6" = "0.0.0.0"
escapeHostName h = h escapeHostName h = h
postgrestSpec :: [ProcDescription] -> [(Table, [Column], [Text])] -> (Text, Text, Integer, Text) -> Maybe Text -> [PrimaryKey] -> Swagger postgrestSpec :: [Relationship] -> [ProcDescription] -> [(Table, [Column], [Text])] -> (Text, Text, Integer, Text) -> Maybe Text -> [PrimaryKey] -> Swagger
postgrestSpec pds ti (s, h, p, b) sd pks = (mempty :: Swagger) postgrestSpec rels pds ti (s, h, p, b) sd pks = (mempty :: Swagger)
& basePath ?~ T.unpack b & basePath ?~ T.unpack b
& schemes ?~ [s'] & schemes ?~ [s']
& info .~ ((mempty :: Info) & info .~ ((mempty :: Info)
@@ -306,7 +320,7 @@ postgrestSpec pds ti (s, h, p, b) sd pks = (mempty :: Swagger)
& description ?~ "PostgREST Documentation" & description ?~ "PostgREST Documentation"
& url .~ URL ("https://postgrest.org/en/" <> docsVersion <> "/api.html")) & url .~ URL ("https://postgrest.org/en/" <> docsVersion <> "/api.html"))
& host .~ h' & host .~ h'
& definitions .~ fromList (makeTableDef pks <$> ti) & definitions .~ fromList (makeTableDef rels pks <$> ti)
& parameters .~ fromList (makeParamDefs ti) & parameters .~ fromList (makeParamDefs ti)
& paths .~ makePathItems pds ti & paths .~ makePathItems pds ti
& produces .~ makeMimeList [CTApplicationJSON, CTSingularJSON, CTTextCSV] & produces .~ makeMimeList [CTApplicationJSON, CTSingularJSON, CTTextCSV]