public static void GetAndVerifyStatusCode(Workspace w, QueryNode query, HttpStatusCode expectedStatusCode) { AstoriaRequest request = w.CreateRequest(query); request.ExpectedStatusCode = expectedStatusCode; AstoriaResponse response = request.GetResponse(); ResponseVerification.VerifyStatusCode(response); }
public GetHighlightResultsNode(QueryNode sourceNode, string preTag, string postTag, bool mergeHighlights) { this.SourceNode = sourceNode; this.PreTag = preTag; this.PostTag = postTag; this.MergeHighlights = mergeHighlights; }
protected string Bind(QueryNode node) { CollectionNode collectionNode = node as CollectionNode; SingleValueNode singleValueNode = node as SingleValueNode; if (collectionNode != null) { switch (node.Kind) { case QueryNodeKind.CollectionNavigationNode: CollectionNavigationNode navigationNode = node as CollectionNavigationNode; return BindNavigationPropertyNode(navigationNode.Source, navigationNode.NavigationProperty); case QueryNodeKind.CollectionPropertyAccess: return BindCollectionPropertyAccessNode(node as CollectionPropertyAccessNode); } } else if (singleValueNode != null) { switch (node.Kind) { case QueryNodeKind.BinaryOperator: return BindBinaryOperatorNode(node as BinaryOperatorNode); case QueryNodeKind.Constant: return BindConstantNode(node as ConstantNode); case QueryNodeKind.Convert: return BindConvertNode(node as ConvertNode); case QueryNodeKind.EntityRangeVariableReference: return BindRangeVariable((node as EntityRangeVariableReferenceNode).RangeVariable); case QueryNodeKind.NonentityRangeVariableReference: return BindRangeVariable((node as NonentityRangeVariableReferenceNode).RangeVariable); case QueryNodeKind.SingleValuePropertyAccess: return BindPropertyAccessQueryNode(node as SingleValuePropertyAccessNode); case QueryNodeKind.UnaryOperator: return BindUnaryOperatorNode(node as UnaryOperatorNode); case QueryNodeKind.SingleValueFunctionCall: return BindSingleValueFunctionCallNode(node as SingleValueFunctionCallNode); case QueryNodeKind.SingleNavigationNode: SingleNavigationNode navigationNode = node as SingleNavigationNode; return BindNavigationPropertyNode(navigationNode.Source, navigationNode.NavigationProperty); case QueryNodeKind.Any: return BindAnyNode(node as AnyNode); case QueryNodeKind.All: return BindAllNode(node as AllNode); } } throw new NotSupportedException(String.Format("Nodes of type {0} are not supported", node.Kind)); }
public WithinRadiusNode(QueryNode sourceNode, string field, double lat, double lon, int radius) { this.SourceNode = sourceNode; this.Field = field; this.Lat = lat; this.Lon = lon; this.Radius = radius; }
/// <summary> /// Creates a <see cref="TopNode"/>. /// </summary> /// <param name="amount">The number of entities to include in the result.</param> /// <param name="collection">The collection to take items from.</param> public TopNode(QueryNode amount, CollectionNode collection) { ExceptionUtils.CheckArgumentNotNull(amount, "amount"); ExceptionUtils.CheckArgumentNotNull(collection, "collection"); this.amount = amount; this.collection = collection; }
protected void AddNode (QueryNode node) { if (node is QueryTermNode) { QueryTermBox box = first_add_node ? FirstRow : CreateRow (true); box.QueryNode = node as QueryTermNode; first_add_node = false; } else { throw new ArgumentException ("Query is too complex for GUI query editor", "node"); } }
public void ReplaceChild(QueryNode old_child, QueryNode new_child) { int index = children.IndexOf(old_child); if(index < 0) { throw new ApplicationException("old_child does not exist"); } children.RemoveAt(index); children.Insert(index, new_child); }
public static string ToString(QueryNode node) { if (node == null) return String.Empty; switch (node.Kind) { case QueryNodeKind.Any: return ToString((AnyNode)node); case QueryNodeKind.All: return ToString((AllNode)node); case QueryNodeKind.NonentityRangeVariableReference: return ToString((NonentityRangeVariableReferenceNode)node); case QueryNodeKind.Convert: return ToString((ConvertNode)node); case QueryNodeKind.BinaryOperator: return ToString((BinaryOperatorNode)node); case QueryNodeKind.UnaryOperator: return ToString((UnaryOperatorNode)node); case QueryNodeKind.SingleValueFunctionCall: return ToString((SingleValueFunctionCallNode)node); case QueryNodeKind.SingleValuePropertyAccess: return ToString((SingleValuePropertyAccessNode)node); case QueryNodeKind.CollectionPropertyAccess: return ToString((CollectionPropertyAccessNode)node); case QueryNodeKind.CollectionOpenPropertyAccess: return ToString((CollectionOpenPropertyAccessNode)node); case QueryNodeKind.SingleEntityCast: return ToString((SingleEntityCastNode)node); case QueryNodeKind.EntityCollectionCast: return ToString((EntityCollectionCastNode)node); case QueryNodeKind.EntityRangeVariableReference: return ToString((EntityRangeVariableReferenceNode)node); case QueryNodeKind.Constant: return ToString((ConstantNode)node); case QueryNodeKind.CollectionNavigationNode: return ToString((CollectionNavigationNode)node); case QueryNodeKind.SingleNavigationNode: return ToString((SingleNavigationNode)node); case QueryNodeKind.SingleEntityFunctionCall: return ToString((SingleEntityFunctionCallNode)node); case QueryNodeKind.NamedFunctionParameter: return ToString((NamedFunctionParameterNode)node); case QueryNodeKind.ParameterAlias: return ToString((ParameterAliasNode)node); case QueryNodeKind.SearchTerm: return ToString((SearchTermNode)node); case QueryNodeKind.CollectionPropertyCast: return ToString((CollectionPropertyCastNode)node); case QueryNodeKind.SingleValueCast: return ToString((SingleValueCastNode)node); default: throw new NotSupportedException(String.Format("Node kind not yet supported: {0}", node.Kind.ToString())); } }
public void Find(QueryNode node) { switch (node.Kind) { case QueryNodeKind.All: case QueryNodeKind.Any: var l = (LambdaNode)node; Find(l.Source); Find(l.Body); break; case QueryNodeKind.BinaryOperator: var bo = (BinaryOperatorNode)node; Find(bo.Left); addPath(); Find(bo.Right); break; case QueryNodeKind.Convert: Find(((ConvertNode)node).Source); break; case QueryNodeKind.NonentityRangeVariableReference: case QueryNodeKind.UnaryOperator: var uo = (UnaryOperatorNode)node; Find(uo.Operand); break; case QueryNodeKind.SingleValuePropertyAccess: var sv = (SingleValuePropertyAccessNode)node; Find(sv.Source); break; /* case QueryNodeKind.CollectionPropertyAccess: var cpa = (CollectionPropertyAccessNode)node; Paths[Paths.Count-1] += '.' + cpa.Property.Name; break; */ case QueryNodeKind.CollectionNavigationNode: var cnn = (CollectionNavigationNode)node; Find(cnn.Source); AddNav(cnn.NavigationProperty.Name); break; case QueryNodeKind.SingleNavigationNode: var snn = (SingleNavigationNode)node; AddNav(snn.NavigationProperty.Name); break; //case QueryNodeKind.SingleValueOpenPropertyAccess: //case QueryNodeKind.SingleEntityCast: //case QueryNodeKind.EntityCollectionCast: case QueryNodeKind.NamedFunctionParameter: Console.WriteLine(node.GetType()); break; } }
internal static bool TryBindIdentifier(string identifier, IEdmEnumTypeReference typeReference, IEdmModel modelWhenNoTypeReference, out QueryNode boundEnum) { boundEnum = null; string text = identifier; // parse the string, e.g., NS.Color'Green' // get type information, and also convert Green into an ODataEnumValue // find the first ', before that, it is namespace.type int indexOfSingleQuote = text.IndexOf('\''); if (indexOfSingleQuote < 0) { return false; } string namespaceAndType = text.Substring(0, indexOfSingleQuote); Debug.Assert((typeReference == null) || (modelWhenNoTypeReference == null), "((typeReference == null) || (modelWhenNoTypeReference == null)"); // validate typeReference but allow type name not found in model for delayed throwing. if ((typeReference != null) && !string.Equals(namespaceAndType, typeReference.ODataFullName())) { return false; } // get the type IEdmEnumType enumType = typeReference != null ? (IEdmEnumType)typeReference.Definition : UriEdmHelpers.FindEnumTypeFromModel(modelWhenNoTypeReference, namespaceAndType); if (enumType == null) { return false; } // now, find out the value UriPrimitiveTypeParser.TryRemovePrefix(namespaceAndType, ref text); UriPrimitiveTypeParser.TryRemoveQuotes(ref text); // parse string or int value to edm enum value string enumValueString = text; ODataEnumValue enumValue; if (!TryParseEnum(enumType, enumValueString, out enumValue)) { return false; } // create an enum node, enclosing an odata enum value IEdmEnumTypeReference enumTypeReference = typeReference ?? new EdmEnumTypeReference(enumType, false); boundEnum = new ConstantNode(enumValue, identifier, enumTypeReference); return true; }
protected override AbstractSolrQuery Visit(QueryNode node, SolrQueryMapperState state) { if (node.NodeType == QueryNodeType.Custom) { if (node is WithinRadiusNode) { return VisitWithinRadius((WithinRadiusNode)node, state); } } return base.Visit(node, state); }
public void AllTokenWithNonEntityCollectionParentNonConstantExpression() { this.parentQueryNode = new CollectionPropertyAccessNode(new ConstantNode(null), HardCodedTestModel.GetDogNicknamesProperty()); this.expressionQueryNode = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, new ConstantNode(1), new ConstantNode(5)); var binder = new LambdaBinder(this.FakeBindMethod); var state = this.GetBindingStateForTest(HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet()); var allToken = this.CreateTestAllQueryToken(); var result = binder.BindLambdaToken(allToken, state); result.ShouldBeAllQueryNode().And.Source.ShouldBeCollectionPropertyAccessQueryNode(HardCodedTestModel.GetDogNicknamesProperty()); result.Body.ShouldBeBinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual); }
protected override QueryNode Visit(QueryNode node, SolrQueryOptimizerState state) { if (node.NodeType == QueryNodeType.Custom) { if (node is WithinRadiusNode) { return VisitWithinRadius((WithinRadiusNode)node, state); } } return base.Visit(node, state); }
public static void VerifyQueryNodesAreEqual(QueryNode expected, QueryNode actual, AssertionHandler assert) { try { if (expected == null) { assert.IsNull(actual, "The node should be null."); return; } else { assert.IsNotNull(actual, "The node should not be null."); } assert.AreEqual(expected.InternalKind, actual.InternalKind, "The node kind differs from expected one."); switch (expected.InternalKind) { case InternalQueryNodeKind.Constant: VerifyConstantQueryNodesAreEqual((ConstantNode)expected, (ConstantNode)actual, assert); break; case InternalQueryNodeKind.Convert: VerifyConvertQueryNodesAreEqual((ConvertNode)expected, (ConvertNode)actual, assert); break; case InternalQueryNodeKind.NonentityRangeVariableReference: VerifyNonentityRangeVariableReferenceNodesAreEqual((NonentityRangeVariableReferenceNode) expected, (NonentityRangeVariableReferenceNode) actual,assert); break; case InternalQueryNodeKind.EntityRangeVariableReference: VerifyEntityRangeVariableReferenceNodesAreEqual((EntityRangeVariableReferenceNode)expected, (EntityRangeVariableReferenceNode)actual, assert); break; case InternalQueryNodeKind.BinaryOperator: VerifyBinaryOperatorQueryNodesAreEqual((BinaryOperatorNode)expected, (BinaryOperatorNode)actual, assert); break; case InternalQueryNodeKind.UnaryOperator: VerifyUnaryOperatorQueryNodesAreEqual((UnaryOperatorNode)expected, (UnaryOperatorNode)actual, assert); break; case InternalQueryNodeKind.SingleValuePropertyAccess: VerifyPropertyAccessQueryNodesAreEqual((SingleValuePropertyAccessNode)expected, (SingleValuePropertyAccessNode)actual, assert); break; case InternalQueryNodeKind.SingleValueFunctionCall: VerifySingleValueFunctionCallQueryNodesAreEqual((SingleValueFunctionCallNode)expected, (SingleValueFunctionCallNode)actual, assert); break; default: throw new Exception("Query node of kind '" + expected.InternalKind.ToString() + "' not yet supported by VerifyQueryNodesAreEqual."); } } catch (Exception) { assert.Warn("Expected query node: " + expected.ToDebugString()); assert.Warn("Actual query node: " + actual.ToDebugString()); throw; } }
public void ArgumentsAreSetCorrectly() { QueryNode[] args = new QueryNode[] { new ConstantNode(1), new ConstantNode(2), new ConstantNode(3), new ConstantNode(4), new ConstantNode(5) }; SingleValueFunctionCallNode singleValueFunction = new SingleValueFunctionCallNode("stuff", args, EdmCoreModel.Instance.GetInt32(true)); singleValueFunction.Parameters.Should().BeEquivalentTo(args); }
public void AnyTokenWithNonConstantExpressionNullParameter() { this.expressionQueryNode = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(false)); var binder = new LambdaBinder(this.FakeBindMethod); var state = this.GetBindingStateForTest(HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet()); var expression = new LiteralToken("foo"); var parent = new LiteralToken("bar"); var anyToken = new AnyToken(expression, null, parent); var result = binder.BindLambdaToken(anyToken, state); result.ShouldBeAnyQueryNode().And.Source.ShouldBeEntitySetQueryNode(HardCodedTestModel.GetPeopleSet()); result.Body.ShouldBeUnaryOperatorNode(UnaryOperatorKind.Negate); }
/// <summary> /// Tries to bind key values to a key lookup on a collection. /// </summary> /// <param name="collectionNode">Already bound collection node.</param> /// <param name="namedValues">The named value tokens to bind.</param> /// <param name="model">The model to be used.</param> /// <param name="collectionItemEntityType">The type of a single item in a collection to apply the key value to.</param> /// <param name="keyLookupNode">The bound key lookup.</param> /// <returns>Returns true if binding succeeded.</returns> private bool TryBindToDeclaredAlternateKey(EntityCollectionNode collectionNode, IEnumerable<NamedValue> namedValues, IEdmModel model, IEdmEntityType collectionItemEntityType, out QueryNode keyLookupNode) { IEnumerable<IDictionary<string, IEdmProperty>> alternateKeys = model.GetAlternateKeysAnnotation(collectionItemEntityType); foreach (IDictionary<string, IEdmProperty> keys in alternateKeys) { if (TryBindToKeys(collectionNode, namedValues, model, collectionItemEntityType, keys, out keyLookupNode)) { return true; } } keyLookupNode = null; return false; }
public IncrementalPullStrategy(MobileServiceTable table, MobileServiceTableQueryDescription query, string queryId, MobileServiceSyncSettingsManager settings, PullCursor cursor, MobileServiceRemoteTableOptions options) : base(query, cursor, options) { this.table = table; this.originalFilter = query.Filter; this.queryId = queryId; this.settings = settings; this.ordered = options.HasFlag(MobileServiceRemoteTableOptions.OrderBy); }
static string Bind(QueryNode node) { CollectionNode collectionNode = node as CollectionNode; SingleValueNode singleValueNode = node as SingleValueNode; if (singleValueNode != null) { switch (singleValueNode.Kind) { case Microsoft.OData.Core.UriParser.TreeNodeKinds.QueryNodeKind.EntityRangeVariableReference: return BindRangeVariable((node as EntityRangeVariableReferenceNode).RangeVariable); case Microsoft.OData.Core.UriParser.TreeNodeKinds.QueryNodeKind.SingleValuePropertyAccess: return BindPropertyAccessQueryNode(node as SingleValuePropertyAccessNode); default: return string.Empty; } } return string.Empty; }
public bool Compare(QueryNode left, QueryNode right) { if (left.Kind != right.Kind) return false; switch (left.Kind) { case QueryNodeKind.Any: return this.Compare((AnyNode)left, (AnyNode)right); case QueryNodeKind.All: return this.Compare((AllNode)left, (AllNode)right); case QueryNodeKind.NonentityRangeVariableReference: return this.Compare((NonentityRangeVariableReferenceNode)left, (NonentityRangeVariableReferenceNode)right); case QueryNodeKind.Convert: return this.Compare((ConvertNode)left, (ConvertNode)right); case QueryNodeKind.BinaryOperator: return this.Compare((BinaryOperatorNode)left, (BinaryOperatorNode)right); case QueryNodeKind.UnaryOperator: return this.Compare((UnaryOperatorNode)left, (UnaryOperatorNode)right); case QueryNodeKind.SingleValueFunctionCall: return this.Compare((SingleValueFunctionCallNode)left, (SingleValueFunctionCallNode)right); case QueryNodeKind.SingleValuePropertyAccess: return this.Compare((SingleValuePropertyAccessNode)left, (SingleValuePropertyAccessNode)right); case QueryNodeKind.CollectionPropertyAccess: return this.Compare((CollectionPropertyAccessNode)left, (CollectionPropertyAccessNode)right); case QueryNodeKind.SingleEntityCast: return this.Compare((SingleEntityCastNode)left, (SingleEntityCastNode)right); case QueryNodeKind.EntityCollectionCast: return this.Compare((EntityCollectionCastNode)left, (EntityCollectionCastNode)right); case QueryNodeKind.EntityRangeVariableReference: return this.Compare((EntityRangeVariableReferenceNode)left, (EntityRangeVariableReferenceNode)right); case QueryNodeKind.Constant: return this.Compare((ConstantNode)left, (ConstantNode)right); case QueryNodeKind.CollectionNavigationNode: return this.Compare((CollectionNavigationNode)left, (CollectionNavigationNode)right); case QueryNodeKind.SingleNavigationNode: return this.Compare((SingleNavigationNode)left, (SingleNavigationNode)right); default: throw new NotSupportedException(String.Format("Node kind not yet supported: {0}", left.Kind.ToString())); } }
private object ProcessNode(QueryNode queryNode) { switch (queryNode.Kind) { case QueryNodeKind.Constant: return ProcessConstant(queryNode as ConstantQueryNode); case QueryNodeKind.EntitySet: return ProcessNode(queryNode as EntitySetQueryNode); case QueryNodeKind.OrderBy: return ProcessNode(queryNode as OrderByQueryNode); case QueryNodeKind.KeyLookup: return ProcessKeyLookup(queryNode as KeyLookupQueryNode); case QueryNodeKind.Skip: return ProcessSkip(queryNode as SkipQueryNode); case QueryNodeKind.Top: return ProcessTop(queryNode as TopQueryNode); case QueryNodeKind.PropertyAccess: return ProcessNode(queryNode as PropertyAccessQueryNode); case QueryNodeKind.Segment: return ProcessNode(queryNode as NavigationPropertyNode); default: throw new NotImplementedException("No processing implemented for " + queryNode.Kind); } }
private string ParseCondition(string value) { if (String.IsNullOrEmpty(value)) { return(null); } // Check for ANDs or ORs and split into conditions as needed string [] conditions; bool ands = true; if (value.IndexOf(") AND (") != -1) { ands = true; conditions = System.Text.RegularExpressions.Regex.Split(value, "\\) AND \\("); } else if (value.IndexOf(") OR (") != -1) { ands = false; conditions = System.Text.RegularExpressions.Regex.Split(value, "\\) OR \\("); } else { conditions = new string [] { value }; } QueryListNode root = new QueryListNode(ands ? Keyword.And : Keyword.Or); // Remove leading spaces and parens from the first condition conditions[0] = conditions[0].Remove(0, 2); // Remove trailing spaces and last paren from the last condition string tmp = conditions[conditions.Length - 1]; tmp = tmp.TrimEnd(new char[] { ' ' }); tmp = tmp.Substring(0, tmp.Length - 1); conditions[conditions.Length - 1] = tmp; int count = 0; foreach (string condition in conditions) { // Add a new row for this condition string col, v1, v2; foreach (QueryOperator op in QueryOperator.Operators) { if (op.MatchesCondition(condition, out col, out v1, out v2)) { QueryTermNode term = new QueryTermNode(); QueryField field = BansheeQuery.FieldSet [col]; bool is_relative_date = false; if (field == null) { if (col.IndexOf("DateAddedStamp") != -1) { field = BansheeQuery.FieldSet ["added"]; } else if (col.IndexOf("LastPlayedStamp") != -1) { field = BansheeQuery.FieldSet ["lastplayed"]; } // Fix ugly implementation of playlist/smart playlist conditions if (op == QueryOperator.InPlaylist || op == QueryOperator.NotInPlaylist) { field = BansheeQuery.FieldSet ["playlist"]; } else if (op == QueryOperator.InSmartPlaylist || op == QueryOperator.NotInSmartPlaylist) { field = BansheeQuery.FieldSet ["smartplaylist"]; } if (field == null) { continue; } is_relative_date = true; } term.Field = field; if (op == QueryOperator.Between) { QueryListNode and = new QueryListNode(Keyword.And); QueryTermNode t2 = new QueryTermNode(); t2.Field = term.Field; if (is_relative_date) { ParseRelativeDateCondition(term, v1, field, ">="); ParseRelativeDateCondition(t2, v2, field, "<="); } else { term.Value = QueryValue.CreateFromUserQuery(v1, field); term.Operator = term.Value.OperatorSet ["<="]; t2.Value = QueryValue.CreateFromUserQuery(v2, field); t2.Operator = t2.Value.OperatorSet [">="]; } and.AddChild(term); and.AddChild(t2); root.AddChild(and); } else if (is_relative_date) { ParseRelativeDateCondition(term, v1, field, op.NewOp); root.AddChild(term); } else { term.Value = QueryValue.CreateFromUserQuery(v1, field); term.Operator = term.Value.OperatorSet [op.NewOp]; root.AddChild(term); } break; } } count++; } QueryNode node = root.Trim(); if (node != null) { //Console.WriteLine ("After XML: {0}", node.ToXml (BansheeQuery.FieldSet, true)); //Console.WriteLine ("After SQL: {0}", node.ToSql (BansheeQuery.FieldSet)); } return(node == null ? String.Empty : node.ToXml(BansheeQuery.FieldSet)); }
public static void VerifyIsFakeSingleValueNode(QueryNode node) { node.Should().NotBeNull(); node.Should().BeSameAs(FakeBindMethods.FakeSingleComplexProperty); }
public override Expression Bind(QueryNode node) { return(base.Bind(node)); }
public static AndConstraint <CollectionResourceCastNode> ShouldBeCollectionResourceCastNode(this QueryNode node, IEdmTypeReference expectedTypeReference) { node.Should().BeOfType <CollectionResourceCastNode>(); var collectionResourceCastNode = node.As <CollectionResourceCastNode>(); collectionResourceCastNode.ItemType.ShouldBeEquivalentTo(expectedTypeReference); return(new AndConstraint <CollectionResourceCastNode>(collectionResourceCastNode)); }
public static AndConstraint <CollectionNavigationNode> ShouldBeCollectionNavigationNode(this QueryNode token, IEdmNavigationProperty expectedProperty) { token.Should().BeOfType <CollectionNavigationNode>(); var navigationPropertyNode = token.As <CollectionNavigationNode>(); navigationPropertyNode.NavigationProperty.Should().BeSameAs(expectedProperty); navigationPropertyNode.ItemType.ShouldBeEquivalentTo(new EdmEntityTypeReference(expectedProperty.ToEntityType(), expectedProperty.TargetMultiplicity() == EdmMultiplicity.ZeroOrOne)); return(new AndConstraint <CollectionNavigationNode>(navigationPropertyNode)); }
private QueryNode ParseMemberAccess(QueryNode instance) { var errorPos = this.lexer.Token.Position; string id = this.GetIdentifier(); this.lexer.NextToken(); if (this.lexer.Token.Kind == QueryTokenKind.OpenParen) { return this.ParseFunction(id, errorPos); } else { return new MemberAccessNode(instance, id); } }
public static ClrValue Visit(QueryNode node) { return(node.Accept(Instance)); }
public Expression TranslateNode(QueryNode node) { return(node.Accept(this)); }
public static object Visit(QueryNode node) { return(node.Accept(Instance)); }
/// <summary> /// Main dispatching visit method for translating query-nodes into expressions. /// </summary> /// <param name="node">The node to visit/translate.</param> /// <returns>The LINQ string resulting from visiting the node.</returns> internal string TranslateNode(QueryNode node) { return(node.Accept(this)); }
public IEnumerable <IEdmEntityObject> ApplyFilter(EdmEntityTypeSettings sourceEdmSetting, IEnumerable <IEdmEntityObject> items, SingleValueNode filter, string commandPrefix = "") { //var typeSetting = sourceEdmSetting.Properties.FirstOrDefault(predicate => predicate.PropertyName == attributeName); //if (typeSetting == null) // throw new InvalidPropertyException("Filter", attributeName); SingleValueNode right = null; SingleValueNode left = null; BinaryOperatorKind opr = BinaryOperatorKind.Equal; QueryNodeKind kind = QueryNodeKind.None; QueryNode param1 = null; QueryNode param2 = null; string function = string.Empty; if (filter.Kind == QueryNodeKind.UnaryOperator) { if (((UnaryOperatorNode)filter).OperatorKind == UnaryOperatorKind.Not) { commandPrefix = "not"; kind = ((UnaryOperatorNode)filter).Kind; right = ((UnaryOperatorNode)filter).Operand; } } else if (filter.Kind == QueryNodeKind.Convert && ((ConvertNode)filter).Source.Kind == QueryNodeKind.UnaryOperator) { if (((UnaryOperatorNode)((ConvertNode)filter).Source).OperatorKind == UnaryOperatorKind.Not) { commandPrefix = "not"; kind = ((UnaryOperatorNode)((ConvertNode)filter).Source).Kind; right = ((UnaryOperatorNode)((ConvertNode)filter).Source).Operand; } } else if (filter.Kind == QueryNodeKind.BinaryOperator) { right = ((BinaryOperatorNode)filter).Right; left = ((BinaryOperatorNode)filter).Left; opr = ((BinaryOperatorNode)filter).OperatorKind; kind = ((BinaryOperatorNode)filter).Kind; } else if (filter.Kind == QueryNodeKind.Convert && ((ConvertNode)filter).Source.Kind == QueryNodeKind.BinaryOperator) { right = ((BinaryOperatorNode)((ConvertNode)filter).Source).Right; left = ((BinaryOperatorNode)((ConvertNode)filter).Source).Left; opr = ((BinaryOperatorNode)((ConvertNode)filter).Source).OperatorKind; kind = ((ConvertNode)filter).Source.Kind; } else if (filter.Kind == QueryNodeKind.SingleValueFunctionCall) { kind = filter.Kind; param1 = ((SingleValueFunctionCallNode)filter).Parameters.ElementAt(0); param2 = ((SingleValueFunctionCallNode)filter).Parameters.ElementAt(1); function = ((SingleValueFunctionCallNode)filter).Name; } else if (filter.Kind == QueryNodeKind.Convert) { if (((ConvertNode)filter).Source.Kind == QueryNodeKind.SingleValueFunctionCall) { kind = ((ConvertNode)filter).Source.Kind; param1 = ((SingleValueFunctionCallNode)((ConvertNode)filter).Source).Parameters.ElementAt(0); param2 = ((SingleValueFunctionCallNode)((ConvertNode)filter).Source).Parameters.ElementAt(1); function = ((SingleValueFunctionCallNode)((ConvertNode)filter).Source).Name; } } if (kind == QueryNodeKind.BinaryOperator || kind == QueryNodeKind.UnaryOperator || kind == QueryNodeKind.SingleValueFunctionCall) { if (opr == BinaryOperatorKind.And) { items = ApplyFilter(sourceEdmSetting, items, left).Intersect(ApplyFilter(sourceEdmSetting, items, right)); } else if (opr == BinaryOperatorKind.Or) { items = ApplyFilter(sourceEdmSetting, items, left).Union(ApplyFilter(sourceEdmSetting, items, right)); } else if (function == "startswith" || function == "endswith" || function == "contains") { var param1AttributeName = GetParamAttributeName(param1); var param2AttributeName = GetParamAttributeName(param2); var param1AttributeValue = GetPropertyValue(param1); var param2AttributeValue = GetPropertyValue(param2); var param1AttributeType = GetDataType(param1); var param2AttributeType = GetDataType(param2); switch (commandPrefix + function) { case "startswith": items = items.Where(x => GetPropertyValue(x, param1AttributeName, param1AttributeValue).ToString().StartsWith(GetPropertyValue(x, param2AttributeName, param2AttributeValue).ToString())); break; case "endswith": items = items.Where(x => GetPropertyValue(x, param1AttributeName, param1AttributeValue).ToString().EndsWith(GetPropertyValue(x, param2AttributeName, param2AttributeValue).ToString())); break; case "contains": items = items.Where(x => GetPropertyValue(x, param1AttributeName, param1AttributeValue).ToString().Contains(GetPropertyValue(x, param2AttributeName, param2AttributeValue).ToString())); break; case "notstartswith": items = items.Where(x => !GetPropertyValue(x, param1AttributeName, param1AttributeValue).ToString().StartsWith(GetPropertyValue(x, param2AttributeName, param2AttributeValue).ToString())); break; case "notendswith": items = items.Where(x => !GetPropertyValue(x, param1AttributeName, param1AttributeValue).ToString().EndsWith(GetPropertyValue(x, param2AttributeName, param2AttributeValue).ToString())); break; case "notcontains": items = items.Where(x => !GetPropertyValue(x, param1AttributeName, param1AttributeValue).ToString().Contains(GetPropertyValue(x, param2AttributeName, param2AttributeValue).ToString())); break; } } else if (commandPrefix == "not") { items = ApplyFilter(sourceEdmSetting, items, right, commandPrefix); } else if (opr == BinaryOperatorKind.Equal || opr == BinaryOperatorKind.NotEqual || opr == BinaryOperatorKind.GreaterThan || opr == BinaryOperatorKind.GreaterThanOrEqual || opr == BinaryOperatorKind.LessThan || opr == BinaryOperatorKind.LessThanOrEqual) { var leftAttributeName = GetAttributeName(left); var rightAttributeName = GetAttributeName(right); var leftAttributeValue = GetPropertyValue(left); var rightAttributeValue = GetPropertyValue(right); var leftAttributeType = GetDataType(left); var rightAttributeType = GetDataType(right); switch (opr) { case BinaryOperatorKind.Equal: if (leftAttributeType == EdmPrimitiveTypeKind.DateTimeOffset) { items = DateEquals(items, leftAttributeName, rightAttributeName, leftAttributeValue, rightAttributeValue, leftAttributeType, left); } else { items = items.Where(x => GetPropertyValue(x, leftAttributeName, leftAttributeValue).Equals(GetPropertyValue(x, rightAttributeName, rightAttributeValue))); } break; case BinaryOperatorKind.NotEqual: if (leftAttributeType == EdmPrimitiveTypeKind.DateTimeOffset) { items = DateNotEquals(items, leftAttributeName, rightAttributeName, leftAttributeValue, rightAttributeValue, leftAttributeType, left); } else { items = items.Where(x => !(GetPropertyValue(x, leftAttributeName, leftAttributeValue).Equals(GetPropertyValue(x, rightAttributeName, rightAttributeValue)))); } break; case BinaryOperatorKind.GreaterThan: items = GreaterThan(items, leftAttributeName, rightAttributeName, leftAttributeValue, rightAttributeValue, leftAttributeType); break; case BinaryOperatorKind.GreaterThanOrEqual: items = GreaterThanOrEqual(items, leftAttributeName, rightAttributeName, leftAttributeValue, rightAttributeValue, leftAttributeType); break; case BinaryOperatorKind.LessThan: items = LesserThan(items, leftAttributeName, rightAttributeName, leftAttributeValue, rightAttributeValue, leftAttributeType); break; case BinaryOperatorKind.LessThanOrEqual: items = LesserThanOrEqual(items, leftAttributeName, rightAttributeName, leftAttributeValue, rightAttributeValue, leftAttributeType); break; } } } return(items); }
public void Visit(QueryNode node) { var orderBy = node.OrderBy != null?Nodes.Pop() as OrderByNode : null; var groupBy = node.GroupBy != null?Nodes.Pop() as GroupByNode : null; var skip = node.Skip != null?Nodes.Pop() as SkipNode : null; var take = node.Take != null?Nodes.Pop() as TakeNode : null; var select = Nodes.Pop() as SelectNode; var where = node.Where != null?Nodes.Pop() as WhereNode : null; var from = Nodes.Pop() as ExpressionFromNode; var scoreSelect = select; var scoreWhere = where; QueryNode query; var splittedNodes = new List <Node>(); var source = from.Alias.ToRowsSource().WithRowsUsage(); QueryNode lastJoinQuery = null; _scope[MetaAttributes.MethodName] = $"ComputeTable_{from.Alias}_{_queryIndex++}"; IReadOnlyList <AccessMethodNode> usedRefreshMethods = null; if (_scope.ScopeSymbolTable.SymbolIsOfType <RefreshMethodsSymbol>(from.Alias.ToRefreshMethodsSymbolName())) { usedRefreshMethods = _scope.ScopeSymbolTable .GetSymbol <RefreshMethodsSymbol>(from.Alias.ToRefreshMethodsSymbolName()).RefreshMethods; } var aliasIndex = 0; var aliasesPositionsSymbol = new AliasesPositionsSymbol(); if (from.Expression is JoinsNode) { var current = _joinedTables[0]; var left = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.Source.Alias); var right = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.With.Alias); var scopeCreateTable = _scope.AddScope("Table"); var scopeJoinedQuery = _scope.AddScope("Query"); var bothForCreateTable = CreateAndConcatFields(left, current.Source.Alias, right, current.With.Alias, (name, alias) => NamingHelper.ToColumnName(alias, name)); var bothForSelect = CreateAndConcatFields(left, current.Source.Alias, right, current.With.Alias, (name, alias) => name); scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.Source.Alias, left); scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.With.Alias, right); var targetTableName = $"{current.Source.Alias}{current.With.Alias}"; aliasesPositionsSymbol.AliasesPositions.Add(current.Source.Alias, aliasIndex++); aliasesPositionsSymbol.AliasesPositions.Add(current.With.Alias, aliasIndex++); scopeJoinedQuery.ScopeSymbolTable.AddSymbol(targetTableName, _scope.ScopeSymbolTable.GetSymbol(targetTableName)); scopeJoinedQuery[MetaAttributes.SelectIntoVariableName] = targetTableName.ToTransitionTable(); scopeJoinedQuery[MetaAttributes.OriginAlias] = targetTableName; scopeJoinedQuery[MetaAttributes.Contexts] = $"{current.Source.Alias},{current.With.Alias}"; scopeCreateTable[MetaAttributes.CreateTableVariableName] = targetTableName.ToTransitionTable(); var joinedQuery = new InternalQueryNode( new SelectNode(bothForSelect), new ExpressionFromNode( new JoinSourcesTableFromNode( current.Source, current.With, current.Expression, current.JoinType)), null, null, null, null, null, new RefreshNode(new AccessMethodNode[0])); var targetTable = new CreateTransformationTableNode(targetTableName, new string[0], bothForCreateTable, false); splittedNodes.Add(targetTable); splittedNodes.Add(joinedQuery); lastJoinQuery = joinedQuery; source = targetTableName.ToTransitionTable().ToTransformedRowsSource(); var usedTables = new Dictionary <string, string> { { current.Source.Alias, targetTableName }, { current.With.Alias, targetTableName } }; for (var i = 1; i < _joinedTables.Count; i++) { current = _joinedTables[i]; left = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.Source.Alias); right = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.With.Alias); targetTableName = $"{current.Source.Alias}{current.With.Alias}"; aliasesPositionsSymbol.AliasesPositions.Add(current.Source.Alias, aliasIndex++); aliasesPositionsSymbol.AliasesPositions.Add(current.With.Alias, aliasIndex++); scopeCreateTable = _scope.AddScope("Table"); scopeJoinedQuery = _scope.AddScope("Query"); bothForCreateTable = CreateAndConcatFields(left, current.Source.Alias, right, current.With.Alias, (name, alias) => NamingHelper.ToColumnName(alias, name)); bothForSelect = CreateAndConcatFields( left, current.Source.Alias, right, current.With.Alias, (name, alias) => NamingHelper.ToColumnName(alias, name), (name, alias) => name, (name, alias) => NamingHelper.ToColumnName(alias, name), (name, alias) => name); scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.Source.Alias, left); scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.With.Alias, right); scopeJoinedQuery.ScopeSymbolTable.AddSymbol(targetTableName, _scope.ScopeSymbolTable.GetSymbol(targetTableName)); scopeJoinedQuery[MetaAttributes.SelectIntoVariableName] = targetTableName.ToTransitionTable(); scopeJoinedQuery[MetaAttributes.OriginAlias] = targetTableName; scopeJoinedQuery[MetaAttributes.Contexts] = $"{current.Source.Alias},{current.With.Alias}"; scopeCreateTable[MetaAttributes.CreateTableVariableName] = targetTableName.ToTransitionTable(); scopeJoinedQuery.ScopeSymbolTable.AddSymbol( MetaAttributes.OuterJoinSelect, new FieldsNamesSymbol(bothForSelect.Select(f => f.FieldName).ToArray())); var expressionUpdater = new RewriteWhereConditionWithUpdatedColumnAccess(usedTables); var traverser = new CloneTraverseVisitor(expressionUpdater); new WhereNode(current.Expression).Accept(traverser); foreach (var key in usedTables.Keys.ToArray()) { usedTables[key] = targetTableName; } usedTables[current.Source.Alias] = targetTableName; usedTables.Add(current.With.Alias, targetTableName); joinedQuery = new InternalQueryNode( new SelectNode(bothForSelect), new ExpressionFromNode( new JoinInMemoryWithSourceTableFromNode( current.Source.Alias, current.With, expressionUpdater.Where.Expression, current.JoinType)), null, null, null, null, null, new RefreshNode(new AccessMethodNode[0])); targetTable = new CreateTransformationTableNode(targetTableName, new string[0], bothForCreateTable, false); splittedNodes.Add(targetTable); splittedNodes.Add(joinedQuery); lastJoinQuery = joinedQuery; source = targetTableName.ToTransitionTable().ToTransformedRowsSource(); } var rewriter = new RewritePartsToUseJoinTransitionTable(); var partsTraverser = new CloneTraverseVisitor(rewriter); select.Accept(partsTraverser); where?.Accept(partsTraverser); scoreSelect = rewriter.ChangedSelect; scoreWhere = rewriter.ChangedWhere; } if (groupBy != null) { var nestedFrom = splittedNodes.Count > 0 ? new ExpressionFromNode(new InMemoryGroupedFromNode(lastJoinQuery.From.Alias)) : from; var splitted = SplitBetweenAggreateAndNonAggreagate(select.Fields, groupBy.Fields, true); var refreshMethods = CreateRefreshMethods(usedRefreshMethods); var aggSelect = new SelectNode(ConcatAggregateFieldsWithGroupByFields(splitted[0], groupBy.Fields) .Reverse().ToArray()); var outSelect = new SelectNode(splitted[1]); var scopeCreateTranformingTable = _scope.AddScope("Table"); var scopeTransformedQuery = _scope.AddScope("Query"); var scopeCreateResultTable = _scope.AddScope("Table"); var scopeResultQuery = _scope.AddScope("Query"); scopeCreateTranformingTable[MetaAttributes.CreateTableVariableName] = nestedFrom.Alias.ToGroupingTable(); scopeCreateResultTable[MetaAttributes.CreateTableVariableName] = nestedFrom.Alias.ToScoreTable(); var destination = nestedFrom.Alias.ToGroupingTable().ToTransformedRowsSource(); scopeTransformedQuery[MetaAttributes.SelectIntoVariableName] = destination; scopeTransformedQuery[MetaAttributes.SourceName] = splittedNodes.Count > 0 ? nestedFrom.Alias.ToTransitionTable().ToTransformedRowsSource() : nestedFrom.Alias.ToRowsSource().WithRowsUsage(); scopeTransformedQuery[MetaAttributes.OriginAlias] = nestedFrom.Alias; scopeTransformedQuery.ScopeSymbolTable.AddSymbol(nestedFrom.Alias, _scope.ScopeSymbolTable.GetSymbol(nestedFrom.Alias)); scopeTransformedQuery[MetaAttributes.Contexts] = $"{nestedFrom.Alias}"; if (splittedNodes.Count > 0) { var selectRewriter = new RewritePartsToUseJoinTransitionTable(nestedFrom.Alias); var selectTraverser = new CloneTraverseVisitor(selectRewriter); groupBy.Accept(selectTraverser); groupBy = selectRewriter.ChangedGroupBy; scopeTransformedQuery.ScopeSymbolTable.AddSymbol("groupFields", new FieldsNamesSymbol(groupBy.Fields.Select(f => f.FieldName).ToArray())); var newRefreshMethods = new List <AccessMethodNode>(); foreach (var method in refreshMethods.Nodes) { var newNodes = new List <Node>(); foreach (var arg in method.Arguments.Args) { arg.Accept(selectTraverser); newNodes.Add(selectRewriter.RewrittenNode); } var newArgs = new ArgsListNode(newNodes.ToArray()); newRefreshMethods.Add(new AccessMethodNode(method.FToken, newArgs, method.ExtraAggregateArguments, method.CanSkipInjectSource, method.Method)); } refreshMethods = new RefreshNode(newRefreshMethods.ToArray()); } else { scopeTransformedQuery.ScopeSymbolTable.AddSymbol("groupFields", new FieldsNamesSymbol(groupBy.Fields.Select(f => f.Expression.ToString()).ToArray())); } var transformingQuery = new InternalQueryNode(aggSelect, nestedFrom, where, groupBy, null, null, null, refreshMethods); var returnScore = nestedFrom.Alias.ToScoreTable(); scopeResultQuery[MetaAttributes.SelectIntoVariableName] = returnScore; scopeResultQuery[MetaAttributes.SourceName] = destination; scopeResultQuery[MetaAttributes.Contexts] = $"{nestedFrom.Alias}"; aliasesPositionsSymbol.AliasesPositions.Add(nestedFrom.Alias, aliasIndex++); aliasesPositionsSymbol.AliasesPositions.Add(returnScore, aliasIndex++); query = new DetailedQueryNode( outSelect, new ExpressionFromNode( new InMemoryGroupedFromNode(returnScore)), null, null, null, skip, take, returnScore); splittedNodes.Add(new CreateTransformationTableNode(destination, new string[0], transformingQuery.Select.Fields, true)); splittedNodes.Add(transformingQuery); splittedNodes.Add(new CreateTransformationTableNode(query.From.Alias, new string[0], query.Select.Fields, false)); splittedNodes.Add(query); Nodes.Push( new MultiStatementNode( splittedNodes.ToArray(), null)); } else { var splitted = SplitBetweenAggreateAndNonAggreagate(select.Fields, new FieldNode[0], true); if (IsQueryWithMixedAggregateAndNonAggregateMethods(splitted)) { query = new InternalQueryNode(select, from, where, null, null, skip, take, CreateRefreshMethods(usedRefreshMethods)); } else { var scopeCreateResultTable = _scope.AddScope("Table"); var scopeResultQuery = _scope.AddScope("Query"); scopeCreateResultTable[MetaAttributes.CreateTableVariableName] = from.Alias.ToScoreTable(); scopeCreateResultTable[MetaAttributes.OriginAlias] = from.Alias; scopeResultQuery[MetaAttributes.SelectIntoVariableName] = from.Alias.ToScoreTable(); scopeResultQuery[MetaAttributes.Contexts] = from.Alias; scopeResultQuery[MetaAttributes.SourceName] = source; var newFrom = lastJoinQuery != null ? new ExpressionFromNode( new InMemoryGroupedFromNode(lastJoinQuery.From.Alias)) : from; aliasesPositionsSymbol.AliasesPositions.Add(newFrom.Alias, aliasIndex++); splittedNodes.Add(new CreateTransformationTableNode(scopeResultQuery[MetaAttributes.SelectIntoVariableName], new string[0], select.Fields, false)); splittedNodes.Add(new DetailedQueryNode(scoreSelect, newFrom, scoreWhere, null, null, skip, take, scopeResultQuery[MetaAttributes.SelectIntoVariableName])); Nodes.Push( new MultiStatementNode( splittedNodes.ToArray(), null)); } } _scope.ScopeSymbolTable.AddSymbol(MetaAttributes.AllQueryContexts, aliasesPositionsSymbol); _joinedTables.Clear(); }
public void RemoveChild(QueryNode child) { child.Parent = null; children.Remove(child); }
public void InsertChild(int index, QueryNode child) { child.Parent = this; children.Insert(index, child); }
public static AndConstraint <NonentityRangeVariableReferenceNode> ShouldBeNonentityRangeVariableReferenceNode(this QueryNode token, string expectedName) { token.Should().BeOfType <NonentityRangeVariableReferenceNode>(); var rangeVariableNode = token.As <NonentityRangeVariableReferenceNode>(); rangeVariableNode.Name.Should().Be(expectedName); return(new AndConstraint <NonentityRangeVariableReferenceNode>(rangeVariableNode)); }
private static void VerifyIsFakeSingleValueNode(QueryNode node) { Assert.NotNull(node); Assert.Same(FakeBindMethods.FakeSingleComplexProperty, node); }
/// <summary> /// Binds a <see cref="IEdmNavigationProperty"/> to create a LINQ <see cref="Expression"/> that /// represents the semantics of the <see cref="IEdmNavigationProperty"/>. /// </summary> /// <param name="sourceNode">The node that represents the navigation source.</param> /// <param name="navigationProperty">The navigation property to bind.</param> /// <returns>The LINQ <see cref="Expression"/> created.</returns> public virtual Expression BindNavigationPropertyNode(QueryNode sourceNode, IEdmNavigationProperty navigationProperty) { return(BindNavigationPropertyNode(sourceNode, navigationProperty, null)); }
public static AndConstraint <SingleResourceCastNode> ShouldBeSingleResourceCastNode(this QueryNode node, IEdmTypeReference expectedTypeReference) { node.Should().BeOfType <SingleResourceCastNode>(); var singleValueCastNode = node.As <SingleResourceCastNode>(); singleValueCastNode.TypeReference.ShouldBeEquivalentTo(expectedTypeReference); return(new AndConstraint <SingleResourceCastNode>(singleValueCastNode)); }
public static AndConstraint <ResourceRangeVariableReferenceNode> ShouldBeResourceRangeVariableReferenceNode(this QueryNode token, string expectedName) { token.Should().BeOfType <ResourceRangeVariableReferenceNode>(); var parameterNode = token.As <ResourceRangeVariableReferenceNode>(); parameterNode.Name.Should().Be(expectedName); return(new AndConstraint <ResourceRangeVariableReferenceNode>(parameterNode)); }
/// <summary> /// Binds a <see cref="InnerPathToken"/>. /// This includes more than just navigations - it includes complex property access and primitive collections. /// </summary> /// <param name="segmentToken">The segment token to bind.</param> /// <returns>The bound node.</returns> internal QueryNode BindInnerPathSegment(InnerPathToken segmentToken) { FunctionCallBinder functionCallBinder = new FunctionCallBinder(this.bindMethod, state); // First we get the parent node QueryNode parent = this.DetermineParentNode(segmentToken, state); Debug.Assert(parent != null, "parent should never be null"); SingleValueNode singleValueParent = parent as SingleValueNode; if (singleValueParent == null) { QueryNode boundFunction; if (functionCallBinder.TryBindInnerPathAsFunctionCall(segmentToken, parent, out boundFunction)) { return(boundFunction); } throw new ODataException(ODataErrorStrings.MetadataBinder_PropertyAccessSourceNotSingleValue(segmentToken.Identifier)); } // Using the parent and name of this token, we try to get the IEdmProperty it represents IEdmProperty property = BindProperty(singleValueParent.TypeReference, segmentToken.Identifier, this.Resolver); if (property == null) { QueryNode boundFunction; if (functionCallBinder.TryBindInnerPathAsFunctionCall(segmentToken, parent, out boundFunction)) { return(boundFunction); } if (singleValueParent.TypeReference != null && !singleValueParent.TypeReference.Definition.IsOpenType()) { throw new ODataException( ODataErrorStrings.MetadataBinder_PropertyNotDeclared( parent.GetEdmTypeReference().ODataFullName(), segmentToken.Identifier)); } return(new SingleValueOpenPropertyAccessNode(singleValueParent, segmentToken.Identifier)); } if (property.Type.IsODataComplexTypeKind()) { return(new SingleValuePropertyAccessNode(singleValueParent, property)); } // Note - this means nonentity collection (primitive or complex) if (property.Type.IsNonEntityCollectionType()) { return(new CollectionPropertyAccessNode(singleValueParent, property)); } IEdmNavigationProperty navigationProperty = property as IEdmNavigationProperty; if (navigationProperty == null) { throw new ODataException(ODataErrorStrings.MetadataBinder_IllegalSegmentType(property.Name)); } SingleEntityNode parentEntity = EnsureParentIsEntityForNavProp(singleValueParent); return(GetNavigationNode(navigationProperty, parentEntity, segmentToken.NamedValues, state, new KeyBinder(this.bindMethod))); }
private bool TryBindIdentifier(string identifier, IEnumerable <FunctionParameterToken> arguments, QueryNode parent, BindingState state, out QueryNode boundFunction) { boundFunction = null; IEdmType bindingType = null; var singleValueParent = parent as SingleValueNode; if (singleValueParent != null) { if (singleValueParent.TypeReference != null) { bindingType = singleValueParent.TypeReference.Definition; } } else { var collectionValueParent = parent as CollectionNode; if (collectionValueParent != null) { bindingType = collectionValueParent.CollectionType.Definition; } } if (!UriEdmHelpers.IsBindingTypeValid(bindingType)) { return(false); } // All functions should be fully qualified, if they aren't they they aren't functions. // When using extension, there may be function call with unqualified name. So loose the restriction here. if (identifier.IndexOf(".", StringComparison.Ordinal) == -1 && this.Resolver.GetType() == typeof(ODataUriResolver)) { return(false); } IEdmOperation operation; List <FunctionParameterToken> syntacticArguments = arguments == null ? new List <FunctionParameterToken>() : arguments.ToList(); if (!FunctionOverloadResolver.ResolveOperationFromList(identifier, syntacticArguments.Select(ar => ar.ParameterName).ToList(), bindingType, state.Model, out operation, this.Resolver)) { // TODO: FunctionOverloadResolver.ResolveOperationFromList() looks up the function by parameter names, but it shouldn't ignore parameter types. (test case ParseFilter_AliasInFunction_PropertyAsValue_TypeMismatch should fail) return(false); } if (singleValueParent != null && singleValueParent.TypeReference == null) { // if the parent exists, but has no type information, then we're in open type land, and we // shouldn't go any farther. throw new ODataException(ODataErrorStrings.FunctionCallBinder_CallingFunctionOnOpenProperty(identifier)); } if (operation.IsAction()) { return(false); } IEdmFunction function = (IEdmFunction)operation; // TODO: $filter $orderby parameter expression which contains complex or collection should NOT be supported in this way // but should be parsed into token tree, and binded to node tree: parsedParameters.Select(p => this.bindMethod(p)); ICollection <FunctionParameterToken> parsedParameters = HandleComplexOrCollectionParameterValueIfExists(state.Configuration.Model, function, syntacticArguments, state.Configuration.Resolver.EnableCaseInsensitive); IEnumerable <QueryNode> boundArguments = parsedParameters.Select(p => this.bindMethod(p)); boundArguments = boundArguments.ToList(); // force enumerable to run : will immediately evaluate all this.bindMethod(p). IEdmTypeReference returnType = function.ReturnType; IEdmEntitySetBase returnSet = null; var singleEntityNode = parent as SingleEntityNode; if (singleEntityNode != null) { returnSet = function.GetTargetEntitySet(singleEntityNode.NavigationSource, state.Model); } string functionName = function.FullName(); if (returnType.IsEntity()) { boundFunction = new SingleEntityFunctionCallNode(functionName, new[] { function }, boundArguments, (IEdmEntityTypeReference)returnType.Definition.ToTypeReference(), returnSet, parent); } else if (returnType.IsEntityCollection()) { IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType; boundFunction = new EntityCollectionFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, returnSet, parent); } else if (returnType.IsCollection()) { IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType; boundFunction = new CollectionFunctionCallNode(functionName, new[] { function }, boundArguments, collectionTypeReference, parent); } else { boundFunction = new SingleValueFunctionCallNode(functionName, new[] { function }, boundArguments, returnType, parent); } return(true); }
/// <summary> /// Main dispatching visit method for translating query-nodes into expressions. /// </summary> /// <param name="node">The node to visit/translate.</param> /// <returns>The LINQ String resulting from visiting the node.</returns> internal String TranslateNode(QueryNode node) { Debug.Assert(node != null, "node != null"); return node.Accept(this); }
//Constructor public FirstExpression(QueryNode input, ResourceType resourceType) : base(input) { _resourceType = resourceType; }
public int TranslateNode(QueryNode node) { return(node.Accept(this)); }
public QueryNode GetRightSibling(QueryNode node) { int index = IndexOfChild(node); if(index < 0 || index > ChildCount - 2) { return null; } return Children[index + 1]; }
public static AndConstraint <SingleResourceFunctionCallNode> ShouldBeSingleResourceFunctionCallNode(this QueryNode token, string name) { token.Should().BeOfType <SingleResourceFunctionCallNode>(); var functionCallNode = token.As <SingleResourceFunctionCallNode>(); functionCallNode.Name.Should().Be(name); return(new AndConstraint <SingleResourceFunctionCallNode>(functionCallNode)); }
public static FilterNode <ClrValue> Visit(QueryNode node) { return(node.Accept(Instance)); }
//Constructor public SingleOrDefaultExpression(QueryNode input, ResourceType resourceType) : base(input) { _resourceType = resourceType; }
public static AndConstraint <CollectionResourceFunctionCallNode> ShouldBeCollectionResourceFunctionCallNode(this QueryNode token, params IEdmFunction[] operationImports) { token.Should().BeOfType <CollectionResourceFunctionCallNode>(); var functionCallNode = token.As <CollectionResourceFunctionCallNode>(); functionCallNode.Functions.Should().ContainExactly(operationImports); return(new AndConstraint <CollectionResourceFunctionCallNode>(functionCallNode)); }
public QueryNode GetLeftSibling(QueryNode node) { int index = IndexOfChild(node); if(index >= 1) { return Children[index - 1]; } return null; }
public static AndConstraint <SingleValuePropertyAccessNode> ShouldBeSingleValuePropertyAccessQueryNode(this QueryNode token, IEdmProperty expectedProperty) { token.Should().BeOfType <SingleValuePropertyAccessNode>(); var propertyAccessNode = token.As <SingleValuePropertyAccessNode>(); propertyAccessNode.Property.Should().BeSameAs(expectedProperty); propertyAccessNode.TypeReference.Should().BeSameAs(expectedProperty.Type); return(new AndConstraint <SingleValuePropertyAccessNode>(propertyAccessNode)); }
public void AddChild(QueryNode child) { child.Parent = this; children.Add(child); }
public static AndConstraint <ConstantNode> ShouldBeConstantQueryNode <TValue>(this QueryNode token, TValue expectedValue) { token.Should().BeOfType <ConstantNode>(); var constantNode = token.As <ConstantNode>(); if (expectedValue == null) { constantNode.Value.Should().BeNull(); } else { constantNode.Value.Should().BeAssignableTo <TValue>(); constantNode.Value.As <TValue>().ShouldBeEquivalentTo(expectedValue); } return(new AndConstraint <ConstantNode>(constantNode)); }
public static AndConstraint <CollectionOpenPropertyAccessNode> ShouldBeCollectionOpenPropertyAccessQueryNode(this QueryNode token, string expectedPropertyName) { token.Should().BeOfType <CollectionOpenPropertyAccessNode>(); var propertyAccessNode = token.As <CollectionOpenPropertyAccessNode>(); propertyAccessNode.Name.Should().Be(expectedPropertyName); return(new AndConstraint <CollectionOpenPropertyAccessNode>(propertyAccessNode)); }
public static AndConstraint <CollectionComplexNode> ShouldBeCollectionComplexNode(this QueryNode token, IEdmProperty expectedProperty) { token.Should().BeOfType <CollectionComplexNode>(); var propertyAccessNode = token.As <CollectionComplexNode>(); propertyAccessNode.Property.Should().Be(expectedProperty); propertyAccessNode.ItemType.ShouldBeEquivalentTo(((IEdmCollectionType)expectedProperty.Type.Definition).ElementType.AsComplex()); return(new AndConstraint <CollectionComplexNode>(propertyAccessNode)); }
public int IndexOfChild(QueryNode child) { return children.IndexOf(child); }
public static AndConstraint <SingleNavigationNode> ShouldBeSingleNavigationNode(this QueryNode token, IEdmNavigationProperty expectedProperty) { token.Should().BeOfType <SingleNavigationNode>(); var navigationPropertyNode = token.As <SingleNavigationNode>(); navigationPropertyNode.NavigationProperty.Should().BeSameAs(expectedProperty); return(new AndConstraint <SingleNavigationNode>(navigationPropertyNode)); }
public static AndConstraint <SingleValueFunctionCallNode> ShouldBeSingleValueFunctionCallQueryNode(this QueryNode token, string name, IEdmTypeReference returnType = null) { token.Should().BeOfType <SingleValueFunctionCallNode>(); SingleValueFunctionCallNode functionCallNode = token.As <SingleValueFunctionCallNode>(); functionCallNode.Name.Should().Be(name); if (returnType != null) { functionCallNode.TypeReference.ShouldBeEquivalentTo(returnType); } return(new AndConstraint <SingleValueFunctionCallNode>(functionCallNode)); }
private void ComparatorVisitor(JProperty property) { // ConditionGroup absent workaround if (CurrentProcessingObjectType != ProcessingObjectType.ConditionGroup) { var criteriaGroup = CurrentQueryNode.AddCriteriaGroup(CriteriaAppendType.And); processingObjectTypeStack.Push(ProcessingObjectType.ConditionGroup); queryNodesStack.Push(criteriaGroup); ComparatorVisitor(property); processingObjectTypeStack.Pop(); queryNodesStack.Pop(); return; } var path = GetPathUp(property); var subjectQuery = SingleQuery.CreateQuery; var query = subjectQuery; QueryNode queryNode = null; var isValuelessCriteria = false; var isPrevNodeCollection = false; foreach (var pathNode in path) { queryNode = GetQueryNode(pathNode); if (queryNode.PivotData == null || !queryNode.PivotData.PivotDefinition.IsCollection) { if (isValuelessCriteria && pathNode == path.Last()) { continue; } query.AddNode(queryNode); isPrevNodeCollection = false; } else { isValuelessCriteria = true; if (!isPrevNodeCollection) { query.AddNode(queryNode); } else { var subQuery = SingleQuery.CreateQuery; subQuery.AddNode(queryNode); query.AddCriteriaGroup(CriteriaAppendType.And).AddCriteria(subQuery); query = subQuery; } isPrevNodeCollection = true; } } var comparatorMapping = this.comparatorMappings[property.Name.ToLower()]; var comparator = comparatorMapping.Key; var notModifier = comparatorMapping.Value; var value = GetValue(property.Value); if (isValuelessCriteria) { var newSubject = SingleQuery.CreateQuery.AddNode(queryNode); query.AddCriteriaGroup(CriteriaAppendType.And).AddCriteria(newSubject, comparator, value, x => x.NotModifier = notModifier); CurrentQueryNode.AddCriteria(subjectQuery); } else { CurrentQueryNode.AddCriteria(subjectQuery, comparator, value, x => x.NotModifier = notModifier); } }