{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE TemplateHaskell #-}

-- | This module provides common building blocks for composing Schema Parsers
-- used in the schema of Update Mutations.
module Hasura.GraphQL.Schema.Update
  ( UpdateOperator (..),
    updateOperator,
    buildUpdateOperators,
    presetColumns,
    setOp,
    incOp,
    updateTable,
    updateTableByPk,
    mkUpdateObject,
  )
where

import Data.Has (Has (getter))
import Data.HashMap.Strict qualified as M
import Data.HashMap.Strict.Extended qualified as M
import Data.List.NonEmpty qualified as NE
import Data.Text.Casing (GQLNameIdentifier, fromAutogeneratedName)
import Data.Text.Extended (toTxt, (<>>))
import Hasura.Base.Error (QErr)
import Hasura.Base.ToErrorValue
import Hasura.GraphQL.Schema.Backend (BackendSchema (..), BackendTableSelectSchema (..), MonadBuildSchema, columnParser)
import Hasura.GraphQL.Schema.BoolExp (AggregationPredicatesSchema, boolExp)
import Hasura.GraphQL.Schema.Common (Scenario (..), SchemaContext (..), mapField, partialSQLExpToUnpreparedValue, retrieve)
import Hasura.GraphQL.Schema.Mutation (mutationSelectionSet, primaryKeysArguments)
import Hasura.GraphQL.Schema.NamingCase
import Hasura.GraphQL.Schema.Parser qualified as P
import Hasura.GraphQL.Schema.Table (getTableIdentifierName, tableColumns, tableUpdateColumns)
import Hasura.GraphQL.Schema.Typename
import Hasura.Prelude
import Hasura.RQL.IR.BoolExp (AnnBoolExp, annBoolExpTrue)
import Hasura.RQL.IR.Returning (MutationOutputG (..))
import Hasura.RQL.IR.Root (RemoteRelationshipField)
import Hasura.RQL.IR.Update (AnnotatedUpdateG (..))
import Hasura.RQL.IR.Value
import Hasura.RQL.Types.Backend (Backend (..))
import Hasura.RQL.Types.Column (ColumnInfo (..), isNumCol)
import Hasura.RQL.Types.Source
import Hasura.RQL.Types.SourceCustomization (applyFieldNameCaseIdentifier, applyTypeNameCaseIdentifier, mkTableOperatorInputTypeName, mkTablePkColumnsInputTypeName)
import Hasura.RQL.Types.Table
import Language.GraphQL.Draft.Syntax (Description (..), Name (..), Nullability (..), litName)

-- | @UpdateOperator b m n op@ represents one single update operator for a
-- backend @b@.
--
-- The type variable @op@ is the backend-specific data type that represents
-- update operators, typically in the form of a sum-type with an
-- @UnpreparedValue b@ in each constructor.
--
-- The @UpdateOperator b m n@ is a @Functor@. There exist building blocks of
-- common update operators (such as 'setOp', etc.) which have @op ~
-- UnpreparedValue b@. The Functor instance lets you wrap the generic update
-- operators in backend-specific tags.
data UpdateOperator b m n op = UpdateOperator
  { UpdateOperator b m n op -> ColumnInfo b -> Bool
updateOperatorApplicableColumn :: ColumnInfo b -> Bool,
    UpdateOperator b m n op
-> GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) op))
updateOperatorParser ::
      GQLNameIdentifier ->
      TableName b ->
      NonEmpty (ColumnInfo b) ->
      m (P.InputFieldsParser n (HashMap (Column b) op))
  }
  deriving (a -> UpdateOperator b m n b -> UpdateOperator b m n a
(a -> b) -> UpdateOperator b m n a -> UpdateOperator b m n b
(forall a b.
 (a -> b) -> UpdateOperator b m n a -> UpdateOperator b m n b)
-> (forall a b.
    a -> UpdateOperator b m n b -> UpdateOperator b m n a)
-> Functor (UpdateOperator b m n)
forall a b. a -> UpdateOperator b m n b -> UpdateOperator b m n a
forall a b.
(a -> b) -> UpdateOperator b m n a -> UpdateOperator b m n b
forall (b :: BackendType) (m :: * -> *) (n :: * -> *) a b.
(Functor m, Functor n) =>
a -> UpdateOperator b m n b -> UpdateOperator b m n a
forall (b :: BackendType) (m :: * -> *) (n :: * -> *) a b.
(Functor m, Functor n) =>
(a -> b) -> UpdateOperator b m n a -> UpdateOperator b m n b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> UpdateOperator b m n b -> UpdateOperator b m n a
$c<$ :: forall (b :: BackendType) (m :: * -> *) (n :: * -> *) a b.
(Functor m, Functor n) =>
a -> UpdateOperator b m n b -> UpdateOperator b m n a
fmap :: (a -> b) -> UpdateOperator b m n a -> UpdateOperator b m n b
$cfmap :: forall (b :: BackendType) (m :: * -> *) (n :: * -> *) a b.
(Functor m, Functor n) =>
(a -> b) -> UpdateOperator b m n a -> UpdateOperator b m n b
Functor)

-- | The top-level component for building update operators parsers.
--
-- * It implements the @preset@ functionality from Update Permissions (see
--   <https://hasura.io/docs/latest/graphql/core/auth/authorization/permission-rules.html#column-presets
--   Permissions user docs>). Use the 'presetColumns' function to extract those from the update permissions.
-- * It validates that that the update fields parsed are sound when taken as a
--   whole, i.e. that some changes are actually specified (either in the
--   mutation query text or in update preset columns) and that each column is
--   only used in one operator.
buildUpdateOperators ::
  forall b r m n op.
  MonadBuildSchema b r m n =>
  -- | Columns with @preset@ expressions
  (HashMap (Column b) op) ->
  -- | Update operators to include in the Schema
  [UpdateOperator b m n op] ->
  TableInfo b ->
  m (P.InputFieldsParser n (HashMap (Column b) op))
buildUpdateOperators :: HashMap (Column b) op
-> [UpdateOperator b m n op]
-> TableInfo b
-> m (InputFieldsParser n (HashMap (Column b) op))
buildUpdateOperators HashMap (Column b) op
presetCols [UpdateOperator b m n op]
ops TableInfo b
tableInfo = do
  parsers :: P.InputFieldsParser n [HashMap (Column b) op] <-
    [InputFieldsParser n (HashMap (Column b) op)]
-> InputFieldsParser MetadataObjId n [HashMap (Column b) op]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA ([InputFieldsParser n (HashMap (Column b) op)]
 -> InputFieldsParser MetadataObjId n [HashMap (Column b) op])
-> ([Maybe (InputFieldsParser n (HashMap (Column b) op))]
    -> [InputFieldsParser n (HashMap (Column b) op)])
-> [Maybe (InputFieldsParser n (HashMap (Column b) op))]
-> InputFieldsParser MetadataObjId n [HashMap (Column b) op]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (InputFieldsParser n (HashMap (Column b) op))]
-> [InputFieldsParser n (HashMap (Column b) op)]
forall (f :: * -> *) a. Filterable f => f (Maybe a) -> f a
catMaybes ([Maybe (InputFieldsParser n (HashMap (Column b) op))]
 -> InputFieldsParser MetadataObjId n [HashMap (Column b) op])
-> m [Maybe (InputFieldsParser n (HashMap (Column b) op))]
-> m (InputFieldsParser MetadataObjId n [HashMap (Column b) op])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (UpdateOperator b m n op
 -> m (Maybe (InputFieldsParser n (HashMap (Column b) op))))
-> [UpdateOperator b m n op]
-> m [Maybe (InputFieldsParser n (HashMap (Column b) op))]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (TableInfo b
-> UpdateOperator b m n op
-> m (Maybe (InputFieldsParser n (HashMap (Column b) op)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *) op.
MonadBuildSchema b r m n =>
TableInfo b
-> UpdateOperator b m n op
-> m (Maybe (InputFieldsParser n (HashMap (Column b) op)))
runUpdateOperator TableInfo b
tableInfo) [UpdateOperator b m n op]
ops
  pure $
    InputFieldsParser MetadataObjId n [HashMap (Column b) op]
parsers
      InputFieldsParser MetadataObjId n [HashMap (Column b) op]
-> ([HashMap (Column b) op] -> n (HashMap (Column b) op))
-> InputFieldsParser n (HashMap (Column b) op)
forall (m :: * -> *) origin a b.
Monad m =>
InputFieldsParser origin m a
-> (a -> m b) -> InputFieldsParser origin m b
`P.bindFields` ( \[HashMap (Column b) op]
opExps -> do
                         let withPreset :: [HashMap (Column b) op]
withPreset = HashMap (Column b) op
presetCols HashMap (Column b) op
-> [HashMap (Column b) op] -> [HashMap (Column b) op]
forall a. a -> [a] -> [a]
: [HashMap (Column b) op]
opExps
                         [HashMap (Column b) op] -> n (HashMap (Column b) op)
forall (b :: BackendType) (m :: * -> *) t.
(Backend b, MonadParse m) =>
[HashMap (Column b) t] -> m (HashMap (Column b) t)
mergeDisjoint @b [HashMap (Column b) op]
withPreset
                     )

-- | The columns that have 'preset' definitions applied to them. (see
-- <https://hasura.io/docs/latest/graphql/core/auth/authorization/permission-rules.html#column-presets
-- Permissions user docs>)
presetColumns :: UpdPermInfo b -> HashMap (Column b) (UnpreparedValue b)
presetColumns :: UpdPermInfo b -> HashMap (Column b) (UnpreparedValue b)
presetColumns = (PartialSQLExp b -> UnpreparedValue b)
-> HashMap (Column b) (PartialSQLExp b)
-> HashMap (Column b) (UnpreparedValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PartialSQLExp b -> UnpreparedValue b
forall (b :: BackendType). PartialSQLExp b -> UnpreparedValue b
partialSQLExpToUnpreparedValue (HashMap (Column b) (PartialSQLExp b)
 -> HashMap (Column b) (UnpreparedValue b))
-> (UpdPermInfo b -> HashMap (Column b) (PartialSQLExp b))
-> UpdPermInfo b
-> HashMap (Column b) (UnpreparedValue b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UpdPermInfo b -> HashMap (Column b) (PartialSQLExp b)
forall (b :: BackendType). UpdPermInfo b -> PreSetColsPartial b
upiSet

-- | Produce an InputFieldsParser from an UpdateOperator, but only if the operator
-- applies to the table (i.e., it admits a non-empty column set).
runUpdateOperator ::
  forall b r m n op.
  MonadBuildSchema b r m n =>
  TableInfo b ->
  UpdateOperator b m n op ->
  m
    ( Maybe
        ( P.InputFieldsParser
            n
            (HashMap (Column b) op)
        )
    )
runUpdateOperator :: TableInfo b
-> UpdateOperator b m n op
-> m (Maybe (InputFieldsParser n (HashMap (Column b) op)))
runUpdateOperator TableInfo b
tableInfo UpdateOperator {GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) op))
ColumnInfo b -> Bool
updateOperatorParser :: GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) op))
updateOperatorApplicableColumn :: ColumnInfo b -> Bool
updateOperatorParser :: forall (b :: BackendType) (m :: * -> *) (n :: * -> *) op.
UpdateOperator b m n op
-> GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) op))
updateOperatorApplicableColumn :: forall (b :: BackendType) (m :: * -> *) (n :: * -> *) op.
UpdateOperator b m n op -> ColumnInfo b -> Bool
..} = do
  let tableName :: TableName b
tableName = TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
  GQLNameIdentifier
tableGQLName <- TableInfo b -> m GQLNameIdentifier
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m GQLNameIdentifier
getTableIdentifierName TableInfo b
tableInfo
  RoleName
roleName <- (SchemaContext -> RoleName) -> m RoleName
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve SchemaContext -> RoleName
scRole
  let columns :: [ColumnInfo b]
columns = RoleName -> TableInfo b -> [ColumnInfo b]
forall (b :: BackendType).
Backend b =>
RoleName -> TableInfo b -> [ColumnInfo b]
tableUpdateColumns RoleName
roleName TableInfo b
tableInfo

  let Maybe (NonEmpty (ColumnInfo b))
applicableCols :: Maybe (NonEmpty (ColumnInfo b)) =
        [ColumnInfo b] -> Maybe (NonEmpty (ColumnInfo b))
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([ColumnInfo b] -> Maybe (NonEmpty (ColumnInfo b)))
-> ([ColumnInfo b] -> [ColumnInfo b])
-> [ColumnInfo b]
-> Maybe (NonEmpty (ColumnInfo b))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ColumnInfo b -> Bool) -> [ColumnInfo b] -> [ColumnInfo b]
forall a. (a -> Bool) -> [a] -> [a]
filter ColumnInfo b -> Bool
updateOperatorApplicableColumn ([ColumnInfo b] -> Maybe (NonEmpty (ColumnInfo b)))
-> [ColumnInfo b] -> Maybe (NonEmpty (ColumnInfo b))
forall a b. (a -> b) -> a -> b
$ [ColumnInfo b]
columns

  (forall a. Maybe (m a) -> m (Maybe a)
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA :: Maybe (m a) -> m (Maybe a))
    (Maybe (NonEmpty (ColumnInfo b))
applicableCols Maybe (NonEmpty (ColumnInfo b))
-> (NonEmpty (ColumnInfo b)
    -> m (InputFieldsParser n (HashMap (Column b) op)))
-> Maybe (m (InputFieldsParser n (HashMap (Column b) op)))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) op))
updateOperatorParser GQLNameIdentifier
tableGQLName TableName b
tableName)

-- | Merge the results of parsed update operators. Throws an error if the same
-- column has been specified in multiple operators.
mergeDisjoint ::
  forall b m t.
  (Backend b, P.MonadParse m) =>
  [HashMap (Column b) t] ->
  m (HashMap (Column b) t)
mergeDisjoint :: [HashMap (Column b) t] -> m (HashMap (Column b) t)
mergeDisjoint [HashMap (Column b) t]
parsedResults = do
  let unioned :: HashMap (Column b) (NonEmpty t)
unioned = [HashMap (Column b) t] -> HashMap (Column b) (NonEmpty t)
forall k (t :: * -> *) v.
(Eq k, Hashable k, Foldable t) =>
t (HashMap k v) -> HashMap k (NonEmpty v)
M.unionsAll [HashMap (Column b) t]
parsedResults
      duplicates :: [Column b]
duplicates = HashMap (Column b) (NonEmpty t) -> [Column b]
forall k v. HashMap k v -> [k]
M.keys (HashMap (Column b) (NonEmpty t) -> [Column b])
-> HashMap (Column b) (NonEmpty t) -> [Column b]
forall a b. (a -> b) -> a -> b
$ (NonEmpty t -> Bool)
-> HashMap (Column b) (NonEmpty t)
-> HashMap (Column b) (NonEmpty t)
forall v k. (v -> Bool) -> HashMap k v -> HashMap k v
M.filter (Bool -> Bool
not (Bool -> Bool) -> (NonEmpty t -> Bool) -> NonEmpty t -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [t] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([t] -> Bool) -> (NonEmpty t -> [t]) -> NonEmpty t -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty t -> [t]
forall a. NonEmpty a -> [a]
NE.tail) HashMap (Column b) (NonEmpty t)
unioned

  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([Column b] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Column b]
duplicates) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
    ErrorMessage -> m ()
forall (m :: * -> *) a. MonadParse m => ErrorMessage -> m a
P.parseError
      ( ErrorMessage
"Column found in multiple operators: "
          ErrorMessage -> ErrorMessage -> ErrorMessage
forall a. Semigroup a => a -> a -> a
<> [Column b] -> ErrorMessage
forall a. ToErrorValue a => a -> ErrorMessage
toErrorValue [Column b]
duplicates
          ErrorMessage -> ErrorMessage -> ErrorMessage
forall a. Semigroup a => a -> a -> a
<> ErrorMessage
"."
      )

  return $ (NonEmpty t -> t)
-> HashMap (Column b) (NonEmpty t) -> HashMap (Column b) t
forall v1 v2 k. (v1 -> v2) -> HashMap k v1 -> HashMap k v2
M.map NonEmpty t -> t
forall a. NonEmpty a -> a
NE.head HashMap (Column b) (NonEmpty t)
unioned

-- | Construct a parser for a single update operator.
--
-- @updateOperator _ "op" fp MkOp ["col1","col2"]@ gives a parser that accepts
-- objects in the shape of:
--
-- > op: {
-- >   col1: "x",
-- >   col2: "y"
-- > }
--
-- And (morally) parses into values:
--
-- > M.fromList [("col1", MkOp (fp "x")), ("col2", MkOp (fp "y"))]
updateOperator ::
  forall n r m b a.
  (P.MonadParse n, MonadReader r m, Has MkTypename r, Has NamingCase r, Backend b) =>
  GQLNameIdentifier ->
  GQLNameIdentifier ->
  GQLNameIdentifier ->
  (ColumnInfo b -> m (P.Parser 'P.Both n a)) ->
  NonEmpty (ColumnInfo b) ->
  Description ->
  Description ->
  m (P.InputFieldsParser n (HashMap (Column b) a))
updateOperator :: GQLNameIdentifier
-> GQLNameIdentifier
-> GQLNameIdentifier
-> (ColumnInfo b -> m (Parser 'Both n a))
-> NonEmpty (ColumnInfo b)
-> Description
-> Description
-> m (InputFieldsParser n (HashMap (Column b) a))
updateOperator GQLNameIdentifier
tableGQLName GQLNameIdentifier
opName GQLNameIdentifier
opFieldName ColumnInfo b -> m (Parser 'Both n a)
mkParser NonEmpty (ColumnInfo b)
columns Description
opDesc Description
objDesc = do
  NamingCase
tCase <- (r -> NamingCase) -> m NamingCase
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> NamingCase
forall a t. Has a t => t -> a
getter
  fieldParsers :: NonEmpty (P.InputFieldsParser n (Maybe (Column b, a))) <-
    NonEmpty (ColumnInfo b)
-> (ColumnInfo b -> m (InputFieldsParser n (Maybe (Column b, a))))
-> m (NonEmpty (InputFieldsParser n (Maybe (Column b, a))))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for NonEmpty (ColumnInfo b)
columns \ColumnInfo b
columnInfo -> do
      let fieldName :: Name
fieldName = ColumnInfo b -> Name
forall (b :: BackendType). ColumnInfo b -> Name
ciName ColumnInfo b
columnInfo
          fieldDesc :: Maybe Description
fieldDesc = ColumnInfo b -> Maybe Description
forall (b :: BackendType). ColumnInfo b -> Maybe Description
ciDescription ColumnInfo b
columnInfo
      Parser 'Both n a
fieldParser <- ColumnInfo b -> m (Parser 'Both n a)
mkParser ColumnInfo b
columnInfo
      pure $
        Name
-> Maybe Description
-> Parser 'Both n a
-> InputFieldsParser MetadataObjId n (Maybe a)
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m (Maybe a)
P.fieldOptional Name
fieldName Maybe Description
fieldDesc Parser 'Both n a
fieldParser
          InputFieldsParser MetadataObjId n (Maybe a)
-> (a -> (Column b, a))
-> InputFieldsParser n (Maybe (Column b, a))
forall (m :: * -> *) a b.
Functor m =>
InputFieldsParser m (Maybe a)
-> (a -> b) -> InputFieldsParser m (Maybe b)
`mapField` \a
value -> (ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
columnInfo, a
value)

  Name
objName <- Name -> m Name
forall r (m :: * -> *).
(MonadReader r m, Has MkTypename r) =>
Name -> m Name
mkTypename (Name -> m Name) -> Name -> m Name
forall a b. (a -> b) -> a -> b
$ NamingCase -> GQLNameIdentifier -> Name
applyTypeNameCaseIdentifier NamingCase
tCase (GQLNameIdentifier -> Name) -> GQLNameIdentifier -> Name
forall a b. (a -> b) -> a -> b
$ GQLNameIdentifier -> GQLNameIdentifier -> GQLNameIdentifier
mkTableOperatorInputTypeName GQLNameIdentifier
tableGQLName GQLNameIdentifier
opName
  pure $
    (Maybe [(Column b, a)] -> HashMap (Column b) a)
-> InputFieldsParser MetadataObjId n (Maybe [(Column b, a)])
-> InputFieldsParser n (HashMap (Column b) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([(Column b, a)] -> HashMap (Column b) a
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
M.fromList ([(Column b, a)] -> HashMap (Column b) a)
-> (Maybe [(Column b, a)] -> [(Column b, a)])
-> Maybe [(Column b, a)]
-> HashMap (Column b) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe [(Column b, a)] -> [(Column b, a)]
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold :: Maybe [(Column b, a)] -> [(Column b, a)])) (InputFieldsParser MetadataObjId n (Maybe [(Column b, a)])
 -> InputFieldsParser n (HashMap (Column b) a))
-> InputFieldsParser MetadataObjId n (Maybe [(Column b, a)])
-> InputFieldsParser n (HashMap (Column b) a)
forall a b. (a -> b) -> a -> b
$
      Name
-> Maybe Description
-> Parser MetadataObjId 'Input n [(Column b, a)]
-> InputFieldsParser MetadataObjId n (Maybe [(Column b, a)])
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m (Maybe a)
P.fieldOptional (NamingCase -> GQLNameIdentifier -> Name
applyFieldNameCaseIdentifier NamingCase
tCase GQLNameIdentifier
opFieldName) (Description -> Maybe Description
forall a. a -> Maybe a
Just Description
opDesc) (Parser MetadataObjId 'Input n [(Column b, a)]
 -> InputFieldsParser MetadataObjId n (Maybe [(Column b, a)]))
-> Parser MetadataObjId 'Input n [(Column b, a)]
-> InputFieldsParser MetadataObjId n (Maybe [(Column b, a)])
forall a b. (a -> b) -> a -> b
$
        Name
-> Maybe Description
-> InputFieldsParser MetadataObjId n [(Column b, a)]
-> Parser MetadataObjId 'Input n [(Column b, a)]
forall (m :: * -> *) origin a.
MonadParse m =>
Name
-> Maybe Description
-> InputFieldsParser origin m a
-> Parser origin 'Input m a
P.object Name
objName (Description -> Maybe Description
forall a. a -> Maybe a
Just Description
objDesc) (InputFieldsParser MetadataObjId n [(Column b, a)]
 -> Parser MetadataObjId 'Input n [(Column b, a)])
-> InputFieldsParser MetadataObjId n [(Column b, a)]
-> Parser MetadataObjId 'Input n [(Column b, a)]
forall a b. (a -> b) -> a -> b
$
          ([Maybe (Column b, a)] -> [(Column b, a)]
forall (f :: * -> *) a. Filterable f => f (Maybe a) -> f a
catMaybes ([Maybe (Column b, a)] -> [(Column b, a)])
-> (NonEmpty (Maybe (Column b, a)) -> [Maybe (Column b, a)])
-> NonEmpty (Maybe (Column b, a))
-> [(Column b, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (Maybe (Column b, a)) -> [Maybe (Column b, a)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList) (NonEmpty (Maybe (Column b, a)) -> [(Column b, a)])
-> InputFieldsParser
     MetadataObjId n (NonEmpty (Maybe (Column b, a)))
-> InputFieldsParser MetadataObjId n [(Column b, a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (InputFieldsParser n (Maybe (Column b, a)))
-> InputFieldsParser
     MetadataObjId n (NonEmpty (Maybe (Column b, a)))
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA NonEmpty (InputFieldsParser n (Maybe (Column b, a)))
fieldParsers
{-# ANN updateOperator ("HLint: ignore Use tuple-section" :: String) #-}

setOp ::
  forall b n r m.
  ( BackendSchema b,
    MonadReader r m,
    Has MkTypename r,
    Has NamingCase r,
    MonadError QErr m,
    P.MonadParse n
  ) =>
  UpdateOperator b m n (UnpreparedValue b)
setOp :: UpdateOperator b m n (UnpreparedValue b)
setOp = UpdateOperator :: forall (b :: BackendType) (m :: * -> *) (n :: * -> *) op.
(ColumnInfo b -> Bool)
-> (GQLNameIdentifier
    -> TableName b
    -> NonEmpty (ColumnInfo b)
    -> m (InputFieldsParser n (HashMap (Column b) op)))
-> UpdateOperator b m n op
UpdateOperator {GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
ColumnInfo b -> Bool
forall b. b -> Bool
updateOperatorParser :: GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
updateOperatorApplicableColumn :: forall b. b -> Bool
updateOperatorParser :: GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
updateOperatorApplicableColumn :: ColumnInfo b -> Bool
..}
  where
    updateOperatorApplicableColumn :: b -> Bool
updateOperatorApplicableColumn = Bool -> b -> Bool
forall a b. a -> b -> a
const Bool
True

    updateOperatorParser :: GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
updateOperatorParser GQLNameIdentifier
tableGQLName TableName b
tableName NonEmpty (ColumnInfo b)
columns = do
      let typedParser :: ColumnInfo b
-> f (Parser MetadataObjId 'Both n (UnpreparedValue b))
typedParser ColumnInfo b
columnInfo =
            (ValueWithOrigin (ColumnValue b) -> UnpreparedValue b)
-> Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b))
-> Parser MetadataObjId 'Both n (UnpreparedValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ValueWithOrigin (ColumnValue b) -> UnpreparedValue b
forall (b :: BackendType).
ValueWithOrigin (ColumnValue b) -> UnpreparedValue b
mkParameter
              (Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b))
 -> Parser MetadataObjId 'Both n (UnpreparedValue b))
-> f (Parser
        MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b)))
-> f (Parser MetadataObjId 'Both n (UnpreparedValue b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ColumnType b
-> Nullability
-> f (Parser
        MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b)))
forall (b :: BackendType) (n :: * -> *) (m :: * -> *) r.
(BackendSchema b, MonadParse n, MonadError QErr m, MonadReader r m,
 Has MkTypename r, Has NamingCase r) =>
ColumnType b
-> Nullability
-> m (Parser 'Both n (ValueWithOrigin (ColumnValue b)))
columnParser
                (ColumnInfo b -> ColumnType b
forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciType ColumnInfo b
columnInfo)
                (Bool -> Nullability
Nullability (Bool -> Nullability) -> Bool -> Nullability
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Bool
forall (b :: BackendType). ColumnInfo b -> Bool
ciIsNullable ColumnInfo b
columnInfo)

      GQLNameIdentifier
-> GQLNameIdentifier
-> GQLNameIdentifier
-> (ColumnInfo b -> m (Parser 'Both n (UnpreparedValue b)))
-> NonEmpty (ColumnInfo b)
-> Description
-> Description
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
forall (n :: * -> *) r (m :: * -> *) (b :: BackendType) a.
(MonadParse n, MonadReader r m, Has MkTypename r, Has NamingCase r,
 Backend b) =>
GQLNameIdentifier
-> GQLNameIdentifier
-> GQLNameIdentifier
-> (ColumnInfo b -> m (Parser 'Both n a))
-> NonEmpty (ColumnInfo b)
-> Description
-> Description
-> m (InputFieldsParser n (HashMap (Column b) a))
updateOperator
        GQLNameIdentifier
tableGQLName
        (Name -> GQLNameIdentifier
fromAutogeneratedName $$(litName "set"))
        (Name -> GQLNameIdentifier
fromAutogeneratedName $$(litName "_set"))
        ColumnInfo b -> m (Parser 'Both n (UnpreparedValue b))
forall (b :: BackendType) (n :: * -> *) (f :: * -> *) r.
(BackendSchema b, MonadParse n, MonadError QErr f, MonadReader r f,
 Has MkTypename r, Has NamingCase r) =>
ColumnInfo b
-> f (Parser MetadataObjId 'Both n (UnpreparedValue b))
typedParser
        NonEmpty (ColumnInfo b)
columns
        Description
"sets the columns of the filtered rows to the given values"
        (Text -> Description
Description (Text -> Description) -> Text -> Description
forall a b. (a -> b) -> a -> b
$ Text
"input type for updating data in table " Text -> TableName b -> Text
forall t. ToTxt t => Text -> t -> Text
<>> TableName b
tableName)

incOp ::
  forall b m n r.
  ( Backend b,
    MonadReader r m,
    MonadError QErr m,
    P.MonadParse n,
    BackendSchema b,
    Has MkTypename r,
    Has NamingCase r
  ) =>
  UpdateOperator b m n (UnpreparedValue b)
incOp :: UpdateOperator b m n (UnpreparedValue b)
incOp = UpdateOperator :: forall (b :: BackendType) (m :: * -> *) (n :: * -> *) op.
(ColumnInfo b -> Bool)
-> (GQLNameIdentifier
    -> TableName b
    -> NonEmpty (ColumnInfo b)
    -> m (InputFieldsParser n (HashMap (Column b) op)))
-> UpdateOperator b m n op
UpdateOperator {GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
ColumnInfo b -> Bool
updateOperatorParser :: GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
updateOperatorApplicableColumn :: ColumnInfo b -> Bool
updateOperatorParser :: GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
updateOperatorApplicableColumn :: ColumnInfo b -> Bool
..}
  where
    updateOperatorApplicableColumn :: ColumnInfo b -> Bool
updateOperatorApplicableColumn = ColumnInfo b -> Bool
forall (b :: BackendType). Backend b => ColumnInfo b -> Bool
isNumCol

    updateOperatorParser :: GQLNameIdentifier
-> TableName b
-> NonEmpty (ColumnInfo b)
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
updateOperatorParser GQLNameIdentifier
tableGQLName TableName b
tableName NonEmpty (ColumnInfo b)
columns = do
      let typedParser :: ColumnInfo b
-> f (Parser MetadataObjId 'Both n (UnpreparedValue b))
typedParser ColumnInfo b
columnInfo =
            (ValueWithOrigin (ColumnValue b) -> UnpreparedValue b)
-> Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b))
-> Parser MetadataObjId 'Both n (UnpreparedValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ValueWithOrigin (ColumnValue b) -> UnpreparedValue b
forall (b :: BackendType).
ValueWithOrigin (ColumnValue b) -> UnpreparedValue b
mkParameter
              (Parser MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b))
 -> Parser MetadataObjId 'Both n (UnpreparedValue b))
-> f (Parser
        MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b)))
-> f (Parser MetadataObjId 'Both n (UnpreparedValue b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ColumnType b
-> Nullability
-> f (Parser
        MetadataObjId 'Both n (ValueWithOrigin (ColumnValue b)))
forall (b :: BackendType) (n :: * -> *) (m :: * -> *) r.
(BackendSchema b, MonadParse n, MonadError QErr m, MonadReader r m,
 Has MkTypename r, Has NamingCase r) =>
ColumnType b
-> Nullability
-> m (Parser 'Both n (ValueWithOrigin (ColumnValue b)))
columnParser
                (ColumnInfo b -> ColumnType b
forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciType ColumnInfo b
columnInfo)
                (Bool -> Nullability
Nullability (Bool -> Nullability) -> Bool -> Nullability
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Bool
forall (b :: BackendType). ColumnInfo b -> Bool
ciIsNullable ColumnInfo b
columnInfo)

      GQLNameIdentifier
-> GQLNameIdentifier
-> GQLNameIdentifier
-> (ColumnInfo b -> m (Parser 'Both n (UnpreparedValue b)))
-> NonEmpty (ColumnInfo b)
-> Description
-> Description
-> m (InputFieldsParser n (HashMap (Column b) (UnpreparedValue b)))
forall (n :: * -> *) r (m :: * -> *) (b :: BackendType) a.
(MonadParse n, MonadReader r m, Has MkTypename r, Has NamingCase r,
 Backend b) =>
GQLNameIdentifier
-> GQLNameIdentifier
-> GQLNameIdentifier
-> (ColumnInfo b -> m (Parser 'Both n a))
-> NonEmpty (ColumnInfo b)
-> Description
-> Description
-> m (InputFieldsParser n (HashMap (Column b) a))
updateOperator
        GQLNameIdentifier
tableGQLName
        (Name -> GQLNameIdentifier
fromAutogeneratedName $$(litName "inc"))
        (Name -> GQLNameIdentifier
fromAutogeneratedName $$(litName "_inc"))
        ColumnInfo b -> m (Parser 'Both n (UnpreparedValue b))
forall (b :: BackendType) (n :: * -> *) (f :: * -> *) r.
(BackendSchema b, MonadParse n, MonadError QErr f, MonadReader r f,
 Has MkTypename r, Has NamingCase r) =>
ColumnInfo b
-> f (Parser MetadataObjId 'Both n (UnpreparedValue b))
typedParser
        NonEmpty (ColumnInfo b)
columns
        Description
"increments the numeric columns with given value of the filtered values"
        (Text -> Description
Description (Text -> Description) -> Text -> Description
forall a b. (a -> b) -> a -> b
$ Text
"input type for incrementing numeric columns in table " Text -> TableName b -> Text
forall t. ToTxt t => Text -> t -> Text
<>> TableName b
tableName)

-- | Construct a root field, normally called update_tablename, that can be used
-- to update rows in a DB table specified by filters. Only returns a parser if
-- there are columns the user is allowed to update; otherwise returns Nothing.
updateTable ::
  forall b r m n.
  ( MonadBuildSchema b r m n,
    AggregationPredicatesSchema b,
    BackendTableSelectSchema b
  ) =>
  -- | backend-specific data needed to perform an update mutation
  P.InputFieldsParser n (BackendUpdate b (UnpreparedValue b)) ->
  Scenario ->
  -- | table source
  SourceInfo b ->
  -- | table info
  TableInfo b ->
  -- | field display name
  Name ->
  -- | field description, if any
  Maybe Description ->
  m (Maybe (P.FieldParser n (AnnotatedUpdateG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
updateTable :: InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
-> Scenario
-> SourceInfo b
-> TableInfo b
-> Name
-> Maybe Description
-> m (Maybe
        (FieldParser
           n
           (AnnotatedUpdateG
              b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
updateTable InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
backendUpdate Scenario
scenario SourceInfo b
sourceInfo TableInfo b
tableInfo Name
fieldName Maybe Description
description = MaybeT
  m
  (FieldParser
     n
     (AnnotatedUpdateG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> m (Maybe
        (FieldParser
           n
           (AnnotatedUpdateG
              b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT do
  let tableName :: TableName b
tableName = TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
      columns :: [ColumnInfo b]
columns = TableInfo b -> [ColumnInfo b]
forall (b :: BackendType). TableInfo b -> [ColumnInfo b]
tableColumns TableInfo b
tableInfo
      whereName :: Name
whereName = $$(litName "where")
      whereDesc :: Description
whereDesc = Description
"filter the rows which have to be updated"
      viewInfo :: Maybe ViewInfo
viewInfo = TableCoreInfoG b (FieldInfo b) (ColumnInfo b) -> Maybe ViewInfo
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> Maybe ViewInfo
_tciViewInfo (TableCoreInfoG b (FieldInfo b) (ColumnInfo b) -> Maybe ViewInfo)
-> TableCoreInfoG b (FieldInfo b) (ColumnInfo b) -> Maybe ViewInfo
forall a b. (a -> b) -> a -> b
$ TableInfo b -> TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
forall (b :: BackendType). TableInfo b -> TableCoreInfo b
_tiCoreInfo TableInfo b
tableInfo
  Bool -> MaybeT m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> MaybeT m ()) -> Bool -> MaybeT m ()
forall a b. (a -> b) -> a -> b
$ (ViewInfo -> Bool) -> Maybe ViewInfo -> Bool
isMutable ViewInfo -> Bool
viIsUpdatable Maybe ViewInfo
viewInfo
  RoleName
roleName <- (SchemaContext -> RoleName) -> MaybeT m RoleName
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve SchemaContext -> RoleName
scRole
  UpdPermInfo b
updatePerms <- Maybe (UpdPermInfo b) -> MaybeT m (UpdPermInfo b)
forall (m :: * -> *) b. Applicative m => Maybe b -> MaybeT m b
hoistMaybe (Maybe (UpdPermInfo b) -> MaybeT m (UpdPermInfo b))
-> Maybe (UpdPermInfo b) -> MaybeT m (UpdPermInfo b)
forall a b. (a -> b) -> a -> b
$ RolePermInfo b -> Maybe (UpdPermInfo b)
forall (b :: BackendType). RolePermInfo b -> Maybe (UpdPermInfo b)
_permUpd (RolePermInfo b -> Maybe (UpdPermInfo b))
-> RolePermInfo b -> Maybe (UpdPermInfo b)
forall a b. (a -> b) -> a -> b
$ RoleName -> TableInfo b -> RolePermInfo b
forall (b :: BackendType).
RoleName -> TableInfo b -> RolePermInfo b
getRolePermInfo RoleName
roleName TableInfo b
tableInfo
  -- If we're in a frontend scenario, we should not include backend_only updates
  -- For more info see Note [Backend only permissions]
  Bool -> MaybeT m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> MaybeT m ()) -> Bool -> MaybeT m ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Scenario
scenario Scenario -> Scenario -> Bool
forall a. Eq a => a -> a -> Bool
== Scenario
Frontend Bool -> Bool -> Bool
&& UpdPermInfo b -> Bool
forall (b :: BackendType). UpdPermInfo b -> Bool
upiBackendOnly UpdPermInfo b
updatePerms
  InputFieldsParser
  MetadataObjId n (AnnBoolExp b (UnpreparedValue b))
whereArg <- m (InputFieldsParser
     MetadataObjId n (AnnBoolExp b (UnpreparedValue b)))
-> MaybeT
     m
     (InputFieldsParser
        MetadataObjId n (AnnBoolExp b (UnpreparedValue b)))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (InputFieldsParser
      MetadataObjId n (AnnBoolExp b (UnpreparedValue b)))
 -> MaybeT
      m
      (InputFieldsParser
         MetadataObjId n (AnnBoolExp b (UnpreparedValue b))))
-> m (InputFieldsParser
        MetadataObjId n (AnnBoolExp b (UnpreparedValue b)))
-> MaybeT
     m
     (InputFieldsParser
        MetadataObjId n (AnnBoolExp b (UnpreparedValue b)))
forall a b. (a -> b) -> a -> b
$ Name
-> Maybe Description
-> Parser MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b))
-> InputFieldsParser
     MetadataObjId n (AnnBoolExp b (UnpreparedValue b))
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m a
P.field Name
whereName (Description -> Maybe Description
forall a. a -> Maybe a
Just Description
whereDesc) (Parser MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b))
 -> InputFieldsParser
      MetadataObjId n (AnnBoolExp b (UnpreparedValue b)))
-> m (Parser
        MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b)))
-> m (InputFieldsParser
        MetadataObjId n (AnnBoolExp b (UnpreparedValue b)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SourceInfo b
-> TableInfo b
-> m (Parser
        MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(MonadBuildSchema b r m n, AggregationPredicatesSchema b) =>
SourceInfo b
-> TableInfo b
-> m (Parser 'Input n (AnnBoolExp b (UnpreparedValue b)))
boolExp SourceInfo b
sourceInfo TableInfo b
tableInfo
  Parser
  'Output
  n
  (MutFldsG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
selection <- m (Parser
     'Output
     n
     (MutFldsG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> MaybeT
     m
     (Parser
        'Output
        n
        (MutFldsG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Parser
      'Output
      n
      (MutFldsG
         b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
 -> MaybeT
      m
      (Parser
         'Output
         n
         (MutFldsG
            b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
-> m (Parser
        'Output
        n
        (MutFldsG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> MaybeT
     m
     (Parser
        'Output
        n
        (MutFldsG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
forall a b. (a -> b) -> a -> b
$ SourceInfo b
-> TableInfo b
-> m (Parser
        'Output
        n
        (MutFldsG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(MonadBuildSchema b r m n, BackendTableSelectSchema b) =>
SourceInfo b
-> TableInfo b
-> m (Parser
        'Output
        n
        (MutFldsG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
mutationSelectionSet SourceInfo b
sourceInfo TableInfo b
tableInfo
  NamingCase
tCase <- (r -> NamingCase) -> MaybeT m NamingCase
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> NamingCase
forall a t. Has a t => t -> a
getter
  let argsParser :: InputFieldsParser
  MetadataObjId
  n
  (BackendUpdate b (UnpreparedValue b),
   AnnBoolExp b (UnpreparedValue b))
argsParser = (BackendUpdate b (UnpreparedValue b)
 -> AnnBoolExp b (UnpreparedValue b)
 -> (BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)))
-> InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
-> InputFieldsParser
     MetadataObjId n (AnnBoolExp b (UnpreparedValue b))
-> InputFieldsParser
     MetadataObjId
     n
     (BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b))
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
backendUpdate InputFieldsParser
  MetadataObjId n (AnnBoolExp b (UnpreparedValue b))
whereArg
  pure $
    Name
-> Maybe Description
-> InputFieldsParser
     MetadataObjId
     n
     (BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b))
-> Parser
     'Output
     n
     (MutFldsG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> FieldParser
     MetadataObjId
     n
     ((BackendUpdate b (UnpreparedValue b),
       AnnBoolExp b (UnpreparedValue b)),
      MutFldsG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
forall (m :: * -> *) origin a b.
MonadParse m =>
Name
-> Maybe Description
-> InputFieldsParser origin m a
-> Parser origin 'Output m b
-> FieldParser origin m (a, b)
P.subselection Name
fieldName Maybe Description
description InputFieldsParser
  MetadataObjId
  n
  (BackendUpdate b (UnpreparedValue b),
   AnnBoolExp b (UnpreparedValue b))
argsParser Parser
  'Output
  n
  (MutFldsG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
selection
      FieldParser
  MetadataObjId
  n
  ((BackendUpdate b (UnpreparedValue b),
    AnnBoolExp b (UnpreparedValue b)),
   MutFldsG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> (((BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b)),
     MutFldsG
       b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
    -> AnnotatedUpdateG
         b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> FieldParser
     n
     (AnnotatedUpdateG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> TableName b
-> [ColumnInfo b]
-> UpdPermInfo b
-> Maybe NamingCase
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
forall (b :: BackendType).
Backend b =>
TableName b
-> [ColumnInfo b]
-> UpdPermInfo b
-> Maybe NamingCase
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
mkUpdateObject TableName b
tableName [ColumnInfo b]
columns UpdPermInfo b
updatePerms (NamingCase -> Maybe NamingCase
forall a. a -> Maybe a
Just NamingCase
tCase) (((BackendUpdate b (UnpreparedValue b),
   AnnBoolExp b (UnpreparedValue b)),
  MutationOutputG
    b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
 -> AnnotatedUpdateG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> (((BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b)),
     MutFldsG
       b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
    -> ((BackendUpdate b (UnpreparedValue b),
         AnnBoolExp b (UnpreparedValue b)),
        MutationOutputG
          b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutFldsG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MutFldsG
   b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
 -> MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutFldsG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MutFldsG
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
-> MutationOutputG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
forall (b :: BackendType) r v.
MutFldsG b r v -> MutationOutputG b r v
MOutMultirowFields

-- | Construct a root field, normally called 'update_tablename_by_pk', that can be used
-- to update a single in a DB table, specified by primary key. Only returns a
-- parser if there are columns the user is allowed to update and if the user has
-- select permissions on all primary keys; otherwise returns Nothing.
updateTableByPk ::
  forall b r m n.
  MonadBuildSchema b r m n =>
  BackendTableSelectSchema b =>
  -- | backend-specific data needed to perform an update mutation
  P.InputFieldsParser n (BackendUpdate b (UnpreparedValue b)) ->
  Scenario ->
  -- | table source
  SourceInfo b ->
  -- | table info
  TableInfo b ->
  -- | field display name
  Name ->
  -- | field description, if any
  Maybe Description ->
  m (Maybe (P.FieldParser n (AnnotatedUpdateG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
updateTableByPk :: InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
-> Scenario
-> SourceInfo b
-> TableInfo b
-> Name
-> Maybe Description
-> m (Maybe
        (FieldParser
           n
           (AnnotatedUpdateG
              b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
updateTableByPk InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
backendUpdate Scenario
scenario SourceInfo b
sourceInfo TableInfo b
tableInfo Name
fieldName Maybe Description
description = MaybeT
  m
  (FieldParser
     n
     (AnnotatedUpdateG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> m (Maybe
        (FieldParser
           n
           (AnnotatedUpdateG
              b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT
   m
   (FieldParser
      n
      (AnnotatedUpdateG
         b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
 -> m (Maybe
         (FieldParser
            n
            (AnnotatedUpdateG
               b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))))
-> MaybeT
     m
     (FieldParser
        n
        (AnnotatedUpdateG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> m (Maybe
        (FieldParser
           n
           (AnnotatedUpdateG
              b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
forall a b. (a -> b) -> a -> b
$ do
  let columns :: [ColumnInfo b]
columns = TableInfo b -> [ColumnInfo b]
forall (b :: BackendType). TableInfo b -> [ColumnInfo b]
tableColumns TableInfo b
tableInfo
      tableName :: TableName b
tableName = TableInfo b -> TableName b
forall (b :: BackendType). TableInfo b -> TableName b
tableInfoName TableInfo b
tableInfo
      viewInfo :: Maybe ViewInfo
viewInfo = TableCoreInfoG b (FieldInfo b) (ColumnInfo b) -> Maybe ViewInfo
forall (b :: BackendType) field primaryKeyColumn.
TableCoreInfoG b field primaryKeyColumn -> Maybe ViewInfo
_tciViewInfo (TableCoreInfoG b (FieldInfo b) (ColumnInfo b) -> Maybe ViewInfo)
-> TableCoreInfoG b (FieldInfo b) (ColumnInfo b) -> Maybe ViewInfo
forall a b. (a -> b) -> a -> b
$ TableInfo b -> TableCoreInfoG b (FieldInfo b) (ColumnInfo b)
forall (b :: BackendType). TableInfo b -> TableCoreInfo b
_tiCoreInfo TableInfo b
tableInfo
  Bool -> MaybeT m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> MaybeT m ()) -> Bool -> MaybeT m ()
forall a b. (a -> b) -> a -> b
$ (ViewInfo -> Bool) -> Maybe ViewInfo -> Bool
isMutable ViewInfo -> Bool
viIsUpdatable Maybe ViewInfo
viewInfo
  RoleName
roleName <- (SchemaContext -> RoleName) -> MaybeT m RoleName
forall r (m :: * -> *) a b.
(MonadReader r m, Has a r) =>
(a -> b) -> m b
retrieve SchemaContext -> RoleName
scRole
  UpdPermInfo b
updatePerms <- Maybe (UpdPermInfo b) -> MaybeT m (UpdPermInfo b)
forall (m :: * -> *) b. Applicative m => Maybe b -> MaybeT m b
hoistMaybe (Maybe (UpdPermInfo b) -> MaybeT m (UpdPermInfo b))
-> Maybe (UpdPermInfo b) -> MaybeT m (UpdPermInfo b)
forall a b. (a -> b) -> a -> b
$ RolePermInfo b -> Maybe (UpdPermInfo b)
forall (b :: BackendType). RolePermInfo b -> Maybe (UpdPermInfo b)
_permUpd (RolePermInfo b -> Maybe (UpdPermInfo b))
-> RolePermInfo b -> Maybe (UpdPermInfo b)
forall a b. (a -> b) -> a -> b
$ RoleName -> TableInfo b -> RolePermInfo b
forall (b :: BackendType).
RoleName -> TableInfo b -> RolePermInfo b
getRolePermInfo RoleName
roleName TableInfo b
tableInfo
  -- If we're in a frontend scenario, we should not include backend_only updates
  -- For more info see Note [Backend only permissions]
  Bool -> MaybeT m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> MaybeT m ()) -> Bool -> MaybeT m ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Scenario
scenario Scenario -> Scenario -> Bool
forall a. Eq a => a -> a -> Bool
== Scenario
Frontend Bool -> Bool -> Bool
&& UpdPermInfo b -> Bool
forall (b :: BackendType). UpdPermInfo b -> Bool
upiBackendOnly UpdPermInfo b
updatePerms
  InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))
pkArgs <- m (Maybe (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))))
-> MaybeT
     m (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b)))
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))))
 -> MaybeT
      m (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))))
-> m (Maybe
        (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))))
-> MaybeT
     m (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b)))
forall a b. (a -> b) -> a -> b
$ TableInfo b
-> m (Maybe
        (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
MonadBuildSchema b r m n =>
TableInfo b
-> m (Maybe
        (InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))))
primaryKeysArguments TableInfo b
tableInfo
  Parser 'Output n (AnnotatedFields b)
selection <- m (Maybe (Parser 'Output n (AnnotatedFields b)))
-> MaybeT m (Parser 'Output n (AnnotatedFields b))
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe (Parser 'Output n (AnnotatedFields b)))
 -> MaybeT m (Parser 'Output n (AnnotatedFields b)))
-> m (Maybe (Parser 'Output n (AnnotatedFields b)))
-> MaybeT m (Parser 'Output n (AnnotatedFields b))
forall a b. (a -> b) -> a -> b
$ SourceInfo b
-> TableInfo b -> m (Maybe (Parser 'Output n (AnnotatedFields b)))
forall (b :: BackendType) r (m :: * -> *) (n :: * -> *).
(BackendTableSelectSchema b, MonadBuildSchemaBase r m n) =>
SourceInfo b
-> TableInfo b -> m (Maybe (Parser 'Output n (AnnotatedFields b)))
tableSelectionSet SourceInfo b
sourceInfo TableInfo b
tableInfo
  NamingCase
tCase <- (r -> NamingCase) -> MaybeT m NamingCase
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks r -> NamingCase
forall a t. Has a t => t -> a
getter
  m (FieldParser
     n
     (AnnotatedUpdateG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> MaybeT
     m
     (FieldParser
        n
        (AnnotatedUpdateG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (FieldParser
      n
      (AnnotatedUpdateG
         b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
 -> MaybeT
      m
      (FieldParser
         n
         (AnnotatedUpdateG
            b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
-> m (FieldParser
        n
        (AnnotatedUpdateG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> MaybeT
     m
     (FieldParser
        n
        (AnnotatedUpdateG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
forall a b. (a -> b) -> a -> b
$ do
    GQLNameIdentifier
tableGQLName <- TableInfo b -> m GQLNameIdentifier
forall (b :: BackendType) (m :: * -> *).
(Backend b, MonadError QErr m) =>
TableInfo b -> m GQLNameIdentifier
getTableIdentifierName TableInfo b
tableInfo
    Name
pkObjectName <- Name -> m Name
forall r (m :: * -> *).
(MonadReader r m, Has MkTypename r) =>
Name -> m Name
mkTypename (Name -> m Name) -> Name -> m Name
forall a b. (a -> b) -> a -> b
$ NamingCase -> GQLNameIdentifier -> Name
applyTypeNameCaseIdentifier NamingCase
tCase (GQLNameIdentifier -> Name) -> GQLNameIdentifier -> Name
forall a b. (a -> b) -> a -> b
$ GQLNameIdentifier -> GQLNameIdentifier
mkTablePkColumnsInputTypeName GQLNameIdentifier
tableGQLName
    let pkFieldName :: Name
pkFieldName = $$(litName "pk_columns")
        pkObjectDesc :: Description
pkObjectDesc = Text -> Description
Description (Text -> Description) -> Text -> Description
forall a b. (a -> b) -> a -> b
$ Text
"primary key columns input for table: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> TableName b -> Text
forall a. ToTxt a => a -> Text
toTxt TableName b
tableName
        pkParser :: Parser MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b))
pkParser = Name
-> Maybe Description
-> InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))
-> Parser MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b))
forall (m :: * -> *) origin a.
MonadParse m =>
Name
-> Maybe Description
-> InputFieldsParser origin m a
-> Parser origin 'Input m a
P.object Name
pkObjectName (Description -> Maybe Description
forall a. a -> Maybe a
Just Description
pkObjectDesc) InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))
pkArgs
        argsParser :: InputFieldsParser
  MetadataObjId
  n
  (BackendUpdate b (UnpreparedValue b),
   AnnBoolExp b (UnpreparedValue b))
argsParser = (,) (BackendUpdate b (UnpreparedValue b)
 -> AnnBoolExp b (UnpreparedValue b)
 -> (BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)))
-> InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
-> InputFieldsParser
     MetadataObjId
     n
     (AnnBoolExp b (UnpreparedValue b)
      -> (BackendUpdate b (UnpreparedValue b),
          AnnBoolExp b (UnpreparedValue b)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> InputFieldsParser n (BackendUpdate b (UnpreparedValue b))
backendUpdate InputFieldsParser
  MetadataObjId
  n
  (AnnBoolExp b (UnpreparedValue b)
   -> (BackendUpdate b (UnpreparedValue b),
       AnnBoolExp b (UnpreparedValue b)))
-> InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))
-> InputFieldsParser
     MetadataObjId
     n
     (BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Name
-> Maybe Description
-> Parser MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b))
-> InputFieldsParser n (AnnBoolExp b (UnpreparedValue b))
forall (m :: * -> *) (k :: Kind) origin a.
(MonadParse m, 'Input <: k) =>
Name
-> Maybe Description
-> Parser origin k m a
-> InputFieldsParser origin m a
P.field Name
pkFieldName Maybe Description
forall a. Maybe a
Nothing Parser MetadataObjId 'Input n (AnnBoolExp b (UnpreparedValue b))
pkParser
    FieldParser
  n
  (AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> m (FieldParser
        n
        (AnnotatedUpdateG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FieldParser
   n
   (AnnotatedUpdateG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
 -> m (FieldParser
         n
         (AnnotatedUpdateG
            b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
-> FieldParser
     n
     (AnnotatedUpdateG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> m (FieldParser
        n
        (AnnotatedUpdateG
           b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
forall a b. (a -> b) -> a -> b
$
      Name
-> Maybe Description
-> InputFieldsParser
     MetadataObjId
     n
     (BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b))
-> Parser 'Output n (AnnotatedFields b)
-> FieldParser
     MetadataObjId
     n
     ((BackendUpdate b (UnpreparedValue b),
       AnnBoolExp b (UnpreparedValue b)),
      AnnotatedFields b)
forall (m :: * -> *) origin a b.
MonadParse m =>
Name
-> Maybe Description
-> InputFieldsParser origin m a
-> Parser origin 'Output m b
-> FieldParser origin m (a, b)
P.subselection Name
fieldName Maybe Description
description InputFieldsParser
  MetadataObjId
  n
  (BackendUpdate b (UnpreparedValue b),
   AnnBoolExp b (UnpreparedValue b))
argsParser Parser 'Output n (AnnotatedFields b)
selection
        FieldParser
  MetadataObjId
  n
  ((BackendUpdate b (UnpreparedValue b),
    AnnBoolExp b (UnpreparedValue b)),
   AnnotatedFields b)
-> (((BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b)),
     AnnotatedFields b)
    -> AnnotatedUpdateG
         b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> FieldParser
     n
     (AnnotatedUpdateG
        b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> TableName b
-> [ColumnInfo b]
-> UpdPermInfo b
-> Maybe NamingCase
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
forall (b :: BackendType).
Backend b =>
TableName b
-> [ColumnInfo b]
-> UpdPermInfo b
-> Maybe NamingCase
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
mkUpdateObject TableName b
tableName [ColumnInfo b]
columns UpdPermInfo b
updatePerms (NamingCase -> Maybe NamingCase
forall a. a -> Maybe a
Just NamingCase
tCase) (((BackendUpdate b (UnpreparedValue b),
   AnnBoolExp b (UnpreparedValue b)),
  MutationOutputG
    b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
 -> AnnotatedUpdateG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> (((BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b)),
     AnnotatedFields b)
    -> ((BackendUpdate b (UnpreparedValue b),
         AnnBoolExp b (UnpreparedValue b)),
        MutationOutputG
          b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)))
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    AnnotatedFields b)
-> AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AnnotatedFields b
 -> MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    AnnotatedFields b)
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AnnotatedFields b
-> MutationOutputG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
forall (b :: BackendType) r v.
AnnFieldsG b r v -> MutationOutputG b r v
MOutSinglerowObject

mkUpdateObject ::
  Backend b =>
  TableName b ->
  [ColumnInfo b] ->
  UpdPermInfo b ->
  (Maybe NamingCase) ->
  ( ( BackendUpdate b (UnpreparedValue b),
      AnnBoolExp b (UnpreparedValue b)
    ),
    MutationOutputG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
  ) ->
  AnnotatedUpdateG b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
mkUpdateObject :: TableName b
-> [ColumnInfo b]
-> UpdPermInfo b
-> Maybe NamingCase
-> ((BackendUpdate b (UnpreparedValue b),
     AnnBoolExp b (UnpreparedValue b)),
    MutationOutputG
      b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))
-> AnnotatedUpdateG
     b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
mkUpdateObject TableName b
_auTable [ColumnInfo b]
_auAllCols UpdPermInfo b
updatePerms Maybe NamingCase
_auNamingConvention ((BackendUpdate b (UnpreparedValue b)
_auBackend, AnnBoolExp b (UnpreparedValue b)
whereExp), MutationOutputG
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
_auOutput) =
  AnnotatedUpdateG :: forall (b :: BackendType) r v.
TableName b
-> (AnnBoolExp b v, AnnBoolExp b v)
-> AnnBoolExp b v
-> BackendUpdate b v
-> MutationOutputG b r v
-> [ColumnInfo b]
-> Maybe NamingCase
-> AnnotatedUpdateG b r v
AnnotatedUpdateG {[ColumnInfo b]
Maybe NamingCase
(AnnBoolExp b (UnpreparedValue b),
 AnnBoolExp b (UnpreparedValue b))
TableName b
BackendUpdate b (UnpreparedValue b)
AnnBoolExp b (UnpreparedValue b)
MutationOutputG
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
_auNamingConvention :: Maybe NamingCase
_auAllCols :: [ColumnInfo b]
_auOutput :: MutationOutputG
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
_auBackend :: BackendUpdate b (UnpreparedValue b)
_auCheck :: AnnBoolExp b (UnpreparedValue b)
_auWhere :: (AnnBoolExp b (UnpreparedValue b),
 AnnBoolExp b (UnpreparedValue b))
_auTable :: TableName b
_auCheck :: AnnBoolExp b (UnpreparedValue b)
_auWhere :: (AnnBoolExp b (UnpreparedValue b),
 AnnBoolExp b (UnpreparedValue b))
_auOutput :: MutationOutputG
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
_auBackend :: BackendUpdate b (UnpreparedValue b)
_auNamingConvention :: Maybe NamingCase
_auAllCols :: [ColumnInfo b]
_auTable :: TableName b
..}
  where
    permissionFilter :: AnnBoolExp b (UnpreparedValue b)
permissionFilter = (PartialSQLExp b -> UnpreparedValue b)
-> AnnBoolExpFld b (PartialSQLExp b)
-> AnnBoolExpFld b (UnpreparedValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PartialSQLExp b -> UnpreparedValue b
forall (b :: BackendType). PartialSQLExp b -> UnpreparedValue b
partialSQLExpToUnpreparedValue (AnnBoolExpFld b (PartialSQLExp b)
 -> AnnBoolExpFld b (UnpreparedValue b))
-> GBoolExp b (AnnBoolExpFld b (PartialSQLExp b))
-> AnnBoolExp b (UnpreparedValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UpdPermInfo b -> GBoolExp b (AnnBoolExpFld b (PartialSQLExp b))
forall (b :: BackendType). UpdPermInfo b -> AnnBoolExpPartialSQL b
upiFilter UpdPermInfo b
updatePerms
    _auWhere :: (AnnBoolExp b (UnpreparedValue b),
 AnnBoolExp b (UnpreparedValue b))
_auWhere = (AnnBoolExp b (UnpreparedValue b)
permissionFilter, AnnBoolExp b (UnpreparedValue b)
whereExp)
    _auCheck :: AnnBoolExp b (UnpreparedValue b)
_auCheck = AnnBoolExp b (UnpreparedValue b)
-> (GBoolExp b (AnnBoolExpFld b (PartialSQLExp b))
    -> AnnBoolExp b (UnpreparedValue b))
-> Maybe (GBoolExp b (AnnBoolExpFld b (PartialSQLExp b)))
-> AnnBoolExp b (UnpreparedValue b)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe AnnBoolExp b (UnpreparedValue b)
forall (backend :: BackendType) scalar. AnnBoolExp backend scalar
annBoolExpTrue (((AnnBoolExpFld b (PartialSQLExp b)
 -> AnnBoolExpFld b (UnpreparedValue b))
-> GBoolExp b (AnnBoolExpFld b (PartialSQLExp b))
-> AnnBoolExp b (UnpreparedValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((AnnBoolExpFld b (PartialSQLExp b)
  -> AnnBoolExpFld b (UnpreparedValue b))
 -> GBoolExp b (AnnBoolExpFld b (PartialSQLExp b))
 -> AnnBoolExp b (UnpreparedValue b))
-> ((PartialSQLExp b -> UnpreparedValue b)
    -> AnnBoolExpFld b (PartialSQLExp b)
    -> AnnBoolExpFld b (UnpreparedValue b))
-> (PartialSQLExp b -> UnpreparedValue b)
-> GBoolExp b (AnnBoolExpFld b (PartialSQLExp b))
-> AnnBoolExp b (UnpreparedValue b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PartialSQLExp b -> UnpreparedValue b)
-> AnnBoolExpFld b (PartialSQLExp b)
-> AnnBoolExpFld b (UnpreparedValue b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) PartialSQLExp b -> UnpreparedValue b
forall (b :: BackendType). PartialSQLExp b -> UnpreparedValue b
partialSQLExpToUnpreparedValue) (Maybe (GBoolExp b (AnnBoolExpFld b (PartialSQLExp b)))
 -> AnnBoolExp b (UnpreparedValue b))
-> Maybe (GBoolExp b (AnnBoolExpFld b (PartialSQLExp b)))
-> AnnBoolExp b (UnpreparedValue b)
forall a b. (a -> b) -> a -> b
$ UpdPermInfo b
-> Maybe (GBoolExp b (AnnBoolExpFld b (PartialSQLExp b)))
forall (b :: BackendType).
UpdPermInfo b -> Maybe (AnnBoolExpPartialSQL b)
upiCheck UpdPermInfo b
updatePerms