module Hasura.RQL.DDL.Endpoint ( runCreateEndpoint, runDropEndpoint, dropEndpointInMetadata, ) where import Data.HashMap.Strict.InsOrd qualified as OMap import Data.Text.Extended import Hasura.Base.Error import Hasura.EncJSON import Hasura.Metadata.Class import Hasura.Prelude import Hasura.RQL.Types.Common import Hasura.RQL.Types.Endpoint import Hasura.RQL.Types.Metadata import Hasura.RQL.Types.Metadata.Object import Hasura.RQL.Types.SchemaCache.Build runCreateEndpoint :: ( CacheRWM m, MetadataM m, MonadMetadataStorageQueryAPI m ) => CreateEndpoint -> m EncJSON runCreateEndpoint :: CreateEndpoint -> m EncJSON runCreateEndpoint endpoint :: CreateEndpoint endpoint@EndpointMetadata {Maybe Text NonEmpty EndpointMethod EndpointUrl EndpointName EndpointDef QueryReference _ceComment :: forall query. EndpointMetadata query -> Maybe Text _ceDefinition :: forall query. EndpointMetadata query -> EndpointDef query _ceMethods :: forall query. EndpointMetadata query -> NonEmpty EndpointMethod _ceUrl :: forall query. EndpointMetadata query -> EndpointUrl _ceName :: forall query. EndpointMetadata query -> EndpointName _ceComment :: Maybe Text _ceDefinition :: EndpointDef QueryReference _ceMethods :: NonEmpty EndpointMethod _ceUrl :: EndpointUrl _ceName :: EndpointName ..} = do Endpoints endpointsMap <- Metadata -> Endpoints _metaRestEndpoints (Metadata -> Endpoints) -> m Metadata -> m Endpoints forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m Metadata forall (m :: * -> *). MetadataM m => m Metadata getMetadata EndpointName -> Endpoints -> Maybe CreateEndpoint forall k v. (Eq k, Hashable k) => k -> InsOrdHashMap k v -> Maybe v OMap.lookup EndpointName _ceName Endpoints endpointsMap Maybe CreateEndpoint -> (CreateEndpoint -> m Any) -> m () forall (t :: * -> *) (f :: * -> *) a b. (Foldable t, Applicative f) => t a -> (a -> f b) -> f () `for_` \CreateEndpoint _ -> Code -> Text -> m Any forall (m :: * -> *) a. QErrM m => Code -> Text -> m a throw400 Code AlreadyExists (Text -> m Any) -> Text -> m Any forall a b. (a -> b) -> a -> b $ Text "Endpoint with name: " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> EndpointName -> Text forall a. ToTxt a => a -> Text toTxt EndpointName _ceName Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " already exists" m () -> m () forall (m :: * -> *) a. (QErrM m, CacheRM m) => m a -> m a withNewInconsistentObjsCheck (m () -> m ()) -> m () -> m () forall a b. (a -> b) -> a -> b $ MetadataObjId -> MetadataModifier -> m () forall (m :: * -> *). (QErrM m, CacheRWM m, MetadataM m) => MetadataObjId -> MetadataModifier -> m () buildSchemaCacheFor (EndpointName -> MetadataObjId MOEndpoint EndpointName _ceName) (MetadataModifier -> m ()) -> MetadataModifier -> m () forall a b. (a -> b) -> a -> b $ (Metadata -> Metadata) -> MetadataModifier MetadataModifier ((Metadata -> Metadata) -> MetadataModifier) -> (Metadata -> Metadata) -> MetadataModifier forall a b. (a -> b) -> a -> b $ (Endpoints -> Identity Endpoints) -> Metadata -> Identity Metadata Lens' Metadata Endpoints metaRestEndpoints ((Endpoints -> Identity Endpoints) -> Metadata -> Identity Metadata) -> (Endpoints -> Endpoints) -> Metadata -> Metadata forall s t a b. ASetter s t a b -> (a -> b) -> s -> t %~ EndpointName -> CreateEndpoint -> Endpoints -> Endpoints forall k v. (Eq k, Hashable k) => k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v OMap.insert EndpointName _ceName CreateEndpoint endpoint EncJSON -> m EncJSON forall (m :: * -> *) a. Monad m => a -> m a return EncJSON successMsg runDropEndpoint :: ( CacheRWM m, MetadataM m, MonadMetadataStorageQueryAPI m ) => DropEndpoint -> m EncJSON runDropEndpoint :: DropEndpoint -> m EncJSON runDropEndpoint DropEndpoint {EndpointName _deName :: DropEndpoint -> EndpointName _deName :: EndpointName ..} = do EndpointName -> m () forall (m :: * -> *). (MetadataM m, MonadError QErr m) => EndpointName -> m () checkExists EndpointName _deName m () -> m () forall (m :: * -> *) a. (QErrM m, CacheRM m) => m a -> m a withNewInconsistentObjsCheck (m () -> m ()) -> m () -> m () forall a b. (a -> b) -> a -> b $ MetadataModifier -> m () forall (m :: * -> *). (MetadataM m, CacheRWM m) => MetadataModifier -> m () buildSchemaCache (MetadataModifier -> m ()) -> MetadataModifier -> m () forall a b. (a -> b) -> a -> b $ EndpointName -> MetadataModifier dropEndpointInMetadata EndpointName _deName EncJSON -> m EncJSON forall (m :: * -> *) a. Monad m => a -> m a return EncJSON successMsg dropEndpointInMetadata :: EndpointName -> MetadataModifier dropEndpointInMetadata :: EndpointName -> MetadataModifier dropEndpointInMetadata EndpointName name = (Metadata -> Metadata) -> MetadataModifier MetadataModifier ((Metadata -> Metadata) -> MetadataModifier) -> (Metadata -> Metadata) -> MetadataModifier forall a b. (a -> b) -> a -> b $ (Endpoints -> Identity Endpoints) -> Metadata -> Identity Metadata Lens' Metadata Endpoints metaRestEndpoints ((Endpoints -> Identity Endpoints) -> Metadata -> Identity Metadata) -> (Endpoints -> Endpoints) -> Metadata -> Metadata forall s t a b. ASetter s t a b -> (a -> b) -> s -> t %~ EndpointName -> Endpoints -> Endpoints forall k v. (Eq k, Hashable k) => k -> InsOrdHashMap k v -> InsOrdHashMap k v OMap.delete EndpointName name checkExists :: (MetadataM m, MonadError QErr m) => EndpointName -> m () checkExists :: EndpointName -> m () checkExists EndpointName name = do Endpoints endpointsMap <- Metadata -> Endpoints _metaRestEndpoints (Metadata -> Endpoints) -> m Metadata -> m Endpoints forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m Metadata forall (m :: * -> *). MetadataM m => m Metadata getMetadata m CreateEndpoint -> m () forall (f :: * -> *) a. Functor f => f a -> f () void (m CreateEndpoint -> m ()) -> m CreateEndpoint -> m () forall a b. (a -> b) -> a -> b $ Maybe CreateEndpoint -> m CreateEndpoint -> m CreateEndpoint forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a onNothing (EndpointName -> Endpoints -> Maybe CreateEndpoint forall k v. (Eq k, Hashable k) => k -> InsOrdHashMap k v -> Maybe v OMap.lookup EndpointName name Endpoints endpointsMap) (m CreateEndpoint -> m CreateEndpoint) -> m CreateEndpoint -> m CreateEndpoint forall a b. (a -> b) -> a -> b $ Code -> Text -> m CreateEndpoint forall (m :: * -> *) a. QErrM m => Code -> Text -> m a throw400 Code NotExists (Text -> m CreateEndpoint) -> Text -> m CreateEndpoint forall a b. (a -> b) -> a -> b $ Text "endpoint with name: " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> EndpointName -> Text forall a. ToTxt a => a -> Text toTxt EndpointName name Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " does not exist"