module Hasura.RQL.DDL.Schema.Enum
(
EnumReference (..),
EnumValues,
EnumValueInfo (..),
EnumValue (..),
resolveEnumReferences,
)
where
import Data.HashMap.Strict qualified as HashMap
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.Table.Cache (ForeignKey (..), PrimaryKey (..), TableConfig (..))
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 :: forall (b :: BackendType).
Backend b =>
HashMap
(TableName b) (PrimaryKey b (Column b), TableConfig b, EnumValues)
-> HashSet (ForeignKey b)
-> HashMap (Column b) (NonEmpty (EnumReference b))
resolveEnumReferences HashMap
(TableName b) (PrimaryKey b (Column b), TableConfig b, EnumValues)
enumTables =
(NonEmpty (EnumReference b)
-> NonEmpty (EnumReference b) -> NonEmpty (EnumReference b))
-> [(Column b, NonEmpty (EnumReference b))]
-> HashMap (Column b) (NonEmpty (EnumReference b))
forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> [(k, v)] -> HashMap k v
HashMap.fromListWith NonEmpty (EnumReference b)
-> NonEmpty (EnumReference b) -> NonEmpty (EnumReference b)
forall a. Semigroup a => a -> a -> a
(<>) ([(Column b, NonEmpty (EnumReference b))]
-> HashMap (Column b) (NonEmpty (EnumReference b)))
-> (HashSet (ForeignKey b)
-> [(Column b, NonEmpty (EnumReference b))])
-> HashSet (ForeignKey b)
-> HashMap (Column b) (NonEmpty (EnumReference b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Column b, EnumReference b)
-> (Column b, NonEmpty (EnumReference b)))
-> [(Column b, EnumReference b)]
-> [(Column b, NonEmpty (EnumReference b))]
forall a b. (a -> b) -> [a] -> [b]
map ((EnumReference b -> NonEmpty (EnumReference b))
-> (Column b, EnumReference b)
-> (Column b, NonEmpty (EnumReference b))
forall a b. (a -> b) -> (Column b, a) -> (Column b, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (EnumReference b -> [EnumReference b] -> NonEmpty (EnumReference b)
forall a. a -> [a] -> NonEmpty a
:| [])) ([(Column b, EnumReference b)]
-> [(Column b, NonEmpty (EnumReference b))])
-> (HashSet (ForeignKey b) -> [(Column b, EnumReference b)])
-> HashSet (ForeignKey b)
-> [(Column b, NonEmpty (EnumReference b))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ForeignKey b -> Maybe (Column b, EnumReference b))
-> [ForeignKey b] -> [(Column b, EnumReference b)]
forall a b. (a -> Maybe b) -> [a] -> [b]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe ForeignKey b -> Maybe (Column b, EnumReference b)
resolveEnumReference ([ForeignKey b] -> [(Column b, EnumReference b)])
-> (HashSet (ForeignKey b) -> [ForeignKey b])
-> HashSet (ForeignKey b)
-> [(Column b, EnumReference b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashSet (ForeignKey b) -> [ForeignKey b]
forall a. HashSet a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
where
resolveEnumReference :: ForeignKey b -> Maybe (Column b, EnumReference b)
resolveEnumReference :: ForeignKey b -> Maybe (Column b, EnumReference b)
resolveEnumReference ForeignKey b
foreignKey = do
[(Column b
localColumn, Column b
foreignColumn)] <- [(Column b, Column b)] -> Maybe [(Column b, Column b)]
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(Column b, Column b)] -> Maybe [(Column b, Column b)])
-> [(Column b, Column b)] -> Maybe [(Column b, Column b)]
forall a b. (a -> b) -> a -> b
$ NEHashMap (Column b) (Column b) -> [(Column b, Column b)]
forall k v. NEHashMap k v -> [(k, v)]
NEHashMap.toList (forall (b :: BackendType).
ForeignKey b -> NEHashMap (Column b) (Column b)
_fkColumnMapping @b ForeignKey b
foreignKey)
let foreignKeyTableName :: TableName b
foreignKeyTableName = ForeignKey b -> TableName b
forall (b :: BackendType). ForeignKey b -> TableName b
_fkForeignTable ForeignKey b
foreignKey
(PrimaryKey b (Column b)
primaryKey, TableConfig b
tConfig, EnumValues
enumValues) <- TableName b
-> HashMap
(TableName b) (PrimaryKey b (Column b), TableConfig b, EnumValues)
-> Maybe (PrimaryKey b (Column b), TableConfig b, EnumValues)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup TableName b
foreignKeyTableName HashMap
(TableName b) (PrimaryKey b (Column b), TableConfig b, EnumValues)
enumTables
let tableCustomName :: Maybe Name
tableCustomName = TableConfig b -> Maybe Name
forall (b :: BackendType). TableConfig b -> Maybe Name
_tcCustomName TableConfig b
tConfig
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (PrimaryKey b (Column b) -> NESeq (Column b)
forall (b :: BackendType) a. PrimaryKey b a -> NESeq a
_pkColumns PrimaryKey b (Column b)
primaryKey NESeq (Column b) -> NESeq (Column b) -> Bool
forall a. Eq a => a -> a -> Bool
== Column b
foreignColumn Column b -> Seq (Column b) -> NESeq (Column b)
forall a. a -> Seq a -> NESeq a
NESeq.:<|| Seq (Column b)
forall a. Seq a
Seq.Empty)
(Column b, EnumReference b) -> Maybe (Column b, EnumReference b)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Column b
localColumn, TableName b -> EnumValues -> Maybe Name -> EnumReference b
forall (b :: BackendType).
TableName b -> EnumValues -> Maybe Name -> EnumReference b
EnumReference TableName b
foreignKeyTableName EnumValues
enumValues Maybe Name
tableCustomName)