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); }
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))); }
/// <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); }
/// <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); }
/// <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); }
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()); }
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); }
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")) }); }
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)); }
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)); }
/// <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); }
public OrderProperty(SingleValuePropertyAccessNode propertyNode, OrderByDirection direction, MemberExpression propertyExpression, ConstantExpression parameterExpression) { PropertyNode = propertyNode; Direction = direction; PropertyExpression = propertyExpression; ParameterExpression = parameterExpression; }
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()); }
/// <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)); }
public override void ValidateSingleValuePropertyAccessNode(SingleValuePropertyAccessNode propertyAccessNode, ODataValidationSettings settings) { if (propertyAccessNode.Property.Name == "ID") { visited = true; } base.ValidateSingleValuePropertyAccessNode(propertyAccessNode, settings); }
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); }
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); }
/// <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 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(); }
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; }
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); }
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); }
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); }
/// <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); }
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); }
/// <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; }
static string BindPropertyAccessQueryNode(SingleValuePropertyAccessNode singleValuePropertyAccessNode) { return singleValuePropertyAccessNode.Property.Name; }
/// <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); }
/// <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); }
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)); }
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")) }; }
private static void VerifyPropertyAccessQueryNodesAreEqual(SingleValuePropertyAccessNode expected, SingleValuePropertyAccessNode actual, AssertionHandler assert) { VerifyQueryNodesAreEqual(expected.Source, actual.Source, assert); QueryTestUtils.VerifyPropertiesAreEqual(expected.Property, actual.Property, assert); }
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))) }