Projects STRLCPY graphql-engine Commits 93d608c1
🤬
  • break out `data_connectors` resolving step (#457)

    <!-- Thank you for submitting this PR! :) -->
    
    ## Description
    
    As per https://github.com/hasura/v3-engine/pull/450, break out creation
    of `data_connectors` info (and related types) into it's own files.
    Functional no-op.
    
    V3_GIT_ORIGIN_REV_ID: 7a8d445217a4fac2bbb135aa48baa20a0789e785
  • Loading...
  • Daniel Harvey committed with hasura-bot 1 month ago
    93d608c1
    1 parent 8c538f57
  • ■ ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/command.rs
     1 +use super::stages::data_connectors;
    1 2  use crate::metadata::resolved::argument::get_argument_mappings;
    2  -use crate::metadata::resolved::data_connector::{DataConnectorContext, DataConnectorLink};
     3 +use crate::metadata::resolved::data_connector::DataConnectorLink;
    3 4  use crate::metadata::resolved::error::Error;
    4 5  use crate::metadata::resolved::ndc_validation;
    5 6  use crate::metadata::resolved::subgraph::{
    skipped 8 lines
    14 15  use open_dds::commands::{
    15 16   self, CommandName, CommandV1, DataConnectorCommand, GraphQlRootFieldKind,
    16 17  };
    17  -use open_dds::data_connector::DataConnectorName;
     18 + 
    18 19  use open_dds::permissions::{CommandPermissionsV1, Role};
    19 20  use open_dds::types::{BaseType, CustomTypeName, Deprecated, TypeName, TypeReference};
    20 21  use serde::{Deserialize, Serialize};
    skipped 124 lines
    145 146   command_source: &commands::CommandSource,
    146 147   command: &mut Command,
    147 148   subgraph: &str,
    148  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     149 + data_connectors: &data_connectors::DataConnectors,
    149 150   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    150 151   data_connector_type_mappings: &DataConnectorTypeMappings,
    151 152  ) -> Result<(), Error> {
    skipped 8 lines
    160 161   subgraph.to_string(),
    161 162   command_source.data_connector_name.clone(),
    162 163   );
     164 + 
    163 165   let data_connector_context = data_connectors
     166 + .data_connectors
    164 167   .get(&qualified_data_connector_name)
    165 168   .ok_or_else(|| Error::UnknownCommandDataConnector {
    166 169   command_name: command.name.clone(),
    skipped 182 lines
  • ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/data_connector.rs
    1 1  use super::error::Error;
    2 2  use super::subgraph::Qualified;
    3  -use crate::metadata::resolved::types::ScalarTypeInfo;
    4 3  use indexmap::IndexMap;
    5 4   
     5 +use super::stages::data_connectors;
    6 6  use lang_graphql::ast::common::OperationType;
    7 7  use ndc_models;
    8 8  use open_dds::{
    9  - data_connector::{
    10  - self, DataConnectorName, DataConnectorUrl, ReadWriteUrls, VersionedSchemaAndCapabilities,
    11  - },
     9 + data_connector::{DataConnectorName, DataConnectorUrl, ReadWriteUrls},
    12 10   EnvironmentValue,
    13 11  };
    14 12  use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
    skipped 185 lines
    200 198   }
    201 199  }
    202 200   
    203  -pub struct DataConnectorContext<'a> {
    204  - pub url: &'a data_connector::DataConnectorUrl,
    205  - pub headers: &'a IndexMap<String, open_dds::EnvironmentValue>,
    206  - pub schema: &'a ndc_models::SchemaResponse,
    207  - pub capabilities: &'a ndc_models::CapabilitiesResponse,
    208  - pub scalars: HashMap<&'a str, ScalarTypeInfo<'a>>,
    209  -}
    210  - 
    211  -impl<'a> DataConnectorContext<'a> {
    212  - pub fn new(data_connector: &'a data_connector::DataConnectorLinkV1) -> Result<Self, Error> {
    213  - let VersionedSchemaAndCapabilities::V01(schema_and_capabilities) = &data_connector.schema;
    214  - Ok(DataConnectorContext {
    215  - url: &data_connector.url,
    216  - headers: &data_connector.headers,
    217  - schema: &schema_and_capabilities.schema,
    218  - capabilities: &schema_and_capabilities.capabilities,
    219  - scalars: schema_and_capabilities
    220  - .schema
    221  - .scalar_types
    222  - .iter()
    223  - .map(|(k, v)| (k.as_str(), ScalarTypeInfo::new(v)))
    224  - .collect(),
    225  - })
    226  - }
    227  -}
    228  - 
    229 201  // helper function to determine whether a ndc type is a simple scalar
    230 202  pub fn get_simple_scalar<'a, 'b>(
    231 203   t: ndc_models::Type,
    232  - scalars: &'a HashMap<&str, ScalarTypeInfo<'b>>,
    233  -) -> Option<(String, &'a ScalarTypeInfo<'b>)> {
     204 + scalars: &'a HashMap<&str, data_connectors::ScalarTypeInfo<'b>>,
     205 +) -> Option<(String, &'a data_connectors::ScalarTypeInfo<'b>)> {
    234 206   match t {
    235 207   ndc_models::Type::Named { name } => scalars.get(name.as_str()).map(|info| (name, info)),
    236 208   ndc_models::Type::Nullable { underlying_type } => {
    skipped 11 lines
    248 220   use ndc_models;
    249 221   use open_dds::data_connector::DataConnectorLinkV1;
    250 222   
    251  - use super::DataConnectorContext;
     223 + use crate::metadata::resolved::stages::data_connectors::types::DataConnectorContext;
    252 224   
    253 225   #[test]
    254 226   fn test_url_serialization_deserialization() {
    skipped 59 lines
  • ■ ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/metadata.rs
    skipped 10 lines
    11 11   types::{CustomTypeName, TypeName},
    12 12  };
    13 13   
    14  -use crate::metadata::resolved::subgraph::Qualified;
    15  - 
    16 14  use crate::metadata::resolved::command;
    17  -use crate::metadata::resolved::data_connector::DataConnectorContext;
     15 + 
    18 16  use crate::metadata::resolved::error::{BooleanExpressionError, Error};
    19 17  use crate::metadata::resolved::model::{
    20 18   resolve_model, resolve_model_graphql_api, resolve_model_select_permissions,
    21 19   resolve_model_source, Model,
    22 20  };
    23 21  use crate::metadata::resolved::relationship::resolve_relationship;
     22 +use crate::metadata::resolved::subgraph::Qualified;
    24 23  use crate::metadata::resolved::types::{
    25 24   mk_name, resolve_object_type, resolve_output_type_permission, store_new_graphql_type,
    26 25   TypeRepresentation,
    skipped 3 lines
    30 29   resolve_data_connector_type_mapping, resolve_object_boolean_expression_type,
    31 30   ObjectBooleanExpressionType, ScalarTypeRepresentation, TypeMapping,
    32 31  };
    33  -use crate::metadata::resolved::stages::graphql_config::{GlobalGraphqlConfig, GraphqlConfig};
     32 +use crate::metadata::resolved::stages::{data_connectors, graphql_config};
    34 33   
    35 34  /// Resolved and validated metadata for a project. Used internally in the v3 server.
    36 35  #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
    skipped 2 lines
    39 38   pub models: IndexMap<Qualified<ModelName>, Model>,
    40 39   pub commands: IndexMap<Qualified<CommandName>, command::Command>,
    41 40   pub boolean_expression_types: HashMap<Qualified<CustomTypeName>, ObjectBooleanExpressionType>,
    42  - pub graphql_config: GlobalGraphqlConfig,
     41 + pub graphql_config: graphql_config::GlobalGraphqlConfig,
    43 42  }
    44 43   
    45 44  pub type DataConnectorTypeMappingsForObjectType =
    skipped 61 lines
    107 106   Functions to validate and resolve OpenDD spec to internal metadata
    108 107  *******************/
    109 108  pub fn resolve_metadata(
    110  - metadata_accessor: open_dds::accessor::MetadataAccessor,
    111  - graphql_config: GraphqlConfig,
     109 + metadata_accessor: &open_dds::accessor::MetadataAccessor,
     110 + graphql_config: graphql_config::GraphqlConfig,
     111 + mut data_connectors: data_connectors::DataConnectors,
    112 112  ) -> Result<Metadata, Error> {
    113  - // resolve data connectors
    114  - let mut data_connectors = resolve_data_connectors(&metadata_accessor)?;
    115  - 
    116 113   let mut existing_graphql_types: HashSet<ast::TypeName> = HashSet::new();
    117 114   
    118 115   // we collect all the types with global id fields, and models with global id source for that field. this is used
    skipped 8 lines
    127 124   
    128 125   // resolve object types
    129 126   let (data_connector_type_mappings, types) = resolve_data_connector_type_mappings_and_objects(
    130  - &metadata_accessor,
     127 + metadata_accessor,
    131 128   &data_connectors,
    132 129   &mut existing_graphql_types,
    133 130   &mut global_id_enabled_types,
    skipped 1 lines
    135 132   )?;
    136 133   
    137 134   // resolve scalar types
    138  - let scalar_types = resolve_scalar_types(&metadata_accessor, &mut existing_graphql_types)?;
     135 + let scalar_types = resolve_scalar_types(metadata_accessor, &mut existing_graphql_types)?;
    139 136   
    140 137   // resolve type permissions
    141  - let types = resolve_type_permissions(&metadata_accessor, extend_types(types, scalar_types)?)?;
     138 + let types = resolve_type_permissions(metadata_accessor, extend_types(types, scalar_types)?)?;
    142 139   
    143 140   // resolve object boolean expression types
    144 141   let boolean_expression_types = resolve_boolean_expression_types(
    145  - &metadata_accessor,
     142 + metadata_accessor,
    146 143   &data_connectors,
    147 144   &data_connector_type_mappings,
    148 145   &types,
    skipped 3 lines
    152 149   // resolve data connector scalar representations
    153 150   // TODO: make this return values rather than blindly mutating it's inputs
    154 151   resolve_data_connector_scalar_representations(
    155  - &metadata_accessor,
     152 + metadata_accessor,
    156 153   &mut data_connectors,
    157 154   &types,
    158 155   &mut existing_graphql_types,
    skipped 2 lines
    161 158   // resolve models
    162 159   // TODO: validate types
    163 160   let mut models = resolve_models(
    164  - &metadata_accessor,
     161 + metadata_accessor,
    165 162   &data_connectors,
    166 163   &data_connector_type_mappings,
    167 164   &types,
    skipped 23 lines
    191 188   
    192 189   // resolve commands
    193 190   let mut commands = resolve_commands(
    194  - &metadata_accessor,
     191 + metadata_accessor,
    195 192   &data_connectors,
    196 193   &data_connector_type_mappings,
    197 194   &types,
    skipped 1 lines
    199 196   
    200 197   // resolve relationships
    201 198   let types = resolve_relationships(
    202  - &metadata_accessor,
     199 + metadata_accessor,
    203 200   &data_connectors,
    204 201   types,
    205 202   &models,
    skipped 2 lines
    208 205   
    209 206   // resolve command permissions
    210 207   // TODO: make this return values rather than blindly mutating it's inputs
    211  - resolve_command_permissions(&metadata_accessor, &mut commands)?;
     208 + resolve_command_permissions(metadata_accessor, &mut commands)?;
    212 209   
    213 210   // resolve model permissions
    214 211   // Note: Model permissions's predicate can include the relationship field,
    215 212   // hence Model permissions should be resolved after the relationships of a
    216 213   // model is resolved.
    217 214   // TODO: make this return values rather than blindly mutating it's inputs
    218  - resolve_model_permissions(&metadata_accessor, &data_connectors, &types, &mut models)?;
     215 + resolve_model_permissions(metadata_accessor, &data_connectors, &types, &mut models)?;
    219 216   
    220 217   Ok(Metadata {
    221 218   types,
    skipped 7 lines
    229 226  /// resolve commands
    230 227  fn resolve_commands(
    231 228   metadata_accessor: &open_dds::accessor::MetadataAccessor,
    232  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     229 + data_connectors: &data_connectors::DataConnectors,
    233 230   data_connector_type_mappings: &DataConnectorTypeMappings,
    234 231   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    235 232  ) -> Result<IndexMap<Qualified<CommandName>, command::Command>, Error> {
    skipped 27 lines
    263 260   Ok(commands)
    264 261  }
    265 262   
    266  -/// resolve data connectors
    267  -fn resolve_data_connectors(
    268  - metadata_accessor: &open_dds::accessor::MetadataAccessor,
    269  -) -> Result<HashMap<Qualified<DataConnectorName>, DataConnectorContext>, Error> {
    270  - let mut data_connectors = HashMap::new();
    271  - for open_dds::accessor::QualifiedObject {
    272  - subgraph,
    273  - object: data_connector,
    274  - } in &metadata_accessor.data_connectors
    275  - {
    276  - let qualified_data_connector_name =
    277  - Qualified::new(subgraph.to_string(), data_connector.name.clone());
    278  - if data_connectors
    279  - .insert(
    280  - qualified_data_connector_name.clone(),
    281  - DataConnectorContext::new(data_connector)?,
    282  - )
    283  - .is_some()
    284  - {
    285  - return Err(Error::DuplicateDataConnectorDefinition {
    286  - name: qualified_data_connector_name,
    287  - });
    288  - }
    289  - }
    290  - Ok(data_connectors)
    291  -}
    292  - 
    293 263  /// resolve object types, matching them to that in the data connectors
    294 264  /// this currently works by mutating `types` and `existing_graphql_types`, we should try
    295 265  /// and change this to return new values here and make the caller combine them together
    296 266  fn resolve_data_connector_type_mappings_and_objects(
    297 267   metadata_accessor: &open_dds::accessor::MetadataAccessor,
    298  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     268 + data_connectors: &data_connectors::DataConnectors,
    299 269   existing_graphql_types: &mut HashSet<ast::TypeName>,
    300 270   global_id_enabled_types: &mut HashMap<Qualified<CustomTypeName>, Vec<Qualified<ModelName>>>,
    301 271   apollo_federation_entity_enabled_types: &mut HashMap<
    skipped 161 lines
    463 433  /// resolve object boolean expression types
    464 434  fn resolve_boolean_expression_types(
    465 435   metadata_accessor: &open_dds::accessor::MetadataAccessor,
    466  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     436 + data_connectors: &data_connectors::DataConnectors,
    467 437   data_connector_type_mappings: &DataConnectorTypeMappings,
    468 438   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    469 439   existing_graphql_types: &mut HashSet<ast::TypeName>,
    skipped 31 lines
    501 471  /// return new values instead if possible
    502 472  fn resolve_data_connector_scalar_representations(
    503 473   metadata_accessor: &open_dds::accessor::MetadataAccessor,
    504  - data_connectors: &mut HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     474 + data_connectors: &mut data_connectors::DataConnectors,
    505 475   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    506 476   existing_graphql_types: &mut HashSet<ast::TypeName>,
    507 477  ) -> Result<(), Error> {
    skipped 8 lines
    516 486   scalar_type_representation.data_connector_name.to_owned(),
    517 487   );
    518 488   let connector_context = data_connectors
     489 + .data_connectors
    519 490   .get_mut(&qualified_data_connector_name)
    520 491   .ok_or_else(|| Error::ScalarTypeFromUnknownDataConnector {
    521 492   scalar_type: scalar_type_name.clone(),
    skipped 56 lines
    578 549  /// resolve models
    579 550  fn resolve_models(
    580 551   metadata_accessor: &open_dds::accessor::MetadataAccessor,
    581  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     552 + data_connectors: &data_connectors::DataConnectors,
    582 553   data_connector_type_mappings: &DataConnectorTypeMappings,
    583 554   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    584 555   existing_graphql_types: &mut HashSet<ast::TypeName>,
    skipped 3 lines
    588 559   Option<Qualified<open_dds::models::ModelName>>,
    589 560   >,
    590 561   boolean_expression_types: &HashMap<Qualified<CustomTypeName>, ObjectBooleanExpressionType>,
    591  - graphql_config: &GraphqlConfig,
     562 + graphql_config: &graphql_config::GraphqlConfig,
    592 563  ) -> Result<IndexMap<Qualified<ModelName>, Model>, Error> {
    593 564   // resolve models
    594 565   // TODO: validate types
    skipped 67 lines
    662 633  /// returns updated `types` value
    663 634  fn resolve_relationships(
    664 635   metadata_accessor: &open_dds::accessor::MetadataAccessor,
    665  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     636 + data_connectors: &data_connectors::DataConnectors,
    666 637   mut types: HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    667 638   models: &IndexMap<Qualified<ModelName>, Model>,
    668 639   commands: &IndexMap<Qualified<CommandName>, command::Command>,
    skipped 84 lines
    753 724  /// return new values instead where possible
    754 725  fn resolve_model_permissions(
    755 726   metadata_accessor: &open_dds::accessor::MetadataAccessor,
    756  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     727 + data_connectors: &data_connectors::DataConnectors,
    757 728   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    758 729   models: &mut IndexMap<Qualified<ModelName>, Model>,
    759 730  ) -> Result<(), Error> {
    skipped 40 lines
  • ■ ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/model.rs
     1 +use super::metadata::DataConnectorTypeMappings;
     2 +use super::permission::{resolve_value_expression, ValueExpression};
     3 +use super::relationship::RelationshipTarget;
     4 +use super::stages::data_connectors;
     5 +use super::typecheck;
     6 +use super::types::{
     7 + collect_type_mapping_for_source, NdcColumnForComparison, ObjectBooleanExpressionType,
     8 + ObjectTypeRepresentation, TypeMappingToCollect,
     9 +};
    1 10  use crate::metadata::resolved::argument::get_argument_mappings;
    2  -use crate::metadata::resolved::data_connector::get_simple_scalar;
    3  -use crate::metadata::resolved::data_connector::{DataConnectorContext, DataConnectorLink};
     11 +use crate::metadata::resolved::data_connector;
     12 +use crate::metadata::resolved::data_connector::DataConnectorLink;
    4 13  use crate::metadata::resolved::error::{
    5 14   BooleanExpressionError, Error, GraphqlConfigError, RelationshipError,
    6 15  };
    skipped 5 lines
    12 21   QualifiedTypeReference,
    13 22  };
    14 23  use crate::metadata::resolved::types::store_new_graphql_type;
     24 +use crate::metadata::resolved::types::TypeRepresentation;
    15 25  use crate::metadata::resolved::types::{mk_name, FieldDefinition, TypeMapping};
    16  -use crate::metadata::resolved::types::{ScalarTypeInfo, TypeRepresentation};
    17 26  use crate::schema::types::output_type::relationship::{
    18 27   ModelTargetSource, PredicateRelationshipAnnotation,
    19 28  };
    skipped 14 lines
    34 43  use serde::{Deserialize, Serialize};
    35 44  use std::collections::{BTreeMap, HashMap, HashSet};
    36 45  use std::iter;
    37  - 
    38  -use super::metadata::DataConnectorTypeMappings;
    39  -use super::permission::{resolve_value_expression, ValueExpression};
    40  -use super::relationship::RelationshipTarget;
    41  -use super::typecheck;
    42  -use super::types::{
    43  - collect_type_mapping_for_source, NdcColumnForComparison, ObjectBooleanExpressionType,
    44  - ObjectTypeRepresentation, TypeMappingToCollect,
    45  -};
    46 46   
    47 47  #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
    48 48  pub struct UniqueIdentifierField {
    skipped 372 lines
    421 421  fn resolve_ndc_type(
    422 422   data_connector: &Qualified<DataConnectorName>,
    423 423   source_type: &ndc_models::Type,
    424  - scalars: &HashMap<&str, ScalarTypeInfo>,
     424 + scalars: &HashMap<&str, data_connectors::ScalarTypeInfo>,
    425 425   subgraph: &str,
    426 426  ) -> Result<QualifiedTypeReference, Error> {
    427 427   match source_type {
    skipped 46 lines
    474 474   data_connector: &Qualified<DataConnectorName>,
    475 475   field_name: &FieldName,
    476 476   fields: &IndexMap<FieldName, FieldDefinition>,
    477  - scalars: &HashMap<&str, ScalarTypeInfo>,
     477 + scalars: &HashMap<&str, data_connectors::ScalarTypeInfo>,
    478 478   ndc_scalar_type: &ndc_models::ScalarType,
    479 479   subgraph: &str,
    480 480  ) -> Result<(String, QualifiedTypeReference), Error> {
    skipped 35 lines
    516 516   model_predicate: &permissions::ModelPredicate,
    517 517   model: &Model,
    518 518   subgraph: &str,
    519  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     519 + data_connectors: &data_connectors::DataConnectors,
    520 520   fields: &IndexMap<FieldName, FieldDefinition>,
    521 521   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    522 522   models: &IndexMap<Qualified<ModelName>, Model>,
    skipped 27 lines
    550 550   })?;
    551 551   // Determine ndc type of the field
    552 552   let field_ndc_type = &field_mapping.column_type;
     553 + 
    553 554   // Determine whether the ndc type is a simple scalar
    554 555   // Get available scalars defined in the data connector
    555 556   let scalars = &data_connectors
     557 + .data_connectors
    556 558   .get(&model_source.data_connector.name)
    557 559   .ok_or(Error::UnknownModelDataConnector {
    558 560   model_name: model.name.clone(),
    559 561   data_connector: model_source.data_connector.name.clone(),
    560 562   })?
    561 563   .scalars;
     564 + 
    562 565   // Get scalar type info from the data connector
    563  - let (_, scalar_type_info) = get_simple_scalar(field_ndc_type.clone(), scalars)
    564  - .ok_or_else(|| Error::UnsupportedFieldInSelectPermissionsPredicate {
    565  - field_name: field.clone(),
    566  - model_name: model.name.clone(),
    567  - })?;
     566 + let (_, scalar_type_info) =
     567 + data_connector::get_simple_scalar(field_ndc_type.clone(), scalars).ok_or_else(
     568 + || Error::UnsupportedFieldInSelectPermissionsPredicate {
     569 + field_name: field.clone(),
     570 + model_name: model.name.clone(),
     571 + },
     572 + )?;
    568 573   
    569 574   let (resolved_operator, argument_type) = resolve_binary_operator(
    570 575   operator,
    skipped 203 lines
    774 779   model: &Model,
    775 780   subgraph: &str,
    776 781   model_permissions: &ModelPermissionsV1,
    777  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     782 + data_connectors: &data_connectors::DataConnectors,
    778 783   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    779 784   models: &IndexMap<Qualified<ModelName>, Model>,
    780 785  ) -> Result<HashMap<Role, SelectPermission>, Error> {
    skipped 76 lines
    857 862   model_data_type: &Qualified<CustomTypeName>,
    858 863   model_source: &ModelSource,
    859 864   field: &FieldName,
    860  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     865 + data_connectors: &data_connectors::DataConnectors,
    861 866   comparison_location: F,
    862 867  ) -> Result<NdcColumnForComparison, Error> {
    863 868   // Get field mappings of model data type
    skipped 5 lines
    869 874   type_name: model_data_type.clone(),
    870 875   data_connector: model_source.data_connector.name.clone(),
    871 876   })?;
     877 + 
    872 878   // Determine field_mapping for the given field
    873 879   let field_mapping =
    874 880   field_mappings
    skipped 3 lines
    878 884   field_name: field.clone(),
    879 885   model_name: model_name.clone(),
    880 886   })?;
     887 + 
    881 888   // Determine ndc type of the field
    882 889   let field_ndc_type = &field_mapping.column_type;
     890 + 
    883 891   // Get available scalars defined in the data connector
    884 892   let scalars = &data_connectors
     893 + .data_connectors
    885 894   .get(&model_source.data_connector.name)
    886 895   .ok_or(Error::UnknownModelDataConnector {
    887 896   model_name: model_name.clone(),
    skipped 2 lines
    890 899   .scalars;
    891 900   // Determine whether the ndc type is a simple scalar and get scalar type info
    892 901   let (_field_ndc_type_scalar, scalar_type_info) =
    893  - get_simple_scalar(field_ndc_type.clone(), scalars).ok_or_else(|| {
     902 + data_connector::get_simple_scalar(field_ndc_type.clone(), scalars).ok_or_else(|| {
    894 903   Error::UncomparableNonScalarFieldType {
    895 904   comparison_location: comparison_location(),
    896 905   field_name: field.clone(),
    skipped 34 lines
    931 940   model: &mut Model,
    932 941   subgraph: &str,
    933 942   existing_graphql_types: &mut HashSet<ast::TypeName>,
    934  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     943 + data_connectors: &data_connectors::DataConnectors,
    935 944   model_description: &Option<String>,
    936 945   graphql_config: &GraphqlConfig,
    937 946  ) -> Result<(), Error> {
    skipped 134 lines
    1072 1081   return Ok(None);
    1073 1082   };
    1074 1083   let mut scalar_fields = HashMap::new();
     1084 + 
    1075 1085   let scalar_types = &data_connectors
     1086 + .data_connectors
    1076 1087   .get(&model_source.data_connector.name)
    1077 1088   .ok_or(Error::UnknownModelDataConnector {
    1078 1089   model_name: model_name.clone(),
    skipped 22 lines
    1101 1112   for (field_name, field_mapping) in field_mappings.iter() {
    1102 1113   // Generate comparison expression for fields mapped to simple scalar type
    1103 1114   if let Some((scalar_type_name, scalar_type_info)) =
    1104  - get_simple_scalar(field_mapping.column_type.clone(), scalar_types)
     1115 + data_connector::get_simple_scalar(
     1116 + field_mapping.column_type.clone(),
     1117 + scalar_types,
     1118 + )
    1105 1119   {
    1106 1120   if let Some(graphql_type_name) =
    1107 1121   &scalar_type_info.comparison_expression_name.clone()
    skipped 152 lines
    1260 1274   model_source: &models::ModelSource,
    1261 1275   model: &mut Model,
    1262 1276   subgraph: &str,
    1263  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     1277 + data_connectors: &data_connectors::DataConnectors,
    1264 1278   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    1265 1279   data_connector_type_mappings: &DataConnectorTypeMappings,
    1266 1280  ) -> Result<(), Error> {
    skipped 7 lines
    1274 1288   model_source.data_connector_name.clone(),
    1275 1289   );
    1276 1290   let data_connector_context = data_connectors
     1291 + .data_connectors
    1277 1292   .get(&qualified_data_connector_name)
    1278 1293   .ok_or_else(|| Error::UnknownModelDataConnector {
    1279 1294   model_name: model.name.clone(),
    skipped 156 lines
  • ■ ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/relationship.rs
    1 1  use super::command::Command;
    2  -use super::data_connector::DataConnectorContext;
     2 + 
    3 3  use super::data_connector::DataConnectorLink;
    4 4  use super::error::{Error, RelationshipError};
    5 5  use super::model::get_ndc_column_for_comparison;
    6 6  use super::model::Model;
     7 +use super::stages::data_connectors;
    7 8  use super::subgraph::Qualified;
    8 9  use super::subgraph::QualifiedTypeReference;
    9 10  use super::types::mk_name;
    skipped 3 lines
    13 14  use lang_graphql::ast::common as ast;
    14 15  use open_dds::arguments::ArgumentName;
    15 16  use open_dds::commands::CommandName;
    16  -use open_dds::data_connector::DataConnectorName;
     17 + 
    17 18  use open_dds::models::ModelName;
    18 19  use open_dds::relationships::{
    19 20   self, FieldAccess, RelationshipName, RelationshipType, RelationshipV1,
    skipped 1 lines
    21 22  use open_dds::types::CustomTypeName;
    22 23  use open_dds::types::Deprecated;
    23 24  use serde::{Deserialize, Serialize};
    24  -use std::collections::HashMap;
     25 + 
    25 26  use std::collections::HashSet;
    26 27   
    27 28  #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
    skipped 124 lines
    152 153   source_type_name: &Qualified<CustomTypeName>,
    153 154   source_type: &ObjectTypeRepresentation,
    154 155   target_model: &Model,
    155  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext<'_>>,
     156 + data_connectors: &data_connectors::DataConnectors,
    156 157  ) -> Result<Vec<RelationshipModelMapping>, Error> {
    157 158   let mut resolved_relationship_mappings = Vec::new();
    158 159   let mut field_mapping_hashset_for_validation: HashSet<&String> = HashSet::new();
    skipped 175 lines
    334 335   relationship_name: &RelationshipName,
    335 336   source_data_connector: &Option<DataConnectorLink>,
    336 337   target_name: &RelationshipTargetName,
    337  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext<'_>>,
     338 + data_connectors: &data_connectors::DataConnectors,
    338 339  ) -> Result<Option<RelationshipCapabilities>, Error> {
    339 340   let data_connector = if let Some(data_connector) = &source_data_connector {
    340 341   data_connector
    skipped 1 lines
    342 343   return Ok(None);
    343 344   };
    344 345   
    345  - let resolved_data_connector =
    346  - data_connectors
    347  - .get(&data_connector.name)
    348  - .ok_or_else(|| match target_name {
    349  - RelationshipTargetName::Model(model_name) => Error::UnknownModelDataConnector {
    350  - model_name: model_name.clone(),
    351  - data_connector: data_connector.name.clone(),
    352  - },
    353  - RelationshipTargetName::Command(command_name) => {
    354  - Error::UnknownCommandDataConnector {
    355  - command_name: command_name.clone(),
    356  - data_connector: data_connector.name.clone(),
    357  - }
    358  - }
    359  - })?;
     346 + let resolved_data_connector = data_connectors
     347 + .data_connectors
     348 + .get(&data_connector.name)
     349 + .ok_or_else(|| match target_name {
     350 + RelationshipTargetName::Model(model_name) => Error::UnknownModelDataConnector {
     351 + model_name: model_name.clone(),
     352 + data_connector: data_connector.name.clone(),
     353 + },
     354 + RelationshipTargetName::Command(command_name) => Error::UnknownCommandDataConnector {
     355 + command_name: command_name.clone(),
     356 + data_connector: data_connector.name.clone(),
     357 + },
     358 + })?;
    360 359   let capabilities = &resolved_data_connector.capabilities.capabilities;
    361 360   
    362 361   if capabilities.query.variables.is_none() {
    skipped 19 lines
    382 381   subgraph: &str,
    383 382   models: &IndexMap<Qualified<ModelName>, Model>,
    384 383   commands: &IndexMap<Qualified<CommandName>, Command>,
    385  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext<'_>>,
     384 + data_connectors: &data_connectors::DataConnectors,
    386 385   source_type: &ObjectTypeRepresentation,
    387 386  ) -> Result<Relationship, Error> {
    388 387   let source_type_name = Qualified::new(subgraph.to_string(), relationship.source.clone());
    skipped 98 lines
  • ■ ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/stages/data_connectors/mod.rs
     1 +use crate::metadata::resolved::error::Error;
     2 +use crate::metadata::resolved::subgraph::Qualified;
     3 + 
     4 +pub mod types;
     5 +use std::collections::HashMap;
     6 +pub use types::{DataConnectors, ScalarTypeInfo};
     7 + 
     8 +/// resolve data connectors
     9 +pub fn resolve(
     10 + metadata_accessor: &open_dds::accessor::MetadataAccessor,
     11 +) -> Result<types::DataConnectors, Error> {
     12 + let mut data_connectors = HashMap::new();
     13 + for open_dds::accessor::QualifiedObject {
     14 + subgraph,
     15 + object: data_connector,
     16 + } in &metadata_accessor.data_connectors
     17 + {
     18 + let qualified_data_connector_name =
     19 + Qualified::new(subgraph.to_string(), data_connector.name.clone());
     20 + 
     21 + if data_connectors
     22 + .insert(
     23 + qualified_data_connector_name.clone(),
     24 + types::DataConnectorContext::new(data_connector)?,
     25 + )
     26 + .is_some()
     27 + {
     28 + return Err(Error::DuplicateDataConnectorDefinition {
     29 + name: qualified_data_connector_name,
     30 + });
     31 + }
     32 + }
     33 + Ok(types::DataConnectors { data_connectors })
     34 +}
     35 + 
  • ■ ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/stages/data_connectors/types.rs
     1 +use crate::metadata::resolved::error::Error;
     2 +use crate::metadata::resolved::subgraph::Qualified;
     3 +use serde::{Deserialize, Serialize};
     4 + 
     5 +use indexmap::IndexMap;
     6 +use lang_graphql::ast::common as ast;
     7 + 
     8 +use ndc_models;
     9 +use open_dds::data_connector::{self, DataConnectorName, VersionedSchemaAndCapabilities};
     10 +use open_dds::types::TypeName;
     11 +use std::collections::HashMap;
     12 + 
     13 +/// information about a data connector
     14 +/// currently this contains partial ScalarTypeInfo, which we add to later
     15 +pub struct DataConnectorContext<'a> {
     16 + pub url: &'a data_connector::DataConnectorUrl,
     17 + pub headers: &'a IndexMap<String, open_dds::EnvironmentValue>,
     18 + pub schema: &'a ndc_models::SchemaResponse,
     19 + pub capabilities: &'a ndc_models::CapabilitiesResponse,
     20 + pub scalars: HashMap<&'a str, ScalarTypeInfo<'a>>,
     21 +}
     22 + 
     23 +impl<'a> DataConnectorContext<'a> {
     24 + pub fn new(data_connector: &'a data_connector::DataConnectorLinkV1) -> Result<Self, Error> {
     25 + let VersionedSchemaAndCapabilities::V01(schema_and_capabilities) = &data_connector.schema;
     26 + Ok(DataConnectorContext {
     27 + url: &data_connector.url,
     28 + headers: &data_connector.headers,
     29 + schema: &schema_and_capabilities.schema,
     30 + capabilities: &schema_and_capabilities.capabilities,
     31 + scalars: schema_and_capabilities
     32 + .schema
     33 + .scalar_types
     34 + .iter()
     35 + .map(|(k, v)| (k.as_str(), ScalarTypeInfo::new(v)))
     36 + .collect(),
     37 + })
     38 + }
     39 +}
     40 + 
     41 +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, Default)]
     42 +pub struct ComparisonOperators {
     43 + pub equal_operators: Vec<String>,
     44 + pub in_operators: Vec<String>,
     45 +}
     46 + 
     47 +// basic scalar type info
     48 +pub struct ScalarTypeInfo<'a> {
     49 + pub scalar_type: &'a ndc_models::ScalarType,
     50 + pub representation: Option<TypeName>,
     51 + pub comparison_expression_name: Option<ast::TypeName>,
     52 + pub comparison_operators: ComparisonOperators,
     53 +}
     54 + 
     55 +impl<'a> ScalarTypeInfo<'a> {
     56 + pub(crate) fn new(source_scalar: &'a ndc_models::ScalarType) -> Self {
     57 + let mut comparison_operators = ComparisonOperators::default();
     58 + for (operator_name, operator_definition) in &source_scalar.comparison_operators {
     59 + match operator_definition {
     60 + ndc_models::ComparisonOperatorDefinition::Equal => {
     61 + comparison_operators
     62 + .equal_operators
     63 + .push(operator_name.clone());
     64 + }
     65 + ndc_models::ComparisonOperatorDefinition::In => {
     66 + comparison_operators
     67 + .in_operators
     68 + .push(operator_name.clone());
     69 + }
     70 + ndc_models::ComparisonOperatorDefinition::Custom { argument_type: _ } => {}
     71 + };
     72 + }
     73 + ScalarTypeInfo {
     74 + scalar_type: source_scalar,
     75 + representation: None,
     76 + comparison_expression_name: None,
     77 + comparison_operators,
     78 + }
     79 + }
     80 +}
     81 + 
     82 +pub struct DataConnectors<'a> {
     83 + pub data_connectors: HashMap<Qualified<DataConnectorName>, DataConnectorContext<'a>>,
     84 +}
     85 + 
  • ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/stages/mod.rs
     1 +pub mod data_connectors;
    1 2  /// This is where we'll be moving explicit metadata resolve stages
    2 3  pub mod graphql_config;
    3 4   
    skipped 10 lines
    14 15   let graphql_config =
    15 16   graphql_config::resolve(&metadata_accessor.graphql_config, &metadata_accessor.flags)?;
    16 17   
    17  - resolve_metadata(metadata_accessor, graphql_config)
     18 + let data_connectors = data_connectors::resolve(&metadata_accessor)?;
     19 + 
     20 + resolve_metadata(&metadata_accessor, graphql_config, data_connectors)
    18 21  }
    19 22   
  • ■ ■ ■ ■ ■
    v3/crates/engine/src/metadata/resolved/types.rs
    skipped 13 lines
    14 14  use open_dds::permissions::{Role, TypeOutputPermission, TypePermissionsV1};
    15 15  use open_dds::types::{
    16 16   self, CustomTypeName, DataConnectorTypeMapping, Deprecated, FieldName,
    17  - ObjectBooleanExpressionTypeV1, ObjectTypeV1, TypeName,
     17 + ObjectBooleanExpressionTypeV1, ObjectTypeV1,
    18 18  };
    19 19  use serde::{Deserialize, Serialize};
    20 20  use std::collections::{BTreeMap, HashMap, HashSet};
    21 21  use std::str::FromStr;
    22 22   
    23  -use super::data_connector::DataConnectorContext;
    24 23  use super::metadata::DataConnectorTypeMappings;
    25 24  use super::ndc_validation::{get_underlying_named_type, NDCValidationError};
     25 +use super::stages::data_connectors;
    26 26   
    27 27  #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, derive_more::Display)]
    28 28  pub enum TypeRepresentation {
    skipped 29 lines
    58 58   pub equal_operator: String,
    59 59  }
    60 60   
    61  -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, Default)]
    62  -pub struct ComparisonOperators {
    63  - pub equal_operators: Vec<String>,
    64  - pub in_operators: Vec<String>,
    65  -}
    66  - 
    67  -pub struct ScalarTypeInfo<'a> {
    68  - pub scalar_type: &'a ndc_models::ScalarType,
    69  - pub representation: Option<TypeName>,
    70  - pub comparison_expression_name: Option<ast::TypeName>,
    71  - pub comparison_operators: ComparisonOperators,
    72  -}
    73  - 
    74  -impl<'a> ScalarTypeInfo<'a> {
    75  - pub(crate) fn new(source_scalar: &'a ndc_models::ScalarType) -> Self {
    76  - let mut comparison_operators = ComparisonOperators::default();
    77  - for (operator_name, operator_definition) in &source_scalar.comparison_operators {
    78  - match operator_definition {
    79  - ndc_models::ComparisonOperatorDefinition::Equal => {
    80  - comparison_operators
    81  - .equal_operators
    82  - .push(operator_name.clone());
    83  - }
    84  - ndc_models::ComparisonOperatorDefinition::In => {
    85  - comparison_operators
    86  - .in_operators
    87  - .push(operator_name.clone());
    88  - }
    89  - ndc_models::ComparisonOperatorDefinition::Custom { argument_type: _ } => {}
    90  - };
    91  - }
    92  - ScalarTypeInfo {
    93  - scalar_type: source_scalar,
    94  - representation: None,
    95  - comparison_expression_name: None,
    96  - comparison_operators,
    97  - }
    98  - }
    99  -}
    100  - 
    101 61  #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
    102 62  pub struct FieldDefinition {
    103 63   pub field_type: QualifiedTypeReference,
    skipped 225 lines
    329 289   qualified_type_name: &Qualified<CustomTypeName>,
    330 290   subgraph: &str,
    331 291   type_representation: &ObjectTypeRepresentation,
    332  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     292 + data_connectors: &data_connectors::DataConnectors,
    333 293  ) -> Result<TypeMapping, TypeMappingValidationError> {
    334 294   let qualified_data_connector_name = Qualified::new(
    335 295   subgraph.to_string(),
    336 296   data_connector_type_mapping.data_connector_name.clone(),
    337 297   );
    338 298   let data_connector_context = data_connectors
     299 + .data_connectors
    339 300   .get(&qualified_data_connector_name)
    340 301   .ok_or_else(|| TypeMappingValidationError::UnknownDataConnector {
    341 302   data_connector: qualified_data_connector_name.clone(),
    skipped 146 lines
    488 449  pub(crate) fn resolve_object_boolean_expression_type(
    489 450   object_boolean_expression: &ObjectBooleanExpressionTypeV1,
    490 451   subgraph: &str,
    491  - data_connectors: &HashMap<Qualified<DataConnectorName>, DataConnectorContext>,
     452 + data_connectors: &data_connectors::DataConnectors,
    492 453   types: &HashMap<Qualified<CustomTypeName>, TypeRepresentation>,
    493 454   data_connector_type_mappings: &DataConnectorTypeMappings,
    494 455   existing_graphql_types: &mut HashSet<ast::TypeName>,
    skipped 30 lines
    525 486   
    526 487   // validate data connector name
    527 488   let data_connector_context = data_connectors
     489 + .data_connectors
    528 490   .get(&qualified_data_connector_name)
    529 491   .ok_or_else(|| {
    530 492   Error::from(
    skipped 235 lines
Please wait...
Page is in error, reload to recover