2022-03-16 03:39:21 +03:00
|
|
|
{-# LANGUAGE TemplateHaskell #-}
|
|
|
|
|
2021-11-04 19:08:33 +03:00
|
|
|
module Hasura.RQL.DDL.Schema.Source
|
2022-08-30 02:51:34 +03:00
|
|
|
( -- * Add Source
|
|
|
|
AddSource,
|
2021-11-04 19:08:33 +03:00
|
|
|
runAddSource,
|
2022-08-30 02:51:34 +03:00
|
|
|
-- Drop Source
|
|
|
|
DropSource (..),
|
2021-11-04 19:08:33 +03:00
|
|
|
runDropSource,
|
2022-04-11 14:24:11 +03:00
|
|
|
dropSource,
|
|
|
|
runPostDropSourceHook,
|
2022-08-30 02:51:34 +03:00
|
|
|
|
|
|
|
-- * Rename Source
|
|
|
|
RenameSource,
|
|
|
|
runRenameSource,
|
|
|
|
|
|
|
|
-- * Update Source
|
|
|
|
UpdateSource,
|
2022-06-22 10:06:19 +03:00
|
|
|
runUpdateSource,
|
2022-08-30 02:51:34 +03:00
|
|
|
|
|
|
|
-- * Get Source Tables
|
|
|
|
GetSourceTables (..),
|
|
|
|
runGetSourceTables,
|
|
|
|
|
|
|
|
-- * Get Table Name
|
|
|
|
GetTableInfo (..),
|
|
|
|
runGetTableInfo,
|
2021-11-04 19:08:33 +03:00
|
|
|
)
|
|
|
|
where
|
2020-12-28 15:56:00 +03:00
|
|
|
|
2022-08-30 02:51:34 +03:00
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
import Control.Lens (at, (.~), (^.))
|
|
|
|
import Control.Monad.Trans.Control (MonadBaseControl)
|
2022-08-30 02:51:34 +03:00
|
|
|
import Data.Aeson qualified as Aeson
|
2022-04-29 05:13:13 +03:00
|
|
|
import Data.Aeson.Extended
|
|
|
|
import Data.Aeson.Extended qualified as J
|
2021-09-24 01:56:37 +03:00
|
|
|
import Data.Aeson.TH
|
|
|
|
import Data.Has
|
|
|
|
import Data.HashMap.Strict qualified as HM
|
2022-08-30 02:51:34 +03:00
|
|
|
import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap
|
2021-09-24 01:56:37 +03:00
|
|
|
import Data.HashMap.Strict.InsOrd qualified as OMap
|
|
|
|
import Data.Text.Extended
|
2022-08-30 02:51:34 +03:00
|
|
|
import Data.Text.Extended qualified as Text.E
|
2022-10-11 03:25:07 +03:00
|
|
|
import Hasura.Backends.DataConnector.API (errorResponseSummary, schemaCase)
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.Backends.DataConnector.API qualified as API
|
2022-10-11 03:25:07 +03:00
|
|
|
import Hasura.Backends.DataConnector.API.V0.ErrorResponse (_crDetails)
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC.Types
|
|
|
|
import Hasura.Backends.DataConnector.Agent.Client qualified as Agent.Client
|
2021-09-24 01:56:37 +03:00
|
|
|
import Hasura.Base.Error
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.Base.Error qualified as Error
|
2021-09-24 01:56:37 +03:00
|
|
|
import Hasura.EncJSON
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.EncJSON qualified as EncJSON
|
2021-09-24 01:56:37 +03:00
|
|
|
import Hasura.Logging qualified as L
|
|
|
|
import Hasura.Prelude
|
2022-04-27 16:57:28 +03:00
|
|
|
import Hasura.RQL.Types.Backend
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.RQL.Types.Backend qualified as RQL.Types
|
2022-04-27 16:57:28 +03:00
|
|
|
import Hasura.RQL.Types.Common
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.RQL.Types.Common qualified as Common
|
2022-09-02 09:33:21 +03:00
|
|
|
import Hasura.RQL.Types.HealthCheck (HealthCheckConfig)
|
2022-04-27 16:57:28 +03:00
|
|
|
import Hasura.RQL.Types.Metadata
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.RQL.Types.Metadata qualified as Metadata
|
2022-04-27 16:57:28 +03:00
|
|
|
import Hasura.RQL.Types.Metadata.Backend
|
2022-05-27 18:40:02 +03:00
|
|
|
import Hasura.RQL.Types.Metadata.Instances ()
|
2022-04-27 16:57:28 +03:00
|
|
|
import Hasura.RQL.Types.Metadata.Object
|
|
|
|
import Hasura.RQL.Types.SchemaCache
|
|
|
|
import Hasura.RQL.Types.SchemaCache.Build
|
|
|
|
import Hasura.RQL.Types.SchemaCacheTypes
|
|
|
|
import Hasura.RQL.Types.Source
|
|
|
|
import Hasura.RQL.Types.SourceCustomization
|
2021-09-24 01:56:37 +03:00
|
|
|
import Hasura.SQL.AnyBackend qualified as AB
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.SQL.AnyBackend qualified as AnyBackend
|
2022-04-29 05:13:13 +03:00
|
|
|
import Hasura.SQL.Backend
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.SQL.Backend qualified as Backend
|
|
|
|
import Hasura.SQL.BackendMap qualified as BackendMap
|
2021-09-24 01:56:37 +03:00
|
|
|
import Hasura.Server.Logging (MetadataLog (..))
|
2022-08-30 02:51:34 +03:00
|
|
|
import Hasura.Tracing qualified as Tracing
|
|
|
|
import Network.HTTP.Client.Manager qualified as HTTP.Manager
|
2022-10-11 03:25:07 +03:00
|
|
|
import Servant.API (Union)
|
2022-08-30 02:51:34 +03:00
|
|
|
import Servant.Client ((//))
|
|
|
|
import Servant.Client.Generic qualified as Servant.Client
|
2020-12-28 15:56:00 +03:00
|
|
|
|
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
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- Add source
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
data AddSource b = AddSource
|
2022-08-01 12:32:04 +03:00
|
|
|
{ _asName :: SourceName,
|
|
|
|
_asBackendKind :: BackendSourceKind b,
|
|
|
|
_asConfiguration :: SourceConnConfiguration b,
|
|
|
|
_asReplaceConfiguration :: Bool,
|
2022-09-02 09:33:21 +03:00
|
|
|
_asCustomization :: SourceCustomization,
|
|
|
|
_asHealthCheckConfig :: Maybe (HealthCheckConfig b)
|
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
|
|
|
}
|
|
|
|
|
2022-04-29 05:13:13 +03:00
|
|
|
instance (Backend b) => FromJSONWithContext (BackendSourceKind b) (AddSource b) where
|
|
|
|
parseJSONWithContext backendKind = withObject "AddSource" $ \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
|
|
|
AddSource
|
|
|
|
<$> o .: "name"
|
2022-04-29 05:13:13 +03:00
|
|
|
<*> pure backendKind
|
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
|
|
|
<*> o .: "configuration"
|
|
|
|
<*> o .:? "replace_configuration" .!= False
|
2021-10-29 17:42:07 +03:00
|
|
|
<*> o .:? "customization" .!= emptySourceCustomization
|
2022-09-02 09:33:21 +03:00
|
|
|
<*> o .:? "health_check"
|
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
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
runAddSource ::
|
|
|
|
forall m b.
|
|
|
|
(MonadError QErr m, CacheRWM m, MetadataM m, BackendMetadata b) =>
|
|
|
|
AddSource b ->
|
|
|
|
m EncJSON
|
2022-09-02 09:33:21 +03:00
|
|
|
runAddSource (AddSource name backendKind sourceConfig replaceConfiguration sourceCustomization healthCheckConfig) = do
|
2021-02-23 20:37:27 +03:00
|
|
|
sources <- scSources <$> askSchemaCache
|
2021-03-30 13:09:29 +03:00
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
metadataModifier <-
|
|
|
|
MetadataModifier
|
|
|
|
<$> if HM.member name sources
|
|
|
|
then
|
|
|
|
if replaceConfiguration
|
2022-06-22 10:06:19 +03:00
|
|
|
then do
|
|
|
|
let sMetadata = metaSources . ix name . toSourceMetadata @b
|
|
|
|
updateConfig = sMetadata . smConfiguration .~ sourceConfig
|
|
|
|
updateCustomization = sMetadata . smCustomization .~ sourceCustomization
|
|
|
|
pure $ updateConfig . updateCustomization
|
2021-09-24 01:56:37 +03:00
|
|
|
else throw400 AlreadyExists $ "source with name " <> name <<> " already exists"
|
|
|
|
else do
|
2022-08-10 12:40:57 +03:00
|
|
|
let sourceMetadata =
|
2022-09-02 09:33:21 +03:00
|
|
|
mkSourceMetadata @b name backendKind sourceConfig sourceCustomization healthCheckConfig
|
2021-09-24 01:56:37 +03:00
|
|
|
pure $ metaSources %~ OMap.insert name sourceMetadata
|
2021-03-30 13:09:29 +03:00
|
|
|
|
|
|
|
buildSchemaCacheFor (MOSource name) metadataModifier
|
2021-01-07 12:04:22 +03:00
|
|
|
pure successMsg
|
|
|
|
|
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
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- Rename source
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
data RenameSource = RenameSource
|
2022-08-01 12:32:04 +03:00
|
|
|
{ _rmName :: SourceName,
|
|
|
|
_rmNewName :: 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
|
|
|
}
|
2021-09-24 01:56:37 +03:00
|
|
|
|
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
|
|
|
$(deriveFromJSON hasuraJSON ''RenameSource)
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
runRenameSource ::
|
|
|
|
forall m.
|
|
|
|
(MonadError QErr m, CacheRWM m, MetadataM m) =>
|
|
|
|
RenameSource ->
|
|
|
|
m EncJSON
|
2021-05-24 16:13:08 +03:00
|
|
|
runRenameSource RenameSource {..} = do
|
|
|
|
sources <- scSources <$> askSchemaCache
|
|
|
|
|
|
|
|
unless (HM.member _rmName sources) $
|
|
|
|
throw400 NotExists $ "Could not find source with name " <>> _rmName
|
|
|
|
|
|
|
|
when (HM.member _rmNewName sources) $
|
|
|
|
throw400 AlreadyExists $ "Source with name " <> _rmNewName <<> " already exists"
|
|
|
|
|
|
|
|
let metadataModifier =
|
2021-09-24 01:56:37 +03:00
|
|
|
MetadataModifier $
|
|
|
|
metaSources %~ renameBackendSourceMetadata _rmName _rmNewName
|
2021-05-24 16:13:08 +03:00
|
|
|
buildSchemaCacheFor (MOSource _rmNewName) metadataModifier
|
|
|
|
|
|
|
|
pure successMsg
|
|
|
|
where
|
2021-09-24 01:56:37 +03:00
|
|
|
renameBackendSourceMetadata ::
|
|
|
|
SourceName ->
|
|
|
|
SourceName ->
|
|
|
|
OMap.InsOrdHashMap SourceName BackendSourceMetadata ->
|
|
|
|
OMap.InsOrdHashMap SourceName BackendSourceMetadata
|
2021-05-24 16:13:08 +03:00
|
|
|
renameBackendSourceMetadata oldKey newKey m =
|
|
|
|
case OMap.lookup oldKey m of
|
|
|
|
Just val ->
|
2022-08-29 03:58:03 +03:00
|
|
|
let renamedSource = BackendSourceMetadata (AB.mapBackend (unBackendSourceMetadata val) (renameSource newKey))
|
|
|
|
in OMap.insert newKey renamedSource $ OMap.delete oldKey $ m
|
2021-05-24 16:13:08 +03:00
|
|
|
Nothing -> m
|
|
|
|
|
|
|
|
renameSource :: forall b. SourceName -> SourceMetadata b -> SourceMetadata b
|
2021-09-24 01:56:37 +03:00
|
|
|
renameSource newName metadata = metadata {_smName = newName}
|
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
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- Drop source
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
data DropSource = DropSource
|
2022-08-01 12:32:04 +03:00
|
|
|
{ _dsName :: SourceName,
|
|
|
|
_dsCascade :: Bool
|
2021-09-24 01:56:37 +03:00
|
|
|
}
|
|
|
|
deriving (Show, Eq)
|
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 DropSource where
|
2021-09-20 22:49:33 +03:00
|
|
|
parseJSON = withObject "DropSource" $ \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
|
|
|
DropSource <$> o .: "name" <*> o .:? "cascade" .!= False
|
|
|
|
|
2021-09-24 01:56:37 +03:00
|
|
|
runDropSource ::
|
|
|
|
forall m r.
|
|
|
|
( MonadError QErr m,
|
|
|
|
CacheRWM m,
|
|
|
|
MonadIO m,
|
|
|
|
MonadBaseControl IO m,
|
|
|
|
MetadataM m,
|
|
|
|
MonadReader r m,
|
|
|
|
Has (L.Logger L.Hasura) r
|
|
|
|
) =>
|
|
|
|
DropSource ->
|
|
|
|
m EncJSON
|
2022-04-11 14:24:11 +03:00
|
|
|
runDropSource dropSourceInfo@(DropSource name cascade) = do
|
|
|
|
schemaCache <- askSchemaCache
|
|
|
|
let sources = scSources schemaCache
|
2021-03-02 07:26:31 +03:00
|
|
|
case HM.lookup name sources of
|
|
|
|
Just backendSourceInfo ->
|
2022-04-11 14:24:11 +03:00
|
|
|
AB.dispatchAnyBackend @BackendMetadata backendSourceInfo $ dropSource schemaCache dropSourceInfo
|
2021-03-02 07:26:31 +03:00
|
|
|
Nothing -> do
|
|
|
|
metadata <- getMetadata
|
2021-09-24 01:56:37 +03:00
|
|
|
void $
|
|
|
|
onNothing (metadata ^. metaSources . at name) $
|
2021-03-02 07:26:31 +03:00
|
|
|
throw400 NotExists $ "source with name " <> name <<> " does not exist"
|
|
|
|
if cascade
|
2021-09-24 01:56:37 +03:00
|
|
|
then -- Without sourceInfo we can't cascade, so throw an error
|
2021-03-02 07:26:31 +03:00
|
|
|
throw400 Unexpected $ "source with name " <> name <<> " is inconsistent"
|
2021-09-24 01:56:37 +03:00
|
|
|
else -- Drop source from metadata
|
2022-04-11 14:24:11 +03:00
|
|
|
buildSchemaCacheFor (MOSource name) (dropSourceMetadataModifier name)
|
2021-02-23 20:37:27 +03:00
|
|
|
pure successMsg
|
2022-04-11 14:24:11 +03:00
|
|
|
|
|
|
|
dropSourceMetadataModifier :: SourceName -> MetadataModifier
|
|
|
|
dropSourceMetadataModifier sourceName = MetadataModifier $ metaSources %~ OMap.delete sourceName
|
|
|
|
|
|
|
|
dropSource ::
|
|
|
|
forall m r b.
|
|
|
|
( MonadError QErr m,
|
|
|
|
CacheRWM m,
|
|
|
|
MonadIO m,
|
|
|
|
MonadBaseControl IO m,
|
|
|
|
MetadataM m,
|
|
|
|
MonadReader r m,
|
|
|
|
Has (L.Logger L.Hasura) r,
|
|
|
|
BackendMetadata b
|
|
|
|
) =>
|
|
|
|
SchemaCache ->
|
|
|
|
DropSource ->
|
|
|
|
SourceInfo b ->
|
|
|
|
m ()
|
|
|
|
dropSource _schemaCache (DropSource sourceName cascade) sourceInfo = do
|
2022-05-27 18:40:02 +03:00
|
|
|
schemaCache <- askSchemaCache
|
|
|
|
let remoteDeps = getRemoteDependencies schemaCache sourceName
|
2022-04-11 14:24:11 +03:00
|
|
|
|
2022-07-01 13:49:31 +03:00
|
|
|
unless (cascade || null remoteDeps) $
|
2022-05-27 18:40:02 +03:00
|
|
|
reportDependentObjectsExist remoteDeps
|
2022-04-11 14:24:11 +03:00
|
|
|
|
|
|
|
metadataModifier <- execWriterT $ do
|
2022-05-27 18:40:02 +03:00
|
|
|
traverse_ purgeSourceAndSchemaDependencies remoteDeps
|
2022-04-11 14:24:11 +03:00
|
|
|
tell $ dropSourceMetadataModifier sourceName
|
|
|
|
|
|
|
|
buildSchemaCacheFor (MOSource sourceName) metadataModifier
|
|
|
|
runPostDropSourceHook sourceName sourceInfo
|
|
|
|
|
|
|
|
runPostDropSourceHook ::
|
|
|
|
forall m r b.
|
|
|
|
( MonadError QErr m,
|
|
|
|
MonadIO m,
|
|
|
|
MonadBaseControl IO m,
|
|
|
|
MonadReader r m,
|
|
|
|
Has (L.Logger L.Hasura) r,
|
|
|
|
BackendMetadata b
|
|
|
|
) =>
|
|
|
|
SourceName ->
|
|
|
|
SourceInfo b ->
|
|
|
|
m ()
|
|
|
|
runPostDropSourceHook sourceName sourceInfo = do
|
|
|
|
logger :: (L.Logger L.Hasura) <- asks getter
|
|
|
|
let sourceConfig = _siConfiguration sourceInfo
|
2022-07-19 14:39:44 +03:00
|
|
|
-- Create a hashmap: {TableName: [Triggers]}
|
|
|
|
let tableTriggersMap = HM.map (HM.keys . _tiEventTriggerInfoMap) (_siTables sourceInfo)
|
2022-04-11 14:24:11 +03:00
|
|
|
-- We only log errors that arise from 'postDropSourceHook' here, and not
|
|
|
|
-- surface them as end-user errors. See comment
|
|
|
|
-- https://github.com/hasura/graphql-engine/issues/7092#issuecomment-873845282
|
2022-07-19 14:39:44 +03:00
|
|
|
runExceptT (postDropSourceHook @b sourceConfig tableTriggersMap) >>= either (logDropSourceHookError logger) pure
|
2021-02-23 20:37:27 +03:00
|
|
|
where
|
2022-04-11 14:24:11 +03:00
|
|
|
logDropSourceHookError logger err =
|
|
|
|
let msg =
|
|
|
|
"Error executing cleanup actions after removing source '" <> toTxt sourceName
|
|
|
|
<> "'. Consider cleaning up tables in hdb_catalog schema manually."
|
|
|
|
in L.unLogger logger $ MetadataLog L.LevelWarn msg (J.toJSON err)
|
2022-06-22 10:06:19 +03:00
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- update source
|
|
|
|
|
|
|
|
data UpdateSource b = UpdateSource
|
2022-08-01 12:32:04 +03:00
|
|
|
{ _usName :: SourceName,
|
|
|
|
_usConfiguration :: Maybe (SourceConnConfiguration b),
|
2022-09-02 09:33:21 +03:00
|
|
|
_usCustomization :: Maybe SourceCustomization,
|
|
|
|
_usHealthCheckConfig :: Maybe (HealthCheckConfig b)
|
2022-06-22 10:06:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
instance (Backend b) => FromJSONWithContext (BackendSourceKind b) (UpdateSource b) where
|
|
|
|
parseJSONWithContext _ = withObject "UpdateSource" $ \o ->
|
|
|
|
UpdateSource
|
|
|
|
<$> o .: "name"
|
|
|
|
<*> o .:? "configuration"
|
|
|
|
<*> o .:? "customization"
|
2022-09-02 09:33:21 +03:00
|
|
|
<*> o .:? "health_check"
|
2022-06-22 10:06:19 +03:00
|
|
|
|
|
|
|
runUpdateSource ::
|
|
|
|
forall m b.
|
|
|
|
(MonadError QErr m, CacheRWM m, MetadataM m, BackendMetadata b) =>
|
|
|
|
UpdateSource b ->
|
|
|
|
m EncJSON
|
2022-09-02 09:33:21 +03:00
|
|
|
runUpdateSource (UpdateSource name sourceConfig sourceCustomization healthCheckConfig) = do
|
2022-06-22 10:06:19 +03:00
|
|
|
sources <- scSources <$> askSchemaCache
|
|
|
|
|
|
|
|
metadataModifier <-
|
|
|
|
MetadataModifier
|
|
|
|
<$> if HM.member name sources
|
|
|
|
then do
|
|
|
|
let sMetadata = metaSources . ix name . toSourceMetadata @b
|
|
|
|
updateConfig = maybe id (\scc -> sMetadata . smConfiguration .~ scc) sourceConfig
|
|
|
|
updateCustomization = maybe id (\scc -> sMetadata . smCustomization .~ scc) sourceCustomization
|
2022-09-02 09:33:21 +03:00
|
|
|
updateHealthCheckConfig = maybe id (\hcc -> sMetadata . smHealthCheckConfig .~ Just hcc) healthCheckConfig
|
|
|
|
pure $ updateHealthCheckConfig . updateConfig . updateCustomization
|
2022-06-22 10:06:19 +03:00
|
|
|
else do
|
|
|
|
throw400 NotExists $ "source with name " <> name <<> " does not exist"
|
|
|
|
|
|
|
|
buildSchemaCacheFor (MOSource name) metadataModifier
|
|
|
|
pure successMsg
|
2022-08-30 02:51:34 +03:00
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
newtype GetSourceTables = GetSourceTables {_gstSourceName :: Common.SourceName}
|
|
|
|
|
|
|
|
instance FromJSON GetSourceTables where
|
|
|
|
parseJSON = Aeson.withObject "GetSourceTables" \o -> do
|
|
|
|
_gstSourceName <- o .: "source"
|
|
|
|
pure $ GetSourceTables {..}
|
|
|
|
|
|
|
|
-- | Fetch a list of tables for the request data source. Currently
|
|
|
|
-- this is only supported for Data Connectors.
|
|
|
|
runGetSourceTables ::
|
|
|
|
( Has (L.Logger L.Hasura) r,
|
|
|
|
HTTP.Manager.HasHttpManagerM m,
|
|
|
|
MonadReader r m,
|
|
|
|
MonadError Error.QErr m,
|
|
|
|
Metadata.MetadataM m,
|
|
|
|
MonadIO m
|
|
|
|
) =>
|
|
|
|
GetSourceTables ->
|
|
|
|
m EncJSON
|
|
|
|
runGetSourceTables GetSourceTables {..} = do
|
|
|
|
metadata <- Metadata.getMetadata
|
|
|
|
|
|
|
|
let sources = fmap Metadata.unBackendSourceMetadata $ Metadata._metaSources metadata
|
|
|
|
bmap = Metadata._metaBackendConfigs metadata
|
|
|
|
|
|
|
|
abSourceMetadata <-
|
|
|
|
InsOrdHashMap.lookup _gstSourceName sources
|
|
|
|
`onNothing` Error.throw400 Error.DataConnectorError ("Source '" <> Text.E.toTxt _gstSourceName <> "' not found")
|
|
|
|
|
|
|
|
AnyBackend.dispatchAnyBackend @RQL.Types.Backend abSourceMetadata $ \Metadata.SourceMetadata {_smKind, _smConfiguration} -> do
|
|
|
|
case _smKind of
|
|
|
|
Backend.DataConnectorKind dcName -> do
|
|
|
|
logger :: L.Logger L.Hasura <- asks getter
|
|
|
|
manager <- HTTP.Manager.askHttpManager
|
|
|
|
let timeout = DC.Types.timeout _smConfiguration
|
|
|
|
apiConfig = DC.Types.value _smConfiguration
|
|
|
|
|
|
|
|
DC.Types.DataConnectorOptions {..} <- do
|
|
|
|
let backendConfig = Metadata.unBackendConfigWrapper <$> BackendMap.lookup @'Backend.DataConnector bmap
|
|
|
|
onNothing
|
|
|
|
(InsOrdHashMap.lookup dcName =<< backendConfig)
|
|
|
|
(Error.throw400 Error.DataConnectorError ("Data connector named " <> Text.E.toTxt dcName <> " was not found in the data connector backend config"))
|
|
|
|
|
|
|
|
schemaResponse <-
|
|
|
|
Tracing.runTraceTWithReporter Tracing.noReporter "resolve source"
|
|
|
|
. flip Agent.Client.runAgentClientT (Agent.Client.AgentClientContext logger _dcoUri manager (DC.Types.sourceTimeoutMicroseconds <$> timeout))
|
2022-10-11 03:25:07 +03:00
|
|
|
$ schemaGuard =<< (Servant.Client.genericClient // API._schema) (Text.E.toTxt _gstSourceName) apiConfig
|
2022-08-30 02:51:34 +03:00
|
|
|
|
2022-09-21 08:11:53 +03:00
|
|
|
let fullyQualifiedTableNames = fmap API._tiName $ API._srTables schemaResponse
|
2022-09-13 05:05:17 +03:00
|
|
|
pure $ EncJSON.encJFromJValue fullyQualifiedTableNames
|
2022-08-30 02:51:34 +03:00
|
|
|
backend -> Error.throw500 ("Schema fetching is not supported for '" <> Text.E.toTxt backend <> "'")
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
data GetTableInfo = GetTableInfo
|
|
|
|
{ _gtiSourceName :: Common.SourceName,
|
|
|
|
_gtiTableName :: API.TableName
|
|
|
|
}
|
|
|
|
|
|
|
|
instance FromJSON GetTableInfo where
|
|
|
|
parseJSON = Aeson.withObject "GetSourceTables" \o -> do
|
|
|
|
_gtiSourceName <- o .: "source"
|
|
|
|
_gtiTableName <- o .: "table"
|
|
|
|
pure $ GetTableInfo {..}
|
|
|
|
|
|
|
|
-- | Fetch a list of tables for the request data source. Currently
|
|
|
|
-- this is only supported for Data Connectors.
|
|
|
|
runGetTableInfo ::
|
|
|
|
( Has (L.Logger L.Hasura) r,
|
|
|
|
HTTP.Manager.HasHttpManagerM m,
|
|
|
|
MonadReader r m,
|
|
|
|
MonadError Error.QErr m,
|
|
|
|
Metadata.MetadataM m,
|
|
|
|
MonadIO m
|
|
|
|
) =>
|
|
|
|
GetTableInfo ->
|
|
|
|
m EncJSON
|
|
|
|
runGetTableInfo GetTableInfo {..} = do
|
|
|
|
metadata <- Metadata.getMetadata
|
|
|
|
|
|
|
|
let sources = fmap Metadata.unBackendSourceMetadata $ Metadata._metaSources metadata
|
|
|
|
bmap = Metadata._metaBackendConfigs metadata
|
|
|
|
|
|
|
|
abSourceMetadata <-
|
|
|
|
InsOrdHashMap.lookup _gtiSourceName sources
|
|
|
|
`onNothing` Error.throw400 Error.DataConnectorError ("Source '" <> Text.E.toTxt _gtiSourceName <> "' not found")
|
|
|
|
|
|
|
|
AnyBackend.dispatchAnyBackend @RQL.Types.Backend abSourceMetadata $ \Metadata.SourceMetadata {_smKind, _smConfiguration} -> do
|
|
|
|
case _smKind of
|
|
|
|
Backend.DataConnectorKind dcName -> do
|
|
|
|
logger :: L.Logger L.Hasura <- asks getter
|
|
|
|
manager <- HTTP.Manager.askHttpManager
|
|
|
|
let timeout = DC.Types.timeout _smConfiguration
|
|
|
|
apiConfig = DC.Types.value _smConfiguration
|
|
|
|
|
|
|
|
DC.Types.DataConnectorOptions {..} <- do
|
|
|
|
let backendConfig = Metadata.unBackendConfigWrapper <$> BackendMap.lookup @'Backend.DataConnector bmap
|
|
|
|
onNothing
|
|
|
|
(InsOrdHashMap.lookup dcName =<< backendConfig)
|
|
|
|
(Error.throw400 Error.DataConnectorError ("Data connector named " <> Text.E.toTxt dcName <> " was not found in the data connector backend config"))
|
|
|
|
|
|
|
|
schemaResponse <-
|
|
|
|
Tracing.runTraceTWithReporter Tracing.noReporter "resolve source"
|
|
|
|
. flip Agent.Client.runAgentClientT (Agent.Client.AgentClientContext logger _dcoUri manager (DC.Types.sourceTimeoutMicroseconds <$> timeout))
|
2022-10-11 03:25:07 +03:00
|
|
|
$ schemaGuard =<< (Servant.Client.genericClient // API._schema) (Text.E.toTxt _gtiSourceName) apiConfig
|
2022-08-30 02:51:34 +03:00
|
|
|
|
2022-09-21 08:11:53 +03:00
|
|
|
let table = find ((== _gtiTableName) . API._tiName) $ API._srTables schemaResponse
|
2022-08-30 02:51:34 +03:00
|
|
|
pure $ EncJSON.encJFromJValue table
|
|
|
|
backend -> Error.throw500 ("Schema fetching is not supported for '" <> Text.E.toTxt backend <> "'")
|
2022-10-11 03:25:07 +03:00
|
|
|
|
|
|
|
schemaGuard :: MonadError QErr m => Union '[API.SchemaResponse, API.ErrorResponse] -> m API.SchemaResponse
|
|
|
|
schemaGuard = schemaCase defaultAction pure errorAction
|
|
|
|
where
|
|
|
|
defaultAction = throw400 DataConnectorError "Error resolving source schema"
|
|
|
|
errorAction e = throw400WithDetail DataConnectorError ("Error resolving source schema: " <> errorResponseSummary e) (_crDetails e)
|