Ejemplo n.º 1
0
        public void ArgumentsSetCorrectly()
        {
            SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.Parameters.Should().HaveCount(1);
            singleEntityFunctionCall.Parameters.ElementAt(0).ShouldBeConstantQueryNode(1);
        }
Ejemplo n.º 2
0
        /// <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(SingleEntityFunctionCallNode left, SingleEntityFunctionCallNode right)
        {
            if (left.Parameters.Count() != right.Parameters.Count())
            {
                return(false);
            }
            if (left.NavigationSource != right.NavigationSource)
            {
                return(false);
            }
            if (left.EntityTypeReference != right.EntityTypeReference)
            {
                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);
        }
Ejemplo n.º 3
0
        public void ParametersSetCorrectly()
        {
            SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", null, null, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), null, null);

            singleEntityFunctionCall.Parameters.Should().NotBeNull();
            singleEntityFunctionCall.Parameters.Should().BeEmpty();
        }
Ejemplo n.º 4
0
        public void EntityTypeReferenceSetCorrectly()
        {
            SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.EntityTypeReference.FullName().Should().Be(HardCodedTestModel.GetPersonTypeReference().FullName());
            singleEntityFunctionCall.TypeReference.FullName().Should().Be(HardCodedTestModel.GetPersonTypeReference().FullName());
        }
 /// <summary>
 /// Translate a SingleEntityFunctionCallNode.
 /// </summary>
 /// <param name="nodeIn">The node to be translated.</param>
 /// <returns>The translated node.</returns>
 public override QueryNode Visit(SingleEntityFunctionCallNode nodeIn)
 {
     return(new SingleEntityFunctionCallNode(
                nodeIn.Name,
                nodeIn.Functions,
                nodeIn.Parameters.Select(p => p.Accept(this)),
                nodeIn.EntityTypeReference,
                nodeIn.NavigationSource,
                nodeIn.Source == null ? null : nodeIn.Source.Accept(this)));
 }
 /// <summary>
 /// Translate a SingleEntityFunctionCallNode.
 /// </summary>
 /// <param name="nodeIn">The node to be translated.</param>
 /// <returns>The translated node.</returns>
 public override QueryNode Visit(SingleEntityFunctionCallNode nodeIn)
 {
     return(new SingleEntityFunctionCallNode(
                nodeIn.Name,
                nodeIn.Functions,
                // TODO 1941: Parameters property of SingleEntityFunctionCallNode should never be null.
                nodeIn.Parameters == null ? null : nodeIn.Parameters.Select(p => p.Accept(this)),
                nodeIn.EntityTypeReference,
                nodeIn.NavigationSource,
                nodeIn.Source == null ? null : nodeIn.Source.Accept(this)));
 }
        /// <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(SingleEntityFunctionCallNode node)
        {
            string result = node.Name;

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

            return(this.TranslateFunctionCall(result, node.Parameters));
        }
Ejemplo n.º 8
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(SingleEntityFunctionCallNode 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));
        }
Ejemplo n.º 9
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(SingleEntityFunctionCallNode node)
        {
            if (node != null)
            {
                return(tabHelper.Prefix + "SingleEntityFunctionCallNode" +
                       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);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Override this method to validate single entity 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 ValidateSingleEntityFunctionCallNode(SingleEntityFunctionCallNode node, ODataValidationSettings settings)
        {
            if (node == null)
            {
                throw Error.ArgumentNull("node");
            }

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

            ValidateFunction(node.Name, settings);
            foreach (QueryNode argumentNode in node.Parameters)
            {
                ValidateQueryNode(argumentNode, settings);
            }
        }
Ejemplo n.º 11
0
        /// <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(SingleEntityFunctionCallNode left, SingleEntityFunctionCallNode right)
        {
            if (left.Parameters.Count() != right.Parameters.Count()) return false;
            if (left.NavigationSource != right.NavigationSource) return false;
            if (left.EntityTypeReference != right.EntityTypeReference) 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;            
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Override this method to validate single entity 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 ValidateSingleEntityFunctionCallNode(SingleEntityFunctionCallNode node, ODataValidationSettings settings)
        {
            if (node == null)
            {
                throw Error.ArgumentNull("node");
            }

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

            ValidateFunction(node.Name, settings);
            foreach (QueryNode argumentNode in node.Parameters)
            {
                ValidateQueryNode(argumentNode, settings);
            }
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Visit a SingleEntityFunctionCallNode
 /// </summary>
 /// <param name="nodeIn">the node to visit</param>
 /// <returns>Defined by the implementer</returns>
 public virtual T Visit(SingleEntityFunctionCallNode nodeIn)
 {
     DebugUtils.CheckNoExternalCallers();
     throw new NotImplementedException();
 }
 /// <summary>
 /// Visit a SingleEntityFunctionCallNode
 /// </summary>
 /// <param name="nodeIn">the node to visit</param>
 /// <returns>Defined by the implementer</returns>
 public virtual T Visit(SingleEntityFunctionCallNode nodeIn)
 {
     throw new NotImplementedException();
 }
 public void ParametersSetCorrectly()
 {
     SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", null, null, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), null, null);
     singleEntityFunctionCall.Parameters.Should().NotBeNull();
     singleEntityFunctionCall.Parameters.Should().BeEmpty();
 }
Ejemplo n.º 16
0
        public void FunctionImportsAreSetCorrectly()
        {
            SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("HasDog", HardCodedTestModel.GetHasDogOverloads(), null, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), ModelBuildingHelpers.BuildValidEntitySet(), null);

            singleEntityFunctionCall.Functions.Should().ContainExactly(HardCodedTestModel.GetHasDogOverloads());
        }
Ejemplo n.º 17
0
 public override IEnumerable <string> Visit(SingleEntityFunctionCallNode nodeIn)
 {
     return(nodeIn.Source.Accept(this));
 }
 public void EntityTypeReferenceSetCorrectly()
 {
     SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet());
     singleEntityFunctionCall.EntityTypeReference.FullName().Should().Be(HardCodedTestModel.GetPersonTypeReference().FullName());
     singleEntityFunctionCall.TypeReference.FullName().Should().Be(HardCodedTestModel.GetPersonTypeReference().FullName());
 }
 public void ArgumentsSetCorrectly()
 {
     SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());
     singleEntityFunctionCall.Parameters.Should().HaveCount(1);
     singleEntityFunctionCall.Parameters.ElementAt(0).ShouldBeConstantQueryNode(1);
 }
Ejemplo n.º 20
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(SingleEntityFunctionCallNode node)
        {
            if (node != null)
            {
                return tabHelper.Prefix + "SingleEntityFunctionCallNode" +
                            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;

        }
Ejemplo n.º 21
0
        private bool TryBindIdentifier(string identifier, IEnumerable <FunctionParameterToken> arguments, QueryNode parent, BindingState state, out QueryNode boundFunction)
        {
            boundFunction = null;

            IEdmType bindingType       = null;
            var      singleValueParent = parent as SingleValueNode;

            if (singleValueParent != null)
            {
                if (singleValueParent.TypeReference != null)
                {
                    bindingType = singleValueParent.TypeReference.Definition;
                }
            }
            else
            {
                var collectionValueParent = parent as CollectionNode;
                if (collectionValueParent != null)
                {
                    bindingType = collectionValueParent.CollectionType.Definition;
                }
            }

            if (!UriEdmHelpers.IsBindingTypeValid(bindingType))
            {
                return(false);
            }

            // All functions should be fully qualified, if they aren't they they aren't functions.
            // When using extension, there may be function call with unqualified name. So loose the restriction here.
            if (identifier.IndexOf(".", StringComparison.Ordinal) == -1 && this.Resolver.GetType() == typeof(ODataUriResolver))
            {
                return(false);
            }

            IEdmOperation operation;
            List <FunctionParameterToken> syntacticArguments = arguments == null ? new List <FunctionParameterToken>() : arguments.ToList();

            if (!FunctionOverloadResolver.ResolveOperationFromList(identifier, syntacticArguments.Select(ar => ar.ParameterName).ToList(), bindingType, state.Model, out operation, this.Resolver))
            {
                // TODO: FunctionOverloadResolver.ResolveOperationFromList() looks up the function by parameter names, but it shouldn't ignore parameter types. (test case ParseFilter_AliasInFunction_PropertyAsValue_TypeMismatch should fail)
                return(false);
            }

            if (singleValueParent != null && singleValueParent.TypeReference == null)
            {
                // if the parent exists, but has no type information, then we're in open type land, and we
                // shouldn't go any farther.
                throw new ODataException(ODataErrorStrings.FunctionCallBinder_CallingFunctionOnOpenProperty(identifier));
            }

            if (operation.IsAction())
            {
                return(false);
            }

            IEdmFunction function = (IEdmFunction)operation;

            // TODO:  $filter $orderby parameter expression which contains complex or collection should NOT be supported in this way
            //     but should be parsed into token tree, and binded to node tree: parsedParameters.Select(p => this.bindMethod(p));
            ICollection <FunctionParameterToken> parsedParameters = HandleComplexOrCollectionParameterValueIfExists(state.Configuration.Model, function, syntacticArguments, state.Configuration.Resolver.EnableCaseInsensitive);

            IEnumerable <QueryNode> boundArguments = parsedParameters.Select(p => this.bindMethod(p));

            boundArguments = boundArguments.ToList(); // force enumerable to run : will immediately evaluate all this.bindMethod(p).
            IEdmTypeReference returnType = function.ReturnType;
            IEdmEntitySetBase returnSet  = null;
            var singleEntityNode         = parent as SingleEntityNode;

            if (singleEntityNode != null)
            {
                returnSet = function.GetTargetEntitySet(singleEntityNode.NavigationSource, state.Model);
            }

            string functionName = function.FullName();

            if (returnType.IsEntity())
            {
                boundFunction = new SingleEntityFunctionCallNode(functionName, new[] { function }, boundArguments, (IEdmEntityTypeReference)returnType.Definition.ToTypeReference(), returnSet, parent);
            }
            else if (returnType.IsEntityCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new EntityCollectionFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, returnSet, parent);
            }
            else if (returnType.IsCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new CollectionFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, parent);
            }
            else
            {
                boundFunction = new SingleValueFunctionCallNode(functionName, new[] { function }, boundArguments, returnType, parent);
            }

            return(true);
        }
Ejemplo n.º 22
0
        private bool TryBindIdentifier(string identifier, IEnumerable<FunctionParameterToken> arguments, QueryNode parent, BindingState state, out QueryNode boundFunction)
        {
            boundFunction = null;

            IEdmType bindingType = null;
            var singleValueParent = parent as SingleValueNode;
            if (singleValueParent != null)
            {
                if (singleValueParent.TypeReference != null)
                {
                    bindingType = singleValueParent.TypeReference.Definition;
                }
            }
            else
            {
                var collectionValueParent = parent as CollectionNode;
                if (collectionValueParent != null)
                {
                    bindingType = collectionValueParent.CollectionType.Definition;
                }
            }

            if (!UriEdmHelpers.IsBindingTypeValid(bindingType))
            {
                return false;
            }

            // All functions should be fully qualified, if they aren't they they aren't functions.
            // When using extension, there may be function call with unqualified name. So loose the restriction here.
            if (identifier.IndexOf(".", StringComparison.Ordinal) == -1 && this.Resolver.GetType() == typeof(ODataUriResolver))
            {
                return false;
            }

            IEdmOperation operation;
            List<FunctionParameterToken> syntacticArguments = arguments == null ? new List<FunctionParameterToken>() : arguments.ToList();
            if (!FunctionOverloadResolver.ResolveOperationFromList(identifier, syntacticArguments.Select(ar => ar.ParameterName).ToList(), bindingType, state.Model, out operation, this.Resolver))
            {
                // TODO: FunctionOverloadResolver.ResolveOperationFromList() looks up the function by parameter names, but it shouldn't ignore parameter types. (test case ParseFilter_AliasInFunction_PropertyAsValue_TypeMismatch should fail)
                return false;
            }

            if (singleValueParent != null && singleValueParent.TypeReference == null)
            {
                // if the parent exists, but has no type information, then we're in open type land, and we 
                // shouldn't go any farther.
                throw new ODataException(ODataErrorStrings.FunctionCallBinder_CallingFunctionOnOpenProperty(identifier));
            }

            if (operation.IsAction())
            {
                return false;
            }

            IEdmFunction function = (IEdmFunction)operation;

            // TODO:  $filter $orderby parameter expression which contains complex or collection should NOT be supported in this way
            //     but should be parsed into token tree, and binded to node tree: parsedParameters.Select(p => this.bindMethod(p));
            ICollection<FunctionParameterToken> parsedParameters = HandleComplexOrCollectionParameterValueIfExists(state.Configuration.Model, function, syntacticArguments, state.Configuration.Resolver.EnableCaseInsensitive);

            IEnumerable<QueryNode> boundArguments = parsedParameters.Select(p => this.bindMethod(p));
            boundArguments = boundArguments.ToList(); // force enumerable to run : will immediately evaluate all this.bindMethod(p).
            IEdmTypeReference returnType = function.ReturnType;
            IEdmEntitySetBase returnSet = null;
            var singleEntityNode = parent as SingleEntityNode;
            if (singleEntityNode != null)
            {
                returnSet = function.GetTargetEntitySet(singleEntityNode.NavigationSource, state.Model);
            }

            string functionName = function.FullName();

            if (returnType.IsEntity())
            {
                boundFunction = new SingleEntityFunctionCallNode(functionName, new[] { function }, boundArguments, (IEdmEntityTypeReference)returnType.Definition.ToTypeReference(), returnSet, parent);
            }
            else if (returnType.IsEntityCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new EntityCollectionFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, returnSet, parent);
            }
            else if (returnType.IsCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new CollectionFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, parent);
            }
            else
            {
                boundFunction = new SingleValueFunctionCallNode(functionName, new[] { function }, boundArguments, returnType, parent);
            }

            return true;
        }
Ejemplo n.º 23
0
        public void NameIsSetCorrectly()
        {
            SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.ShouldBeSingleEntityFunctionCallNode("stuff");
        }
 public void KindIsSingleEntityFunction()
 {
     SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());
     singleEntityFunctionCall.Kind.Should().Be(QueryNodeKind.SingleEntityFunctionCall);
 }
Ejemplo n.º 25
0
 /// <summary>
 /// Visit a SingleEntityFunctionCallNode
 /// </summary>
 /// <param name="nodeIn">The node to visit</param>
 /// <returns>The translated expression</returns>
 public override Expression Visit(SingleEntityFunctionCallNode nodeIn)
 {
     throw new NotImplementedException();
 }
 public void FunctionImportsAreSetCorrectly()
 {
     SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("HasDog", HardCodedTestModel.GetHasDogOverloads(), null, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), ModelBuildingHelpers.BuildValidEntitySet(), null);
     singleEntityFunctionCall.Functions.Should().ContainExactly(HardCodedTestModel.GetHasDogOverloads());
 }
 public void NameIsSetCorrectly()
 {
     SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());
     singleEntityFunctionCall.ShouldBeSingleEntityFunctionCallNode("stuff");
 }
Ejemplo n.º 28
0
        public void KindIsSingleEntityFunction()
        {
            SingleEntityFunctionCallNode singleEntityFunctionCall = new SingleEntityFunctionCallNode("stuff", new QueryNode[] { new ConstantNode(1) }, ModelBuildingHelpers.BuildValidEntityType().ToTypeReference().AsEntity(), HardCodedTestModel.GetPeopleSet());

            singleEntityFunctionCall.Kind.Should().Be(QueryNodeKind.SingleEntityFunctionCall);
        }