コード例 #1
0
        public void EntityTypeReferenceSetCorrectly()
        {
            SingleResourceFunctionCallNode singleEntityFunctionCall = new SingleResourceFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.StructuredTypeReference.FullName().Should().Be(HardCodedTestModel.GetPersonTypeReference().FullName());
            singleEntityFunctionCall.TypeReference.FullName().Should().Be(HardCodedTestModel.GetPersonTypeReference().FullName());
        }
コード例 #2
0
ファイル: QueryNodeComparer.cs プロジェクト: zhonli/odata.net
        /// <summary>
        /// Compares SingleEntityFunctionCall nodes.
        /// </summary>
        /// <param name="left">Left side of comparison</param>
        /// <param name="right">Right side of comparison</param>
        /// <returns>True if equal, otherwise false</returns>
        private bool Compare(SingleResourceFunctionCallNode left, SingleResourceFunctionCallNode right)
        {
            if (left.Parameters.Count() != right.Parameters.Count())
            {
                return(false);
            }
            if (left.NavigationSource != right.NavigationSource)
            {
                return(false);
            }
            if (left.StructuredTypeReference != right.StructuredTypeReference)
            {
                return(false);
            }
            if (left.Name != right.Name)
            {
                return(false);
            }
            if (left.TypeReference != right.TypeReference)
            {
                return(false);
            }

            for (int i = 0; i < left.Parameters.Count(); ++i)
            {
                if (!this.Compare(left.Parameters.ElementAt(i), right.Parameters.ElementAt(i)))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #3
0
        public void ArgumentsSetCorrectly()
        {
            SingleResourceFunctionCallNode singleEntityFunctionCall = new SingleResourceFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.Parameters.Should().HaveCount(1);
            singleEntityFunctionCall.Parameters.ElementAt(0).ShouldBeConstantQueryNode(1);
        }
コード例 #4
0
ファイル: FilterBinder.cs プロジェクト: weitzhandler/WebApi
        private Expression BindSingleResourceCastFunctionCall(SingleResourceFunctionCallNode node)
        {
            Contract.Assert(ClrCanonicalFunctions.CastFunctionName == node.Name);

            Expression[] arguments = BindArguments(node.Parameters);

            Contract.Assert(arguments.Length == 2);

            string   targetEdmTypeName = (string)((ConstantNode)node.Parameters.Last()).Value;
            IEdmType targetEdmType     = Model.FindType(targetEdmTypeName);
            Type     targetClrType     = null;

            if (targetEdmType != null)
            {
                targetClrType = EdmLibHelpers.GetClrType(targetEdmType.ToEdmTypeReference(false), Model);
            }

            if (arguments[0].Type == targetClrType)
            {
                // We only support to cast Entity type to the same type now.
                return(arguments[0]);
            }
            else if (arguments[0].Type.IsAssignableFrom(targetClrType))
            {
                // To support to cast Entity/Complex type to the sub type now.
                Expression source = BindCastSourceNode(node.Source);

                return(Expression.TypeAs(source, targetClrType));
            }
            else
            {
                // Cast fails and return null.
                return(NullConstant);
            }
        }
コード例 #5
0
        public void ParametersSetCorrectly()
        {
            SingleResourceFunctionCallNode singleEntityFunctionCall = new SingleResourceFunctionCallNode("stuff", null, null, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), null, null);

            singleEntityFunctionCall.Parameters.Should().NotBeNull();
            singleEntityFunctionCall.Parameters.Should().BeEmpty();
        }
コード例 #6
0
        /// <summary>
        /// We return the <see cref="ResourceRangeVariableReferenceNode"/> within a <see cref="QueryNode"/>
        /// </summary>
        /// <param name="node">The node to extract the ResourceRangeVariableReferenceNode.</param>
        /// <returns>The extracted ResourceRangeVariableReferenceNode.</returns>
        private ResourceRangeVariableReferenceNode GetResourceRangeVariableReferenceNode(QueryNode node)
        {
            if (node == null)
            {
                return(null);
            }

            switch (node.Kind)
            {
            case QueryNodeKind.SingleValuePropertyAccess:
                SingleValuePropertyAccessNode singleValuePropertyAccessNode = node as SingleValuePropertyAccessNode;
                return(GetResourceRangeVariableReferenceNode(singleValuePropertyAccessNode.Source));

            case QueryNodeKind.Convert:
                ConvertNode convertNode = node as ConvertNode;
                return(GetResourceRangeVariableReferenceNode(convertNode.Source));

            case QueryNodeKind.Any:
                AnyNode anyNode = node as AnyNode;
                return(GetResourceRangeVariableReferenceNode(anyNode.Source));

            case QueryNodeKind.SingleValueFunctionCall:
                SingleValueFunctionCallNode singleValueFunctionCallNode = node as SingleValueFunctionCallNode;
                return(GetResourceRangeVariableReferenceNode(singleValueFunctionCallNode.Parameters.First()));

            case QueryNodeKind.ResourceRangeVariableReference:
                return(node as ResourceRangeVariableReferenceNode);

            case QueryNodeKind.SingleValueOpenPropertyAccess:
                SingleValueOpenPropertyAccessNode singleValueOpenPropertyAccessNode = node as SingleValueOpenPropertyAccessNode;
                return(GetResourceRangeVariableReferenceNode(singleValueOpenPropertyAccessNode.Source));

            case QueryNodeKind.SingleComplexNode:
                SingleComplexNode singleComplexNode = node as SingleComplexNode;
                return(GetResourceRangeVariableReferenceNode(singleComplexNode.Source));

            case QueryNodeKind.CollectionComplexNode:
                CollectionComplexNode collectionComplexNode = node as CollectionComplexNode;
                return(GetResourceRangeVariableReferenceNode(collectionComplexNode.Source));

            case QueryNodeKind.CollectionNavigationNode:
                CollectionNavigationNode collectionNavigationNode = node as CollectionNavigationNode;
                return(GetResourceRangeVariableReferenceNode(collectionNavigationNode.Source));

            case QueryNodeKind.SingleNavigationNode:
                SingleNavigationNode singleNavigationNode = node as SingleNavigationNode;
                return(GetResourceRangeVariableReferenceNode(singleNavigationNode.Source));

            case QueryNodeKind.CollectionResourceFunctionCall:
                CollectionResourceFunctionCallNode collectionResourceFunctionCallNode = node as CollectionResourceFunctionCallNode;
                return(GetResourceRangeVariableReferenceNode(collectionResourceFunctionCallNode.Source));

            case QueryNodeKind.SingleResourceFunctionCall:
                SingleResourceFunctionCallNode singleResourceFunctionCallNode = node as SingleResourceFunctionCallNode;
                return(GetResourceRangeVariableReferenceNode(singleResourceFunctionCallNode.Source));
            }

            return(null);
        }
コード例 #7
0
        public void EntityTypeReferenceSetCorrectly()
        {
            string name = HardCodedTestModel.GetPersonTypeReference().FullName();
            SingleResourceFunctionCallNode singleEntityFunctionCall = new SingleResourceFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet());

            Assert.Equal(name, singleEntityFunctionCall.StructuredTypeReference.FullName());
            Assert.Equal(name, singleEntityFunctionCall.TypeReference.FullName());
        }
コード例 #8
0
        private void ValidateSingleResourceFunctionCallNode(SingleResourceFunctionCallNode node, ValidationSettings settings)
        {
            ValidateFunction(node.Name, settings);

            foreach (var argumentNode in node.Parameters)
            {
                ValidateQueryNode(argumentNode, settings);
            }
        }
コード例 #9
0
 /// <summary>
 /// Translate a SingleResourceFunctionCallNode.
 /// </summary>
 /// <param name="nodeIn">The node to be translated.</param>
 /// <returns>The translated node.</returns>
 public override QueryNode Visit(SingleResourceFunctionCallNode nodeIn)
 {
     return(new SingleResourceFunctionCallNode(
                nodeIn.Name,
                nodeIn.Functions,
                nodeIn.Parameters.Select(p => p.Accept(this)),
                nodeIn.StructuredTypeReference,
                nodeIn.NavigationSource,
                nodeIn.Source == null ? null : nodeIn.Source.Accept(this)));
 }
コード例 #10
0
        /// <summary>
        /// Translates a <see cref="SingleEntityFunctionCallNode"/> into a corresponding <see cref="string"/>.
        /// </summary>
        /// <param name="node">The node to translate.</param>
        /// <returns>The translated string.</returns>
        public override string Visit(SingleResourceFunctionCallNode node)
        {
            string result = node.Name;

            if (node.Source != null)
            {
                result = this.TranslatePropertyAccess(node.Source, result);
            }

            return(this.TranslateFunctionCall(result, node.Parameters));
        }
コード例 #11
0
ファイル: FilterBinder.cs プロジェクト: weitzhandler/WebApi
        /// <summary>
        /// Binds a <see cref="SingleResourceFunctionCallNode"/> to create a LINQ <see cref="Expression"/> that
        /// represents the semantics of the <see cref="SingleResourceFunctionCallNode"/>.
        /// </summary>
        /// <param name="node">The node to bind.</param>
        /// <returns>The LINQ <see cref="Expression"/> created.</returns>
        public virtual Expression BindSingleResourceFunctionCallNode(SingleResourceFunctionCallNode node)
        {
            switch (node.Name)
            {
            case ClrCanonicalFunctions.CastFunctionName:
                return(BindSingleResourceCastFunctionCall(node));

            default:
                throw Error.NotSupported(SRResources.ODataFunctionNotSupported, node.Name);
            }
        }
コード例 #12
0
        /// <summary>
        /// Override this method to validate single resource function calls, such as 'cast'.
        /// </summary>
        /// <param name="node">The node to validate.</param>
        /// <param name="settings">The settings to use while validating.</param>
        /// <remarks>
        /// This method is intended to be called from method overrides in subclasses. This method also supports unit
        /// testing scenarios and is not intended to be called from user code. Call the Validate method to validate a
        /// <see cref="FilterQueryOption" /> instance.
        /// </remarks>
        protected virtual void ValidateSingleResourceFunctionCallNode(SingleResourceFunctionCallNode node, ODataValidationSettings settings)
        {
            Contract.Assert(node != null);
            Contract.Assert(settings != null);

            ValidateFunction(node.Name, settings);
            foreach (QueryNode argumentNode in node.Parameters)
            {
                ValidateQueryNode(argumentNode, settings);
            }
        }
コード例 #13
0
        public override QueryNode Visit(SingleResourceFunctionCallNode nodeIn)
        {
            QueryNode?source = nodeIn.Source == null ? null : Visit(nodeIn.Source);
            IEnumerable <QueryNode>?parameters = VisitParameters(nodeIn.Parameters);

            if (nodeIn.Source != source || nodeIn.Parameters != parameters)
            {
                nodeIn = new SingleResourceFunctionCallNode(nodeIn.Name, nodeIn.Functions, parameters, nodeIn.StructuredTypeReference, nodeIn.NavigationSource, source);
            }
            return(nodeIn);
        }
コード例 #14
0
        /// <summary>
        /// Translates a <see cref="SingleResourceFunctionCallNode"/> into a corresponding <see cref="String"/>.
        /// </summary>
        /// <param name="node">The node to translate.</param>
        /// <returns>The translated String.</returns>
        public override String Visit(SingleResourceFunctionCallNode node)
        {
            ExceptionUtils.CheckArgumentNotNull(node, "node");
            String result = node.Name;
            if (node.Source != null)
            {
                result = this.TranslatePropertyAccess(node.Source, result);
            }

            return this.TranslateFunctionCall(result, node.Parameters);
        }
コード例 #15
0
 /// <summary>
 /// Visit a SingleResourceFunctionCallNode
 /// </summary>
 /// <param name="nodeIn">the node to visit</param>
 /// <returns>true, indicating that the node has been visited.</returns>
 public override bool Visit(SingleResourceFunctionCallNode nodeIn)
 {
     validate(nodeIn);
     validate(nodeIn.TypeReference.Definition);
     foreach (IEdmFunction function in nodeIn.Functions)
     {
         validate(function);
     }
     foreach (QueryNode param in nodeIn.Parameters)
     {
         ValidateNode(param);
     }
     return(true);
 }
コード例 #16
0
        /// <summary>
        /// Writes single entity function call node to string.
        /// </summary>
        /// <param name="node">Node to write to string</param>
        /// <returns>String representation of node.</returns>
        private static string ToString(SingleResourceFunctionCallNode node)
        {
            if (node != null)
            {
                return(tabHelper.Prefix + "SingleResourceFunctionCallNode" +
                       tabHelper.Indent(() =>
                                        tabHelper.Prefix + "NavigationSource = " + node.NavigationSource.Name +
                                        tabHelper.Prefix + "Type Reference = " + node.TypeReference +
                                        tabHelper.Prefix + "Name = " + node.Name +
                                        tabHelper.Prefix + "Function = " + ToString(node.Functions) +
                                        ArgumentsToString(node.Parameters)
                                        ));
            }

            return(String.Empty);
        }
コード例 #17
0
        private Expression BindSingleResourceCastFunctionCall(SingleResourceFunctionCallNode node)
        {
            Contract.Assert(ClrCanonicalFunctions.CastFunctionName == node.Name);

            Expression[] arguments = BindArguments(node.Parameters);

            Contract.Assert(arguments.Length == 2);

            string   targetEdmTypeName = (string)((ConstantNode)node.Parameters.Last()).Value;
            IEdmType targetEdmType     = Model.FindType(targetEdmTypeName);
            Type     targetClrType     = null;

            if (targetEdmType != null)
            {
                targetClrType = Model.GetClrType(targetEdmType.ToEdmTypeReference(false));
            }

            if (arguments[0].Type == targetClrType)
            {
                // We only support to cast Entity type to the same type now.
                return(arguments[0]);
            }
            else if (arguments[0].Type.IsAssignableFrom(targetClrType))
            {
                // To support to cast Entity/Complex type to the sub type now.
                Expression source;
                if (node.Source != null)
                {
                    source = BindCastSourceNode(node.Source);
                }
                else
                {
                    // if the cast is on the root i.e $it (~/Products?$filter=NS.PopularProducts/.....),
                    // node.Source would be null. Calling BindCastSourceNode will always return '$it'.
                    // In scenarios where we are casting a navigation property to return an expression that queries against the parent property,
                    // we need to have a memberAccess expression e.g '$it.Category'. We can get this from arguments[0].
                    source = arguments[0];
                }

                return(Expression.TypeAs(source, targetClrType));
            }
            else
            {
                // Cast fails and return null.
                return(NullConstant);
            }
        }
コード例 #18
0
        /// <summary>
        /// Override this method to validate single resource function calls, such as 'cast'.
        /// </summary>
        /// <param name="node">The node to validate.</param>
        /// <param name="settings">The settings to use while validating.</param>
        /// <remarks>
        /// This method is intended to be called from method overrides in subclasses. This method also supports unit
        /// testing scenarios and is not intended to be called from user code. Call the Validate method to validate a
        /// <see cref="FilterQueryOption" /> instance.
        /// </remarks>
        public virtual void ValidateSingleResourceFunctionCallNode(SingleResourceFunctionCallNode node, ODataValidationSettings settings)
        {
            if (node == null)
            {
                throw Error.ArgumentNull(nameof(node));
            }

            if (settings == null)
            {
                throw Error.ArgumentNull(nameof(settings));
            }

            ValidateFunction(node.Name, settings);
            foreach (QueryNode argumentNode in node.Parameters)
            {
                ValidateQueryNode(argumentNode, settings);
            }
        }
コード例 #19
0
        public void NameIsSetCorrectly()
        {
            SingleResourceFunctionCallNode singleEntityFunctionCall = new SingleResourceFunctionCallNode("stuff", new QueryNode[] { }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.ShouldBeSingleResourceFunctionCallNode("stuff");
        }
コード例 #20
0
 /// <summary>
 /// Visit a SingleResourceFunctionCallNode
 /// </summary>
 /// <param name="nodeIn">The node to visit</param>
 /// <returns>The translated expression</returns>
 public override Expression Visit(SingleResourceFunctionCallNode nodeIn)
 {
     throw new NotImplementedException();
 }
コード例 #21
0
 public override T Visit(SingleResourceFunctionCallNode nodeIn) => DebuggerBreakVisited(nodeIn);
コード例 #22
0
        public void KindIsSingleEntityFunction()
        {
            SingleResourceFunctionCallNode singleEntityFunctionCall = new SingleResourceFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.Kind.Should().Be(QueryNodeKind.SingleResourceFunctionCall);
        }
コード例 #23
0
        public void FunctionImportsAreSetCorrectly()
        {
            SingleResourceFunctionCallNode singleEntityFunctionCall = new SingleResourceFunctionCallNode("HasDog", HardCodedTestModel.GetHasDogOverloads(), null, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), ModelBuildingHelpers.BuildValidEntitySet(), null);

            singleEntityFunctionCall.Functions.Should().ContainExactly(HardCodedTestModel.GetHasDogOverloads());
        }