mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-20 22:11:45 +03:00
2152911e24
GitOrigin-RevId: 0dd10f1ccd338b1cf382ebff59b6ee7f209d39a1
155 lines
5.2 KiB
Haskell
155 lines
5.2 KiB
Haskell
module Hasura.RQL.DDL.QueryCollection
|
|
( runCreateCollection
|
|
, runDropCollection
|
|
, runAddQueryToCollection
|
|
, runDropQueryFromCollection
|
|
, runAddCollectionToAllowlist
|
|
, runDropCollectionFromAllowlist
|
|
, fetchAllCollections
|
|
, fetchAllowlist
|
|
, module Hasura.RQL.Types.QueryCollection
|
|
) where
|
|
|
|
import Hasura.Prelude
|
|
|
|
import qualified Data.HashMap.Strict.InsOrd as OMap
|
|
import qualified Data.HashSet.InsOrd as HSIns
|
|
|
|
import Data.List.Extended (duplicates)
|
|
import Data.Text.Extended
|
|
import Data.Text.NonEmpty
|
|
|
|
import Hasura.Base.Error
|
|
import Hasura.EncJSON
|
|
import Hasura.RQL.Types
|
|
import Hasura.RQL.Types.QueryCollection
|
|
import Hasura.Session
|
|
|
|
|
|
addCollectionP2
|
|
:: (QErrM m)
|
|
=> CollectionDef -> m ()
|
|
addCollectionP2 (CollectionDef queryList) =
|
|
withPathK "queries" $
|
|
unless (null duplicateNames) $ throw400 NotSupported $
|
|
"found duplicate query names "
|
|
<> dquoteList (unNonEmptyText . unQueryName <$> toList duplicateNames)
|
|
where
|
|
duplicateNames = duplicates $ map _lqName queryList
|
|
|
|
runCreateCollection
|
|
:: (QErrM m, CacheRWM m, MetadataM m)
|
|
=> CreateCollection -> m EncJSON
|
|
runCreateCollection cc = do
|
|
collDetM <- getCollectionDefM collName
|
|
withPathK "name" $
|
|
onJust collDetM $ const $ throw400 AlreadyExists $
|
|
"query collection with name " <> collName <<> " already exists"
|
|
withPathK "definition" $ addCollectionP2 def
|
|
withNewInconsistentObjsCheck
|
|
$ buildSchemaCache
|
|
$ MetadataModifier
|
|
$ metaQueryCollections %~ OMap.insert collName cc
|
|
return successMsg
|
|
where
|
|
CreateCollection collName def _ = cc
|
|
|
|
runAddQueryToCollection
|
|
:: (CacheRWM m, MonadError QErr m, MetadataM m)
|
|
=> AddQueryToCollection -> m EncJSON
|
|
runAddQueryToCollection (AddQueryToCollection collName queryName query) = do
|
|
(CreateCollection _ (CollectionDef qList) comment) <- getCollectionDef collName
|
|
let queryExists = flip any qList $ \q -> _lqName q == queryName
|
|
|
|
when queryExists $ throw400 AlreadyExists $ "query with name "
|
|
<> queryName <<> " already exists in collection " <>> collName
|
|
let collDef = CollectionDef $ qList <> pure listQ
|
|
withNewInconsistentObjsCheck
|
|
$ buildSchemaCache
|
|
$ MetadataModifier
|
|
$ metaQueryCollections
|
|
%~ OMap.insert collName (CreateCollection collName collDef comment)
|
|
return successMsg
|
|
where
|
|
listQ = ListedQuery queryName query
|
|
|
|
runDropCollection
|
|
:: (MonadError QErr m, MetadataM m, CacheRWM m)
|
|
=> DropCollection -> m EncJSON
|
|
runDropCollection (DropCollection collName cascade) = do
|
|
allowlistModifier <- withPathK "collection" $ do
|
|
void $ getCollectionDef collName
|
|
allowlist <- fetchAllowlist
|
|
if collName `elem` allowlist && not cascade then
|
|
throw400 DependencyError $ "query collection with name "
|
|
<> collName <<> " is present in allowlist; cannot proceed to drop"
|
|
else
|
|
pure $ metaAllowlist %~ HSIns.delete (CollectionReq collName)
|
|
|
|
withNewInconsistentObjsCheck
|
|
$ buildSchemaCache
|
|
$ MetadataModifier
|
|
$ allowlistModifier . (metaQueryCollections %~ OMap.delete collName)
|
|
|
|
pure successMsg
|
|
|
|
runDropQueryFromCollection
|
|
:: (CacheRWM m, MonadError QErr m, MetadataM m)
|
|
=> DropQueryFromCollection -> m EncJSON
|
|
runDropQueryFromCollection (DropQueryFromCollection collName queryName) = do
|
|
CreateCollection _ (CollectionDef qList) _ <- getCollectionDef collName
|
|
let queryExists = flip any qList $ \q -> _lqName q == queryName
|
|
unless queryExists $ throw400 NotFound $ "query with name "
|
|
<> queryName <<> " not found in collection " <>> collName
|
|
|
|
withNewInconsistentObjsCheck
|
|
$ buildSchemaCache
|
|
$ MetadataModifier
|
|
$ metaQueryCollections.ix collName.ccDefinition.cdQueries
|
|
%~ filter ((/=) queryName . _lqName)
|
|
pure successMsg
|
|
|
|
runAddCollectionToAllowlist
|
|
:: (MonadError QErr m, MetadataM m, CacheRWM m)
|
|
=> CollectionReq -> m EncJSON
|
|
runAddCollectionToAllowlist req@(CollectionReq collName) = do
|
|
void $ withPathK "collection" $ getCollectionDef collName
|
|
withNewInconsistentObjsCheck
|
|
$ buildSchemaCache
|
|
$ MetadataModifier
|
|
$ metaAllowlist %~ HSIns.insert req
|
|
pure successMsg
|
|
|
|
runDropCollectionFromAllowlist
|
|
:: (UserInfoM m, MonadError QErr m, MetadataM m, CacheRWM m)
|
|
=> CollectionReq -> m EncJSON
|
|
runDropCollectionFromAllowlist req@(CollectionReq collName) = do
|
|
void $ withPathK "collection" $ getCollectionDef collName
|
|
withNewInconsistentObjsCheck
|
|
$ buildSchemaCache
|
|
$ MetadataModifier
|
|
$ metaAllowlist %~ HSIns.delete req
|
|
return successMsg
|
|
|
|
getCollectionDef
|
|
:: (QErrM m, MetadataM m)
|
|
=> CollectionName -> m CreateCollection
|
|
getCollectionDef collName = do
|
|
detM <- getCollectionDefM collName
|
|
onNothing detM $ throw400 NotExists $
|
|
"query collection with name " <> collName <<> " does not exists"
|
|
|
|
getCollectionDefM
|
|
:: (QErrM m, MetadataM m)
|
|
=> CollectionName -> m (Maybe CreateCollection)
|
|
getCollectionDefM collName =
|
|
OMap.lookup collName <$> fetchAllCollections
|
|
|
|
fetchAllCollections :: MetadataM m => m QueryCollections
|
|
fetchAllCollections =
|
|
_metaQueryCollections <$> getMetadata
|
|
|
|
fetchAllowlist :: MetadataM m => m [CollectionName]
|
|
fetchAllowlist =
|
|
(map _crCollection . toList . _metaAllowlist) <$> getMetadata
|