module Hasura.RQL.DDL.QueryTags ( SetQueryTagsConfig, runSetQueryTagsConfig, ) where import Control.Lens import Data.Aeson import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap import Data.Text.Extended (toTxt, (<<>)) import Hasura.Base.Error import Hasura.EncJSON import Hasura.Prelude import Hasura.QueryTags.Types import Hasura.RQL.Types.Backend import Hasura.RQL.Types.BackendTag import Hasura.RQL.Types.BackendType import Hasura.RQL.Types.Common import Hasura.RQL.Types.Metadata import Hasura.RQL.Types.Metadata.Object import Hasura.RQL.Types.SchemaCache.Build import Hasura.SQL.AnyBackend qualified as AB data SetQueryTagsConfig = SetQueryTagsConfig { SetQueryTagsConfig -> SourceName _sqtSourceName :: SourceName, SetQueryTagsConfig -> QueryTagsConfig _sqtConfig :: QueryTagsConfig } deriving stock ((forall x. SetQueryTagsConfig -> Rep SetQueryTagsConfig x) -> (forall x. Rep SetQueryTagsConfig x -> SetQueryTagsConfig) -> Generic SetQueryTagsConfig forall x. Rep SetQueryTagsConfig x -> SetQueryTagsConfig forall x. SetQueryTagsConfig -> Rep SetQueryTagsConfig x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. SetQueryTagsConfig -> Rep SetQueryTagsConfig x from :: forall x. SetQueryTagsConfig -> Rep SetQueryTagsConfig x $cto :: forall x. Rep SetQueryTagsConfig x -> SetQueryTagsConfig to :: forall x. Rep SetQueryTagsConfig x -> SetQueryTagsConfig Generic) instance ToJSON SetQueryTagsConfig where toJSON :: SetQueryTagsConfig -> Value toJSON = Options -> SetQueryTagsConfig -> Value forall a. (Generic a, GToJSON' Value Zero (Rep a)) => Options -> a -> Value genericToJSON Options hasuraJSON {omitNothingFields :: Bool omitNothingFields = Bool True} toEncoding :: SetQueryTagsConfig -> Encoding toEncoding = Options -> SetQueryTagsConfig -> Encoding forall a. (Generic a, GToJSON' Encoding Zero (Rep a)) => Options -> a -> Encoding genericToEncoding Options hasuraJSON {omitNothingFields :: Bool omitNothingFields = Bool True} instance FromJSON SetQueryTagsConfig where parseJSON :: Value -> Parser SetQueryTagsConfig parseJSON = String -> (Object -> Parser SetQueryTagsConfig) -> Value -> Parser SetQueryTagsConfig forall a. String -> (Object -> Parser a) -> Value -> Parser a withObject String "SetQueryTagsConfig" ((Object -> Parser SetQueryTagsConfig) -> Value -> Parser SetQueryTagsConfig) -> (Object -> Parser SetQueryTagsConfig) -> Value -> Parser SetQueryTagsConfig forall a b. (a -> b) -> a -> b $ \Object o -> do SourceName sourceName <- Object o Object -> Key -> Parser SourceName forall a. FromJSON a => Object -> Key -> Parser a .: Key "source_name" QueryTagsConfig queryTagsConfig <- Value -> Parser QueryTagsConfig forall a. FromJSON a => Value -> Parser a parseJSON (Value -> Parser QueryTagsConfig) -> Value -> Parser QueryTagsConfig forall a b. (a -> b) -> a -> b $ Object -> Value Object Object o SetQueryTagsConfig -> Parser SetQueryTagsConfig forall a. a -> Parser a forall (f :: * -> *) a. Applicative f => a -> f a pure (SetQueryTagsConfig -> Parser SetQueryTagsConfig) -> SetQueryTagsConfig -> Parser SetQueryTagsConfig forall a b. (a -> b) -> a -> b $ SourceName -> QueryTagsConfig -> SetQueryTagsConfig SetQueryTagsConfig SourceName sourceName QueryTagsConfig queryTagsConfig runSetQueryTagsConfig :: (MonadError QErr m, MetadataM m, CacheRWM m) => SetQueryTagsConfig -> m EncJSON runSetQueryTagsConfig :: forall (m :: * -> *). (MonadError QErr m, MetadataM m, CacheRWM m) => SetQueryTagsConfig -> m EncJSON runSetQueryTagsConfig (SetQueryTagsConfig SourceName sourceName QueryTagsConfig queryTagsConfig) = do Metadata oldMetadata <- m Metadata forall (m :: * -> *). MetadataM m => m Metadata getMetadata case SourceName -> InsOrdHashMap SourceName BackendSourceMetadata -> Maybe BackendSourceMetadata forall k v. (Eq k, Hashable k) => k -> InsOrdHashMap k v -> Maybe v InsOrdHashMap.lookup SourceName sourceName (Metadata -> InsOrdHashMap SourceName BackendSourceMetadata _metaSources Metadata oldMetadata) of Maybe BackendSourceMetadata Nothing -> Code -> Text -> m EncJSON forall (m :: * -> *) a. QErrM m => Code -> Text -> m a throw400 Code NotExists (Text -> m EncJSON) -> Text -> m EncJSON forall a b. (a -> b) -> a -> b $ Text "source with name " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> SourceName sourceName SourceName -> Text -> Text forall t. ToTxt t => t -> Text -> Text <<> Text " does not exist" Just BackendSourceMetadata exists -> do let backendType :: BackendType backendType = BackendSourceMetadata -> BackendType getBackendType BackendSourceMetadata exists case BackendType backendType of Postgres PostgresKind _ -> AnyBackend SourceMetadata -> Maybe QueryTagsConfig -> m EncJSON setQueryTagsConfigInMetadata (BackendSourceMetadata -> AnyBackend SourceMetadata unBackendSourceMetadata BackendSourceMetadata exists) (QueryTagsConfig -> Maybe QueryTagsConfig forall a. a -> Maybe a Just QueryTagsConfig queryTagsConfig) BackendType _ -> BackendType -> m EncJSON forall {m :: * -> *} {a} {a}. (MonadError QErr m, ToTxt a) => a -> m a queryTagsNotSupported BackendType backendType where getBackendType :: BackendSourceMetadata -> BackendType getBackendType :: BackendSourceMetadata -> BackendType getBackendType BackendSourceMetadata exists = forall (c :: BackendType -> Constraint) (i :: BackendType -> *) r. AllBackendsSatisfy c => AnyBackend i -> (forall (b :: BackendType). c b => i b -> r) -> r AB.dispatchAnyBackend @Backend (BackendSourceMetadata -> AnyBackend SourceMetadata unBackendSourceMetadata BackendSourceMetadata exists) ((forall (b :: BackendType). Backend b => SourceMetadata b -> BackendType) -> BackendType) -> (forall (b :: BackendType). Backend b => SourceMetadata b -> BackendType) -> BackendType forall a b. (a -> b) -> a -> b $ \(SourceMetadata b _sourceMetadata :: SourceMetadata b) -> BackendTag b -> BackendType forall (b :: BackendType). BackendTag b -> BackendType reify (BackendTag b -> BackendType) -> BackendTag b -> BackendType forall a b. (a -> b) -> a -> b $ forall (b :: BackendType). HasTag b => BackendTag b backendTag @b setQueryTagsConfigInMetadata :: AnyBackend SourceMetadata -> Maybe QueryTagsConfig -> m EncJSON setQueryTagsConfigInMetadata AnyBackend SourceMetadata exists Maybe QueryTagsConfig qtConfig = do let metadataModifier :: MetadataModifier metadataModifier = AnyBackend SourceMetadata -> Maybe QueryTagsConfig -> MetadataModifier queryTagsMetadataModifier AnyBackend SourceMetadata exists Maybe QueryTagsConfig qtConfig MetadataObjId -> MetadataModifier -> m () forall (m :: * -> *). (QErrM m, CacheRWM m, MetadataM m) => MetadataObjId -> MetadataModifier -> m () buildSchemaCacheFor (SourceName -> MetadataObjId MOSource SourceName sourceName) MetadataModifier metadataModifier EncJSON -> m EncJSON forall a. a -> m a forall (m :: * -> *) a. Monad m => a -> m a return EncJSON successMsg queryTagsNotSupported :: a -> m a queryTagsNotSupported a backendType = Code -> Text -> m a forall (m :: * -> *) a. QErrM m => Code -> Text -> m a throw400 Code NotSupported (Text -> m a) -> Text -> m a forall a b. (a -> b) -> a -> b $ a -> Text forall a. ToTxt a => a -> Text toTxt a backendType Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " sources do not support query-tags yet" queryTagsMetadataModifier :: AnyBackend SourceMetadata -> Maybe QueryTagsConfig -> MetadataModifier queryTagsMetadataModifier AnyBackend SourceMetadata exists Maybe QueryTagsConfig qtConfig = forall (c :: BackendType -> Constraint) (i :: BackendType -> *) r. AllBackendsSatisfy c => AnyBackend i -> (forall (b :: BackendType). c b => i b -> r) -> r AB.dispatchAnyBackend @Backend AnyBackend SourceMetadata exists ((forall (b :: BackendType). Backend b => SourceMetadata b -> MetadataModifier) -> MetadataModifier) -> (forall (b :: BackendType). Backend b => SourceMetadata b -> MetadataModifier) -> MetadataModifier forall a b. (a -> b) -> a -> b $ \(SourceMetadata b _sourceMetadata :: SourceMetadata b) -> (Metadata -> Metadata) -> MetadataModifier MetadataModifier ((Metadata -> Metadata) -> MetadataModifier) -> (Metadata -> Metadata) -> MetadataModifier forall a b. (a -> b) -> a -> b $ (InsOrdHashMap SourceName BackendSourceMetadata -> Identity (InsOrdHashMap SourceName BackendSourceMetadata)) -> Metadata -> Identity Metadata Lens' Metadata (InsOrdHashMap SourceName BackendSourceMetadata) metaSources ((InsOrdHashMap SourceName BackendSourceMetadata -> Identity (InsOrdHashMap SourceName BackendSourceMetadata)) -> Metadata -> Identity Metadata) -> ((Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> InsOrdHashMap SourceName BackendSourceMetadata -> Identity (InsOrdHashMap SourceName BackendSourceMetadata)) -> (Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> Metadata -> Identity Metadata forall b c a. (b -> c) -> (a -> b) -> a -> c . Index (InsOrdHashMap SourceName BackendSourceMetadata) -> Traversal' (InsOrdHashMap SourceName BackendSourceMetadata) (IxValue (InsOrdHashMap SourceName BackendSourceMetadata)) forall m. Ixed m => Index m -> Traversal' m (IxValue m) ix Index (InsOrdHashMap SourceName BackendSourceMetadata) SourceName sourceName ((BackendSourceMetadata -> Identity BackendSourceMetadata) -> InsOrdHashMap SourceName BackendSourceMetadata -> Identity (InsOrdHashMap SourceName BackendSourceMetadata)) -> ((Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> BackendSourceMetadata -> Identity BackendSourceMetadata) -> (Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> InsOrdHashMap SourceName BackendSourceMetadata -> Identity (InsOrdHashMap SourceName BackendSourceMetadata) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall (b :: BackendType). Backend b => Prism' BackendSourceMetadata (SourceMetadata b) toSourceMetadata @b ((SourceMetadata b -> Identity (SourceMetadata b)) -> BackendSourceMetadata -> Identity BackendSourceMetadata) -> ((Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> SourceMetadata b -> Identity (SourceMetadata b)) -> (Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> BackendSourceMetadata -> Identity BackendSourceMetadata forall b c a. (b -> c) -> (a -> b) -> a -> c . (Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> SourceMetadata b -> Identity (SourceMetadata b) forall (b :: BackendType) (f :: * -> *). Functor f => (Maybe QueryTagsConfig -> f (Maybe QueryTagsConfig)) -> SourceMetadata b -> f (SourceMetadata b) smQueryTags ((Maybe QueryTagsConfig -> Identity (Maybe QueryTagsConfig)) -> Metadata -> Identity Metadata) -> Maybe QueryTagsConfig -> Metadata -> Metadata forall s t a b. ASetter s t a b -> b -> s -> t .~ Maybe QueryTagsConfig qtConfig