Ejemplo n.º 1
0
        public QueryResponse <Into> ResponseFilter <From, Into>(QueryResponse <Into> response, SqlExpression <From> sqlExpression, IQueryDb dto)
        {
            response.Meta = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            var commands = dto.Include.ParseCommands();

            var ctx = new QueryDbFilterContext
            {
                Db            = Db,
                Commands      = commands,
                Dto           = dto,
                SqlExpression = sqlExpression,
                Response      = response,
            };

            if (IncludeTotal)
            {
                var totalCountRequested = commands.Any(x =>
                                                       "COUNT".EqualsIgnoreCase(x.Name) &&
                                                       (x.Args.Count == 0 || (x.Args.Count == 1 && x.Args[0] == "*")));

                if (!totalCountRequested)
                {
                    commands.Add(new Command {
                        Name = "COUNT", Args = { "*" }
                    });
                }

                foreach (var responseFilter in ResponseFilters)
                {
                    responseFilter(ctx);
                }

                string total;
                response.Total = response.Meta.TryGetValue("COUNT(*)", out total)
                    ? total.ToInt()
                    : (int)Db.Count(sqlExpression); //fallback if it's not populated (i.e. if stripped by custom ResponseFilter)

                //reduce payload on wire
                if (!totalCountRequested)
                {
                    response.Meta.Remove("COUNT(*)");
                    if (response.Meta.Count == 0)
                    {
                        response.Meta = null;
                    }
                }
            }
            else
            {
                foreach (var responseFilter in ResponseFilters)
                {
                    responseFilter(ctx);
                }
            }

            return(response);
        }
Ejemplo n.º 2
0
        public QueryResponse <Into> ResponseFilter <From, Into>(QueryResponse <Into> response, SqlExpression <From> expr, IQueryDb dto)
        {
            response.Meta = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            var commands = dto.Include.ParseCommands();

            var ctx = new QueryDbFilterContext
            {
                Db            = Db,
                Commands      = commands,
                Dto           = dto,
                SqlExpression = expr,
                Response      = response,
            };

            var totalCommand = commands.FirstOrDefault(x => x.Name.EqualsIgnoreCase("Total"));

            if (totalCommand != null)
            {
                totalCommand.Name = "COUNT";
            }

            var totalRequested = commands.Any(x =>
                                              x.Name.EqualsIgnoreCase("COUNT") &&
                                              (x.Args.Count == 0 || x.Args.Count == 1 && x.Args[0].EqualsOrdinal("*")));

            if (IncludeTotal || totalRequested)
            {
                if (!totalRequested)
                {
                    commands.Add(new Command {
                        Name = "COUNT", Args = { "*".AsMemory() }
                    });
                }

                foreach (var responseFilter in ResponseFilters)
                {
                    responseFilter(ctx);
                }

                response.Total = response.Meta.TryGetValue("COUNT(*)", out var total)
                    ? total.ToInt()
                    : (int)Db.Count(expr); //fallback if it's not populated (i.e. if stripped by custom ResponseFilter)

                //reduce payload on wire
                if (totalCommand != null || !totalRequested)
                {
                    response.Meta.Remove("COUNT(*)");
                    if (response.Meta.Count == 0)
                    {
                        response.Meta = null;
                    }
                }
            }
            else
            {
                foreach (var responseFilter in ResponseFilters)
                {
                    responseFilter(ctx);
                }
            }

            return(response);
        }
Ejemplo n.º 3
0
        public void IncludeAggregates(QueryDbFilterContext ctx)
        {
            var commands = ctx.Commands;

            if (commands.Count == 0)
            {
                return;
            }

            var q = ctx.SqlExpression.GetUntypedSqlExpression()
                    .Clone()
                    .ClearLimits()
                    .OrderBy();

            var aggregateCommands = new List <Command>();

            foreach (var cmd in commands)
            {
                if (!SqlAggregateFunctions.Contains(cmd.Name))
                {
                    continue;
                }

                aggregateCommands.Add(cmd);

                if (cmd.Args.Count == 0)
                {
                    cmd.Args.Add("*".AsMemory());
                }

                cmd.Original = cmd.AsMemory();

                var hasAlias = !cmd.Suffix.IsNullOrWhiteSpace();

                for (var i = 0; i < cmd.Args.Count; i++)
                {
                    var arg = cmd.Args[i];

                    string modifier = "";
                    if (arg.StartsWith("DISTINCT ", StringComparison.OrdinalIgnoreCase))
                    {
                        arg.SplitOnFirst(' ', out var first, out var last);
                        modifier = first + " ";
                        arg      = last;
                    }

                    var fieldRef = q.FirstMatchingField(arg.ToString());
                    if (fieldRef != null)
                    {
                        //To return predictable aliases, if it's primary table don't fully qualify name
                        var fieldName    = fieldRef.Item2.FieldName;
                        var needsRewrite = !fieldName.EqualsIgnoreCase(q.DialectProvider.NamingStrategy.GetColumnName(fieldName));
                        if (fieldRef.Item1 != q.ModelDef || fieldRef.Item2.Alias != null || needsRewrite || hasAlias)
                        {
                            cmd.Args[i] = (modifier + q.DialectProvider.GetQuotedColumnName(fieldRef.Item1, fieldRef.Item2)).AsMemory();
                        }
                    }
                    else
                    {
                        double d;
                        if (!arg.EqualsOrdinal("*") && !double.TryParse(arg.ToString(), out d))
                        {
                            cmd.Args[i] = "{0}".SqlFmt(arg).AsMemory();
                        }
                    }
                }

                if (hasAlias)
                {
                    var alias = cmd.Suffix.TrimStart().ToString();
                    if (alias.StartsWith("as ", StringComparison.OrdinalIgnoreCase))
                    {
                        alias = alias.Substring("as ".Length);
                    }

                    cmd.Suffix = (" " + alias.SafeVarName()).AsMemory();
                }
                else
                {
                    cmd.Suffix = (" " + q.DialectProvider.GetQuotedName(cmd.Original.ToString())).AsMemory();
                }
            }

            var selectSql = string.Join(", ", aggregateCommands.Map(x => x.ToString()));

            q.UnsafeSelect(selectSql);

            var rows = ctx.Db.Select <Dictionary <string, object> >(q);
            var row  = rows.FirstOrDefault();

            foreach (var key in row.Keys)
            {
                ctx.Response.Meta[key] = row[key]?.ToString();
            }

            ctx.Commands.RemoveAll(aggregateCommands.Contains);
        }
Ejemplo n.º 4
0
        public void IncludeAggregates(QueryDbFilterContext ctx)
        {
            var commands = ctx.Commands;

            if (commands.Count == 0)
            {
                return;
            }

            var q = ctx.SqlExpression.GetUntypedSqlExpression()
                    .Clone()
                    .ClearLimits()
                    .OrderBy();

            var aggregateCommands = new List <Command>();

            foreach (var cmd in commands)
            {
                if (!SqlAggregateFunctions.Contains(cmd.Name))
                {
                    continue;
                }

                aggregateCommands.Add(cmd);

                if (cmd.Args.Count == 0)
                {
                    cmd.Args.Add("*");
                }

                var hasAlias = !string.IsNullOrWhiteSpace(cmd.Suffix);

                for (var i = 0; i < cmd.Args.Count; i++)
                {
                    var arg = cmd.Args[i];

                    string modifier = "";
                    if (arg.StartsWithIgnoreCase("DISTINCT "))
                    {
                        var argParts = arg.SplitOnFirst(' ');
                        modifier = argParts[0] + " ";
                        arg      = argParts[1];
                    }

                    var fieldRef = q.FirstMatchingField(arg);
                    if (fieldRef != null)
                    {
                        //To return predictable aliases, if it's primary table don't fully qualify name
                        if (fieldRef.Item1 != q.ModelDef || hasAlias)
                        {
                            cmd.Args[i] = modifier + q.DialectProvider.GetQuotedColumnName(fieldRef.Item1, fieldRef.Item2);
                        }
                    }
                    else
                    {
                        double d;
                        if (arg != "*" && !double.TryParse(arg, out d))
                        {
                            cmd.Args[i] = "{0}".SqlFmt(arg);
                        }
                    }
                }

                if (hasAlias)
                {
                    var alias = cmd.Suffix.TrimStart();
                    if (alias.StartsWithIgnoreCase("as "))
                    {
                        alias = alias.Substring("as ".Length);
                    }

                    cmd.Suffix = " " + alias.SafeVarName();
                }
                else
                {
                    cmd.Suffix = " " + q.DialectProvider.GetQuotedName(cmd.ToString());
                }
            }

            var selectSql = string.Join(", ", aggregateCommands.Map(x => x.ToString()));

            q.UnsafeSelect(selectSql);

            var rows = ctx.Db.Select <Dictionary <string, object> >(q);
            var row  = rows.FirstOrDefault();

            foreach (var key in row.Keys)
            {
                ctx.Response.Meta[key] = row[key].ToString();
            }

            ctx.Commands.RemoveAll(aggregateCommands.Contains);
        }