Remove MonadTableInfo and MonadRole.

### Description

This PR moves Hasura-specific schema functions from `Hasura.GraphQL.Parser.Class` into `Hasura.GraphQL.Schema.Common`. It also removes the two corresponding monad aliases, and consequently harmonizes several parts of the code to use the same common constraint.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3947
GitOrigin-RevId: 40985a7d86da97a311bd480f9a57cc18c350c2a8
This commit is contained in:
Antoine Leblanc 2022-03-10 12:12:36 +00:00 committed by hasura-bot
parent 45af1d99f4
commit 80243a5c34
11 changed files with 89 additions and 121 deletions

View File

@ -13,7 +13,6 @@ module Hasura.Backends.MSSQL.Schema.IfMatched
) )
where where
import Data.Has
import Data.Text.Extended import Data.Text.Extended
import Hasura.Backends.MSSQL.Types.Insert import Hasura.Backends.MSSQL.Types.Insert
import Hasura.Backends.MSSQL.Types.Internal (ScalarType (..)) import Hasura.Backends.MSSQL.Types.Internal (ScalarType (..))
@ -59,7 +58,7 @@ ifMatchedFieldParser sourceName tableInfo = do
-- | Parse a @tablename_if_matched@ object. -- | Parse a @tablename_if_matched@ object.
ifMatchedObjectParser :: ifMatchedObjectParser ::
forall r m n. forall r m n.
(MonadBuildSchema 'MSSQL r m n) => MonadBuildSchema 'MSSQL r m n =>
SourceName -> SourceName ->
TableInfo 'MSSQL -> TableInfo 'MSSQL ->
m (Maybe (Parser 'Input n (IfMatched (UnpreparedValue 'MSSQL)))) m (Maybe (Parser 'Input n (IfMatched (UnpreparedValue 'MSSQL))))
@ -101,8 +100,8 @@ ifMatchedObjectParser sourceName tableInfo = runMaybeT do
-- Return Nothing if there's no column the current user has "select" -- Return Nothing if there's no column the current user has "select"
-- permissions for. -- permissions for.
tableInsertMatchColumnsEnum :: tableInsertMatchColumnsEnum ::
forall m n r. forall r m n.
(MonadSchema n m, MonadRole r m, MonadTableInfo r m, Has P.MkTypename r) => MonadBuildSchemaBase r m n =>
SourceName -> SourceName ->
TableInfo 'MSSQL -> TableInfo 'MSSQL ->
m (Maybe (Parser 'Both n (Column 'MSSQL))) m (Maybe (Parser 'Both n (Column 'MSSQL)))

View File

@ -1,24 +1,16 @@
-- | Classes for monads used during schema construction and query parsing. -- | Classes for monads used during schema construction and query parsing.
module Hasura.GraphQL.Parser.Class module Hasura.GraphQL.Parser.Class
( MonadParse (..), ( MonadSchema (..),
memoize,
MonadParse (..),
parseError, parseError,
module Hasura.GraphQL.Parser.Class,
) )
where where
import Data.Has
import Data.HashMap.Strict qualified as Map
import Data.Text.Extended
import GHC.Stack (HasCallStack) import GHC.Stack (HasCallStack)
import Hasura.Base.Error
import Hasura.GraphQL.Parser.Class.Parse import Hasura.GraphQL.Parser.Class.Parse
import Hasura.GraphQL.Parser.Internal.Types import Hasura.GraphQL.Parser.Internal.Types
import Hasura.Prelude import Hasura.Prelude
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.Source
import Hasura.RQL.Types.Table
import Hasura.Session (RoleName)
import Language.Haskell.TH qualified as TH import Language.Haskell.TH qualified as TH
import Type.Reflection (Typeable) import Type.Reflection (Typeable)
@ -113,34 +105,6 @@ class (Monad m, MonadParse n) => MonadSchema n m | m -> n where
m (p n b) -> m (p n b) ->
m (p n b) m (p n b)
type MonadRole r m = (MonadReader r m, Has RoleName r)
-- | Gets the current role the schema is being built for.
askRoleName ::
MonadRole r m =>
m RoleName
askRoleName = asks getter
type MonadTableInfo r m = (MonadReader r m, Has SourceCache r, MonadError QErr m)
-- | Looks up table information for the given table name. This function
-- should never fail, since the schema cache construction process is
-- supposed to ensure all dependencies are resolved.
askTableInfo ::
forall b r m.
(Backend b, MonadTableInfo r m) =>
SourceName ->
TableName b ->
m (TableInfo b)
askTableInfo sourceName tableName = do
tableInfo <- asks $ getTableInfo . getter
-- This should never fail, since the schema cache construction process is
-- supposed to ensure that all dependencies are resolved.
tableInfo `onNothing` throw500 ("askTableInfo: no info for table " <> dquote tableName <> " in source " <> dquote sourceName)
where
getTableInfo :: SourceCache -> Maybe (TableInfo b)
getTableInfo = Map.lookup tableName <=< unsafeSourceTables <=< Map.lookup sourceName
-- | A wrapper around 'memoizeOn' that memoizes a function by using its argument -- | A wrapper around 'memoizeOn' that memoizes a function by using its argument
-- as the key. -- as the key.
memoize :: memoize ::

View File

@ -522,7 +522,7 @@ buildQueryFields ::
Maybe QueryTagsConfig -> Maybe QueryTagsConfig ->
m [P.FieldParser n (QueryRootField UnpreparedValue)] m [P.FieldParser n (QueryRootField UnpreparedValue)]
buildQueryFields sourceName sourceConfig tables (takeExposedAs FEAQuery -> functions) queryTagsConfig = do buildQueryFields sourceName sourceConfig tables (takeExposedAs FEAQuery -> functions) queryTagsConfig = do
roleName <- askRoleName roleName <- asks getter
functionPermsCtx <- asks $ qcFunctionPermsContext . getter functionPermsCtx <- asks $ qcFunctionPermsContext . getter
tableSelectExpParsers <- for (Map.toList tables) \(tableName, tableInfo) -> do tableSelectExpParsers <- for (Map.toList tables) \(tableName, tableInfo) -> do
tableGQLName <- getTableGQLName @b tableInfo tableGQLName <- getTableGQLName @b tableInfo
@ -573,7 +573,7 @@ buildMutationFields ::
Maybe QueryTagsConfig -> Maybe QueryTagsConfig ->
m [P.FieldParser n (MutationRootField UnpreparedValue)] m [P.FieldParser n (MutationRootField UnpreparedValue)]
buildMutationFields scenario sourceName sourceConfig tables (takeExposedAs FEAMutation -> functions) queryTagsConfig = do buildMutationFields scenario sourceName sourceConfig tables (takeExposedAs FEAMutation -> functions) queryTagsConfig = do
roleName <- askRoleName roleName <- asks getter
tableMutations <- for (Map.toList tables) \(tableName, tableInfo) -> do tableMutations <- for (Map.toList tables) \(tableName, tableInfo) -> do
tableGQLName <- getTableGQLName @b tableInfo tableGQLName <- getTableGQLName @b tableInfo
inserts <- inserts <-
@ -603,15 +603,8 @@ buildMutationFields scenario sourceName sourceConfig tables (takeExposedAs FEAMu
-- | Prepare the parser for query-type GraphQL requests, but with introspection -- | Prepare the parser for query-type GraphQL requests, but with introspection
-- for queries, mutations and subscriptions built in. -- for queries, mutations and subscriptions built in.
buildQueryParser :: buildQueryParser ::
forall m n r. forall r m n.
( MonadSchema n m, MonadBuildSchemaBase r m n =>
MonadTableInfo r m,
MonadRole r m,
Has QueryContext r,
Has P.MkTypename r,
Has MkRootFieldName r,
Has CustomizeRemoteFieldName r
) =>
[P.FieldParser n (NamespacedField (QueryRootField UnpreparedValue))] -> [P.FieldParser n (NamespacedField (QueryRootField UnpreparedValue))] ->
[P.FieldParser n (NamespacedField (RemoteSchemaRootField (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable))] -> [P.FieldParser n (NamespacedField (RemoteSchemaRootField (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable))] ->
[ActionInfo] -> [ActionInfo] ->
@ -681,15 +674,8 @@ queryRootFromFields fps =
-- exposed as a subscription along with fields to get the status of -- exposed as a subscription along with fields to get the status of
-- asynchronous actions. -- asynchronous actions.
buildSubscriptionParser :: buildSubscriptionParser ::
forall m n r. forall r m n.
( MonadSchema n m, MonadBuildSchemaBase r m n =>
MonadTableInfo r m,
MonadRole r m,
Has QueryContext r,
Has P.MkTypename r,
Has MkRootFieldName r,
Has CustomizeRemoteFieldName r
) =>
[P.FieldParser n (NamespacedField (QueryRootField UnpreparedValue))] -> [P.FieldParser n (NamespacedField (QueryRootField UnpreparedValue))] ->
[ActionInfo] -> [ActionInfo] ->
AnnotatedCustomTypes -> AnnotatedCustomTypes ->
@ -702,15 +688,8 @@ buildSubscriptionParser queryFields allActions customTypes = do
<&> fmap (flattenNamespaces . fmap typenameToNamespacedRawRF) <&> fmap (flattenNamespaces . fmap typenameToNamespacedRawRF)
buildMutationParser :: buildMutationParser ::
forall m n r. forall r m n.
( MonadSchema n m, MonadBuildSchemaBase r m n =>
MonadTableInfo r m,
MonadRole r m,
Has QueryContext r,
Has P.MkTypename r,
Has MkRootFieldName r,
Has CustomizeRemoteFieldName r
) =>
[P.FieldParser n (NamespacedField (RemoteSchemaRootField (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable))] -> [P.FieldParser n (NamespacedField (RemoteSchemaRootField (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable))] ->
[ActionInfo] -> [ActionInfo] ->
AnnotatedCustomTypes -> AnnotatedCustomTypes ->

View File

@ -52,7 +52,7 @@ actionExecute ::
ActionInfo -> ActionInfo ->
m (Maybe (FieldParser n (AnnActionExecution (RQL.RemoteRelationshipField UnpreparedValue)))) m (Maybe (FieldParser n (AnnActionExecution (RQL.RemoteRelationshipField UnpreparedValue))))
actionExecute customTypes actionInfo = runMaybeT do actionExecute customTypes actionInfo = runMaybeT do
roleName <- askRoleName roleName <- asks getter
guard (roleName == adminRoleName || roleName `Map.member` permissions) guard (roleName == adminRoleName || roleName `Map.member` permissions)
let fieldName = unActionName actionName let fieldName = unActionName actionName
description = G.Description <$> comment description = G.Description <$> comment
@ -90,13 +90,13 @@ actionExecute customTypes actionInfo = runMaybeT do
-- --
-- > action_name(action_input_arguments) -- > action_name(action_input_arguments)
actionAsyncMutation :: actionAsyncMutation ::
forall m n r. forall r m n.
(MonadSchema n m, MonadTableInfo r m, MonadRole r m) => MonadBuildSchemaBase r m n =>
NonObjectTypeMap -> NonObjectTypeMap ->
ActionInfo -> ActionInfo ->
m (Maybe (FieldParser n AnnActionMutationAsync)) m (Maybe (FieldParser n AnnActionMutationAsync))
actionAsyncMutation nonObjectTypeMap actionInfo = runMaybeT do actionAsyncMutation nonObjectTypeMap actionInfo = runMaybeT do
roleName <- lift askRoleName roleName <- asks getter
guard $ roleName == adminRoleName || roleName `Map.member` permissions guard $ roleName == adminRoleName || roleName `Map.member` permissions
inputArguments <- lift $ actionInputArguments nonObjectTypeMap $ _adArguments definition inputArguments <- lift $ actionInputArguments nonObjectTypeMap $ _adArguments definition
let fieldName = unActionName actionName let fieldName = unActionName actionName
@ -127,7 +127,7 @@ actionAsyncQuery ::
ActionInfo -> ActionInfo ->
m (Maybe (FieldParser n (AnnActionAsyncQuery ('Postgres 'Vanilla) (RQL.RemoteRelationshipField UnpreparedValue)))) m (Maybe (FieldParser n (AnnActionAsyncQuery ('Postgres 'Vanilla) (RQL.RemoteRelationshipField UnpreparedValue))))
actionAsyncQuery objectTypes actionInfo = runMaybeT do actionAsyncQuery objectTypes actionInfo = runMaybeT do
roleName <- askRoleName roleName <- asks getter
guard $ roleName == adminRoleName || roleName `Map.member` permissions guard $ roleName == adminRoleName || roleName `Map.member` permissions
createdAtFieldParser <- createdAtFieldParser <-
lift $ columnParser @('Postgres 'Vanilla) (ColumnScalar PGTimeStampTZ) (G.Nullability False) lift $ columnParser @('Postgres 'Vanilla) (ColumnScalar PGTimeStampTZ) (G.Nullability False)
@ -294,8 +294,8 @@ mkDefinitionList (AOTObject AnnotatedObjectType {..}) =
Map.unions $ map _trFieldMapping $ maybe [] toList _otdRelationships Map.unions $ map _trFieldMapping $ maybe [] toList _otdRelationships
actionInputArguments :: actionInputArguments ::
forall m n r. forall r m n.
(MonadSchema n m, MonadTableInfo r m) => MonadBuildSchemaBase r m n =>
NonObjectTypeMap -> NonObjectTypeMap ->
[ArgumentDefinition (G.GType, NonObjectCustomType)] -> [ArgumentDefinition (G.GType, NonObjectCustomType)] ->
m (InputFieldsParser n J.Value) m (InputFieldsParser n J.Value)

View File

@ -18,7 +18,7 @@ import Hasura.GraphQL.Parser
import Hasura.GraphQL.Parser qualified as P import Hasura.GraphQL.Parser qualified as P
import Hasura.GraphQL.Parser.Class import Hasura.GraphQL.Parser.Class
import Hasura.GraphQL.Schema.Backend import Hasura.GraphQL.Schema.Backend
import Hasura.GraphQL.Schema.Common (partialSQLExpToUnpreparedValue) import Hasura.GraphQL.Schema.Common (askTableInfo, partialSQLExpToUnpreparedValue)
import Hasura.GraphQL.Schema.Table import Hasura.GraphQL.Schema.Table
import Hasura.Prelude import Hasura.Prelude
import Hasura.RQL.Types import Hasura.RQL.Types

View File

@ -14,6 +14,7 @@ module Hasura.GraphQL.Schema.Common
SelectArgs, SelectArgs,
SelectExp, SelectExp,
TablePerms, TablePerms,
askTableInfo,
comparisonAggOperators, comparisonAggOperators,
currentNodeIdVersion, currentNodeIdVersion,
mapField, mapField,
@ -46,14 +47,16 @@ import Hasura.RQL.IR.Action qualified as IR
import Hasura.RQL.IR.Root qualified as IR import Hasura.RQL.IR.Root qualified as IR
import Hasura.RQL.IR.Select qualified as IR import Hasura.RQL.IR.Select qualified as IR
import Hasura.RQL.Types import Hasura.RQL.Types
import Hasura.Session (RoleName)
import Language.GraphQL.Draft.Syntax as G import Language.GraphQL.Draft.Syntax as G
-- | the set of common constraints required to build the schema -- | the set of common constraints required to build the schema
type MonadBuildSchemaBase r m n = type MonadBuildSchemaBase r m n =
( MonadError QErr m, ( MonadError QErr m,
MonadReader r m,
P.MonadSchema n m, P.MonadSchema n m,
P.MonadTableInfo r m, Has RoleName r,
P.MonadRole r m, Has SourceCache r,
Has QueryContext r, Has QueryContext r,
Has MkTypename r, Has MkTypename r,
Has MkRootFieldName r, Has MkRootFieldName r,
@ -99,6 +102,24 @@ data QueryContext = QueryContext
qcOptimizePermissionFilters :: Bool qcOptimizePermissionFilters :: Bool
} }
-- | Looks up table information for the given table name. This function
-- should never fail, since the schema cache construction process is
-- supposed to ensure all dependencies are resolved.
askTableInfo ::
forall b r m.
(Backend b, MonadError QErr m, MonadReader r m, Has SourceCache r) =>
SourceName ->
TableName b ->
m (TableInfo b)
askTableInfo sourceName tableName = do
tableInfo <- asks $ getTableInfo . getter
-- This should never fail, since the schema cache construction process is
-- supposed to ensure that all dependencies are resolved.
tableInfo `onNothing` throw500 ("askTableInfo: no info for table " <> dquote tableName <> " in source " <> dquote sourceName)
where
getTableInfo :: SourceCache -> Maybe (TableInfo b)
getTableInfo = Map.lookup tableName <=< unsafeSourceTables <=< Map.lookup sourceName
-- | Whether the request is sent with `x-hasura-use-backend-only-permissions` set to `true`. -- | Whether the request is sent with `x-hasura-use-backend-only-permissions` set to `true`.
data Scenario = Backend | Frontend deriving (Enum, Show, Eq) data Scenario = Backend | Frontend deriving (Enum, Show, Eq)

View File

@ -35,8 +35,8 @@ import Language.GraphQL.Draft.Syntax qualified as G
-- > obj-rel: <remote-table>_order_by -- > obj-rel: <remote-table>_order_by
-- > } -- > }
orderByExp :: orderByExp ::
forall m n r b. forall b r m n.
(BackendSchema b, MonadSchema n m, MonadTableInfo r m, MonadRole r m, Has P.MkTypename r) => MonadBuildSchema b r m n =>
SourceName -> SourceName ->
TableInfo b -> TableInfo b ->
m (Parser 'Input n [IR.AnnotatedOrderByItemG b (UnpreparedValue b)]) m (Parser 'Input n [IR.AnnotatedOrderByItemG b (UnpreparedValue b)])
@ -116,8 +116,8 @@ orderByExp sourceName tableInfo = memoizeOn 'orderByExp (sourceName, tableInfoNa
-- order, rather than using a general intermediary representation -- order, rather than using a general intermediary representation
orderByAggregation :: orderByAggregation ::
forall m n r b. forall b r m n.
(BackendSchema b, MonadSchema n m, MonadTableInfo r m, MonadRole r m, Has P.MkTypename r) => MonadBuildSchema b r m n =>
SourceName -> SourceName ->
TableInfo b -> TableInfo b ->
m (Parser 'Input n [IR.OrderByItemG b (IR.AnnotatedAggregateOrderBy b)]) m (Parser 'Input n [IR.OrderByItemG b (IR.AnnotatedAggregateOrderBy b)])

View File

@ -67,11 +67,11 @@ remoteRelationshipToSchemaField lhsFields RemoteSchemaFieldInfo {..} = runMaybeT
-- The remote relationship field should not be accessible -- The remote relationship field should not be accessible
-- if the remote schema is not accessible to the said role -- if the remote schema is not accessible to the said role
hoistMaybe $ Map.lookup _rrfiRemoteSchemaName remoteRelationshipQueryCtx hoistMaybe $ Map.lookup _rrfiRemoteSchemaName remoteRelationshipQueryCtx
role <- askRoleName roleName <- asks getter
let hasuraFieldNames = Map.keysSet lhsFields let hasuraFieldNames = Map.keysSet lhsFields
relationshipDef = ToSchemaRelationshipDef _rrfiRemoteSchemaName hasuraFieldNames _rrfiRemoteFields relationshipDef = ToSchemaRelationshipDef _rrfiRemoteSchemaName hasuraFieldNames _rrfiRemoteFields
(newInpValDefns :: [G.TypeDefinition [G.Name] RemoteSchemaInputValueDefinition], remoteFieldParamMap) <- (newInpValDefns :: [G.TypeDefinition [G.Name] RemoteSchemaInputValueDefinition], remoteFieldParamMap) <-
if role == adminRoleName if roleName == adminRoleName
then do then do
-- we don't validate the remote relationship when the role is admin -- we don't validate the remote relationship when the role is admin
-- because it's already been validated, when the remote relationship -- because it's already been validated, when the remote relationship

View File

@ -58,12 +58,6 @@ import Hasura.GraphQL.Parser
) )
import Hasura.GraphQL.Parser qualified as P import Hasura.GraphQL.Parser qualified as P
import Hasura.GraphQL.Parser.Class import Hasura.GraphQL.Parser.Class
( MonadParse (parseErrorWith, withPath),
MonadSchema (..),
MonadTableInfo,
askTableInfo,
parseError,
)
import Hasura.GraphQL.Parser.Internal.Parser qualified as P import Hasura.GraphQL.Parser.Internal.Parser qualified as P
import Hasura.GraphQL.Schema.Backend import Hasura.GraphQL.Schema.Backend
import Hasura.GraphQL.Schema.BoolExp import Hasura.GraphQL.Schema.BoolExp
@ -1394,7 +1388,7 @@ computedFieldPG sourceName ComputedFieldInfo {..} parentTable tableInfo = runMay
-- | The custom SQL functions' input "args" field parser -- | The custom SQL functions' input "args" field parser
-- > function_name(args: function_args) -- > function_name(args: function_args)
customSQLFunctionArgs :: customSQLFunctionArgs ::
(BackendSchema b, MonadSchema n m, MonadTableInfo r m, Has P.MkTypename r) => MonadBuildSchema b r m n =>
FunctionInfo b -> FunctionInfo b ->
G.Name -> G.Name ->
G.Name -> G.Name ->
@ -1421,12 +1415,8 @@ customSQLFunctionArgs FunctionInfo {..} functionName functionArgsName =
-- table row argument in the case of computed fields), the args object will -- table row argument in the case of computed fields), the args object will
-- be omitted. -- be omitted.
functionArgs :: functionArgs ::
forall b m n r. forall b r m n.
( BackendSchema b, MonadBuildSchema b r m n =>
MonadSchema n m,
MonadTableInfo r m,
Has P.MkTypename r
) =>
FunctionTrackedAs b -> FunctionTrackedAs b ->
Seq.Seq (FunctionInputArgument b) -> Seq.Seq (FunctionInputArgument b) ->
m (InputFieldsParser n (IR.FunctionArgsExpTableRow (UnpreparedValue b))) m (InputFieldsParser n (IR.FunctionArgsExpTableRow (UnpreparedValue b)))

View File

@ -20,11 +20,12 @@ import Data.Text.Extended
import Hasura.Base.Error (QErr) import Hasura.Base.Error (QErr)
import Hasura.GraphQL.Parser (Kind (..), Parser) import Hasura.GraphQL.Parser (Kind (..), Parser)
import Hasura.GraphQL.Parser qualified as P import Hasura.GraphQL.Parser qualified as P
import Hasura.GraphQL.Parser.Class
import Hasura.GraphQL.Schema.Backend import Hasura.GraphQL.Schema.Backend
import Hasura.GraphQL.Schema.Common
import Hasura.Prelude import Hasura.Prelude
import Hasura.RQL.DML.Internal (getRolePermInfo) import Hasura.RQL.DML.Internal (getRolePermInfo)
import Hasura.RQL.Types import Hasura.RQL.Types
import Hasura.Session (RoleName)
import Language.GraphQL.Draft.Syntax qualified as G import Language.GraphQL.Draft.Syntax qualified as G
-- | Helper function to get the table GraphQL name. A table may have a -- | Helper function to get the table GraphQL name. A table may have a
@ -57,8 +58,8 @@ getTableGQLName tableInfo = do
-- Return Nothing if there's no column the current user has "select" -- Return Nothing if there's no column the current user has "select"
-- permissions for. -- permissions for.
tableSelectColumnsEnum :: tableSelectColumnsEnum ::
forall m n r b. forall b r m n.
(BackendSchema b, MonadSchema n m, MonadRole r m, MonadTableInfo r m, Has P.MkTypename r) => MonadBuildSchema b r m n =>
SourceName -> SourceName ->
TableInfo b -> TableInfo b ->
m (Maybe (Parser 'Both n (Column b))) m (Maybe (Parser 'Both n (Column b)))
@ -88,8 +89,8 @@ tableSelectColumnsEnum sourceName tableInfo = do
-- table. Used for conflict resolution in "insert" mutations, among -- table. Used for conflict resolution in "insert" mutations, among
-- others. Maps to the table_update_column object. -- others. Maps to the table_update_column object.
tableUpdateColumnsEnum :: tableUpdateColumnsEnum ::
forall m n r b. forall b r m n.
(BackendSchema b, MonadSchema n m, MonadTableInfo r m, MonadRole r m, Has P.MkTypename r) => MonadBuildSchema b r m n =>
TableInfo b -> TableInfo b ->
m (Maybe (Parser 'Both n (Column b))) m (Maybe (Parser 'Both n (Column b)))
tableUpdateColumnsEnum tableInfo = do tableUpdateColumnsEnum tableInfo = do
@ -127,24 +128,29 @@ updateColumnsPlaceholderParser tableInfo = do
) )
tablePermissions :: tablePermissions ::
forall m n r b. forall b r m.
(MonadSchema n m, MonadRole r m) => (MonadReader r m, Has RoleName r) =>
TableInfo b -> TableInfo b ->
m (Maybe (RolePermInfo b)) m (Maybe (RolePermInfo b))
tablePermissions tableInfo = do tablePermissions tableInfo = do
roleName <- askRoleName roleName <- asks getter
pure $ getRolePermInfo roleName tableInfo pure $ getRolePermInfo roleName tableInfo
tableSelectPermissions :: tableSelectPermissions ::
forall b r m n. forall b r m.
(MonadSchema n m, MonadRole r m) => (MonadReader r m, Has RoleName r) =>
TableInfo b -> TableInfo b ->
m (Maybe (SelPermInfo b)) m (Maybe (SelPermInfo b))
tableSelectPermissions tableInfo = (_permSel =<<) <$> tablePermissions tableInfo tableSelectPermissions tableInfo = (_permSel =<<) <$> tablePermissions tableInfo
tableSelectFields :: tableSelectFields ::
forall m n r b. forall b r m.
(Backend b, MonadSchema n m, MonadTableInfo r m, MonadRole r m) => ( Backend b,
MonadError QErr m,
MonadReader r m,
Has SourceCache r,
Has RoleName r
) =>
SourceName -> SourceName ->
TableInfo b -> TableInfo b ->
m [FieldInfo b] m [FieldInfo b]
@ -179,8 +185,13 @@ tableColumns tableInfo =
-- | Get the columns of a table that my be selected under the given select -- | Get the columns of a table that my be selected under the given select
-- permissions. -- permissions.
tableSelectColumns :: tableSelectColumns ::
forall m n r b. forall b r m.
(Backend b, MonadSchema n m, MonadTableInfo r m, MonadRole r m) => ( Backend b,
MonadError QErr m,
MonadReader r m,
Has SourceCache r,
Has RoleName r
) =>
SourceName -> SourceName ->
TableInfo b -> TableInfo b ->
m [ColumnInfo b] m [ColumnInfo b]
@ -193,8 +204,12 @@ tableSelectColumns sourceName tableInfo =
-- | Get the columns of a table that my be updated under the given update -- | Get the columns of a table that my be updated under the given update
-- permissions. -- permissions.
tableUpdateColumns :: tableUpdateColumns ::
forall m n r b. forall b r m.
(Backend b, MonadSchema n m, MonadTableInfo r m, MonadRole r m) => ( Backend b,
MonadError QErr m,
MonadReader r m,
Has RoleName r
) =>
TableInfo b -> TableInfo b ->
m [ColumnInfo b] m [ColumnInfo b]
tableUpdateColumns tableInfo = do tableUpdateColumns tableInfo = do

View File

@ -69,8 +69,8 @@ data UpdateOperator b m n op = UpdateOperator
-- mutation query text or in update preset columns) and that each column is -- mutation query text or in update preset columns) and that each column is
-- only used in one operator. -- only used in one operator.
buildUpdateOperators :: buildUpdateOperators ::
forall b n r op m. forall b r m n op.
(BackendSchema b, P.MonadSchema n m, P.MonadRole r m, P.MonadTableInfo r m) => MonadBuildSchema b r m n =>
-- | Columns with @preset@ expressions -- | Columns with @preset@ expressions
(HashMap (Column b) op) -> (HashMap (Column b) op) ->
-- | Update operators to include in the Schema -- | Update operators to include in the Schema
@ -96,8 +96,8 @@ presetColumns = fmap partialSQLExpToUnpreparedValue . upiSet
-- | Produce an InputFieldsParser from an UpdateOperator, but only if the operator -- | Produce an InputFieldsParser from an UpdateOperator, but only if the operator
-- applies to the table (i.e., it admits a non-empty column set). -- applies to the table (i.e., it admits a non-empty column set).
runUpdateOperator :: runUpdateOperator ::
forall b m n r op. forall b r m n op.
(Backend b, P.MonadSchema n m, P.MonadRole r m, P.MonadTableInfo r m) => MonadBuildSchema b r m n =>
TableInfo b -> TableInfo b ->
UpdateOperator b m n op -> UpdateOperator b m n op ->
m m