mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-16 18:42:30 +03:00
187bf385fc
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5094 GitOrigin-RevId: 3342e571d3574a4d94fe3bfedb60f332b8c10853
49 lines
2.1 KiB
Haskell
49 lines
2.1 KiB
Haskell
-- | Types and functions for interacting with and manipulating SQL enums represented by
|
||
-- /single-column tables/, __not__ native Postgres enum types. Native enum types in Postgres are
|
||
-- difficult to change, so we discourage their use, but we might add support for native enum types
|
||
-- in the future.
|
||
module Hasura.RQL.DDL.Schema.Enum
|
||
( -- * Re-exports from "Hasura.RQL.Types.Column"
|
||
EnumReference (..),
|
||
EnumValues,
|
||
EnumValueInfo (..),
|
||
EnumValue (..),
|
||
|
||
-- * Loading table info
|
||
resolveEnumReferences,
|
||
)
|
||
where
|
||
|
||
import Data.HashMap.Strict qualified as M
|
||
import Data.HashMap.Strict.NonEmpty qualified as NEHashMap
|
||
import Data.Sequence qualified as Seq
|
||
import Data.Sequence.NonEmpty qualified as NESeq
|
||
import Hasura.Prelude
|
||
import Hasura.RQL.Types.Backend
|
||
import Hasura.RQL.Types.Column
|
||
import Hasura.RQL.Types.Table
|
||
|
||
-- | Given a map of enum tables, computes all enum references implied by the given set of foreign
|
||
-- keys. A foreign key constitutes an enum reference iff the following conditions hold:
|
||
--
|
||
-- 1. The key only includes a single column.
|
||
-- 2. The referenced column is the table’s primary key.
|
||
-- 3. The referenced table is, in fact, an enum table.
|
||
resolveEnumReferences ::
|
||
forall b.
|
||
Backend b =>
|
||
HashMap (TableName b) (PrimaryKey b (Column b), TableConfig b, EnumValues) ->
|
||
HashSet (ForeignKey b) ->
|
||
HashMap (Column b) (NonEmpty (EnumReference b))
|
||
resolveEnumReferences enumTables =
|
||
M.fromListWith (<>) . map (fmap (:| [])) . mapMaybe resolveEnumReference . toList
|
||
where
|
||
resolveEnumReference :: ForeignKey b -> Maybe (Column b, EnumReference b)
|
||
resolveEnumReference foreignKey = do
|
||
[(localColumn, foreignColumn)] <- pure $ NEHashMap.toList (_fkColumnMapping @b foreignKey)
|
||
let foreignKeyTableName = _fkForeignTable foreignKey
|
||
(primaryKey, tConfig, enumValues) <- M.lookup foreignKeyTableName enumTables
|
||
let tableCustomName = _tcCustomName tConfig
|
||
guard (_pkColumns primaryKey == foreignColumn NESeq.:<|| Seq.Empty)
|
||
pure (localColumn, EnumReference foreignKeyTableName enumValues tableCustomName)
|