Separate scalar_types into discreet metadata resolve stage (#470)

<!-- Thank you for submitting this PR! :) -->

## Description

Following from https://github.com/hasura/v3-engine/pull/469 , we split
scalar type resolution too. That will need to be merged before this so
we can tidy up the data passing between them.

No functional change.

V3_GIT_ORIGIN_REV_ID: 5e157c4d15d0223d2bbd24f911ebee24e98b81cd
This commit is contained in:
Daniel Harvey 2024-04-18 11:56:36 +01:00 committed by hasura-bot
parent 4b34cddd8a
commit f775580dc9
3 changed files with 100 additions and 72 deletions

View File

@ -20,12 +20,10 @@ use crate::metadata::resolved::model::{
use crate::metadata::resolved::relationship::resolve_relationship; use crate::metadata::resolved::relationship::resolve_relationship;
use crate::metadata::resolved::subgraph::Qualified; use crate::metadata::resolved::subgraph::Qualified;
use crate::metadata::resolved::types::{ use crate::metadata::resolved::types::{
mk_name, resolve_output_type_permission, store_new_graphql_type, ObjectTypeRepresentation, mk_name, resolve_object_boolean_expression_type, resolve_output_type_permission,
ObjectBooleanExpressionType, ObjectTypeRepresentation, ScalarTypeRepresentation,
}; };
use super::types::{
resolve_object_boolean_expression_type, ObjectBooleanExpressionType, ScalarTypeRepresentation,
};
use crate::metadata::resolved::stages::{ use crate::metadata::resolved::stages::{
data_connector_type_mappings, data_connectors, graphql_config, data_connector_type_mappings, data_connectors, graphql_config,
}; };
@ -46,21 +44,18 @@ pub struct Metadata {
*******************/ *******************/
pub fn resolve_metadata( pub fn resolve_metadata(
metadata_accessor: &open_dds::accessor::MetadataAccessor, metadata_accessor: &open_dds::accessor::MetadataAccessor,
graphql_config: graphql_config::GraphqlConfig, graphql_config: &graphql_config::GraphqlConfig,
mut data_connectors: data_connectors::DataConnectors, mut data_connectors: data_connectors::DataConnectors,
data_connector_type_mappings_output: data_connector_type_mappings::DataConnectorTypeMappingsOutput, mut existing_graphql_types: HashSet<ast::TypeName>,
mut global_id_enabled_types: HashMap<Qualified<CustomTypeName>, Vec<Qualified<ModelName>>>,
mut apollo_federation_entity_enabled_types: HashMap<
Qualified<CustomTypeName>,
Option<Qualified<open_dds::models::ModelName>>,
>,
data_connector_type_mappings: &data_connector_type_mappings::DataConnectorTypeMappings,
object_types: HashMap<Qualified<CustomTypeName>, ObjectTypeRepresentation>,
scalar_types: &HashMap<Qualified<CustomTypeName>, ScalarTypeRepresentation>,
) -> Result<Metadata, Error> { ) -> Result<Metadata, Error> {
let data_connector_type_mappings::DataConnectorTypeMappingsOutput {
mut existing_graphql_types,
mut global_id_enabled_types,
mut apollo_federation_entity_enabled_types,
object_types,
data_connector_type_mappings,
} = data_connector_type_mappings_output;
// resolve scalar types
let scalar_types = resolve_scalar_types(metadata_accessor, &mut existing_graphql_types)?;
// resolve type permissions // resolve type permissions
let object_types = resolve_type_permissions(metadata_accessor, object_types)?; let object_types = resolve_type_permissions(metadata_accessor, object_types)?;
@ -68,7 +63,7 @@ pub fn resolve_metadata(
let boolean_expression_types = resolve_boolean_expression_types( let boolean_expression_types = resolve_boolean_expression_types(
metadata_accessor, metadata_accessor,
&data_connectors, &data_connectors,
&data_connector_type_mappings, data_connector_type_mappings,
&object_types, &object_types,
&mut existing_graphql_types, &mut existing_graphql_types,
)?; )?;
@ -78,7 +73,7 @@ pub fn resolve_metadata(
resolve_data_connector_scalar_representations( resolve_data_connector_scalar_representations(
metadata_accessor, metadata_accessor,
&mut data_connectors, &mut data_connectors,
&scalar_types, scalar_types,
&mut existing_graphql_types, &mut existing_graphql_types,
)?; )?;
@ -87,14 +82,14 @@ pub fn resolve_metadata(
let mut models = resolve_models( let mut models = resolve_models(
metadata_accessor, metadata_accessor,
&data_connectors, &data_connectors,
&data_connector_type_mappings, data_connector_type_mappings,
&object_types, &object_types,
&scalar_types, scalar_types,
&mut existing_graphql_types, &mut existing_graphql_types,
&mut global_id_enabled_types, &mut global_id_enabled_types,
&mut apollo_federation_entity_enabled_types, &mut apollo_federation_entity_enabled_types,
&boolean_expression_types, &boolean_expression_types,
&graphql_config, graphql_config,
)?; )?;
// To check if global_id_fields are defined in object type but no model has global_id_source set to true: // To check if global_id_fields are defined in object type but no model has global_id_source set to true:
@ -118,9 +113,9 @@ pub fn resolve_metadata(
let mut commands = resolve_commands( let mut commands = resolve_commands(
metadata_accessor, metadata_accessor,
&data_connectors, &data_connectors,
&data_connector_type_mappings, data_connector_type_mappings,
&object_types, &object_types,
&scalar_types, scalar_types,
)?; )?;
// resolve relationships // resolve relationships
@ -149,7 +144,7 @@ pub fn resolve_metadata(
)?; )?;
Ok(Metadata { Ok(Metadata {
scalar_types, scalar_types: scalar_types.clone(),
object_types, object_types,
models, models,
commands, commands,
@ -198,48 +193,6 @@ fn resolve_commands(
Ok(commands) Ok(commands)
} }
/// resolve scalar types
/// this currently works by mutating `existing_graphql_types`, we should try
/// and change this to return new values here and make the caller combine them together
fn resolve_scalar_types(
metadata_accessor: &open_dds::accessor::MetadataAccessor,
existing_graphql_types: &mut HashSet<ast::TypeName>,
) -> Result<HashMap<Qualified<CustomTypeName>, ScalarTypeRepresentation>, Error> {
let mut scalar_types = HashMap::new();
for open_dds::accessor::QualifiedObject {
subgraph,
object: scalar_type,
} in &metadata_accessor.scalar_types
{
let graphql_type_name = match scalar_type.graphql.as_ref() {
None => Ok(None),
Some(type_name) => mk_name(type_name.type_name.0.as_ref())
.map(ast::TypeName)
.map(Some),
}?;
let qualified_scalar_type_name =
Qualified::new(subgraph.to_string(), scalar_type.name.clone());
if scalar_types
.insert(
qualified_scalar_type_name.clone(),
ScalarTypeRepresentation {
graphql_type_name: graphql_type_name.clone(),
description: scalar_type.description.clone(),
},
)
.is_some()
{
return Err(Error::DuplicateTypeDefinition {
name: qualified_scalar_type_name,
});
}
store_new_graphql_type(existing_graphql_types, graphql_type_name.as_ref())?;
}
Ok(scalar_types)
}
/// resolve type permissions /// resolve type permissions
/// this works by mutating `types`, and returning an owned value /// this works by mutating `types`, and returning an owned value
fn resolve_type_permissions( fn resolve_type_permissions(

View File

@ -1,7 +1,8 @@
/// This is where we'll be moving explicit metadata resolve stages
pub mod data_connector_type_mappings; pub mod data_connector_type_mappings;
pub mod data_connectors; pub mod data_connectors;
/// This is where we'll be moving explicit metadata resolve stages
pub mod graphql_config; pub mod graphql_config;
pub mod scalar_types;
use crate::metadata::resolved::error::Error; use crate::metadata::resolved::error::Error;
use crate::metadata::resolved::metadata::{resolve_metadata, Metadata}; use crate::metadata::resolved::metadata::{resolve_metadata, Metadata};
@ -18,13 +19,28 @@ pub fn resolve(metadata: open_dds::Metadata) -> Result<Metadata, Error> {
let data_connectors = data_connectors::resolve(&metadata_accessor)?; let data_connectors = data_connectors::resolve(&metadata_accessor)?;
let data_connector_type_mappings = let data_connector_type_mappings::DataConnectorTypeMappingsOutput {
data_connector_type_mappings::resolve(&metadata_accessor, &data_connectors)?; data_connector_type_mappings,
existing_graphql_types,
global_id_enabled_types,
apollo_federation_entity_enabled_types,
object_types,
} = data_connector_type_mappings::resolve(&metadata_accessor, &data_connectors)?;
let scalar_types::ScalarTypesOutput {
scalar_types,
graphql_types,
} = scalar_types::resolve(&metadata_accessor, &existing_graphql_types)?;
resolve_metadata( resolve_metadata(
&metadata_accessor, &metadata_accessor,
graphql_config, &graphql_config,
data_connectors, data_connectors,
data_connector_type_mappings, graphql_types,
global_id_enabled_types,
apollo_federation_entity_enabled_types,
&data_connector_type_mappings,
object_types,
&scalar_types,
) )
} }

View File

@ -0,0 +1,59 @@
use std::collections::{HashMap, HashSet};
use lang_graphql::ast::common as ast;
use open_dds::types::CustomTypeName;
use crate::metadata::resolved::error::Error;
use crate::metadata::resolved::subgraph::Qualified;
use crate::metadata::resolved::types::{mk_name, store_new_graphql_type, ScalarTypeRepresentation};
pub struct ScalarTypesOutput {
pub scalar_types: HashMap<Qualified<CustomTypeName>, ScalarTypeRepresentation>,
pub graphql_types: HashSet<ast::TypeName>,
}
/// resolve scalar types
pub fn resolve(
metadata_accessor: &open_dds::accessor::MetadataAccessor,
existing_graphql_types: &HashSet<ast::TypeName>,
) -> Result<ScalarTypesOutput, Error> {
let mut scalar_types = HashMap::new();
let mut graphql_types = existing_graphql_types.clone();
for open_dds::accessor::QualifiedObject {
subgraph,
object: scalar_type,
} in &metadata_accessor.scalar_types
{
let graphql_type_name = match scalar_type.graphql.as_ref() {
None => Ok(None),
Some(type_name) => mk_name(type_name.type_name.0.as_ref())
.map(ast::TypeName)
.map(Some),
}?;
let qualified_scalar_type_name =
Qualified::new(subgraph.to_string(), scalar_type.name.clone());
if scalar_types
.insert(
qualified_scalar_type_name.clone(),
ScalarTypeRepresentation {
graphql_type_name: graphql_type_name.clone(),
description: scalar_type.description.clone(),
},
)
.is_some()
{
return Err(Error::DuplicateTypeDefinition {
name: qualified_scalar_type_name,
});
}
store_new_graphql_type(&mut graphql_types, graphql_type_name.as_ref())?;
}
Ok(ScalarTypesOutput {
scalar_types,
graphql_types,
})
}