Exemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="token"></param>
        /// <param name="q"></param>
        public void Token(string token, QueryTranslator q)
        {
            string lctoken = token.ToLower(System.Globalization.CultureInfo.InvariantCulture);

            if (first)
            {
                first = false;
                if (lctoken.Equals("distinct"))
                {
                    q.Distinct = true;
                    return;
                }
                else if (lctoken.Equals("all"))
                {
                    q.Distinct = false;
                    return;
                }
            }

            if (afterNew)
            {
                afterNew    = false;
                holderClass = q.GetImportedClass(token);
                if (holderClass == null)
                {
                    throw new QueryException("class not found: " + token);
                }
                q.HolderClass = holderClass;
                insideNew     = true;
            }
            else if (token.Equals(StringHelper.Comma))
            {
                if (ready)
                {
                    throw new QueryException("alias or expression expected in SELECT");
                }
                q.AppendScalarSelectToken(StringHelper.CommaSpace);
                ready = true;
            }
            else if ("new".Equals(lctoken))
            {
                afterNew = true;
                ready    = false;
            }
            else if (StringHelper.OpenParen.Equals(token))
            {
                if (!aggregate && holderClass != null && !ready)
                {
                    //opening paren in new Foo ( ... )
                    ready = true;
                }
                else if (aggregate)
                {
                    q.AppendScalarSelectToken(token);
                }
                else
                {
                    throw new QueryException("aggregate function expected before ( in SELECT");
                }
                ready = true;
            }
            else if (StringHelper.ClosedParen.Equals(token))
            {
                if (insideNew && !aggregate && !ready)
                {
                    //if we are inside a new Result(), but not inside a nested function
                    insideNew = false;
                }
                else if (aggregate && ready)
                {
                    q.AppendScalarSelectToken(token);
                    aggregateFuncTokenList.RemoveAt(0);
                    if (aggregateFuncTokenList.Count < 1)
                    {
                        aggregate = false;
                        ready     = false;
                    }
                }
                else
                {
                    throw new QueryException("( expected before ) in select");
                }
            }
            else if (countArguments.Contains(lctoken))
            {
                if (!ready || !aggregate)
                {
                    throw new QueryException(token + " only allowed inside aggregate function in SELECT");
                }
                q.AppendScalarSelectToken(token);
                if ("*".Equals(token))
                {
                    q.AddSelectScalar(NHibernateUtil.Int32);
                }                 //special case
            }
            else if (GetFunction(lctoken, q) != null && token == q.Unalias(token))
            {
                // the name of an SQL function
                if (!ready)
                {
                    throw new QueryException(", expected before aggregate function in SELECT: " + token);
                }
                aggregate = true;
                aggregateAddSelectScalar = true;
                aggregateFuncTokenList.Insert(0, lctoken);
                ready = false;
                q.AppendScalarSelectToken(token);
                if (!AggregateHasArgs(lctoken, q))
                {
                    q.AddSelectScalar(AggregateType(aggregateFuncTokenList, null, q));
                    if (!AggregateFuncNoArgsHasParenthesis(lctoken, q))
                    {
                        aggregateFuncTokenList.RemoveAt(0);
                        if (aggregateFuncTokenList.Count < 1)
                        {
                            aggregate = false;
                            ready     = false;
                        }
                        else
                        {
                            ready = true;
                        }
                    }
                }
            }
            else if (aggregate)
            {
                bool constantToken = false;
                if (!ready)
                {
                    throw new QueryException("( expected after aggregate function in SELECT");
                }
                try
                {
                    ParserHelper.Parse(aggregatePathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q);
                }
                catch (QueryException)
                {
                    constantToken = true;
                }

                if (constantToken)
                {
                    q.AppendScalarSelectToken(token);
                }
                else
                {
                    if (aggregatePathExpressionParser.IsCollectionValued)
                    {
                        q.AddCollection(
                            aggregatePathExpressionParser.CollectionName,
                            aggregatePathExpressionParser.CollectionRole);
                    }
                    q.AppendScalarSelectToken(aggregatePathExpressionParser.WhereColumn);
                    if (aggregateAddSelectScalar)
                    {
                        q.AddSelectScalar(AggregateType(aggregateFuncTokenList, aggregatePathExpressionParser.WhereColumnType, q));
                        aggregateAddSelectScalar = false;
                    }
                    aggregatePathExpressionParser.AddAssociation(q);
                }
            }
            else
            {
                if (!ready)
                {
                    throw new QueryException(", expected in SELECT");
                }

                ParserHelper.Parse(pathExpressionParser, q.Unalias(token), ParserHelper.PathSeparators, q);
                if (pathExpressionParser.IsCollectionValued)
                {
                    q.AddCollection(
                        pathExpressionParser.CollectionName,
                        pathExpressionParser.CollectionRole);
                }
                else if (pathExpressionParser.WhereColumnType.IsEntityType)
                {
                    q.AddSelectClass(pathExpressionParser.SelectName);
                }
                q.AppendScalarSelectTokens(pathExpressionParser.WhereColumns);
                q.AddSelectScalar(pathExpressionParser.WhereColumnType);
                pathExpressionParser.AddAssociation(q);

                ready = false;
            }
        }