Fix several issues with remote relationships.

## Remaining Work

- [x] changelog entry
- [x] more tests: `<backend>_delete_remote_relationship` is definitely untested
- [x] negative tests: we probably want to assert that there are some APIs we DON'T support
- [x] update the console to use the new API, if necessary
- [x] ~~adding the corresponding documentation for the API for other backends (only `pg_` was added here)~~
  - deferred to https://github.com/hasura/graphql-engine-mono/issues/3170
- [x] ~~deciding which backends should support this API~~
  - deferred to https://github.com/hasura/graphql-engine-mono/issues/3170
- [x] ~~deciding what to do about potentially overlapping schematic representations~~
  - ~~cf. https://github.com/hasura/graphql-engine-mono/pull/3157#issuecomment-995307624~~
  - deferred to https://github.com/hasura/graphql-engine-mono/issues/3171
- [x] ~~add more descriptive versioning information to some of the types that are changing in this PR~~
  -  cf. https://github.com/hasura/graphql-engine-mono/pull/3157#discussion_r769830920
  - deferred to https://github.com/hasura/graphql-engine-mono/issues/3172

## Description

This PR fixes several important issues wrt. the remote relationship API.

- it fixes a regression introduced by [#3124](https://github.com/hasura/graphql-engine-mono/pull/3124), which prevented `<backend>_create_remote_relationship` from accepting the old argument format (break of backwards compatibility, broke the console)
- it removes the command `create_remote_relationship` added to the v1/metadata API as a work-around as part of [#3124](https://github.com/hasura/graphql-engine-mono/pull/3124)
- it reverts the subsequent fix in the console: [#3149](https://github.com/hasura/graphql-engine-mono/pull/3149)

Furthermore, this PR also addresses two other issues:
- THE DOCUMENTATION OF THE METADATA API WAS WRONG, and documented `create_remote_relationship` instead of `<backend>_create_remote_relationship`: this PR fixes this by adding `pg_` everywhere, but does not attempt to add the corresponding documentation for other backends, partly because:
- `<backend>_delete_remote_relationship` WAS BROKEN ON NON-POSTGRES BACKENDS; it always expected an argument parameterized by Postgres.

As of main, the `<backend>_(create|update|delete)_remote_relationship` commands are supported on Postgres, Citus, BigQuery, but **NOT MSSQL**. I do not know if this is intentional or not, if it even should be publicized or not, and as a result this PR doesn't change this.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/3157
Co-authored-by: jkachmar <8461423+jkachmar@users.noreply.github.com>
GitOrigin-RevId: 37e2f41522a9229a11c595574c3f4984317d652a
This commit is contained in:
Antoine Leblanc 2021-12-16 20:28:08 +00:00 committed by hasura-bot
parent 40678855d0
commit bacadc30da
10 changed files with 185 additions and 158 deletions

View File

@ -7,6 +7,7 @@
(Add entries below in the order of server, console, cli, docs, others)
- server: implement update mutations for MS SQL Server (closes #7834)
- server: provides a more comprehensive fix for the JSON ser/de backwards incompatibility that was initially addressed by 45481db (#7906)
## v2.1.0

View File

@ -140,7 +140,7 @@ export const getMetadataQuery = (
prefix = 'pg_';
}
return {
type: type !== 'create_remote_relationship' ? `${prefix}${type}` : type,
type: `${prefix}${type}`,
args: { ...args, source },
};
};

View File

@ -376,7 +376,7 @@ The various types of queries are listed in the following table:
- :ref:`create_scheduled_event_args <metadata_create_scheduled_event_syntax>`
- 1
- Create a new scheduled event
* - :ref:`metadata_delete_scheduled_event`
- :ref:`delete_scheduled_event_args <metadata_delete_scheduled_event_syntax>`
- 1
@ -412,18 +412,18 @@ The various types of queries are listed in the following table:
- 1
- Drop existing permissions defined for a role for a remote schema
* - :ref:`metadata_create_remote_relationship`
- :ref:`create_remote_relationship_args <metadata_create_remote_relationship_syntax>`
* - :ref:`metadata_pg_create_remote_relationship`
- :ref:`pg_create_remote_relationship_args <metadata_pg_create_remote_relationship_syntax>`
- 1
- Create a remote relationship with an existing remote schema
* - :ref:`metadata_update_remote_relationship`
- :ref:`update_remote_relationship_args <metadata_update_remote_relationship_syntax>`
* - :ref:`metadata_pg_update_remote_relationship`
- :ref:`pg_update_remote_relationship_args <metadata_pg_update_remote_relationship_syntax>`
- 1
- Update an existing remote relationship
* - :ref:`metadata_delete_remote_relationship`
- :ref:`delete_remote_relationship_args <metadata_delete_remote_relationship_syntax>`
* - :ref:`metadata_pg_delete_remote_relationship`
- :ref:`pg_delete_remote_relationship_args <metadata_pg_delete_remote_relationship_syntax>`
- 1
- Delete an existing remote relationship

View File

@ -20,12 +20,12 @@ Remote Relationships allow you to join tables with remote schemas.
The metadata API is supported for versions ``v2.0.0`` and above and replaces the older
:ref:`schema/metadata API <schema_metadata_apis>`.
.. _metadata_create_remote_relationship:
.. _metadata_pg_create_remote_relationship:
create_remote_relationship
pg_create_remote_relationship
--------------------------
``create_remote_relationship`` is used to create a new remote relationship with an existing remote schema.
``pg_create_remote_relationship`` is used to create a new remote relationship with an existing remote schema.
.. code-block:: http
@ -34,7 +34,7 @@ create_remote_relationship
X-Hasura-Role: admin
{
"type":"create_remote_relationship",
"type":"pg_create_remote_relationship",
"args":{
"name": "sample_remote_relationship",
"table": "users",
@ -50,7 +50,7 @@ create_remote_relationship
}
}
.. _metadata_create_remote_relationship_syntax:
.. _metadata_pg_create_remote_relationship_syntax:
Args syntax
^^^^^^^^^^^
@ -83,12 +83,12 @@ Args syntax
- :ref:`RemoteField`
- The schema tree ending at the field in remote schema which needs to be joined with.
.. _metadata_update_remote_relationship:
.. _metadata_pg_update_remote_relationship:
update_remote_relationship
pg_update_remote_relationship
--------------------------
``update_remote_relationship`` is used to update an existing remote relationship.
``pg_update_remote_relationship`` is used to update an existing remote relationship.
.. code-block:: http
@ -97,7 +97,7 @@ update_remote_relationship
X-Hasura-Role: admin
{
"type": "update_remote_relationship",
"type": "pg_update_remote_relationship",
"args": {
"name": "sample_remote_relationship",
"table": "users",
@ -116,7 +116,7 @@ update_remote_relationship
}
}
.. _metadata_update_remote_relationship_syntax:
.. _metadata_pg_update_remote_relationship_syntax:
Args syntax
^^^^^^^^^^^
@ -149,12 +149,12 @@ Args syntax
- :ref:`RemoteField`
- The schema tree ending at the field in remote schema which needs to be joined with.
.. _metadata_delete_remote_relationship:
.. _metadata_pg_delete_remote_relationship:
delete_remote_relationship
pg_delete_remote_relationship
--------------------------
``delete_remote_relationship`` is used to delete an existing remote relationship.
``pg_delete_remote_relationship`` is used to delete an existing remote relationship.
.. code-block:: http
@ -163,7 +163,7 @@ delete_remote_relationship
X-Hasura-Role: admin
{
"type" : "delete_remote_relationship",
"type" : "pg_delete_remote_relationship",
"args" : {
"table":{
"name":"users",
@ -173,7 +173,7 @@ delete_remote_relationship
}
}
.. _metadata_delete_remote_relationship_syntax:
.. _metadata_pg_delete_remote_relationship_syntax:
Args syntax
^^^^^^^^^^^

View File

@ -2,7 +2,6 @@
module Hasura.RQL.DDL.RemoteRelationship
( CreateFromSourceRelationship (..),
LegacyCreateRemoteRelationship (..),
runCreateRemoteRelationship,
runDeleteRemoteRelationship,
runUpdateRemoteRelationship,
@ -13,10 +12,8 @@ module Hasura.RQL.DDL.RemoteRelationship
)
where
import Control.Lens (foldOf, to)
import Data.Aeson (FromJSON (..), ToJSON (..), (.!=), (.:), (.:?), (.=))
import Data.Aeson qualified as J
import Data.Aeson.Lens (_Object)
import Data.HashMap.Strict qualified as Map
import Data.HashMap.Strict.InsOrd qualified as OMap
import Data.HashSet qualified as S
@ -61,65 +58,42 @@ instance Backend b => FromJSON (CreateFromSourceRelationship b) where
_crrSource <- o .:? "source" .!= defaultSource
_crrTable <- o .: "table"
_crrName <- o .: "name"
_crrDefinition <- o .: "definition"
-- In the old format, the definition is inlined; in the new format, the
-- definition is in the "definition" object.
remoteSchema :: Maybe J.Value <- o .:? "remote_schema"
definition <- o .:? "definition"
_crrDefinition <- case (remoteSchema, definition) of
-- old format
(Just _, Nothing) -> parseJSON $ J.Object o
-- new format
(Nothing, Just def) -> parseJSON def
-- both or neither
_ -> fail "create_remote_relationship expects exactly one of: remote_schema, definition"
pure $ CreateFromSourceRelationship {..}
instance (Backend b) => ToJSON (CreateFromSourceRelationship b) where
toJSON (CreateFromSourceRelationship {..}) =
J.toJSON . J.object $
[ "source" .= _crrSource,
"table" .= _crrTable,
"name" .= _crrName,
"definition" .= _crrDefinition
]
toEncoding (CreateFromSourceRelationship {..}) =
J.pairs $
"source" .= _crrSource
<> "table" .= _crrTable
<> "name" .= _crrName
<> "definition" .= _crrDefinition
-- | Opaque type wrapper around 'CreateFromSourceRelationship' which exists
-- solely to provide customized 'FromJSON' and 'ToJSON' instances that
-- preserves legacy JSON ser/de behavior.
--
-- See the associated 'FromJSON' and 'ToJSON' instances for details.
newtype LegacyCreateRemoteRelationship = LegacyCreateRemoteRelationship
{ unLegacyCreateRemoteRelationship ::
CreateFromSourceRelationship ('Postgres 'Vanilla)
}
deriving newtype (Eq, Show)
instance FromJSON LegacyCreateRemoteRelationship where
parseJSON = J.withObject "LegacyCreateRemoteRelationship" $ \o -> do
_crrSource <- o .:? "source" .!= defaultSource
_crrTable <- o .: "table"
_crrName <- o .: "name"
_crrDefinition <- parseJSON (J.Object o)
pure . LegacyCreateRemoteRelationship $ CreateFromSourceRelationship {..}
instance ToJSON LegacyCreateRemoteRelationship where
toJSON (LegacyCreateRemoteRelationship (CreateFromSourceRelationship {..})) =
-- The "legacy" serialization logic included the fields that are now a part
-- of the nested '_crrDefinition'.
--
-- To work around this, while sharing as much serialization logic with
-- 'RemoteRelationshipDefinition' as possible, '_crrDefinition' is
-- serialized to a 'J.Value' and then immediately converted back to a list
-- of key/value pairs.
--
-- 'definitionKeyValues' will be an empty list if this conversion fails
-- (which it should _never_ do), in which case those fields will be omitted
-- from the serialized JSON.
let definitionKeyValues =
foldOf (_Object . to Map.toList) (J.toJSON _crrDefinition)
in J.toJSON . J.object $
[ "source" .= _crrSource,
"table" .= _crrTable,
"name" .= _crrName
]
<> definitionKeyValues
-- We need to introspect the definition, to know whether we need to inline
-- it, or if it needs to be in a distinct "definition" object.
J.object $ case _crrDefinition of
-- old format
RelationshipToSchema RRFOldDBToRemoteSchema _ ->
case J.toJSON _crrDefinition of
-- The result of this serialization will be an empty list if this
-- conversion fails (which it should _never_ do), in which case those
-- fields will be omitted from the serialized JSON. This could only
-- happen if the ToJSON instance of RemoteRelationshipDefinition were
-- changed to return something that isn't an object.
J.Object obj -> commonFields <> Map.toList obj
_ -> []
-- new format
_ -> ("definition" .= _crrDefinition) : commonFields
where
commonFields =
[ "source" .= _crrSource,
"table" .= _crrTable,
"name" .= _crrName
]
runCreateRemoteRelationship ::
forall b m.

View File

@ -115,7 +115,7 @@ relationshipCommands =
remoteRelationshipCommands =
[ commandParser "create_remote_relationship" $ RMCreateRemoteRelationship . mkAnyBackend @b,
commandParser "update_remote_relationship" $ RMUpdateRemoteRelationship . mkAnyBackend @b,
commandParser "delete_remote_relationship" $ RMDeleteRemoteRelationship
commandParser "delete_remote_relationship" $ RMDeleteRemoteRelationship . mkAnyBackend @b
]
eventTriggerCommands =
[ commandParser "invoke_event_trigger" $ RMInvokeEventTrigger . mkAnyBackend @b,

View File

@ -82,10 +82,9 @@ data RQLMetadataV1
| RMSetRelationshipComment !(AnyBackend SetRelComment)
| RMRenameRelationship !(AnyBackend RenameRel)
| -- Tables remote relationships
-- (backend)_create_remote_relationship, create_remote_relationship
RMCreateRemoteRelationship !(AnyBackend CreateFromSourceRelationship)
| RMUpdateRemoteRelationship !(AnyBackend CreateFromSourceRelationship)
| RMDeleteRemoteRelationship !(DeleteFromSourceRelationship ('Postgres 'Vanilla))
| RMDeleteRemoteRelationship !(AnyBackend DeleteFromSourceRelationship)
| -- Functions
RMTrackFunction !(AnyBackend TrackFunctionV2)
| RMUntrackFunction !(AnyBackend UnTrackFunction)
@ -222,7 +221,6 @@ instance FromJSON RQLMetadataV1 where
"test_webhook_transform" -> RMTestWebhookTransform <$> args
"set_query_tags" -> RMSetQueryTagsConfig <$> args
"bulk" -> RMBulk <$> args
"create_remote_relationship" -> RMCreateRemoteRelationship . mkAnyBackend . unLegacyCreateRemoteRelationship <$> args
-- backend specific
_ -> do
let (prefix, T.drop 1 -> cmd) = T.breakOn "_" queryType
@ -419,7 +417,7 @@ runMetadataQueryV1M env currentResourceVersion = \case
RMRenameRelationship q -> dispatchMetadata runRenameRel q
RMCreateRemoteRelationship q -> dispatchMetadata runCreateRemoteRelationship q
RMUpdateRemoteRelationship q -> dispatchMetadata runUpdateRemoteRelationship q
RMDeleteRemoteRelationship q -> runDeleteRemoteRelationship q
RMDeleteRemoteRelationship q -> dispatchMetadata runDeleteRemoteRelationship q
RMTrackFunction q -> dispatchMetadata runTrackFunctionV2 q
RMUntrackFunction q -> dispatchMetadata runUntrackFunc q
RMCreateFunctionPermission q -> dispatchMetadata runCreateFunctionPermission q

View File

@ -48,7 +48,7 @@ data RQLMetadataV1
| -- Tables remote relationships
RMCreateRemoteRelationship !(AnyBackend CreateFromSourceRelationship)
| RMUpdateRemoteRelationship !(AnyBackend CreateFromSourceRelationship)
| RMDeleteRemoteRelationship !(DeleteFromSourceRelationship ('Postgres 'Vanilla))
| RMDeleteRemoteRelationship !(AnyBackend DeleteFromSourceRelationship)
| -- Functions
RMTrackFunction !(AnyBackend TrackFunctionV2)
| RMUntrackFunction !(AnyBackend UnTrackFunction)

View File

@ -65,8 +65,8 @@ data RQLQueryV1
| -- computed fields related
RQAddComputedField !(AddComputedField ('Postgres 'Vanilla))
| RQDropComputedField !(DropComputedField ('Postgres 'Vanilla))
| RQCreateRemoteRelationship !LegacyCreateRemoteRelationship
| RQUpdateRemoteRelationship !LegacyCreateRemoteRelationship
| RQCreateRemoteRelationship !(CreateFromSourceRelationship ('Postgres 'Vanilla))
| RQUpdateRemoteRelationship !(CreateFromSourceRelationship ('Postgres 'Vanilla))
| RQDeleteRemoteRelationship !(DeleteFromSourceRelationship ('Postgres 'Vanilla))
| RQCreateInsertPermission !(CreatePerm InsPerm ('Postgres 'Vanilla))
| RQCreateSelectPermission !(CreatePerm SelPerm ('Postgres 'Vanilla))
@ -418,8 +418,8 @@ runQueryM env rq = withPathK "args" $ case rq of
RQRemoveRemoteSchema q -> runRemoveRemoteSchema q
RQReloadRemoteSchema q -> runReloadRemoteSchema q
RQIntrospectRemoteSchema q -> runIntrospectRemoteSchema q
RQCreateRemoteRelationship q -> runCreateRemoteRelationship $ unLegacyCreateRemoteRelationship q
RQUpdateRemoteRelationship q -> runUpdateRemoteRelationship $ unLegacyCreateRemoteRelationship q
RQCreateRemoteRelationship q -> runCreateRemoteRelationship q
RQUpdateRemoteRelationship q -> runUpdateRemoteRelationship q
RQDeleteRemoteRelationship q -> runDeleteRemoteRelationship q
RQCreateEventTrigger q -> runCreateEventTriggerQuery q
RQDeleteEventTrigger q -> runDeleteEventTriggerQuery q

View File

@ -10,17 +10,17 @@ where
-------------------------------------------------------------------------------
import Control.Lens ((%~), (^?!))
import Control.Lens ((%~), (.~), (^?!))
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson qualified as Aeson
import Data.Aeson.Lens (key, _Object)
import Data.HashMap.Strict qualified as HM
import Data.Text qualified as T
import Data.Yaml.TH (yamlQQ)
import GHC.Stack (HasCallStack)
import Hasura.Prelude hiding ((%~))
import Hasura.RQL.DDL.RemoteRelationship
( CreateFromSourceRelationship,
LegacyCreateRemoteRelationship,
)
import Hasura.RQL.Types.Metadata (Metadata)
import Hasura.SQL.Backend (BackendType (BigQuery, MSSQL, Postgres), PostgresKind (Vanilla))
@ -42,9 +42,9 @@ spec = describe "Remote Relationship Metadata" do
-------------------------------------------------------------------------------
spec_roundtrip :: Spec
spec_roundtrip = describe "Roundtrip" do
spec_roundtrip = describe "JSON Roundtrip" do
describe "Metadata" do
it "passes JSON roundtrip tests for an example remote relationship fragment" $
it "example remote relationship fragment" $
hedgehog do
metadata :: Metadata <-
evalAesonResult $
@ -52,35 +52,34 @@ spec_roundtrip = describe "Roundtrip" do
trippingJSONValue metadata
describe "CreateFromSourceRelationship" do
it "passes JSON roundtrip tests for a 'pg_create_remote_relationship' query fragment" $
it "'pg_create_remote_relationship' query" $
hedgehog $ do
let fragment = pg_create_remote_relationship_fragment ^?! key "args"
let argument = mk_pg_remote_relationship_argument "create" ^?! key "args"
cfsr :: (CreateFromSourceRelationship ('Postgres 'Vanilla)) <-
evalAesonResult $ Aeson.fromJSON fragment
evalAesonResult $ Aeson.fromJSON argument
trippingJSON cfsr
it "passes JSON roundtrip tests for an 'mssql_create_remote_relationship' query fragment" $
it "'pg_create_remote_relationship' query with the 'old' schema" $
hedgehog $ do
let fragment = mssql_create_remote_relationship_fragment ^?! key "args"
let argument = mk_pg_remote_relationship_old_argument "create" ^?! key "args"
cfsr :: (CreateFromSourceRelationship ('Postgres 'Vanilla)) <-
evalAesonResult $ Aeson.fromJSON argument
trippingJSON cfsr
it "'mssql_create_remote_relationship' query" $
hedgehog $ do
let argument = mk_mssql_remote_relationship_argument "create" ^?! key "args"
cfsr :: (CreateFromSourceRelationship 'MSSQL) <-
evalAesonResult $ Aeson.fromJSON fragment
evalAesonResult $ Aeson.fromJSON argument
trippingJSON cfsr
it "passes JSON roundtrip tests for a 'bigquery_create_remote_relationship' query fragment" $
it "'bigquery_create_remote_relationship' query" $
hedgehog $ do
let fragment = bigquery_create_remote_relationship_fragment ^?! key "args"
let argument = mk_bigquery_remote_relationship_argument "create" ^?! key "args"
cfsr :: (CreateFromSourceRelationship 'BigQuery) <-
evalAesonResult $ Aeson.fromJSON fragment
evalAesonResult $ Aeson.fromJSON argument
trippingJSON cfsr
describe "LegacyCreateRemoteRelationship" do
it "passes JSON roundtrip tests for a 'create_remote_relationship' query fragment" $
hedgehog do
let fragment = create_remote_relationship_fragment ^?! key "args"
lcrr :: LegacyCreateRemoteRelationship <-
evalAesonResult $ Aeson.fromJSON fragment
trippingJSON lcrr
-------------------------------------------------------------------------------
spec_Metadata_examples :: Spec
@ -94,8 +93,8 @@ spec_Metadata_examples = describe "Metadata" $ do
spec_RQLQuery_examples :: Spec
spec_RQLQuery_examples = describe "V1 RQLQuery" do
it "parses a 'create_remote_relationship' query fragment as a V1 'RQLQuery' type" do
case Aeson.fromJSON @V1.RQLQuery create_remote_relationship_fragment of
it "parses a 'create_remote_relationship' query with the 'old' schema" do
case Aeson.fromJSON @V1.RQLQuery create_remote_relationship_argument of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
@ -103,20 +102,39 @@ spec_RQLQuery_examples = describe "V1 RQLQuery" do
spec_RQLMetadataV1_examples :: Spec
spec_RQLMetadataV1_examples = describe "RQLMetadataV1" do
it "parses a 'create_remote_relationship' query fragment" do
case Aeson.fromJSON @RQLMetadataV1 create_remote_relationship_fragment of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
describe "Success" do
for_ ["create", "update", "delete"] \action ->
it ("parses a 'pg_" <> T.unpack action <> "_remote_relationship query") do
case Aeson.fromJSON @RQLMetadataV1 (mk_pg_remote_relationship_argument action) of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
it "parses a 'pg_create_remote_relationship' query fragment" do
case Aeson.fromJSON @RQLMetadataV1 pg_create_remote_relationship_fragment of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
for_ ["create", "update", "delete"] \action ->
it ("parses a 'pg_" <> T.unpack action <> "_remote_relationship query using the 'old' schema") do
case Aeson.fromJSON @RQLMetadataV1 (mk_pg_remote_relationship_old_argument action) of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
it "parses a 'bigquery_create_remote_relationship' query fragment" do
case Aeson.fromJSON @RQLMetadataV1 bigquery_create_remote_relationship_fragment of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
for_ ["create", "update", "delete"] \action ->
it ("parses a 'citus_" <> T.unpack action <> "_remote_relationship query") do
case Aeson.fromJSON @RQLMetadataV1 (mk_citus_remote_relationship_argument action) of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
for_ ["create", "update", "delete"] \action ->
it ("parses a 'bigquery_" <> T.unpack action <> "_remote_relationship query") do
case Aeson.fromJSON @RQLMetadataV1 (mk_bigquery_remote_relationship_argument action) of
Aeson.Success _ -> pure ()
Aeson.Error err -> expectationFailure err
describe "Failure" do
for_ ["create", "update", "delete"] \action ->
it ("fails to parse an 'mssql_" <> T.unpack action <> "_remote_relationship query") do
case Aeson.fromJSON @RQLMetadataV1 (mk_mssql_remote_relationship_argument action) of
Aeson.Error _ -> pure ()
Aeson.Success _ ->
let errMsg = "expected 'mssql_" <> T.unpack action <> "' query to fail to parse"
in expectationFailure errMsg
-------------------------------------------------------------------------------
-- Example YAML fragments for the metadata and query tests above.
@ -144,8 +162,8 @@ sources:
remote_schema: some_remote_schema_name
|]
create_remote_relationship_fragment :: Aeson.Value
create_remote_relationship_fragment =
create_remote_relationship_argument :: Aeson.Value
create_remote_relationship_argument =
[yamlQQ|
type: create_remote_relationship
args:
@ -161,12 +179,13 @@ args:
id: "$id"
|]
-- | Backend-agnostic query fragment which omits the @type@ field.
-- | Backend-agnostic @v1/metadata@ argument fragment which omits the @type@
-- field.
--
-- This should be used to construct backend-specific fragments by adding the
-- correct type and/or modifying any of the fields specified here as needed.
--
-- See 'pg_create_remote_relationship_fragment' for details.
-- See 'mk_backend_remote_relationship_argument for example usage.
backend_create_remote_relationship_fragment :: Aeson.Value
backend_create_remote_relationship_fragment =
[yamlQQ|
@ -185,41 +204,76 @@ args:
id: "$id"
|]
pg_create_remote_relationship_fragment :: Aeson.Value
pg_create_remote_relationship_fragment =
-- | Constructor for @v1/metadata@ @<backend>_(create|update|delete)_remote_relationship@
-- arguments using the new, unified schema.
--
-- See 'mk_pg_backend_remote_relationship_argument for example usage.
mk_backend_remote_relationship_argument :: Text -> Text -> Aeson.Value
mk_backend_remote_relationship_argument backend action =
backend_create_remote_relationship_fragment
& _Object %~ HM.insert ("type" :: Text) "pg_create_remote_relationship"
& _Object
%~ HM.insert
("type" :: Text)
(Aeson.String $ backend <> "_" <> action <> "_remote_relationship")
mssql_create_remote_relationship_fragment :: Aeson.Value
mssql_create_remote_relationship_fragment =
backend_create_remote_relationship_fragment
& _Object %~ HM.insert ("type" :: Text) "mssql_create_remote_relationship"
-- | Constructor for @v1/metadata@ @mssql_(create|update|delete)_remote_relationship@
-- arguments using the new, unified schema.
mk_mssql_remote_relationship_argument :: Text -> Aeson.Value
mk_mssql_remote_relationship_argument action =
mk_backend_remote_relationship_argument "mssql" action
-- | Constructor for @v1/metadata@ @citus_(create|update|delete)_remote_relationship@
-- arguments using the new, unified schema.
mk_citus_remote_relationship_argument :: Text -> Aeson.Value
mk_citus_remote_relationship_argument action =
mk_backend_remote_relationship_argument "citus" action
-- | Constructor for @v1/metadata@ @pg_(create|update|delete)_remote_relationship@
-- arguments using the new, unified schema.
mk_pg_remote_relationship_argument :: Text -> Aeson.Value
mk_pg_remote_relationship_argument action =
mk_backend_remote_relationship_argument "pg" action
-- | Constructor for @v1/metadata@ @bigquery_(create|update|delete)_remote_relationship@
-- arguments using the new, unified schema.
--
-- NOTE: The 'BigQuery' backend expects its @table@ argument to be of type
-- 'Aeson.Object' (all of the other backends support 'Aeson.String').
--
-- Rather than trying to wrangle even more of this with @lens-aeson@, it's
-- easier to just duplicate the structure in-place for the time being.
bigquery_create_remote_relationship_fragment :: Aeson.Value
bigquery_create_remote_relationship_fragment =
[yamlQQ|
type: bigquery_create_remote_relationship
mk_bigquery_remote_relationship_argument :: Text -> Aeson.Value
mk_bigquery_remote_relationship_argument action =
mk_backend_remote_relationship_argument "bigquery" action
& key "args" . key "table"
.~ ( Aeson.Object $
HM.fromList
[ ("name" :: Text, "profiles"),
("dataset" :: Text, "test")
]
)
-- | Constructor for @v1/metadata@ @pg_(create|update|delete)_remote_relationship@
-- arguments using the old, non-unified schema.
mk_pg_remote_relationship_old_argument :: Text -> Aeson.Value
mk_pg_remote_relationship_old_argument action =
fragment
& _Object
%~ HM.insert
("type" :: Text)
(Aeson.String $ "pg_" <> action <> "_remote_relationship")
where
fragment =
[yamlQQ|
args:
name: message
table:
name: profiles
dataset: test
definition:
to_remote_schema:
lhs_fields:
- id
- name
remote_schema: my-remote-schema
remote_field:
message:
arguments:
id: "$id"
|]
table: profiles
hasura_fields:
- id
- name
remote_schema: my-remote-schema
remote_field:
message:
arguments:
id: "$id"
|]
-------------------------------------------------------------------------------
-- Utility functions.