Revenj.DatabasePersistence.Postgres.QueryGeneration.QueryComposition.QueryParts.ProcessLimitAndOffsetOperators C# (CSharp) Method

ProcessLimitAndOffsetOperators() protected method

protected ProcessLimitAndOffsetOperators ( StringBuilder sb, List limit, List offset, List first, List single ) : void
sb StringBuilder
limit List
offset List
first List
single List
return void
        protected virtual void ProcessLimitAndOffsetOperators(
            StringBuilder sb,
            List<TakeResultOperator> limit,
            List<SkipResultOperator> offset,
            List<FirstResultOperator> first,
            List<SingleResultOperator> single)
        {
            if (first.Count == 1)
            {
                sb.AppendLine("LIMIT 1");
                if (offset.Count == 1)
                    sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
            }
            else if (single.Count == 1)
            {
                if (limit.Count == 0)
                    sb.Append("LIMIT 2");
                else
                {
                    if (limit.TrueForAll(it => it.Count is ConstantExpression))
                    {
                        var min = limit.Min(it => (int)(it.Count as ConstantExpression).Value);
                        if (min > 1) min = 2;
                        sb.Append("LIMIT ").Append(min);
                    }
                    else
                    {
                        sb.Append("LIMIT LEAST(2,");
                        sb.Append(string.Join(", ", limit.Select(it => GetSqlExpression(it.Count))));
                        sb.AppendLine(")");
                    }
                }
                if (offset.Count == 1)
                    sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
            }
            else if (limit.Count > 0 && offset.Count == 0)
            {
                sb.Append("LIMIT ");
                if (limit.Count > 1)
                    sb.Append("LEAST(")
                        .Append(
                            string.Join(
                                ", ",
                                limit.Select(it => GetSqlExpression(it.Count))))
                        .AppendLine(")");
                else sb.AppendLine(GetSqlExpression(limit[0].Count));
            }
            else if (limit.Count == 0 && offset.Count > 0)
            {
                sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
                for (int i = 1; i < offset.Count; i++)
                    sb.Append(" + " + GetSqlExpression(offset[i].Count));
            }
            else if (limit.Count == 1 && offset.Count == 1)
            {
                if (ResultOperators.IndexOf(limit[0]) < ResultOperators.IndexOf(offset[0]))
                    sb.AppendLine("LIMIT ({0} - {1})".With(GetSqlExpression(limit[0].Count), GetSqlExpression(offset[0].Count)));
                else
                    sb.AppendLine("LIMIT " + GetSqlExpression(limit[0].Count));
                sb.AppendLine("OFFSET " + GetSqlExpression(offset[0].Count));
            }
            else if (limit.Count > 1 || offset.Count > 1)
                throw new NotSupportedException("Unsupported combination of limits and offsets in query. More than one offset and more than one limit found.");
        }