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

            var commands = model.Include.ParseCommands();

            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 = { "*" }
                });
            }

            var ctx = new QueryFilterContext
            {
                Db            = Db,
                Commands      = commands,
                Request       = model,
                SqlExpression = sqlExpression,
                Response      = response,
            };

            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;
                }
            }

            return(response);
        }
Ejemplo n.º 2
0
        public void IncludeAggregates(QueryFilterContext 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);
        }