Esempio n. 1
0
        private MappedFragmentSpread MapFragmentSpread(FragmentSpread fs, ObjectTypeDef objectTypeDef, bool isForUnion)
        {
            // if it is not inline fragment, it might need to map to FragmentDef; inline fragments are auto-mapped at construction
            if (fs.Fragment == null)
            {
                fs.Fragment = GetFragmentDef(fs.Name);
            }
            if (fs.Fragment == null)
            {
                AddError($"Fragment {fs.Name} not defined.", fs);
                return(null);
            }
            // inline fragments are mapped in-place, here.
            // we need to map them here, once we know the target type
            if (fs.IsInline)
            {
                var onTypeRef = fs.Fragment.OnTypeRef;
                var skip      = onTypeRef != null && onTypeRef.TypeDef != objectTypeDef;
                if (skip)
                {
                    return(null);
                }
                MapObjectSelectionSubset(fs.Fragment.SelectionSubset, objectTypeDef, fs.Directives, isForUnion);
            }
            // there must be mapped field set now
            var mappedFragmItemSet = fs.Fragment.SelectionSubset.MappedItemSets.FirstOrDefault(fset => fset.ObjectTypeDef == objectTypeDef);

            if (mappedFragmItemSet == null)
            {
                AddError($"FATAL: Could not retrieve mapped item list for fragment spread {fs.Name}", fs, ErrorCodes.ServerError);
                return(null);
            }
            var mappedSpread = new MappedFragmentSpread(fs, mappedFragmItemSet.Items);

            return(mappedSpread);
        }
Esempio n. 2
0
        // Might be called for ObjectType or Interface (for intf - just to check fields exist)
        private void MapObjectSelectionSubset(SelectionSubset selSubset, ObjectTypeDef objectTypeDef, bool isForUnion = false)
        {
            // Map arguments on fields, add directives, map fragments
            foreach (var item in selSubset.Items)
            {
                AddRuntimeRequestDirectives(item);
                switch (item)
                {
                case SelectionField selFld:
                    var fldDef = objectTypeDef.Fields[selFld.Name];
                    if (fldDef == null)
                    {
                        // if field not found, the behavior depends if it is a union; it is error for a union
                        if (!isForUnion)
                        {
                            AddError($"Field '{selFld.Name}' not found on type '{objectTypeDef.Name}'.", selFld);
                        }
                        continue;
                    }
                    selFld.MappedArgs = MapArguments(selFld.Args, fldDef.Args, selFld);
                    AddRuntimeModelDirectives(fldDef);
                    MapSelectionFieldSubsetIfPresent(selFld, fldDef.TypeRef.TypeDef);
                    break;

                case FragmentSpread fspread:
                    // Named fragment refs are NOT set by parser; parser sets only Inline fragmDefs; we need to match named fragms here
                    if (!fspread.IsInline && fspread.Fragment == null)
                    {
                        fspread.Fragment = GetFragmentDef(fspread.Name);
                        if (fspread.Fragment == null)
                        {
                            AddError($"Fragment {fspread.Name} not defined.", fspread);
                        }
                    }
                    break;
                } //switch
            }     //foreach item

            if (_requestContext.Failed)
            {
                return;
            }

            // Now create mappings for all possible entity types
            foreach (var typeMapping in objectTypeDef.Mappings)
            {
                // It is possible mapped set already exists (with unions and especially fragments)
                var existing = selSubset.MappedSubSets.FirstOrDefault(ms => ms.Mapping == typeMapping);
                if (existing != null)
                {
                    continue;
                }
                var mappedItems = new List <MappedSelectionItem>();
                foreach (var item in selSubset.Items)
                {
                    switch (item)
                    {
                    case SelectionField selFld:
                        var fldDef = typeMapping.TypeDef.Fields[selFld.Name];
                        if (fldDef == null)
                        {
                            // it is not error, it should have been caught earlier; it is unmatch for union
                            continue;
                        }
                        var fldResolver = typeMapping.GetResolver(fldDef);
                        //.FirstOrDefault(fr => fr.Field.Name == selFld.Name);
                        var mappedFld = new MappedSelectionField(selFld, fldResolver);
                        mappedItems.Add(mappedFld);
                        break;

                    case FragmentSpread fs:
                        var onType = fs.Fragment.OnTypeRef?.TypeDef;
                        var skip   = onType != null && onType.Kind == TypeKind.Object && onType != objectTypeDef;
                        if (skip)
                        {
                            continue;
                        }
                        if (fs.IsInline) // only inline fragments should be mapped from here; named fragments are mapped separately, upfront
                        {
                            MapObjectSelectionSubset(fs.Fragment.SelectionSubset, objectTypeDef, isForUnion);
                        }
                        var mappedSpread = new MappedFragmentSpread(fs);
                        mappedItems.Add(mappedSpread);
                        break;
                    } //switch
                }     //foreach item

                selSubset.MappedSubSets.Add(new MappedSelectionSubSet()
                {
                    Mapping = typeMapping, MappedItems = mappedItems
                });
            } //foreach typeMapping
        }