mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-17 04:24:35 +03:00
306162f477
### Description This PR removes `ServerConfigCtx` and `HasServerConfigCtx`. Instead, it favours different approaches: - when the code was only using one field, it passes that field explicitly (usually `SQLGenCtx` or `CheckFeatureFlag`) - when the code was using several fields, but in only one function, it inlines - for the cache build, it introduces `CacheStaticConfig` and `CacheDynamicConfig`, which are subsets of `AppEnv` and `AppContext` respectively The main goal of this is to help with the modularization of the engine: as `ServerConfigCtx` had fields whose types were imported from several unrelated parts of the engine, using it tied together parts of the engine that should not be aware of one another (such as tying together `Hasura.LogicalModel` and `Hasura.GraphQL.Schema`). The bulk of this PR is a change to the cache build, as a follow up to #8509: instead of giving the entire `ServerConfigCtx` as a incremental rule argument, we only give the new `CacheDynamicConfig` struct, which has fewer fields. The other required fields, that were coming from the `AppEnv`, are now given via the `HasCacheStaticConfig` constraint, which is a "subset" of `HasAppEnv`. (Some further work could include moving `StringifyNumbers` out of `GraphQL.Schema.Options`, given how it is used all across the codebase, including in `RQL.DML`.) PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8513 GitOrigin-RevId: 818cbcd71494e3cd946b06adbb02ca328a8a298e
127 lines
3.6 KiB
Haskell
127 lines
3.6 KiB
Haskell
module Hasura.RQL.DML.Delete
|
|
( validateDeleteQWith,
|
|
validateDeleteQ,
|
|
AnnDelG (..),
|
|
AnnDel,
|
|
execDeleteQuery,
|
|
runDelete,
|
|
)
|
|
where
|
|
|
|
import Control.Monad.Trans.Control (MonadBaseControl)
|
|
import Data.Aeson
|
|
import Data.Sequence qualified as DS
|
|
import Database.PG.Query qualified as PG
|
|
import Hasura.Backends.Postgres.Connection
|
|
import Hasura.Backends.Postgres.Execute.Mutation
|
|
import Hasura.Backends.Postgres.SQL.DML qualified as S
|
|
import Hasura.Backends.Postgres.Translate.Returning
|
|
import Hasura.Backends.Postgres.Types.Table
|
|
import Hasura.Base.Error
|
|
import Hasura.EncJSON
|
|
import Hasura.Prelude
|
|
import Hasura.QueryTags
|
|
import Hasura.RQL.DML.Internal
|
|
import Hasura.RQL.DML.Types
|
|
import Hasura.RQL.IR.Delete
|
|
import Hasura.RQL.Types.Column
|
|
import Hasura.RQL.Types.Common
|
|
import Hasura.RQL.Types.Metadata
|
|
import Hasura.RQL.Types.SchemaCache
|
|
import Hasura.SQL.Backend
|
|
import Hasura.Session
|
|
import Hasura.Tracing qualified as Tracing
|
|
|
|
validateDeleteQWith ::
|
|
(UserInfoM m, QErrM m, TableInfoRM ('Postgres 'Vanilla) m) =>
|
|
SessionVariableBuilder m ->
|
|
(ColumnType ('Postgres 'Vanilla) -> Value -> m S.SQLExp) ->
|
|
DeleteQuery ->
|
|
m (AnnDel ('Postgres 'Vanilla))
|
|
validateDeleteQWith
|
|
sessVarBldr
|
|
prepValBldr
|
|
(DeleteQuery tableName _ rqlBE mRetCols) = do
|
|
tableInfo <- askTableInfoSource tableName
|
|
let coreInfo = _tiCoreInfo tableInfo
|
|
|
|
-- If table is view then check if it deletable
|
|
mutableView
|
|
tableName
|
|
viIsDeletable
|
|
(_tciViewInfo coreInfo)
|
|
"deletable"
|
|
|
|
-- Check if the role has delete permissions
|
|
delPerm <- askDelPermInfo tableInfo
|
|
|
|
-- Check if all dependent headers are present
|
|
validateHeaders $ dpiRequiredHeaders delPerm
|
|
|
|
-- Check if select is allowed
|
|
selPerm <-
|
|
modifyErr (<> selNecessaryMsg) $
|
|
askSelPermInfo tableInfo
|
|
|
|
let fieldInfoMap = _tciFieldInfoMap coreInfo
|
|
allCols = getCols fieldInfoMap
|
|
|
|
-- convert the returning cols into sql returing exp
|
|
mAnnRetCols <- forM mRetCols $ \retCols ->
|
|
withPathK "returning" $ checkRetCols fieldInfoMap selPerm retCols
|
|
|
|
-- convert the where clause
|
|
annSQLBoolExp <-
|
|
withPathK "where" $
|
|
convBoolExp fieldInfoMap selPerm rqlBE sessVarBldr fieldInfoMap (valueParserWithCollectableType prepValBldr)
|
|
|
|
resolvedDelFltr <-
|
|
convAnnBoolExpPartialSQL sessVarBldr $
|
|
dpiFilter delPerm
|
|
|
|
return $
|
|
AnnDel
|
|
tableName
|
|
(resolvedDelFltr, annSQLBoolExp)
|
|
(mkDefaultMutFlds mAnnRetCols)
|
|
allCols
|
|
Nothing
|
|
where
|
|
selNecessaryMsg =
|
|
"; \"delete\" is only allowed if the role "
|
|
<> "has \"select\" permission as \"where\" can't be used "
|
|
<> "without \"select\" permission on the table"
|
|
|
|
validateDeleteQ ::
|
|
(QErrM m, UserInfoM m, CacheRM m) =>
|
|
DeleteQuery ->
|
|
m (AnnDel ('Postgres 'Vanilla), DS.Seq PG.PrepArg)
|
|
validateDeleteQ query = do
|
|
let source = doSource query
|
|
tableCache :: TableCache ('Postgres 'Vanilla) <- fold <$> askTableCache source
|
|
flip runTableCacheRT tableCache $
|
|
runDMLP1T $
|
|
validateDeleteQWith sessVarFromCurrentSetting binRHSBuilder query
|
|
|
|
runDelete ::
|
|
forall m.
|
|
( QErrM m,
|
|
UserInfoM m,
|
|
CacheRM m,
|
|
MonadIO m,
|
|
Tracing.MonadTrace m,
|
|
MonadBaseControl IO m,
|
|
MetadataM m
|
|
) =>
|
|
SQLGenCtx ->
|
|
DeleteQuery ->
|
|
m EncJSON
|
|
runDelete sqlGen q = do
|
|
sourceConfig <- askSourceConfig @('Postgres 'Vanilla) (doSource q)
|
|
let strfyNum = stringifyNum sqlGen
|
|
userInfo <- askUserInfo
|
|
validateDeleteQ q
|
|
>>= runTxWithCtx (_pscExecCtx sourceConfig) (Tx PG.ReadWrite Nothing) LegacyRQLQuery
|
|
. flip runReaderT emptyQueryTagsComment
|
|
. execDeleteQuery strfyNum Nothing userInfo
|