private void ProcessChainedExpression(ChainedExpression chainedExpression, List <SearchParamTableExpression> tableExpressions, int chainLevel)
        {
            SearchParamTableExpressionQueryGenerator queryGenerator = chainedExpression.Expression.AcceptVisitor(_searchParamTableExpressionQueryGeneratorFactory, null);

            Expression expressionOnTarget = queryGenerator == null ? chainedExpression.Expression : null;

            var sqlChainLinkExpression = new SqlChainLinkExpression(
                chainedExpression.ResourceTypes,
                chainedExpression.ReferenceSearchParameter,
                chainedExpression.TargetResourceTypes,
                chainedExpression.Reversed,
                expressionOnTarget: expressionOnTarget);

            tableExpressions.Add(
                new SearchParamTableExpression(
                    ChainLinkQueryGenerator.Instance,
                    sqlChainLinkExpression,
                    SearchParamTableExpressionKind.Chain,
                    chainLevel));

            if (chainedExpression.Expression is ChainedExpression nestedChainedExpression)
            {
                ProcessChainedExpression(nestedChainedExpression, tableExpressions, chainLevel + 1);
            }
            else if (queryGenerator != null)
            {
                tableExpressions.Add(
                    new SearchParamTableExpression(
                        queryGenerator,
                        chainedExpression.Expression,
                        SearchParamTableExpressionKind.Normal,
                        chainLevel));
            }
        }
Example #2
0
        public ComponentDesigner(ComponentTemplateSD componentSD, FactionTechDB factionTech)
        {
            var staticData = StaticRefLib.StaticData;

            TypeName = componentSD.Name;
            Name     = componentSD.Name;

            _design.ID          = Guid.NewGuid();
            MassFormula         = new ChainedExpression(componentSD.MassFormula, this, factionTech, staticData);
            VolumeFormula       = new ChainedExpression(componentSD.VolumeFormula, this, factionTech, staticData);
            CrewFormula         = new ChainedExpression(componentSD.CrewReqFormula, this, factionTech, staticData);
            HTKFormula          = new ChainedExpression(componentSD.HTKFormula, this, factionTech, staticData);
            ResearchCostFormula = new ChainedExpression(componentSD.ResearchCostFormula, this, factionTech, staticData);
            BuildCostFormula    = new ChainedExpression(componentSD.BuildPointCostFormula, this, factionTech, staticData);
            CreditCostFormula   = new ChainedExpression(componentSD.CreditCostFormula, this, factionTech, staticData);
            ComponentMountType  = componentSD.MountType;
            IndustryType        = componentSD.IndustryTypeID;
            CargoTypeID         = componentSD.CargoTypeID;
            _design.CargoTypeID = componentSD.CargoTypeID;
            if (componentSD.MountType.HasFlag(ComponentMountType.PlanetInstallation))
            {
                _design.GuiHints = ConstructableGuiHints.CanBeInstalled;
            }
            if (!string.IsNullOrEmpty(componentSD.DescriptionFormula))
            {
                DescriptionFormula = new ChainedExpression(componentSD.DescriptionFormula, this, factionTech, staticData);
            }

            Dictionary <Guid, ChainedExpression> resourceCostForulas = new Dictionary <Guid, ChainedExpression>();

            foreach (var kvp in componentSD.ResourceCostFormula)
            {
                if (staticData.CargoGoods.GetAny(kvp.Key) != null)
                {
                    resourceCostForulas.Add(kvp.Key, new ChainedExpression(kvp.Value, this, factionTech));
                }
                else //TODO: log don't crash.
                {
                    throw new Exception("GUID object {" + kvp.Key + "} not found in resourceCosting for " + this.TypeName + " This object needs to be either a mineral, material or component defined in the Data folder");
                }
            }

            ResourceCostFormulas = resourceCostForulas;

            foreach (ComponentTemplateAttributeSD attrbSD in componentSD.ComponentAtbSDs)
            {
                ComponentDesignAttribute designAttribute = new ComponentDesignAttribute(this, attrbSD, factionTech);
                ComponentDesignAttributes.Add(designAttribute.Name, designAttribute);
                ComponentDesignAttributeList.Add(designAttribute);
            }

            EvalAll();
        }
        public static void ValidateChainedExpression(
            Expression expression,
            Type resourceType,
            string key,
            Type targetResourceType,
            Action <Expression> childExpressionValidator)
        {
            ChainedExpression chainedExpression = Assert.IsType <ChainedExpression>(expression);

            Assert.Equal(resourceType.ToString(), chainedExpression.ResourceType);
            Assert.Equal(key, chainedExpression.ParamName);
            Assert.Equal(targetResourceType.ToString(), chainedExpression.TargetResourceType.ToString());

            childExpressionValidator(chainedExpression.Expression);
        }
        public static void ValidateChainedExpression(
            Expression expression,
            Type resourceType,
            SearchParameterInfo referenceSearchParam,
            Type targetResourceType,
            Action <Expression> childExpressionValidator)
        {
            ChainedExpression chainedExpression = Assert.IsType <ChainedExpression>(expression);

            Assert.Collection(chainedExpression.ResourceTypes, x => Assert.Equal(resourceType.ToString(), x));
            Assert.Equal(referenceSearchParam, chainedExpression.ReferenceSearchParameter);
            Assert.Collection(chainedExpression.TargetResourceTypes, x => Assert.Equal(targetResourceType.ToString(), x));

            childExpressionValidator(chainedExpression.Expression);
        }
        public static void ValidateChainedExpression(
            Expression expression,
            Hl7.Fhir.Model.ResourceType resourceType,
            SearchParameterInfo referenceSearchParam,
            string[] targetResourceTypes,
            Action <Expression> childExpressionValidator)
        {
            ChainedExpression chainedExpression = Assert.IsType <ChainedExpression>(expression);

            Assert.Collection(chainedExpression.ResourceTypes, x => Assert.Equal(resourceType.ToString(), x));
            Assert.Equal(referenceSearchParam, chainedExpression.ReferenceSearchParameter);
            Assert.Collection(chainedExpression.TargetResourceTypes, targetResourceTypes.Select <string, Action <string> >(t => x => Assert.Equal(t, x)).ToArray());

            childExpressionValidator(chainedExpression.Expression);
        }
Example #6
0
        public static void ValidateChainedExpression(
            Expression expression,
            Hl7.Fhir.Model.ResourceType resourceType,
            SearchParameterInfo referenceSearchParam,
            string targetResourceType,
            Action <Expression> childExpressionValidator)
        {
            ChainedExpression chainedExpression = Assert.IsType <ChainedExpression>(expression);

            Assert.Equal(resourceType.ToString(), chainedExpression.ResourceType);
            Assert.Equal(referenceSearchParam, chainedExpression.ReferenceSearchParameter);
            Assert.Equal(targetResourceType, chainedExpression.TargetResourceType);

            childExpressionValidator(chainedExpression.Expression);
        }
Example #7
0
        private Expression ParseChainedExpression(string[] resourceTypes, SearchParameterInfo searchParameter, string[] targetResourceTypes, ReadOnlySpan <char> remainingKey, string value, bool reversed)
        {
            // We have more paths after this so this is a chained expression.
            // Since this is chained expression, the expression must be a reference type.
            if (searchParameter.Type != ValueSets.SearchParamType.Reference)
            {
                // The search parameter is not a reference type, which is not allowed.
                throw new InvalidSearchOperationException(Core.Resources.ChainedParameterMustBeReferenceSearchParamType);
            }

            // Check to see if the client has specifically specified the target resource type to scope to.
            if (targetResourceTypes.Any())
            {
                // A target resource type is specified.
                foreach (var targetResourceType in targetResourceTypes)
                {
                    if (!ModelInfoProvider.IsKnownResource(targetResourceType))
                    {
                        throw new InvalidSearchOperationException(string.Format(Core.Resources.ResourceNotSupported, targetResourceType));
                    }
                }
            }

            var possibleTargetResourceTypes = targetResourceTypes.Any()
                ? targetResourceTypes.Intersect(searchParameter.TargetResourceTypes)
                : searchParameter.TargetResourceTypes;

            ChainedExpression chainedExpression = null;

            foreach (var possibleTargetResourceType in possibleTargetResourceTypes)
            {
                var wrappedTargetResourceType = new[] { possibleTargetResourceType };
                var multipleChainType         = reversed ? resourceTypes : wrappedTargetResourceType;

                ChainedExpression expression;
                try
                {
                    expression = Expression.Chained(
                        resourceTypes,
                        searchParameter,
                        wrappedTargetResourceType,
                        reversed,
                        ParseImpl(
                            multipleChainType,
                            remainingKey,
                            value));
                }
                catch (Exception ex) when(ex is ResourceNotSupportedException || ex is SearchParameterNotSupportedException)
                {
                    // The resource or search parameter is not supported for the resource.
                    // We will ignore these unsupported types.
                    continue;
                }

                if (chainedExpression == null)
                {
                    chainedExpression = expression;
                }
                else if (reversed)
                {
                    chainedExpression = Expression.Chained(
                        resourceTypes,
                        searchParameter,
                        chainedExpression.TargetResourceTypes.Append(possibleTargetResourceType).ToArray(),
                        reversed,
                        ParseImpl(
                            multipleChainType,
                            remainingKey,
                            value));
                }
                else
                {
                    // If the target resource type is ambiguous, we throw an error.
                    // At the moment, this is not supported

                    throw new InvalidSearchOperationException(
                              string.Format(
                                  CultureInfo.CurrentCulture,
                                  Core.Resources.ChainedParameterSpecifyType,
                                  searchParameter.Name,
                                  string.Join(Core.Resources.OrDelimiter, searchParameter.TargetResourceTypes.Select(c => $"{searchParameter.Code}:{c}"))));
                }
            }

            if (chainedExpression == null)
            {
                // There was no reference that supports the search parameter.
                throw new InvalidSearchOperationException(Core.Resources.ChainedParameterNotSupported);
            }

            return(chainedExpression);
        }
Example #8
0
 /// <summary>
 /// Implemented in <see cref="FhirCosmosSearchService"/>
 /// </summary>
 public object VisitChained(ChainedExpression expression, Context context)
 {
     // Chained expressions require additional queries and are handled in the FhirCosmosSearchService.
     return(null);
 }
Example #9
0
 public object VisitChained(ChainedExpression expression, Context context)
 {
     // Chained expressions require additional queries and are handled in the FhirCosmosSearchService.
     throw new SearchOperationNotSupportedException(Resources.ChainedExpressionNotSupported);
 }
 public void Visit(ChainedExpression expression)
 {
     // TODO: This will be removed once it's implemented.
     throw new SearchOperationNotSupportedException("ChainedExpression is not supported.");
 }
 public NormalizedSearchParameterQueryGenerator VisitChained(ChainedExpression expression, object context)
 {
     return(ChainAnchorQueryGenerator.Instance);
 }
Example #12
0
        public ComponentDesigner(ComponentTemplateSD componentSD, FactionTechDB factionTech)
        {
            var staticData = StaticRefLib.StaticData;

            TypeName            = componentSD.Name;
            Name                = componentSD.Name;
            Description         = componentSD.Description;
            _design.ID          = Guid.NewGuid();
            MassFormula         = new ChainedExpression(componentSD.MassFormula, this, factionTech, staticData);
            VolumeFormula       = new ChainedExpression(componentSD.VolumeFormula, this, factionTech, staticData);
            CrewFormula         = new ChainedExpression(componentSD.CrewReqFormula, this, factionTech, staticData);
            HTKFormula          = new ChainedExpression(componentSD.HTKFormula, this, factionTech, staticData);
            ResearchCostFormula = new ChainedExpression(componentSD.ResearchCostFormula, this, factionTech, staticData);
            BuildCostFormula    = new ChainedExpression(componentSD.BuildPointCostFormula, this, factionTech, staticData);
            CreditCostFormula   = new ChainedExpression(componentSD.CreditCostFormula, this, factionTech, staticData);
            ComponentMountType  = componentSD.MountType;
            IndustryType        = componentSD.IndustryTypeID;
            CargoTypeID         = componentSD.CargoTypeID;
            _design.CargoTypeID = componentSD.CargoTypeID;
            if (componentSD.MountType.HasFlag(ComponentMountType.PlanetInstallation))
            {
                _design.GuiHints = ConstructableGuiHints.CanBeInstalled;
            }

            Dictionary <Guid, ChainedExpression> resourceCostForulas = new Dictionary <Guid, ChainedExpression>();

            //Dictionary<Guid, ChainedExpression> mineralCostFormulas = new Dictionary<Guid, ChainedExpression>();
            //Dictionary<Guid, ChainedExpression> materalCostFormulas = new Dictionary<Guid, ChainedExpression>();
            //Dictionary<Guid, ChainedExpression> componentCostForulas = new Dictionary<Guid, ChainedExpression>();
            foreach (var kvp in componentSD.ResourceCostFormula)
            {
                /*
                 * if (staticData.CargoGoods.IsMaterial(kvp.Key))
                 * {
                 *  materalCostFormulas.Add(kvp.Key, new ChainedExpression(kvp.Value, this, factionTech, staticData));
                 * }
                 * else if (staticData.ComponentTemplates.ContainsKey(kvp.Key))
                 * {
                 *  componentCostForulas.Add(kvp.Key, new ChainedExpression(kvp.Value, this, factionTech, staticData));
                 * }
                 * else if (staticData.CargoGoods.IsMineral(kvp.Key))
                 * {
                 *  mineralCostFormulas.Add(kvp.Key, new ChainedExpression(kvp.Value, this, factionTech, staticData));
                 * }
                 * else //TODO: log don't crash.
                 *  throw new Exception("GUID object {" + kvp.Key + "} not found in materialCosting for " + this.TypeName + " This object needs to be either a mineral, material or component defined in the Data folder");
                 *
                 */
                if (staticData.CargoGoods.GetAny(kvp.Key) != null)
                {
                    resourceCostForulas.Add(kvp.Key, new ChainedExpression(kvp.Value, this, factionTech));
                }
                else //TODO: log don't crash.
                {
                    throw new Exception("GUID object {" + kvp.Key + "} not found in resourceCosting for " + this.TypeName + " This object needs to be either a mineral, material or component defined in the Data folder");
                }
            }

            ResourceCostFormulas = resourceCostForulas;
            //MineralCostFormulas = mineralCostFormulas;
            // MaterialCostFormulas = materalCostFormulas;
            //ComponentCostFormulas = componentCostForulas;

            foreach (ComponentTemplateAbilitySD abilitySD in componentSD.ComponentAbilitySDs)
            {
                ComponentDesignAttribute designAttribute = new ComponentDesignAttribute(this);

                if (abilitySD.Name == null) //TODO: Log this, and don't use this component instead of throwing.
                {
                    throw new Exception("Bad Static Data. Ability name is null");
                }

                designAttribute.Name        = abilitySD.Name;
                designAttribute.Description = abilitySD.Description;
                designAttribute.GuiHint     = abilitySD.GuiHint;

                if (abilitySD.AbilityFormula != null)
                {
                    designAttribute.Formula = new ChainedExpression(abilitySD.AbilityFormula, designAttribute, factionTech, staticData);
                }

                if (abilitySD.GuidDictionary != null)
                {
                    designAttribute.GuidDictionary = new Dictionary <object, ChainedExpression>();
                    if (designAttribute.GuiHint == GuiHint.GuiTechSelectionList)
                    {
                        foreach (var kvp in abilitySD.GuidDictionary)
                        {
                            if (factionTech.ResearchedTechs.ContainsKey(Guid.Parse(kvp.Key.ToString())))
                            {
                                TechSD techSD = staticData.Techs[Guid.Parse(kvp.Key.ToString())];
                                designAttribute.GuidDictionary.Add(kvp.Key, new ChainedExpression(ResearchProcessor.DataFormula(factionTech, techSD).ToString(), designAttribute, factionTech, staticData));
                            }
                        }
                    }
                    else
                    {
                        foreach (var kvp in abilitySD.GuidDictionary)
                        {
                            designAttribute.GuidDictionary.Add(kvp.Key, new ChainedExpression(kvp.Value, designAttribute, factionTech, staticData));
                        }
                    }
                }
                if (designAttribute.GuiHint == GuiHint.GuiSelectionMaxMin)
                {
                    designAttribute.MaxValueFormula  = new ChainedExpression(abilitySD.MaxFormula, designAttribute, factionTech, staticData);
                    designAttribute.MinValueFormula  = new ChainedExpression(abilitySD.MinFormula, designAttribute, factionTech, staticData);
                    designAttribute.StepValueFormula = new ChainedExpression(abilitySD.StepFormula, designAttribute, factionTech, staticData);
                }
                if (abilitySD.AbilityDataBlobType != null)
                {
                    designAttribute.DataBlobType = Type.GetType(abilitySD.AbilityDataBlobType);
                }

                ComponentDesignAttributes.Add(designAttribute.Name, designAttribute);

                //TODO: get rid of this once json data is rewritten to use names instead of indexes
                ComponentDesignAttributeList.Add(designAttribute);
            }

            EvalAll();
        }
 public SearchParamTableExpressionQueryGenerator VisitChained(ChainedExpression expression, object context)
 {
     return(ChainLinkQueryGenerator.Instance);
 }
 /// <summary>
 /// Chained expression can be created either by search service or member-match service. In first case chain expression would contain only one nested expression
 /// because this is how '_has' works. `_has:Observation:patient:code=1234-5` as example. In that case we carry on, visit expression, and created proper table expression.
 /// For member-match service we can pass multiple restrain expression to chained expression which we put behind 'And' expression.
 /// 'And' visitor unfortunetelly can pick up only one queryGenerator, so it will pick first one in 'And' list and if expression inside 'And' are for different tables,
 /// that would lead to incorrect table expressions. So we handle that case separatly and create table generator for each expression in `And` expression.
 /// </summary>
 private void ProcessChainedExpression(ChainedExpression chainedExpression, List <SearchParamTableExpression> tableExpressions, int chainLevel)
 {
     if (chainedExpression.Expression is MultiaryExpression multiaryExpression && multiaryExpression.MultiaryOperation == MultiaryOperator.And)
     {
         HandleAndExpression(chainedExpression, tableExpressions, chainLevel, multiaryExpression);
     }
 public object VisitChained(ChainedExpression expression, Context context)
 {
     // TODO: This will be removed once it's implemented.
     throw new SearchOperationNotSupportedException(Resources.ChainedExpressionNotSupported);
 }