/// <summary> /// Inspects the input value to see if it contains any data that must be resolved /// at execution time (i.e. variable references) thus deferring a complete resolution of the data value to a later time. /// </summary> /// <param name="value">The value.</param> /// <returns><c>true</c> if execution should be deferred, <c>false</c> otherwise.</returns> private bool ShouldDeferResolution(QueryInputValue value) { switch (value) { case QueryVariableReferenceInputValue _: return(true); case QueryListInputValue liv: foreach (var child in liv.ListItems) { if (this.ShouldDeferResolution(child)) { return(true); } } break; case QueryComplexInputValue civ: foreach (var argument in civ.Arguments.Values) { if (this.ShouldDeferResolution(argument.Value)) { return(true); } } break; } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="DeferredInputArgumentValue"/> class. /// </summary> /// <param name="coreValue">The core value.</param> /// <param name="valueResolver">The resolver to use when rendering out a variable value for this /// argument.</param> public DeferredInputArgumentValue( QueryInputValue coreValue, IInputValueResolver valueResolver) { _coreValue = Validation.ThrowIfNullOrReturn(coreValue, nameof(coreValue)); _resolver = Validation.ThrowIfNullOrReturn(valueResolver, nameof(valueResolver)); }
/// <summary> /// Attempts to find the variable using the input value and the user supplied variable data collection. /// </summary> /// <param name="variableCollection">The variable collection.</param> /// <param name="inputValue">The input value representing a value to be resolved from a query document.</param> /// <param name="variable">The variable that was found in the collection.</param> /// <returns><c>true</c> if the varible was found, <c>false</c> otherwise.</returns> public bool TryGetVariable(IInputVariableCollection variableCollection, QueryInputValue inputValue, out IInputVariable variable) { variable = null; if (variableCollection == null || !(inputValue is QueryVariableReferenceInputValue varReference)) { return(false); } return(variableCollection.TryGetVariable(varReference.VariableName, out variable)); }
/// <summary> /// Assigns the value to this argument as its singular top level value. /// </summary> /// <param name="value">The value.</param> public void AssignValue(QueryInputValue value) { Validation.ThrowIfNull(value, nameof(value)); value.AssignParent(this); this.Value = value; }
/// <summary> /// Validates the context input data for correctness against the argument definition on the schema. /// </summary> /// <param name="value">The value.</param> /// <returns><c>true</c> if the data is valid for this rule, <c>false</c> otherwise.</returns> private bool EvaluateContextData(QueryInputValue value) { if (value == null) { return(false); } var queryArg = value.OwnerArgument; var valueTypeExpression = value.OwnerArgument.TypeExpression.Clone(); var valueSet = new List <QueryInputValue>(); valueSet.Add(value); // walk all type expression wrappers (IsList and IsNotNull) // and check the items in scope at the given level for their "correctness" // when a list is encountered expand its items so as to check the "next level" // such as when a type expression is a list of lists (e.g. [[Int]]) while (valueTypeExpression.Wrappers.Any()) { var nextValueSet = new List <QueryInputValue>(); foreach (var item in valueSet) { // ensure a variable reference is of the correct type expression // for this level // then elimnate it if (item is QueryVariableReferenceInputValue qvr) { var typeExpression = qvr.Variable.TypeExpression; if (!typeExpression.Equals(valueTypeExpression)) { return(false); } continue; } switch (valueTypeExpression.Wrappers[0]) { case MetaGraphTypes.IsNotNull: if (item is QueryNullInputValue) { return(false); } else { nextValueSet.Add(item); } break; case MetaGraphTypes.IsList: if (!(item is QueryListInputValue qliv)) { if (!this.EnsureSingleValueChain(item)) { return(false); } nextValueSet.Add(item); } else { foreach (var childItem in qliv.ListItems) { nextValueSet.Add(childItem); } } break; } } valueSet = nextValueSet; valueTypeExpression = valueTypeExpression.UnWrapExpression(); }