mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-19 13:31:43 +03:00
9ef603360c
Co-authored-by: Vamshi Surabhi <vamshi@hasura.io> Co-authored-by: Vladimir Ciobanu <admin@cvlad.info> Co-authored-by: Antoine Leblanc <antoine@hasura.io> Co-authored-by: Stylish Haskell Bot <stylish-haskell@users.noreply.github.com> GitOrigin-RevId: 9d631878037637f3ed2994b5d0525efd978f7b8f
48 lines
1.9 KiB
Haskell
48 lines
1.9 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 Hasura.Prelude
|
||
|
||
import qualified Data.HashMap.Strict as M
|
||
import qualified Data.Sequence as Seq
|
||
import qualified Data.Sequence.NonEmpty as NESeq
|
||
|
||
|
||
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), 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 $ M.toList (_fkColumnMapping @b foreignKey)
|
||
(primaryKey, enumValues) <- M.lookup (_fkForeignTable foreignKey) enumTables
|
||
guard (_pkColumns primaryKey == foreignColumn NESeq.:<|| Seq.Empty)
|
||
pure (localColumn, EnumReference (_fkForeignTable foreignKey) enumValues)
|