2019-03-25 20:10:52 +03:00
|
|
|
module Hasura.RQL.DDL.EventTrigger
|
2021-09-24 01:56:37 +03:00
|
|
|
( CreateEventTriggerQuery,
|
|
|
|
runCreateEventTriggerQuery,
|
|
|
|
DeleteEventTriggerQuery,
|
|
|
|
runDeleteEventTriggerQuery,
|
|
|
|
dropEventTriggerInMetadata,
|
|
|
|
RedeliverEventQuery,
|
|
|
|
runRedeliverEvent,
|
|
|
|
InvokeEventTriggerQuery,
|
|
|
|
runInvokeEventTrigger,
|
|
|
|
-- TODO(from master): review
|
|
|
|
getHeaderInfosFromConf,
|
|
|
|
getWebhookInfoFromConf,
|
|
|
|
buildEventTriggerInfo,
|
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
import Control.Lens ((.~))
|
|
|
|
import Data.Aeson
|
|
|
|
import Data.ByteString.Lazy qualified as LBS
|
|
|
|
import Data.Environment qualified as Env
|
|
|
|
import Data.HashMap.Strict qualified as HM
|
|
|
|
import Data.HashMap.Strict.InsOrd qualified as OMap
|
|
|
|
import Data.Text qualified as T
|
|
|
|
import Data.Text.Extended
|
|
|
|
import Hasura.Base.Error
|
|
|
|
import Hasura.EncJSON
|
|
|
|
import Hasura.Prelude
|
|
|
|
import Hasura.RQL.DDL.Headers
|
|
|
|
import Hasura.RQL.DDL.RequestTransform (MetadataTransform)
|
|
|
|
import Hasura.RQL.Types
|
|
|
|
import Hasura.RQL.Types.Eventing.Backend
|
|
|
|
import Hasura.SQL.AnyBackend qualified as AB
|
|
|
|
import Hasura.Session
|
|
|
|
import Hasura.Tracing qualified as Tracing
|
|
|
|
import Text.Regex.TDFA qualified as TDFA
|
|
|
|
|
|
|
|
data CreateEventTriggerQuery (b :: BackendType) = CreateEventTriggerQuery
|
|
|
|
{ _cetqSource :: !SourceName,
|
|
|
|
_cetqName :: !TriggerName,
|
|
|
|
_cetqTable :: !(TableName b),
|
|
|
|
_cetqInsert :: !(Maybe (SubscribeOpSpec b)),
|
|
|
|
_cetqUpdate :: !(Maybe (SubscribeOpSpec b)),
|
|
|
|
_cetqDelete :: !(Maybe (SubscribeOpSpec b)),
|
|
|
|
_cetqEnableManual :: !(Maybe Bool),
|
|
|
|
_cetqRetryConf :: !(Maybe RetryConf),
|
|
|
|
_cetqWebhook :: !(Maybe InputWebhook),
|
|
|
|
_cetqWebhookFromEnv :: !(Maybe Text),
|
|
|
|
_cetqHeaders :: !(Maybe [HeaderConf]),
|
|
|
|
_cetqReplace :: !Bool,
|
2021-09-29 11:13:30 +03:00
|
|
|
_cetqRequestTransform :: !(Maybe MetadataTransform)
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
instance Backend b => FromJSON (CreateEventTriggerQuery b) where
|
2021-09-24 01:56:37 +03:00
|
|
|
parseJSON = withObject "CreateEventTriggerQuery" \o -> do
|
|
|
|
sourceName <- o .:? "source" .!= defaultSource
|
|
|
|
name <- o .: "name"
|
|
|
|
table <- o .: "table"
|
|
|
|
insert <- o .:? "insert"
|
|
|
|
update <- o .:? "update"
|
|
|
|
delete <- o .:? "delete"
|
|
|
|
enableManual <- o .:? "enable_manual" .!= False
|
|
|
|
retryConf <- o .:? "retry_conf"
|
|
|
|
webhook <- o .:? "webhook"
|
|
|
|
webhookFromEnv <- o .:? "webhook_from_env"
|
|
|
|
headers <- o .:? "headers"
|
|
|
|
replace <- o .:? "replace" .!= False
|
2021-09-29 11:13:30 +03:00
|
|
|
requestTransform <- o .:? "request_transform"
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
let regex = "^[A-Za-z]+[A-Za-z0-9_\\-]*$" :: LBS.ByteString
|
|
|
|
compiledRegex = TDFA.makeRegex regex :: TDFA.Regex
|
|
|
|
isMatch = TDFA.match compiledRegex . T.unpack $ triggerNameToTxt name
|
|
|
|
unless isMatch $
|
|
|
|
fail "only alphanumeric and underscore and hyphens allowed for name"
|
|
|
|
unless (T.length (triggerNameToTxt name) <= maxTriggerNameLength) $
|
|
|
|
fail "event trigger name can be at most 42 characters"
|
|
|
|
unless (any isJust [insert, update, delete] || enableManual) $
|
|
|
|
fail "atleast one amongst insert/update/delete/enable_manual spec must be provided"
|
|
|
|
case (webhook, webhookFromEnv) of
|
|
|
|
(Just _, Nothing) -> return ()
|
|
|
|
(Nothing, Just _) -> return ()
|
2021-09-24 01:56:37 +03:00
|
|
|
(Just _, Just _) -> fail "only one of webhook or webhook_from_env should be given"
|
|
|
|
_ -> fail "must provide webhook or webhook_from_env"
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
mapM_ checkEmptyCols [insert, update, delete]
|
2021-09-29 11:13:30 +03:00
|
|
|
return $ CreateEventTriggerQuery sourceName name table insert update delete (Just enableManual) retryConf webhook webhookFromEnv headers replace requestTransform
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
where
|
2021-09-24 01:56:37 +03:00
|
|
|
checkEmptyCols spec =
|
|
|
|
case spec of
|
|
|
|
Just (SubscribeOpSpec (SubCArray cols) _) -> when (null cols) (fail "found empty column specification")
|
|
|
|
Just (SubscribeOpSpec _ (Just (SubCArray cols))) -> when (null cols) (fail "found empty payload specification")
|
|
|
|
_ -> return ()
|
|
|
|
|
|
|
|
data DeleteEventTriggerQuery (b :: BackendType) = DeleteEventTriggerQuery
|
|
|
|
{ _detqSource :: !SourceName,
|
|
|
|
_detqName :: !TriggerName
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
instance FromJSON (DeleteEventTriggerQuery b) where
|
2021-09-20 22:49:33 +03:00
|
|
|
parseJSON = withObject "DeleteEventTriggerQuery" $ \o ->
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
DeleteEventTriggerQuery
|
|
|
|
<$> o .:? "source" .!= defaultSource
|
|
|
|
<*> o .: "name"
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
data RedeliverEventQuery (b :: BackendType) = RedeliverEventQuery
|
|
|
|
{ _rdeqEventId :: !EventId,
|
|
|
|
_rdeqSource :: !SourceName
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
instance FromJSON (RedeliverEventQuery b) where
|
2021-09-20 22:49:33 +03:00
|
|
|
parseJSON = withObject "RedeliverEventQuery" $ \o ->
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
RedeliverEventQuery
|
|
|
|
<$> o .: "event_id"
|
|
|
|
<*> o .:? "source" .!= defaultSource
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
data InvokeEventTriggerQuery (b :: BackendType) = InvokeEventTriggerQuery
|
|
|
|
{ _ietqName :: !TriggerName,
|
|
|
|
_ietqSource :: !SourceName,
|
|
|
|
_ietqPayload :: !Value
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
instance Backend b => FromJSON (InvokeEventTriggerQuery b) where
|
2021-09-20 22:49:33 +03:00
|
|
|
parseJSON = withObject "InvokeEventTriggerQuery" $ \o ->
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
InvokeEventTriggerQuery
|
|
|
|
<$> o .: "name"
|
|
|
|
<*> o .:? "source" .!= defaultSource
|
|
|
|
<*> o .: "payload"
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
resolveEventTriggerQuery ::
|
|
|
|
forall b m.
|
|
|
|
(Backend b, UserInfoM m, QErrM m, CacheRM m) =>
|
|
|
|
CreateEventTriggerQuery b ->
|
|
|
|
m (TableCoreInfo b, Bool, EventTriggerConf b)
|
2021-09-16 14:03:01 +03:00
|
|
|
resolveEventTriggerQuery (CreateEventTriggerQuery source name qt insert update delete enableManual retryConf webhook webhookFromEnv mheaders replace metaTransform) = do
|
2020-12-28 15:56:00 +03:00
|
|
|
ti <- askTableCoreInfo source qt
|
2018-09-19 15:12:57 +03:00
|
|
|
-- can only replace for same table
|
|
|
|
when replace $ do
|
2021-09-06 14:15:36 +03:00
|
|
|
ti' <- _tiCoreInfo <$> askTabInfoFromTrigger @b source name
|
2019-11-20 21:21:30 +03:00
|
|
|
when (_tciName ti' /= _tciName ti) $ throw400 NotSupported "cannot replace table or schema for trigger"
|
2018-09-19 15:12:57 +03:00
|
|
|
|
2018-09-05 14:26:46 +03:00
|
|
|
assertCols ti insert
|
|
|
|
assertCols ti update
|
|
|
|
assertCols ti delete
|
2018-09-19 15:12:57 +03:00
|
|
|
|
2019-02-14 10:37:59 +03:00
|
|
|
let rconf = fromMaybe defaultRetryConf retryConf
|
2021-09-16 14:03:01 +03:00
|
|
|
return (ti, replace, EventTriggerConf name (TriggerOpsDef insert update delete enableManual) webhook webhookFromEnv rconf mheaders metaTransform)
|
2018-09-05 14:26:46 +03:00
|
|
|
where
|
2021-09-20 10:34:59 +03:00
|
|
|
assertCols :: TableCoreInfo b -> Maybe (SubscribeOpSpec b) -> m ()
|
2021-01-20 03:31:53 +03:00
|
|
|
assertCols ti opSpec = onJust opSpec \sos -> case sosColumns sos of
|
2021-09-24 01:56:37 +03:00
|
|
|
SubCStar -> return ()
|
2021-09-09 14:54:19 +03:00
|
|
|
SubCArray columns -> forM_ columns (assertColumnExists @b (_tciFieldInfoMap ti) "")
|
2018-11-23 16:02:46 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
createEventTriggerQueryMetadata ::
|
|
|
|
forall b m.
|
|
|
|
(BackendMetadata b, QErrM m, UserInfoM m, CacheRWM m, MetadataM m) =>
|
|
|
|
CreateEventTriggerQuery b ->
|
|
|
|
m (TableCoreInfo b, EventTriggerConf b)
|
2020-12-28 15:56:00 +03:00
|
|
|
createEventTriggerQueryMetadata q = do
|
|
|
|
(tableCoreInfo, replace, triggerConf) <- resolveEventTriggerQuery q
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
let table = _cetqTable q
|
|
|
|
source = _cetqSource q
|
2020-12-28 15:56:00 +03:00
|
|
|
triggerName = etcName triggerConf
|
2021-03-15 16:02:58 +03:00
|
|
|
metadataObj =
|
2021-09-24 01:56:37 +03:00
|
|
|
MOSourceObjId source $
|
|
|
|
AB.mkAnyBackend $
|
|
|
|
SMOTableObj @b table $
|
|
|
|
MTOTrigger triggerName
|
|
|
|
buildSchemaCacheFor metadataObj $
|
|
|
|
MetadataModifier $
|
|
|
|
tableMetadataSetter @b source table . tmEventTriggers
|
|
|
|
%~ if replace
|
|
|
|
then ix triggerName .~ triggerConf
|
|
|
|
else OMap.insert triggerName triggerConf
|
2020-12-28 15:56:00 +03:00
|
|
|
pure (tableCoreInfo, triggerConf)
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
runCreateEventTriggerQuery ::
|
|
|
|
forall b m.
|
|
|
|
(BackendMetadata b, QErrM m, UserInfoM m, CacheRWM m, MetadataM m) =>
|
|
|
|
CreateEventTriggerQuery b ->
|
|
|
|
m EncJSON
|
2018-12-13 10:26:15 +03:00
|
|
|
runCreateEventTriggerQuery q = do
|
2021-09-09 14:54:19 +03:00
|
|
|
void $ createEventTriggerQueryMetadata @b q
|
2020-12-08 17:22:31 +03:00
|
|
|
pure successMsg
|
2018-09-05 14:26:46 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
runDeleteEventTriggerQuery ::
|
|
|
|
forall b m.
|
2021-10-22 17:49:15 +03:00
|
|
|
(BackendEventTrigger b, MonadError QErr m, CacheRWM m, MonadIO m, MetadataM m) =>
|
2021-09-24 01:56:37 +03:00
|
|
|
DeleteEventTriggerQuery b ->
|
|
|
|
m EncJSON
|
2020-12-28 15:56:00 +03:00
|
|
|
runDeleteEventTriggerQuery (DeleteEventTriggerQuery source name) = do
|
2021-01-20 03:31:53 +03:00
|
|
|
sourceInfo <- askSourceInfo source
|
2021-09-24 01:56:37 +03:00
|
|
|
let maybeTable = HM.lookup name $
|
|
|
|
HM.unions $
|
|
|
|
flip map (HM.toList $ _siTables @b sourceInfo) $ \(table, tableInfo) ->
|
|
|
|
HM.map (const table) $ _tiEventTriggerInfoMap tableInfo
|
|
|
|
table <-
|
|
|
|
onNothing maybeTable $
|
|
|
|
throw400 NotExists $
|
|
|
|
"event trigger with name " <> name <<> " does not exist"
|
|
|
|
|
|
|
|
withNewInconsistentObjsCheck $
|
|
|
|
buildSchemaCache $
|
|
|
|
MetadataModifier $
|
|
|
|
tableMetadataSetter @b source table %~ dropEventTriggerInMetadata name
|
2021-09-09 14:54:19 +03:00
|
|
|
|
|
|
|
dropTriggerAndArchiveEvents @b (_siConfiguration sourceInfo) name
|
2020-12-28 15:56:00 +03:00
|
|
|
|
2019-11-20 21:21:30 +03:00
|
|
|
pure successMsg
|
2018-09-07 14:51:01 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
runRedeliverEvent ::
|
|
|
|
forall b m.
|
|
|
|
(BackendEventTrigger b, MonadIO m, CacheRM m, QErrM m, MetadataM m) =>
|
|
|
|
RedeliverEventQuery b ->
|
|
|
|
m EncJSON
|
2020-12-28 15:56:00 +03:00
|
|
|
runRedeliverEvent (RedeliverEventQuery eventId source) = do
|
2021-09-06 14:15:36 +03:00
|
|
|
sourceConfig <- askSourceConfig @b source
|
|
|
|
redeliverEvent @b sourceConfig eventId
|
2020-12-28 15:56:00 +03:00
|
|
|
pure successMsg
|
2018-09-19 15:12:57 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
runInvokeEventTrigger ::
|
|
|
|
forall b m.
|
|
|
|
( MonadIO m,
|
|
|
|
QErrM m,
|
|
|
|
CacheRM m,
|
|
|
|
MetadataM m,
|
|
|
|
Tracing.MonadTrace m,
|
|
|
|
UserInfoM m,
|
|
|
|
BackendEventTrigger b
|
|
|
|
) =>
|
|
|
|
InvokeEventTriggerQuery b ->
|
|
|
|
m EncJSON
|
2020-12-28 15:56:00 +03:00
|
|
|
runInvokeEventTrigger (InvokeEventTriggerQuery name source payload) = do
|
2021-09-06 14:15:36 +03:00
|
|
|
trigInfo <- askEventTriggerInfo @b source name
|
2019-05-13 12:41:07 +03:00
|
|
|
assertManual $ etiOpsDef trigInfo
|
2021-09-24 01:56:37 +03:00
|
|
|
ti <- askTabInfoFromTrigger source name
|
2021-09-06 14:15:36 +03:00
|
|
|
sourceConfig <- askSourceConfig @b source
|
2021-07-27 11:05:33 +03:00
|
|
|
traceCtx <- Tracing.currentContext
|
|
|
|
userInfo <- askUserInfo
|
2021-09-06 14:15:36 +03:00
|
|
|
eid <- insertManualEvent @b sourceConfig (tableInfoName @b ti) name (makePayload payload) userInfo traceCtx
|
2019-05-13 12:41:07 +03:00
|
|
|
return $ encJFromJValue $ object ["event_id" .= eid]
|
|
|
|
where
|
2021-09-24 01:56:37 +03:00
|
|
|
makePayload o = object ["old" .= Null, "new" .= o]
|
2021-08-17 13:21:56 +03:00
|
|
|
|
2019-05-13 12:41:07 +03:00
|
|
|
assertManual (TriggerOpsDef _ _ _ man) = case man of
|
|
|
|
Just True -> return ()
|
2021-09-24 01:56:37 +03:00
|
|
|
_ -> throw400 NotSupported "manual mode is not enabled for event trigger"
|
2019-05-13 12:41:07 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
askTabInfoFromTrigger ::
|
|
|
|
(Backend b, QErrM m, CacheRM m) =>
|
|
|
|
SourceName ->
|
|
|
|
TriggerName ->
|
|
|
|
m (TableInfo b)
|
2021-09-06 14:15:36 +03:00
|
|
|
askTabInfoFromTrigger sourceName triggerName = do
|
2021-01-09 02:09:15 +03:00
|
|
|
sc <- askSchemaCache
|
2021-02-23 20:37:27 +03:00
|
|
|
let tabInfos = HM.elems $ fromMaybe mempty $ unsafeTableCache sourceName $ scSources sc
|
2021-09-06 14:15:36 +03:00
|
|
|
find (isJust . HM.lookup triggerName . _tiEventTriggerInfoMap) tabInfos
|
2021-01-09 02:09:15 +03:00
|
|
|
`onNothing` throw400 NotExists errMsg
|
|
|
|
where
|
2021-09-06 14:15:36 +03:00
|
|
|
errMsg = "event trigger " <> triggerName <<> " does not exist"
|
2021-01-09 02:09:15 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
askEventTriggerInfo ::
|
|
|
|
forall b m.
|
|
|
|
(QErrM m, CacheRM m, Backend b) =>
|
|
|
|
SourceName ->
|
|
|
|
TriggerName ->
|
|
|
|
m (EventTriggerInfo b)
|
2021-09-06 14:15:36 +03:00
|
|
|
askEventTriggerInfo sourceName triggerName = do
|
|
|
|
triggerInfo <- askTabInfoFromTrigger @b sourceName triggerName
|
|
|
|
let eventTriggerInfoMap = _tiEventTriggerInfoMap triggerInfo
|
|
|
|
HM.lookup triggerName eventTriggerInfoMap `onNothing` throw400 NotExists errMsg
|
2021-01-09 02:09:15 +03:00
|
|
|
where
|
2021-09-06 14:15:36 +03:00
|
|
|
errMsg = "event trigger " <> triggerName <<> " does not exist"
|
Clean metadata arguments
## Description
Thanks to #1664, the Metadata API types no longer require a `ToJSON` instance. This PR follows up with a cleanup of the types of the arguments to the metadata API:
- whenever possible, it moves those argument types to where they're used (RQL.DDL.*)
- it removes all unrequired instances (mostly `ToJSON`)
This PR does not attempt to do it for _all_ such argument types. For some of the metadata operations, the type used to describe the argument to the API and used to represent the value in the metadata are one and the same (like for `CreateEndpoint`). Sometimes, the two types are intertwined in complex ways (`RemoteRelationship` and `RemoteRelationshipDef`). In the spirit of only doing uncontroversial cleaning work, this PR only moves types that are not used outside of RQL.DDL.
Furthermore, this is a small step towards separating the different types all jumbled together in RQL.Types.
## Notes
This PR also improves several `FromJSON` instances to make use of `withObject`, and to use a human readable string instead of a type name in error messages whenever possible. For instance:
- before: `expected Object for Object, but encountered X`
after: `expected Object for add computed field, but encountered X`
- before: `Expecting an object for update query`
after: `expected Object for update query, but encountered X`
This PR also renames `CreateFunctionPermission` to `FunctionPermissionArgument`, to remove the quite surprising `type DropFunctionPermission = CreateFunctionPermission`.
This PR also deletes some dead code, mostly in RQL.DML.
This PR also moves a PG-specific source resolving function from DDL.Schema.Source to the only place where it is used: App.hs.
https://github.com/hasura/graphql-engine-mono/pull/1844
GitOrigin-RevId: a594521194bb7fe6a111b02a9e099896f9fed59c
2021-07-27 13:41:42 +03:00
|
|
|
|
|
|
|
-- This change helps us create functions for the event triggers
|
|
|
|
-- without the function name being truncated by PG, since PG allows
|
|
|
|
-- for only 63 chars for identifiers.
|
|
|
|
-- Reasoning for the 42 characters:
|
|
|
|
-- 63 - (notify_hasura_) - (_INSERT | _UPDATE | _DELETE)
|
|
|
|
maxTriggerNameLength :: Int
|
|
|
|
maxTriggerNameLength = 42
|
2021-09-09 14:54:19 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
getHeaderInfosFromConf ::
|
|
|
|
QErrM m =>
|
|
|
|
Env.Environment ->
|
|
|
|
[HeaderConf] ->
|
|
|
|
m [EventHeaderInfo]
|
2021-09-09 14:54:19 +03:00
|
|
|
getHeaderInfosFromConf env = mapM getHeader
|
|
|
|
where
|
|
|
|
getHeader :: QErrM m => HeaderConf -> m EventHeaderInfo
|
|
|
|
getHeader hconf = case hconf of
|
|
|
|
(HeaderConf _ (HVValue val)) -> return $ EventHeaderInfo hconf val
|
2021-09-24 01:56:37 +03:00
|
|
|
(HeaderConf _ (HVEnv val)) -> do
|
2021-09-09 14:54:19 +03:00
|
|
|
envVal <- getEnv env val
|
|
|
|
return $ EventHeaderInfo hconf envVal
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
getWebhookInfoFromConf ::
|
|
|
|
QErrM m =>
|
|
|
|
Env.Environment ->
|
|
|
|
WebhookConf ->
|
|
|
|
m WebhookConfInfo
|
2021-09-20 16:14:28 +03:00
|
|
|
getWebhookInfoFromConf env webhookConf = case webhookConf of
|
2021-09-09 14:54:19 +03:00
|
|
|
WCValue w -> do
|
|
|
|
resolvedWebhook <- resolveWebhook env w
|
2021-09-20 16:14:28 +03:00
|
|
|
return $ WebhookConfInfo webhookConf resolvedWebhook
|
|
|
|
WCEnv webhookEnvVar -> do
|
|
|
|
envVal <- getEnv env webhookEnvVar
|
|
|
|
return $ WebhookConfInfo webhookConf (ResolvedWebhook envVal)
|
2021-09-09 14:54:19 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
buildEventTriggerInfo ::
|
|
|
|
forall b m.
|
|
|
|
(Backend b, QErrM m) =>
|
|
|
|
Env.Environment ->
|
|
|
|
SourceName ->
|
|
|
|
TableName b ->
|
|
|
|
EventTriggerConf b ->
|
|
|
|
m (EventTriggerInfo b, [SchemaDependency])
|
2021-09-16 14:03:01 +03:00
|
|
|
buildEventTriggerInfo env source tableName (EventTriggerConf name def webhook webhookFromEnv rconf mheaders metaTransform) = do
|
2021-09-09 14:54:19 +03:00
|
|
|
webhookConf <- case (webhook, webhookFromEnv) of
|
2021-09-24 01:56:37 +03:00
|
|
|
(Just w, Nothing) -> return $ WCValue w
|
2021-09-09 14:54:19 +03:00
|
|
|
(Nothing, Just wEnv) -> return $ WCEnv wEnv
|
2021-09-24 01:56:37 +03:00
|
|
|
_ -> throw500 "expected webhook or webhook_from_env"
|
2021-09-09 14:54:19 +03:00
|
|
|
let headerConfs = fromMaybe [] mheaders
|
|
|
|
webhookInfo <- getWebhookInfoFromConf env webhookConf
|
|
|
|
headerInfos <- getHeaderInfosFromConf env headerConfs
|
2021-09-16 14:03:01 +03:00
|
|
|
let eTrigInfo = EventTriggerInfo name def rconf webhookInfo headerInfos metaTransform
|
2021-09-24 01:56:37 +03:00
|
|
|
tabDep =
|
|
|
|
SchemaDependency
|
|
|
|
( SOSourceObj source $
|
|
|
|
AB.mkAnyBackend $
|
|
|
|
SOITable @b tableName
|
|
|
|
)
|
|
|
|
DRParent
|
|
|
|
pure (eTrigInfo, tabDep : getTrigDefDeps @b source tableName def)
|
|
|
|
|
|
|
|
getTrigDefDeps ::
|
|
|
|
forall b.
|
|
|
|
Backend b =>
|
|
|
|
SourceName ->
|
|
|
|
TableName b ->
|
|
|
|
TriggerOpsDef b ->
|
|
|
|
[SchemaDependency]
|
2021-09-09 14:54:19 +03:00
|
|
|
getTrigDefDeps source tableName (TriggerOpsDef mIns mUpd mDel _) =
|
2021-09-24 01:56:37 +03:00
|
|
|
mconcat $
|
|
|
|
catMaybes
|
|
|
|
[ subsOpSpecDeps <$> mIns,
|
|
|
|
subsOpSpecDeps <$> mUpd,
|
|
|
|
subsOpSpecDeps <$> mDel
|
|
|
|
]
|
2021-09-09 14:54:19 +03:00
|
|
|
where
|
|
|
|
subsOpSpecDeps :: SubscribeOpSpec b -> [SchemaDependency]
|
|
|
|
subsOpSpecDeps os =
|
|
|
|
let cols = getColsFromSub $ sosColumns os
|
|
|
|
mkColDependency dependencyReason col =
|
|
|
|
SchemaDependency
|
2021-09-24 01:56:37 +03:00
|
|
|
( SOSourceObj source $
|
|
|
|
AB.mkAnyBackend $
|
|
|
|
SOITableObj @b tableName (TOCol @b col)
|
|
|
|
)
|
2021-09-09 14:54:19 +03:00
|
|
|
dependencyReason
|
|
|
|
colDeps = map (mkColDependency DRColumn) cols
|
|
|
|
payload = maybe [] getColsFromSub (sosPayload os)
|
|
|
|
payloadDeps = map (mkColDependency DRPayload) payload
|
2021-09-24 01:56:37 +03:00
|
|
|
in colDeps <> payloadDeps
|
2021-09-09 14:54:19 +03:00
|
|
|
getColsFromSub sc = case sc of
|
2021-09-24 01:56:37 +03:00
|
|
|
SubCStar -> []
|
2021-09-09 14:54:19 +03:00
|
|
|
SubCArray cols -> cols
|