server: Include column mutability data in the schema generation code

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3182
Co-authored-by: Philip Lykke Carlsen <358550+plcplc@users.noreply.github.com>
GitOrigin-RevId: ba9d31f5443aa936b1d5b58b0f4e10abf0064a7e
This commit is contained in:
Abby Sassel 2021-12-17 17:25:47 +00:00 committed by hasura-bot
parent 175391bb88
commit 6c6bb678f8
4 changed files with 32 additions and 12 deletions

View File

@ -310,6 +310,10 @@ rawSelection name description argumentsParser resultParser =
-- | Builds a 'FieldParser' for a field that takes a subselection set, i.e. a
-- field that returns an object.
--
-- For example, @subselection name _ args fields@ produces schema:
--
-- > name (args) { fields }
--
-- See also Note [The delicate balance of GraphQL kinds] in "Hasura.GraphQL.Parser.Schema".
subselection ::
forall m a b.

View File

@ -44,7 +44,7 @@ import Language.GraphQL.Draft.Syntax qualified as G
-- This function is used to create the insert_tablename root field.
-- The field accepts the following arguments:
-- - objects: the list of objects to insert into the table (see 'tableFieldsInput')
-- - on_conflict: an object describing how to perform an upsert in case of conflict
-- - parser for backend-specific fields, e.g. upsert fields on_conflict or if_matched
insertIntoTable ::
forall b r m n.
MonadBuildSchema b r m n =>
@ -64,9 +64,11 @@ insertIntoTable ::
Maybe (UpdPermInfo b) ->
m (FieldParser n (IR.AnnInsert b (IR.RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
insertIntoTable backendInsertAction sourceName tableInfo fieldName description insertPerms selectPerms updatePerms = do
selectionParser <- mutationSelectionSet sourceName tableInfo selectPerms
-- objects [{ ... }]
objectParser <- tableFieldsInput sourceName tableInfo insertPerms
backendInsertParser <- backendInsertAction sourceName tableInfo selectPerms updatePerms
-- returning clause, affected rows, etc.
selectionParser <- mutationSelectionSet sourceName tableInfo selectPerms
let argsParser = do
backendInsert <- backendInsertParser
objects <- mkObjectsArg objectParser
@ -128,6 +130,17 @@ insertOneIntoTable backendInsertAction sourceName tableInfo fieldName descriptio
-- This function creates an input object type named "tablename_insert_input" in
-- the GraphQL shema, which has a field for each of the columns of that table
-- that the user has insert permissions for.
--
-- > {
-- > insert_author (
-- > objects: [
-- > { # tableFieldsInput output
-- > name: "John",
-- > id:12
-- > }
-- > ] ...
-- > ) ...
-- > }
tableFieldsInput ::
forall b r m n.
MonadBuildSchema b r m n =>
@ -164,7 +177,10 @@ tableFieldsInput sourceName tableInfo insertPerms =
mkFieldParser = \case
FIComputedField _ -> pure Nothing
FIRemoteRelationship _ -> pure Nothing
FIColumn columnInfo -> mkColumnParser columnInfo
FIColumn columnInfo -> do
if (_cmIsInsertable $ pgiMutability columnInfo)
then mkColumnParser columnInfo
else pure Nothing
FIRelationship relInfo -> mkRelationshipParser sourceName relInfo
mkColumnParser ::

View File

@ -178,13 +178,11 @@ tableUpdateColumns ::
TableInfo b ->
UpdPermInfo b ->
m [ColumnInfo b]
tableUpdateColumns tableInfo permissions = do
let tableFields = _tciFieldInfoMap . _tiCoreInfo $ tableInfo
pure $ mapMaybe isUpdatable $ Map.elems tableFields
tableUpdateColumns tableInfo permissions = pure $ filter isUpdatable $ tableColumns tableInfo
where
isUpdatable (FIColumn columnInfo) =
if Set.member (pgiColumn columnInfo) (upiCols permissions)
&& not (Map.member (pgiColumn columnInfo) (upiSet permissions))
then Just columnInfo
else Nothing
isUpdatable _ = Nothing
isUpdatable :: ColumnInfo b -> Bool
isUpdatable columnInfo = columnIsUpdatable && columnIsPermitted && columnHasNoPreset
where
columnIsUpdatable = _cmIsUpdatable (pgiMutability columnInfo)
columnIsPermitted = Set.member (pgiColumn columnInfo) (upiCols permissions)
columnHasNoPreset = not (Map.member (pgiColumn columnInfo) (upiSet permissions))

View File

@ -199,6 +199,8 @@ instance Backend b => FromJSON (RawColumnInfo b) where
-- This guides the schema parsers such that they only generate fields for
-- columns where they're valid without having to model the exact circumstances
-- which cause a column to appear or not.
--
-- See <https://github.com/hasura/graphql-engine/blob/master/rfcs/column-mutability.md>.
data ColumnMutability = ColumnMutability
{ _cmIsInsertable :: Bool,
_cmIsUpdatable :: Bool