refactor: remove colFK from Column
This commit is contained in:
committed by
Steve Chavez
parent
6670a3214b
commit
0f6a13191c
@@ -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 (==','))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user