/// <summary> /// Write the orderby token as URI part to this builder. /// </summary> /// <param name="orderBy">To write as URI part.</param> protected virtual void WriteOrderBy(OrderByQueryToken orderBy) { ExceptionUtils.CheckArgumentNotNull(orderBy, "orderBy"); this.WriteQuery(orderBy.Expression); if (orderBy.Direction == OrderByDirection.Descending) { this.builder.Append(ExpressionConstants.SymbolEscapedSpace); this.builder.Append(ExpressionConstants.KeywordDescending); } }
/// <summary> /// Parses the $orderby expression. /// </summary> /// <param name="orderBy">The $orderby expression string to parse.</param> /// <returns>The enumeraion of lexical tokens representing order by tokens.</returns> internal IEnumerable <OrderByQueryToken> ParseOrderBy(string orderBy) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(orderBy != null, "orderBy != null"); this.recursionDepth = 0; this.lexer = new ExpressionLexer(orderBy); List <OrderByQueryToken> orderByTokens = new List <OrderByQueryToken>(); while (true) { QueryToken expression = this.ParseExpression(); bool ascending = true; if (this.TokenIdentifierIs(ExpressionConstants.KeywordAscending)) { this.lexer.NextToken(); } else if (this.TokenIdentifierIs(ExpressionConstants.KeywordDescending)) { this.lexer.NextToken(); ascending = false; } OrderByQueryToken orderByToken = new OrderByQueryToken() { Direction = ascending ? OrderByDirection.Ascending : OrderByDirection.Descending, Expression = expression }; orderByTokens.Add(orderByToken); if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.Comma) { break; } this.lexer.NextToken(); } this.lexer.ValidateToken(ExpressionTokenKind.End); return(new ReadOnlyCollection <OrderByQueryToken>(orderByTokens)); }
/// <summary> /// Processes the specified order-by token. /// </summary> /// <param name="query">The query tree constructed so far.</param> /// <param name="orderByToken">The order-by token to bind.</param> /// <returns>Returns the combined query including the ordering.</returns> private QueryNode ProcessSingleOrderBy(QueryNode query, OrderByQueryToken orderByToken) { Debug.Assert(query != null, "query != null"); ExceptionUtils.CheckArgumentNotNull(orderByToken, "orderByToken"); CollectionQueryNode entityCollection = query.AsEntityCollectionNode(); if (entityCollection == null) { throw new ODataException(Strings.MetadataBinder_OrderByNotApplicable); } this.parameter = new ParameterQueryNode() { ParameterType = entityCollection.ItemType }; QueryNode expressionNode = this.Bind(orderByToken.Expression); // TODO: shall we really restrict order-by expressions to primitive types? SingleValueQueryNode expressionResultNode = expressionNode as SingleValueQueryNode; if (expressionResultNode == null || (expressionResultNode.TypeReference != null && !expressionResultNode.TypeReference.IsODataPrimitiveTypeKind())) { throw new ODataException(Strings.MetadataBinder_OrderByExpressionNotSingleValue); } query = new OrderByQueryNode() { Collection = entityCollection, Direction = orderByToken.Direction, Parameter = this.parameter, Expression = expressionResultNode }; this.parameter = null; return query; }
/// <summary> /// Parses the $orderby expression. /// </summary> /// <param name="orderBy">The $orderby expression string to parse.</param> /// <returns>The enumeraion of lexical tokens representing order by tokens.</returns> internal IEnumerable<OrderByQueryToken> ParseOrderBy(string orderBy) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(orderBy != null, "orderBy != null"); this.recursionDepth = 0; this.lexer = new ExpressionLexer(orderBy); List<OrderByQueryToken> orderByTokens = new List<OrderByQueryToken>(); while (true) { QueryToken expression = this.ParseExpression(); bool ascending = true; if (this.TokenIdentifierIs(ExpressionConstants.KeywordAscending)) { this.lexer.NextToken(); } else if (this.TokenIdentifierIs(ExpressionConstants.KeywordDescending)) { this.lexer.NextToken(); ascending = false; } OrderByQueryToken orderByToken = new OrderByQueryToken() { Direction = ascending ? OrderByDirection.Ascending : OrderByDirection.Descending, Expression = expression }; orderByTokens.Add(orderByToken); if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.Comma) { break; } this.lexer.NextToken(); } this.lexer.ValidateToken(ExpressionTokenKind.End); return new ReadOnlyCollection<OrderByQueryToken>(orderByTokens); }