Пример #1
0
        private static string BindPropertyAccessQueryNode(SingleValuePropertyAccessNode singleValuePropertyAccessNode)
        {
            if (singleValuePropertyAccessNode.Source.TypeReference.Definition.TypeKind == EdmTypeKind.Complex)
            {
                var type = singleValuePropertyAccessNode.Source.TypeReference.Definition as EdmComplexType;

                if (type == null)
                {
                    return(singleValuePropertyAccessNode.Property.Name);
                }

                switch (type.Name)
                {
                case "OptionSet":
                case "EntityReference":
                    if (singleValuePropertyAccessNode.Property.Name == "Name")
                    {
                        throw new ODataException(string.Format("Equality comparison on Complex type {0} property {1} isn't supported.", type.Name, singleValuePropertyAccessNode.Property.Name));
                    }
                    var sourceSingleValuePropertyAccessNode = singleValuePropertyAccessNode.Source as SingleValuePropertyAccessNode;
                    if (sourceSingleValuePropertyAccessNode != null)
                    {
                        return(sourceSingleValuePropertyAccessNode.Property.Name);
                    }
                    break;
                }
            }

            return(singleValuePropertyAccessNode.Property.Name);
        }
Пример #2
0
        private static Expression BindPropertyAccessQueryNode(SingleValuePropertyAccessNode propertyAccessNode, IList <ODataQueryNode> queryNodes)
        {
            //Expression source = Bind(propertyAccessNode.Source, queryNodes);
            string propertyName = propertyAccessNode.Property.Name;

            return(Expression.Constant(propertyName, typeof(string)));
        }
Пример #3
0
        /// <summary>Validates the single value property access node.</summary>
        /// <param name="propertyAccessNode">The property access node.</param>
        /// <param name="settings">Options for controlling the operation.</param>
        public override void ValidateSingleValuePropertyAccessNode(
            SingleValuePropertyAccessNode propertyAccessNode,
            ODataValidationSettings settings)
        {
            if (this.IsValid || this.MinimumFilterProperties == null || !this.MinimumFilterProperties.Any())
            {
                this.IsValid = true;
            }
            else
            {
                string propertyName = null;

                if (propertyAccessNode != null)
                {
                    propertyName = propertyAccessNode.Property.Name;
                }

                if (!string.IsNullOrWhiteSpace(propertyName) && this.MinimumFilterProperties.Contains(propertyName))
                {
                    this.IsValid = true;
                }
            }

            base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
        }
        /// <summary>
        /// Extracts the filter definition once a leaf is found.
        /// </summary>
        /// <param name="info">QueryInformation being filled.</param>
        /// <param name="binaryNode">BinaryOperatorNode the leaf belongs to.</param>
        /// <param name="constantNode">ConstantNode with the parameter definition.</param>
        private void ProcessLeafNode(QueryInformation info, BinaryOperatorNode binaryNode, ConstantNode constantNode)
        {
            try
            {
                // Necesary variables
                SingleValuePropertyAccessNode propertyAccessNode = binaryNode.Left as SingleValuePropertyAccessNode;
                SingleValueFunctionCallNode   functioncall       = binaryNode.Left as SingleValueFunctionCallNode;

                // The filter definition that is going to be added.
                FilterParameterDefinition filterdefinition = new FilterParameterDefinition();

                // Populating common values.
                filterdefinition.FilteringOperator = (FilteringOperator)binaryNode.OperatorKind;
                filterdefinition.StringValue       = constantNode.Value.ToString();


                if (functioncall != null)
                {
                    // it contains a function call
                    propertyAccessNode = ParseFunctionCall(propertyAccessNode, functioncall, filterdefinition);
                }

                if (propertyAccessNode != null)
                {
                    //it is a simple equals
                    ParsePropertyAccessNode(info, propertyAccessNode, filterdefinition);
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }
        public void SourceIsSet()
        {
            var source = new ConstantNode(null);
            var node   = new SingleValuePropertyAccessNode(source, HardCodedTestModel.GetDogColorProp());

            node.Source.Should().BeSameAs(source);
        }
Пример #6
0
 /// <summary>
 /// Visit a SingleValuePropertyAccessNode
 /// </summary>
 /// <param name="nodeIn">the node to visit</param>
 /// <returns>true, indicating that the node has been visited.</returns>
 public override bool Visit(SingleValuePropertyAccessNode nodeIn)
 {
     validate(nodeIn);
     validate(nodeIn.Property);
     validate(nodeIn.TypeReference.Definition);
     return(true);
 }
        public override SingleValueNode Visit(SingleValuePropertyAccessNode nodeIn)
        {
            if (nodeIn.Source != null)
            {
                if (nodeIn.Source.Kind == QueryNodeKind.SingleNavigationNode)
                {
                    SingleNavigationNode singleNavigationNode = nodeIn.Source as SingleNavigationNode;
                    if (EdmLibHelpers.IsNotSortable(nodeIn.Property, singleNavigationNode.NavigationProperty,
                                                    singleNavigationNode.NavigationProperty.ToEntityType(), _model, _enableOrderBy))
                    {
                        return(nodeIn);
                    }
                }
                else if (nodeIn.Source.Kind == QueryNodeKind.SingleComplexNode)
                {
                    SingleComplexNode singleComplexNode = nodeIn.Source as SingleComplexNode;
                    if (EdmLibHelpers.IsNotSortable(nodeIn.Property, singleComplexNode.Property,
                                                    nodeIn.Property.DeclaringType, _model, _enableOrderBy))
                    {
                        return(nodeIn);
                    }
                }
                else if (EdmLibHelpers.IsNotSortable(nodeIn.Property, _property, _structuredType, _model, _enableOrderBy))
                {
                    return(nodeIn);
                }
            }

            if (nodeIn.Source != null)
            {
                return(nodeIn.Source.Accept(this));
            }

            return(null);
        }
Пример #8
0
        /// <summary>
        /// Creates a list of <see cref="OrderByPropertyNode"/> instances from a linked list of <see cref="OrderByClause"/> instances.
        /// </summary>
        /// <param name="orderByClause">The head of the <see cref="OrderByClause"/> linked list.</param>
        /// <returns>The list of new <see cref="OrderByPropertyNode"/> instances.</returns>
        public static IList <OrderByNode> CreateCollection(OrderByClause orderByClause)
        {
            List <OrderByNode> result = new List <OrderByNode>();

            for (OrderByClause clause = orderByClause; clause != null; clause = clause.ThenBy)
            {
                if (clause.Expression is NonentityRangeVariableReferenceNode || clause.Expression is EntityRangeVariableReferenceNode)
                {
                    result.Add(new OrderByItNode(clause.Direction));
                }
                else
                {
                    SingleValuePropertyAccessNode property = clause.Expression as SingleValuePropertyAccessNode;

                    if (property == null || !(property.Source is EntityRangeVariableReferenceNode))
                    {
                        throw new ODataException(SRResources.OrderByClauseNotSupported);
                    }

                    result.Add(new OrderByPropertyNode(property.Property, clause.Direction));
                }
            }

            return(result);
        }
 public void OrderByOptionSetCorrectly()
 {
     SingleValuePropertyAccessNode propertyAccessNode = new SingleValuePropertyAccessNode(new ConstantNode(1), HardCodedTestModel.GetPersonNameProp());
     OrderByClause orderBy = new OrderByClause(null, propertyAccessNode, OrderByDirection.Descending, new EntityRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet()));
     ExpandedNavigationSelectItem expansion = new ExpandedNavigationSelectItem(new ODataExpandPath(new NavigationPropertySegment(ModelBuildingHelpers.BuildValidNavigationProperty(), null)), HardCodedTestModel.GetPeopleSet(), null, null, orderBy, null, null, null, null, null);
     expansion.OrderByOption.Expression.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp());
 }
        public void SingleValuePropertyAccessNodesCanUseGeography()
        {
            ConstantNode constant = new ConstantNode(2);
            SingleValuePropertyAccessNode accessNode = new SingleValuePropertyAccessNode(constant, HardCodedTestModel.GetPersonGeographyPointProp());

            Assert.Same(HardCodedTestModel.GetPersonGeographyPointProp(), accessNode.Property);
        }
Пример #11
0
        public void EqualsOnComplexTypesWithDifferentNullabilityIsSupported()
        {
            var notNullableType = new EdmComplexTypeReference(HardCodedTestModel.GetAddressType(), false);
            var nullableType    = new EdmComplexTypeReference(HardCodedTestModel.GetAddressType(), true);

            IEdmTypeReference left      = notNullableType;
            IEdmTypeReference right     = nullableType;
            SingleValueNode   leftNode  = new SingleValuePropertyAccessNode(new ConstantNode(null) /*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", left));
            SingleValueNode   rightNode = new SingleValuePropertyAccessNode(new ConstantNode(null) /*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", right));
            var result = TypePromotionUtils.PromoteOperandTypes(BinaryOperatorKind.Equal, leftNode, rightNode, out left, out right);

            result.Should().BeTrue();
            left.ShouldBeEquivalentTo(nullableType);
            right.ShouldBeEquivalentTo(nullableType);

            // Reverse order
            left      = nullableType;
            right     = notNullableType;
            leftNode  = new SingleValuePropertyAccessNode(new ConstantNode(null) /*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", left));
            rightNode = new SingleValuePropertyAccessNode(new ConstantNode(null) /*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", right));
            result    = TypePromotionUtils.PromoteOperandTypes(BinaryOperatorKind.Equal, leftNode, rightNode, out left, out right);

            result.Should().BeTrue();
            left.ShouldBeEquivalentTo(nullableType);
            right.ShouldBeEquivalentTo(nullableType);
        }
        private Expression GetPropertyExpression(SingleValuePropertyAccessNode nodeIn)
        {
            Expression   e        = TranslateNode(nodeIn.Source);
            PropertyInfo property = e.Type.GetPropertyIgnoreCase(nodeIn.Property);

            return(Expression.Property(e, property));
        }
        public void SingleValuePropertyAccessNodesCanUseGeometry()
        {
            ConstantNode constant = new ConstantNode(2);
            SingleValuePropertyAccessNode accessNode = new SingleValuePropertyAccessNode(constant, HardCodedTestModel.GetPersonGeometryPointProp());

            accessNode.Property.Should().Be(HardCodedTestModel.GetPersonGeometryPointProp());
        }
Пример #14
0
        private BinaryOperatorNode BuildFilterExpression(SingleResourceNode source, GraphQLFieldSelection selection)
        {
            BinaryOperatorNode compositeNode = null;
            IEdmEntityType     entityType    = source.NavigationSource.EntityType();

            foreach (GraphQLArgument argument in selection.Arguments)
            {
                IEdmProperty edmProperty = FindEdmProperty(entityType, argument.Name.Value);
                var          left        = new SingleValuePropertyAccessNode(source, edmProperty);

                Object value = GetArgumentValue(edmProperty.Type, argument.Value);
                var    right = new ConstantNode(value, ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4));
                var    node  = new BinaryOperatorNode(BinaryOperatorKind.Equal, left, right);
                compositeNode = ComposeExpression(compositeNode, node);
            }

            //foreach (ASTNode astNode in selection.SelectionSet.Selections)
            //    if (astNode is GraphQLFieldSelection fieldSelection && fieldSelection.SelectionSet != null)
            //    {
            //        var navigationProperty = (IEdmNavigationProperty)FindEdmProperty(entityType, fieldSelection.Name.Value);
            //        if (navigationProperty.Type is IEdmCollectionTypeReference)
            //            continue;

            //        var parentSource = new SingleNavigationNode(source, navigationProperty, null);
            //        BinaryOperatorNode node = BuildFilterExpression(parentSource, fieldSelection);
            //        compositeNode = ComposeExpression(compositeNode, node);
            //    }

            return(compositeNode);
        }
Пример #15
0
        public static IEnumerable <FilterTestCase> PropertyAccessTestCases(IEdmModel model)
        {
            // Accessing a primitive property on the entity type
            ResourceRangeVariable         customersEntityRangeVariable = new ResourceRangeVariable("dummy", model.ResolveTypeReference("TestNS.Customer", false).AsEntity(), model.FindEntityContainer("BinderTestMetadata").FindEntitySet("Customers"));
            SingleValuePropertyAccessNode propertyAccessNode           = new SingleValuePropertyAccessNode(new ResourceRangeVariableReferenceNode(customersEntityRangeVariable.Name, customersEntityRangeVariable),
                                                                                                           model.ResolveProperty("TestNS.Customer.Name"));

            yield return(new FilterTestCase()
            {
                Filter = "Name eq 'Vitek'",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.Equal, propertyAccessNode, new ConstantNode("Vitek"))
            });

            // Accessing a complex on entity and primitive on complex
            SingleValuePropertyAccessNode propertyAccessNode2 = new SingleValuePropertyAccessNode(
                new SingleComplexNode(
                    new ResourceRangeVariableReferenceNode(customersEntityRangeVariable.Name, customersEntityRangeVariable),
                    model.ResolveProperty("TestNS.Customer.Address")
                    ),
                model.ResolveProperty("TestNS.Address.City")
                );

            yield return(new FilterTestCase()
            {
                Filter = "Address/City ne 'Prague'",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.NotEqual, propertyAccessNode2, new ConstantNode("Prague"))
            });
        }
Пример #16
0
        private static Expression GetThenByCall(this Expression expression, OrderByClause orderByClause)
        {
            const string ThenBy           = "ThenBy";
            const string ThenByDescending = "ThenByDescending";

            return(orderByClause.ThenBy == null
                ? GetMethodCall()
                : GetMethodCall().GetThenByCall(orderByClause.ThenBy));

            Expression GetMethodCall()
            {
                return(orderByClause.Expression switch
                {
                    CountNode countNode => expression.GetOrderByCountCall
                    (
                        countNode.GetPropertyPath(),
                        orderByClause.Direction == OrderByDirection.Ascending
                            ? ThenBy
                            : ThenByDescending
                    ),
                    SingleValuePropertyAccessNode propertyNode => expression.GetOrderByCall
                    (
                        propertyNode.GetPropertyPath(),
                        orderByClause.Direction == OrderByDirection.Ascending
                            ? ThenBy
                            : ThenByDescending
                    ),
                    _ => throw new ArgumentException($"Unsupported SingleValueNode value: {orderByClause.Expression.GetType()}"),
                });
            }
        private Expression GetPropertyExpression(SingleValuePropertyAccessNode nodeIn)
        {
            Expression   e        = TranslateNode(nodeIn.Source);
            PropertyInfo property = e.Type.GetProperty(nodeIn.Property.Name);

            if (property == null)
            {
                if (!OeExpressionHelper.IsTupleType(e.Type))
                {
                    throw new InvalidOperationException("must by Tuple " + e.Type.ToString());
                }

                IEdmNavigationSource navigationSource = ((ResourceRangeVariableReferenceNode)nodeIn.Source).NavigationSource;
                property = GetTuplePropertyByEntityType(e.Type, navigationSource.EntityType());
                if (property == null)
                {
                    if (TuplePropertyByEdmProperty == null)
                    {
                        throw new InvalidOperationException("entity type " + navigationSource.EntityType().FullName() + " not found in tuple properties");
                    }

                    return(TuplePropertyByEdmProperty(Parameter, nodeIn.Property));
                }
                else
                {
                    e        = Expression.Property(e, property);
                    property = e.Type.GetProperty(nodeIn.Property.Name);
                }
            }
            return(Expression.Property(e, property));
        }
Пример #18
0
        private static FilterClause CreateFilterClause(IEdmEntitySet entitySet, IEnumerable <KeyValuePair <String, Object> > keys)
        {
            var entityTypeRef = (IEdmEntityTypeReference)((IEdmCollectionType)entitySet.Type).ElementType;
            var range         = new ResourceRangeVariable("", entityTypeRef, entitySet);
            var refNode       = new ResourceRangeVariableReferenceNode("$it", range);

            BinaryOperatorNode compositeNode = null;
            var entityType = (IEdmEntityType)entityTypeRef.Definition;

            foreach (KeyValuePair <String, Object> keyValue in keys)
            {
                IEdmProperty property = entityType.FindProperty(keyValue.Key);
                var          left     = new SingleValuePropertyAccessNode(refNode, property);
                var          right    = new ConstantNode(keyValue.Value, ODataUriUtils.ConvertToUriLiteral(keyValue.Value, ODataVersion.V4));
                var          node     = new BinaryOperatorNode(BinaryOperatorKind.Equal, left, right);

                if (compositeNode == null)
                {
                    compositeNode = node;
                }
                else
                {
                    compositeNode = new BinaryOperatorNode(BinaryOperatorKind.And, compositeNode, node);
                }
            }
            return(new FilterClause(compositeNode, range));
        }
Пример #19
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);
        }
Пример #20
0
 public OrderProperty(SingleValuePropertyAccessNode propertyNode, OrderByDirection direction,
                      MemberExpression propertyExpression, ConstantExpression parameterExpression)
 {
     PropertyNode        = propertyNode;
     Direction           = direction;
     PropertyExpression  = propertyExpression;
     ParameterExpression = parameterExpression;
 }
Пример #21
0
        public void OrderByOptionSetCorrectly()
        {
            SingleValuePropertyAccessNode propertyAccessNode = new SingleValuePropertyAccessNode(new ConstantNode(1), HardCodedTestModel.GetPersonNameProp());
            OrderByClause orderBy = new OrderByClause(null, propertyAccessNode, OrderByDirection.Descending, new EntityRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet()));
            ExpandedNavigationSelectItem expansion = new ExpandedNavigationSelectItem(new ODataExpandPath(new NavigationPropertySegment(ModelBuildingHelpers.BuildValidNavigationProperty(), null)), HardCodedTestModel.GetPeopleSet(), null, orderBy, null, null, null, null, null, null);

            expansion.OrderByOption.Expression.ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp());
        }
Пример #22
0
        /// <summary>
        /// Translate a SingleValuePropertyAccessNode.
        /// </summary>
        /// <param name="nodeIn">The node to be translated.</param>
        /// <returns>The translated node.</returns>
        public override QueryNode Visit(SingleValuePropertyAccessNode nodeIn)
        {
            Contract.Assert(nodeIn != null);

            return(new SingleValuePropertyAccessNode(
                       (SingleValueNode)nodeIn.Source.Accept(this),
                       nodeIn.Property));
        }
Пример #23
0
 public override void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
 {
     if (propertyAccessNode.Property.Name == "ID")
     {
         visited = true;
     }
     base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
 }
Пример #24
0
 public override void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
 {
     if (restrictedProperties.Contains <string>(propertyAccessNode.Property.Name))
     {
         throw new ODataException(string.Format("{0} is an invalid filter property"));
     }
     base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
 }
 public override void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode,
                                                            ODataValidationSettings settings)
 {
     if (propertyAccessNode.Source.TypeReference.FullName().Contains("Product") && propertyAccessNode.Property.Name == "Name")
     {
         throw new ODataException("No se puede filtrar por nombre en Products");
     }
     base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
 }
Пример #26
0
        public void ODataUriBuilderWithKeyAsSegment()
        {
            Uri            fullUri        = new Uri("http://www.example.com/People/1?$filter=MyDog%2FColor%20eq%20%27Brown%27&$select=ID&$expand=MyDog&$top=1&$skip=2&$count=false");
            ODataUriParser oDataUriParser = new ODataUriParser(this.GetModel(), serviceRoot, fullUri);

            oDataUriParser.UrlConventions = ODataUrlConventions.KeyAsSegment;
            SetODataUriParserSettingsTo(this.settings, oDataUriParser.Settings);
            ODataUri odataUri = oDataUriParser.ParseUri();

            //verify path
            EntitySetSegment entitySet  = (EntitySetSegment)odataUri.Path.FirstSegment;
            KeySegment       keySegment = (KeySegment)odataUri.Path.LastSegment;
            IEnumerable <KeyValuePair <string, object> > keyValuePairs = keySegment.Keys;

            Assert.AreEqual(odataUri.Path.Count, 2);
            Assert.AreEqual(entitySet.EntitySet.Name, "People");
            foreach (var keyValuePair in keyValuePairs)
            {
                Assert.AreEqual(keyValuePair.Key, "ID");
                Assert.AreEqual(keyValuePair.Value, 1);
            }

            //verify $filter
            BinaryOperatorNode            binaryOperator      = (BinaryOperatorNode)odataUri.Filter.Expression;
            SingleValuePropertyAccessNode singleValueProperty = (SingleValuePropertyAccessNode)binaryOperator.Left;
            SingleNavigationNode          singleNavigation    = (SingleNavigationNode)singleValueProperty.Source;
            ConstantNode constantNode = (ConstantNode)binaryOperator.Right;

            Assert.AreEqual(binaryOperator.OperatorKind, BinaryOperatorKind.Equal);
            Assert.AreEqual(singleValueProperty.Property.Name, "Color");
            Assert.AreEqual(singleNavigation.NavigationProperty.Name, "MyDog");
            Assert.AreEqual(constantNode.LiteralText, "'Brown'");

            //verify $select and $expand
            IEnumerable <SelectItem> selectItems = odataUri.SelectAndExpand.SelectedItems;

            foreach (ExpandedNavigationSelectItem selectItem in selectItems)
            {
                NavigationPropertySegment navigationProperty = (NavigationPropertySegment)selectItem.PathToNavigationProperty.FirstSegment;
                Assert.AreEqual(navigationProperty.NavigationProperty.Name, "MyDog");
                break;
            }

            //verify $top
            Assert.AreEqual(odataUri.Top, 1);

            //verify $skip
            Assert.AreEqual(odataUri.Skip, 2);

            //verify $count
            Assert.AreEqual(odataUri.QueryCount, false);

            ODataUriBuilder uriBuilderWithKeyAsSegment = new ODataUriBuilder(ODataUrlConventions.KeyAsSegment, odataUri);
            Uri             actualUri = uriBuilderWithKeyAsSegment.BuildUri();

            Assert.AreEqual(new Uri("http://www.example.com/People/1?$filter=MyDog%2FColor%20eq%20%27Brown%27&$select=ID%2CMyDog&$expand=MyDog&$top=1&$skip=2&$count=false"), actualUri);
        }
Пример #27
0
 /// <summary>
 /// Writes single value property access node to string.
 /// </summary>
 /// <param name="node">Node to write to string</param>
 /// <returns>String representation of node.</returns>
 private static string ToString(SingleValuePropertyAccessNode node)
 {
     return(tabHelper.Prefix + "SingleValuePropertyAccessNode" +
            tabHelper.Indent(() =>
                             tabHelper.Prefix + "Property = " + node.Property.Name +
                             tabHelper.Prefix + "TypeReference = " + node.TypeReference +
                             tabHelper.Prefix + "Source = " + ToString(node.Source)
                             ));
 }
Пример #28
0
 public override TSource Visit(SingleValuePropertyAccessNode nodeIn)
 {
     current.FieldName = nodeIn.Property.Name;
     //We are finished, add current to collection.
     filterValueList.Add(current);
     //Reset current
     current = new FilterValue();
     return(null);
 }
     public override bool Visit(SingleValuePropertyAccessNode propertyNode)
     {
         if (propertyNode == null)
         {
             return false;
         }
 
         return propertyNode.TypeReference.IsBoolean();
 }
Пример #30
0
        private GroupByTransformationNode BindGroupByToken(GroupByToken token)
        {
            List <GroupByPropertyNode> properties = new List <GroupByPropertyNode>();

            foreach (EndPathToken propertyToken in token.Properties)
            {
                QueryNode bindResult = this.bindMethod(propertyToken);
                SingleValuePropertyAccessNode property        = bindResult as SingleValuePropertyAccessNode;
                SingleComplexNode             complexProperty = bindResult as SingleComplexNode;

                if (property != null)
                {
                    RegisterProperty(properties, ReversePropertyPath(property));
                }
                else if (complexProperty != null)
                {
                    RegisterProperty(properties, ReversePropertyPath(complexProperty));
                }
                else
                {
                    SingleValueOpenPropertyAccessNode openProperty = bindResult as SingleValueOpenPropertyAccessNode;
                    if (openProperty != null)
                    {
                        IEdmTypeReference type = GetTypeReferenceByPropertyName(openProperty.Name);
                        properties.Add(new GroupByPropertyNode(openProperty.Name, openProperty, type));
                    }
                    else
                    {
                        throw new ODataException(
                                  ODataErrorStrings.ApplyBinder_GroupByPropertyNotPropertyAccessValue(propertyToken.Identifier));
                    }
                }
            }

            var newProperties = new HashSet <EndPathToken>(((GroupByToken)token).Properties);

            TransformationNode aggregate = null;

            if (token.Child != null)
            {
                if (token.Child.Kind == QueryTokenKind.Aggregate)
                {
                    aggregate = BindAggregateToken((AggregateToken)token.Child);
                    aggregateExpressionsCache = ((AggregateTransformationNode)aggregate).AggregateExpressions;
                    newProperties.UnionWith(aggregateExpressionsCache.Select(statement => new EndPathToken(statement.Alias, null)));
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ApplyBinder_UnsupportedGroupByChild(token.Child.Kind));
                }
            }

            state.AggregatedPropertyNames = newProperties;

            // TODO: Determine source
            return(new GroupByTransformationNode(properties, aggregate, null));
        }
            public OrderProperty(SingleValuePropertyAccessNode propertyNode, OrderByDirection direction, Object value)
            {
                PropertyNode = propertyNode;
                Direction    = direction;
                Value        = value;

                ParmeterExpression = null;
                PropertyExpression = null;
            }
Пример #32
0
            public override void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
            {
                // Validate if we are accessing some sensitive property of Order, such as Quantity
                if (propertyAccessNode.Property.Name == "Quantity")
                {
                    throw new ODataException("Filter with Quantity is not allowed.");
                }

                base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
            }
Пример #33
0
        public void NotEqualsOnNullAndComplexIsSupported()
        {
            IEdmTypeReference left = null;
            IEdmTypeReference right = HardCodedTestModel.GetPersonAddressProp().Type;
            SingleValueNode leftNode = new SingleValueOpenPropertyAccessNode(new ConstantNode(null)/*parent*/, "myOpenPropertyname"); // open property's TypeReference is null
            SingleValueNode rightNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", right));
            var result = TypePromotionUtils.PromoteOperandTypes(BinaryOperatorKind.NotEqual, leftNode, rightNode, out left, out right);

            result.Should().BeTrue();
            left.ShouldBeEquivalentTo(HardCodedTestModel.GetPersonAddressProp().Type);
            right.ShouldBeEquivalentTo(HardCodedTestModel.GetPersonAddressProp().Type);
        }
Пример #34
0
        public void OtherOperandsWithComplexAreNotSupported()
        {
            IEdmTypeReference left = HardCodedTestModel.GetPersonAddressProp().Type;
            IEdmTypeReference right = HardCodedTestModel.GetPersonAddressProp().Type;
            SingleValueNode leftNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", left));
            SingleValueNode rightNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", right));
            var result = TypePromotionUtils.PromoteOperandTypes(BinaryOperatorKind.GreaterThan, leftNode, rightNode, out left, out right);

            result.Should().BeFalse();
            left.ShouldBeEquivalentTo(HardCodedTestModel.GetPersonAddressProp().Type);
            right.ShouldBeEquivalentTo(HardCodedTestModel.GetPersonAddressProp().Type);
        }
Пример #35
0
        /// <summary>
        /// Create a AggregateStatement.
        /// </summary>
        /// <param name="expression">The aggregation expression.</param>
        /// <param name="withVerb">The <see cref="AggregationVerb"/>.</param>
        /// <param name="from">The aggregation from <see cref="SingleValuePropertyAccessNode"/>.</param>
        /// <param name="alias">The aggregation alias.</param>
        /// <param name="typeReference">The <see cref="IEdmTypeReference"/> of this aggregate statement.</param>
        public AggregateStatement(SingleValueNode expression, AggregationVerb withVerb, SingleValuePropertyAccessNode from, string alias, IEdmTypeReference typeReference)
        {
            ExceptionUtils.CheckArgumentNotNull(expression, "expression");
            ExceptionUtils.CheckArgumentNotNull(alias, "alias");
            ExceptionUtils.CheckArgumentNotNull(typeReference, "typeReference");

            this.expression = expression;
            this.withVerb = withVerb;
            this.from = from;
            this.alias = alias;
            this.typeReference = typeReference;
        }
        public void Ctor_TakingOrderByClause_InitializesProperty_Property()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            IEdmProperty property = model.Customer.FindProperty("ID");
            EntityRangeVariable variable = new EntityRangeVariable("it", model.Customer.AsReference(), model.Customers);
            SingleValuePropertyAccessNode node = new SingleValuePropertyAccessNode(new EntityRangeVariableReferenceNode("it", variable), property);
            OrderByClause orderBy = new OrderByClause(thenBy: null, expression: node, direction: OrderByDirection.Ascending, rangeVariable: variable);

            // Act
            OrderByPropertyNode orderByNode = new OrderByPropertyNode(orderBy);

            // Assert
            Assert.Equal(property, orderByNode.Property);
        }
Пример #37
0
        private static void BuildOrderBy()
        {
            var productTypeRef = new EdmEntityTypeReference(V4Model.Product, false);
            var supplierProperty = (IEdmNavigationProperty)V4Model.Product.FindProperty("Supplier");
            var nameProperty = V4Model.Supplier.FindProperty("Name");

            var topIt = new EntityRangeVariable("$it", productTypeRef, V4Model.ProductsSet);
            var topItRef = new EntityRangeVariableReferenceNode("$it", topIt);
            var supplierNavNode = new SingleNavigationNode(supplierProperty, topItRef);
            var nameNode = new SingleValuePropertyAccessNode(supplierNavNode, nameProperty);

            var orderby = new OrderByClause(null, nameNode, OrderByDirection.Ascending, topIt);
            var odataUri = new ODataUri
            {
                Path = new ODataPath(new EntitySetSegment(V4Model.ProductsSet)),
                ServiceRoot = V4Root,
                OrderBy = orderby
            };
            var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Console.WriteLine(builder.BuildUri());
            // http://services.odata.org/V4/OData/OData.svc/Products?$orderby=Supplier%2FName
        }
        /// <summary>
        /// Override this method to validate property accessor.
        /// </summary>
        /// <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>
        /// <param name="propertyAccessNode"></param>
        /// <param name="settings"></param>
        public virtual void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
        {
            if (propertyAccessNode == null)
            {
                throw Error.ArgumentNull("propertyAccessNode");
            }

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

            // no default validation logic here 
            ValidateQueryNode(propertyAccessNode.Source, settings);
        }
Пример #39
0
 /// <summary>
 /// Writes single value property access node to string.
 /// </summary>
 /// <param name="node">Node to write to string</param>
 /// <returns>String representation of node.</returns>
 private static string ToString(SingleValuePropertyAccessNode node)
 {
     return tabHelper.Prefix + "SingleValuePropertyAccessNode" +
         tabHelper.Indent(() =>
             tabHelper.Prefix + "Property = " + node.Property.Name +
             tabHelper.Prefix + "TypeReference = " + node.TypeReference +
             tabHelper.Prefix + "Source = " + ToString(node.Source)
         );
 }
 public override void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
 {
     IncrementCount("ValidateSingleValuePropertyAccessNode");
     base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings);
 }
 public void PropertyIsSet()
 {
     var node = new SingleValuePropertyAccessNode(new ConstantNode(null), HardCodedTestModel.GetDogColorProp());
     node.Property.Should().BeSameAs(HardCodedTestModel.GetDogColorProp());
 }
 private string BindPropertyAccessQueryNode(SingleValuePropertyAccessNode singleValuePropertyAccessNode)
 {
     return Bind(singleValuePropertyAccessNode.Source) + "." + singleValuePropertyAccessNode.Property.Name;
 }
Пример #43
0
 static string BindPropertyAccessQueryNode(SingleValuePropertyAccessNode singleValuePropertyAccessNode)
 {
     return singleValuePropertyAccessNode.Property.Name;
 }
 public void SourceIsSet()
 {
     var source = new ConstantNode(null);
     var node = new SingleValuePropertyAccessNode(source, HardCodedTestModel.GetDogColorProp());
     node.Source.Should().BeSameAs(source);
 }
Пример #45
0
        /// <summary>
        /// Override this method to validate property accessor.
        /// </summary>
        /// <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>
        /// <param name="propertyAccessNode"></param>
        /// <param name="settings"></param>
        public virtual void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings)
        {
            if (propertyAccessNode == null)
            {
                throw Error.ArgumentNull("propertyAccessNode");
            }

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

            // Check whether the property is NonFilterable
            IEdmProperty property = propertyAccessNode.Property;
            if (EdmLibHelpers.IsNonFilterable(property, _model))
            {
                throw new ODataException(Error.Format(SRResources.NonFilterablePropertyUsedInFilter, property.Name));
            }

            // no default validation logic here 
            ValidateQueryNode(propertyAccessNode.Source, settings);
        }
Пример #46
0
 /// <summary>
 /// Compares Single Value Property Access query 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(SingleValuePropertyAccessNode left, SingleValuePropertyAccessNode right)
 {
     if (left.Property != right.Property) return false;
     if (left.TypeReference != right.TypeReference) return false;
     return this.Compare(left.Source, right.Source);
 }
Пример #47
0
        public void EqualsOnEntityAndPrimitiveIsNotSupported()
        {
            IEdmTypeReference left = HardCodedTestModel.GetPersonTypeReference();
            IEdmTypeReference right = EdmCoreModel.Instance.GetInt32(true);
            SingleValueNode leftNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", left));
            SingleValueNode rightNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", right));
            var result = TypePromotionUtils.PromoteOperandTypes(BinaryOperatorKind.Equal, leftNode, rightNode, out left, out right);

            result.Should().BeFalse();
            left.ShouldBeEquivalentTo(HardCodedTestModel.GetPersonTypeReference());
            right.ShouldBeEquivalentTo(EdmCoreModel.Instance.GetInt32(true));
        }
Пример #48
0
        public void EqualsOnComplexTypesWithDifferentNullabilityIsSupported()
        {
            var notNullableType = new EdmComplexTypeReference(HardCodedTestModel.GetAddressType(), false);
            var nullableType = new EdmComplexTypeReference(HardCodedTestModel.GetAddressType(), true);

            IEdmTypeReference left = notNullableType;
            IEdmTypeReference right = nullableType;
            SingleValueNode leftNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", left));
            SingleValueNode rightNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", right));
            var result = TypePromotionUtils.PromoteOperandTypes(BinaryOperatorKind.Equal, leftNode, rightNode, out left, out right);

            result.Should().BeTrue();
            left.ShouldBeEquivalentTo(nullableType);
            right.ShouldBeEquivalentTo(nullableType);

            // Reverse order
            left = nullableType;
            right = notNullableType;
            leftNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", left));
            rightNode = new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", right));
            result = TypePromotionUtils.PromoteOperandTypes(BinaryOperatorKind.Equal, leftNode, rightNode, out left, out right);

            result.Should().BeTrue();
            left.ShouldBeEquivalentTo(nullableType);
            right.ShouldBeEquivalentTo(nullableType);
        }
        public static IEnumerable<FilterTestCase> PropertyAccessTestCases(IEdmModel model)
        {
            // Accessing a primitive property on the entity type
            EntityRangeVariable customersEntityRangeVariable = new EntityRangeVariable("dummy", model.ResolveTypeReference("TestNS.Customer", false).AsEntity(), model.FindEntityContainer("BinderTestMetadata").FindEntitySet("Customers"));
            SingleValuePropertyAccessNode propertyAccessNode = new SingleValuePropertyAccessNode(new EntityRangeVariableReferenceNode(customersEntityRangeVariable.Name, customersEntityRangeVariable),
                        model.ResolveProperty("TestNS.Customer.Name"));
            yield return new FilterTestCase()
            {
                Filter = "Name eq 'Vitek'",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.Equal, propertyAccessNode, new ConstantNode("Vitek"))
            };

            // Accessing a complex on entity and primitive on complex
            SingleValuePropertyAccessNode propertyAccessNode2 = new SingleValuePropertyAccessNode(
                new SingleValuePropertyAccessNode(
                    new EntityRangeVariableReferenceNode(customersEntityRangeVariable.Name, customersEntityRangeVariable),
                    model.ResolveProperty("TestNS.Customer.Address")
                    ),
                model.ResolveProperty("TestNS.Address.City")
                );
            yield return new FilterTestCase()
            {
                Filter = "Address/City ne 'Prague'",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.NotEqual, propertyAccessNode2, new ConstantNode("Prague"))
            };
        }
Пример #50
0
 private static void VerifyPropertyAccessQueryNodesAreEqual(SingleValuePropertyAccessNode expected, SingleValuePropertyAccessNode actual, AssertionHandler assert)
 {
     VerifyQueryNodesAreEqual(expected.Source, actual.Source, assert);
     QueryTestUtils.VerifyPropertiesAreEqual(expected.Property, actual.Property, assert);
 }
Пример #51
0
        private static void BuildFilterWithNestedAny()
        {
            var personTypeRef = new EdmEntityTypeReference(TripPinModel.Person, false);
            var tripTypeRef = new EdmEntityTypeReference(TripPinModel.Trip, false);

            var friendsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Friends");
            var tripsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Trips");
            var budgetProp = TripPinModel.Trip.FindProperty("Budget");

            var topIt = new EntityRangeVariable("$it", personTypeRef, TripPinModel.PeopleSet);
            var topItRef = new EntityRangeVariableReferenceNode("$it", topIt);

            var friendsNavNode0 = new CollectionNavigationNode(friendsProp, topItRef);
            var e0 = new EntityRangeVariable("e0", personTypeRef, friendsNavNode0);
            var e0Ref = new EntityRangeVariableReferenceNode("e0", e0);

            var friendsNavNode1 = new CollectionNavigationNode(friendsProp, e0Ref);
            var e1 = new EntityRangeVariable("e1", personTypeRef, friendsNavNode1);
            var e1Ref = new EntityRangeVariableReferenceNode("e1", e1);

            var tripNavNode = new CollectionNavigationNode(tripsProp, e1Ref);
            var e2 = new EntityRangeVariable("e2", tripTypeRef, friendsNavNode1);
            var e2Ref = new EntityRangeVariableReferenceNode("e2", e2);

            var bugetNode = new SingleValuePropertyAccessNode(e2Ref, budgetProp);

            var gt = new BinaryOperatorNode(
                BinaryOperatorKind.GreaterThan,
                bugetNode,
                new ConstantNode(1200, "1200"));

            var any2 = new AnyNode(new Collection<RangeVariable> { e2 }, e2) { Body = gt, Source = tripNavNode };
            var any1 = new AnyNode(new Collection<RangeVariable> { e1 }, e1) { Body = any2, Source = friendsNavNode1 };
            var any0 = new AnyNode(new Collection<RangeVariable> { e0 }, e0) { Body = any1, Source = friendsNavNode0 };


            var odataUri = new ODataUri
            {
                Path = new ODataPath(new EntitySetSegment(TripPinModel.PeopleSet)),
                ServiceRoot = TripPinRoot,
                Filter = new FilterClause(any0, topIt)
            };
            var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Console.WriteLine(builder.BuildUri());
            // http://services.odata.org/V4/TripPinService/People?$filter=Friends%2Fany(e0:e0%2FFriends%2Fany(e1:e1%2FTrips%2Fany(e2:e2%2FBudget gt 1200)))
        }
 public void SingleValuePropertyAccessNodesCanUseGeometry()
 {
     ConstantNode constant = new ConstantNode(2);
     SingleValuePropertyAccessNode accessNode = new SingleValuePropertyAccessNode(constant, HardCodedTestModel.GetPersonGeometryPointProp());
     accessNode.Property.Should().Be(HardCodedTestModel.GetPersonGeometryPointProp());
 }