示例#1
0
        public void QueryTotals(AggregationPool pool)
        {
            int attrLen            = Index.Length;
            List <Attribute> index = new List <Attribute>();

            for (int i = 0; i < attrLen - 1; i++)
            {
                index.Add(Index[i]);
                Aggregation agg = pool.FindAggregation(index.ToArray());
                if (agg != null)
                {
                    foreach (int row in TotalIndices)
                    {
                        AttributeMember[] tuple = Tuples[row];
                        if (!tuple[i].IsTotal && tuple[i + 1].IsTotal)
                        {
                            int targetIndex = agg.GetIndex(tuple.Take(i + 1));
                            if (targetIndex >= 0)
                            {
                                for (int j = 0; j < Values.Count; j++)
                                {
                                    Values[j].Values[row] = agg.Values[j].Values[targetIndex];
                                }
                            }
                        }
                    }
                }
            }
        }
示例#2
0
        public CellSet Execute(QueryCommand cmd)
        {
            Joiner joiner = new Joiner(_pool, _connection, cmd);

            joiner.Run();

            if (_pool.Aggregations.Count == 0)
            {
                return(new CellSet());
            }

            CellSet  cs = new CellSet();
            DateTime t  = DateTime.Now;

            QuerySets.JoinedMembers columns = cmd.Columns.JoinMembers(_pool.FindAggregation(cmd.Columns.Attributes));
            QuerySets.JoinedMembers rows    = cmd.Rows.Count > 0 ?
                                              cmd.Rows.JoinMembers(_pool.FindAggregation(cmd.Rows.Attributes)) :
                                              new QuerySets.JoinedMembers();

            QuerySets.JoinedMembers filters;
            bool reverseFilter = cmd.Filters.ShouldReverse;

            if (!reverseFilter)
            {
                filters = cmd.Filters.Count > 0 ?
                          cmd.Filters.JoinMembers(_pool.FindAggregation(cmd.Filters.Attributes), true) :
                          new QuerySets.JoinedMembers();
            }
            else
            {
                reverseFilter = true;
                QuerySets reversed = cmd.Filters.ReverseMembers();
                filters = reversed.Count > 0 ?
                          reversed.JoinMembers(_pool.FindAggregation(reversed.Attributes), true) :
                          new QuerySets.JoinedMembers();
            }

            // AggregationPointer is for total lookup
            AggregationPointer root = null;
            Aggregation        defaultAggregation = _pool.FindAggregation(GetAttributes());

            if (defaultAggregation != null)
            {
                List <Position> cps = cs.Axes[0].Positions;
                List <Position> rps = cs.Axes[1].Positions;
                for (int i = 0; i < rows.Count; i++)
                {
                    rps.Add(new Position(rows[i], i));
                }
                for (int i = 0; i < columns.Count; i++)
                {
                    cps.Add(new Position(columns[i], i));
                }

                if (filters.Count > 0)
                {
                    if (reverseFilter)
                    {
                        // Query values without filters first
                        Attribute[] crIndex = cmd.Columns.Attributes.Concat(cmd.Rows.Attributes).ToArray();
                        DirectQuery(_pool.FindAggregation(crIndex));

                        // Then query values with filter
                        if (root != null)
                        {
                            root.Clear();
                        }
                        root = null;
                        IEnumerable <Cell> filtered = IncrementalQuery(defaultAggregation);

                        // Substract
                        int i = 0;
                        foreach (Cell cell in filtered)
                        {
                            if (cell.Value != null)
                            {
                                if (cell.DataType == typeof(int))
                                {
                                    cs.Cells[i].Value = (int)cs.Cells[i].Value - (int)cell.Value;
                                }
                                else
                                {
                                    cs.Cells[i].Value = (decimal)cs.Cells[i].Value - (decimal)cell.Value;
                                }
                            }
                            i++;
                        }
                    }
                    else
                    {
                        IncrementalQuery(defaultAggregation, cs.Cells);
                    }
                }
                else
                {
                    DirectQuery(defaultAggregation);
                }
            }

            cs.QueryTime = (DateTime.Now - t).TotalMilliseconds;
            return(cs);

            Attribute[] GetAttributes()
            {
                List <Attribute> attrs = new List <Attribute>();

                attrs.AddRange(filters.Attributes);
                attrs.AddRange(columns.Attributes);
                attrs.AddRange(rows.Attributes);
                return(attrs.ToArray());
            }

            IEnumerable <Cell> IncrementalQuery(Aggregation agg, List <Cell> cells = null)
            {
                List <CellAggregator> cas = new List <CellAggregator>();

                if (rows.Count == 0)
                {
                    for (int i = 0; i < filters.Count; i++)
                    {
                        int pointer = 0;
                        for (int j = 0; j < columns.Count; j++)
                        {
                            if (i == 0)
                            {
                                cas.Add(new CellAggregator(GetValueInfo(agg.GetValue(false, filters[i], columns[j]))));
                            }
                            else
                            {
                                cas[pointer].Add(GetValueInfo(agg.GetValue(false, filters[i], columns[j])));
                                pointer++;
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < filters.Count; i++)
                    {
                        int pointer = 0;
                        for (int j = 0; j < rows.Count; j++)
                        {
                            for (int k = 0; k < columns.Count; k++)
                            {
                                if (i == 0)
                                {
                                    cas.Add(new CellAggregator(GetValueInfo(agg.GetValue(false, filters[i], columns[k], rows[j]))));
                                }
                                else
                                {
                                    cas[pointer].Add(GetValueInfo(agg.GetValue(false, filters[i], columns[k], rows[j])));
                                    pointer++;
                                }
                            }
                        }
                    }
                }
                //cas.ForEach(_ => cs.Cells.Add(new Cell(_.Calculate())));
                if (cells != null)
                {
                    cas.ForEach(_ => cells.Add(new Cell(_.Calculate())));
                    return(null);
                }
                else
                {
                    return(cas.Select(_ => new Cell(_.Calculate(), _.DataType)));
                }
            }

            void DirectQuery(Aggregation agg)
            {
                if (rows.Count == 0)
                {
                    for (int i = 0; i < columns.Count; i++)
                    {
                        cs.Cells.Add(new Cell(GetValueInfo(agg.GetValue(false, columns[i])).Value));
                    }
                }
                else
                {
                    for (int i = 0; i < rows.Count; i++)
                    {
                        for (int j = 0; j < columns.Count; j++)
                        {
                            cs.Cells.Add(new Cell(GetValueInfo(agg.GetValue(false, columns[j], rows[i])).Value));
                        }
                    }
                }
            }

            Aggregation.ValueInfo GetValueInfo(Aggregation.ValueInfo vinfo)
            {
                // vinfo.IsTotal -> Place holder for total
                // AggregationPointer -> Point to total aggregation indexed by total place holder's attributes
                if (vinfo.IsTotal)
                {
                    // Find or create AggregationPointer based on total place holder's attributes
                    int c = 0;
                    AggregationPointer cp = root;
                    foreach (AttributeMember[] members in vinfo.Members)
                    {
                        foreach (AttributeMember m in members)
                        {
                            if (!m.IsTotal && m.LinkedMeasure == null)
                            {
                                if (c == 0)
                                {
                                    if (root == null)
                                    {
                                        root = new AggregationPointer(m.Attribute);
                                    }
                                    cp = root;
                                }
                                else
                                {
                                    AggregationPointer p = cp[m.Attribute];
                                    if (p == null)
                                    {
                                        p = new AggregationPointer(cp, m.Attribute);
                                        cp.Children.Add(p);
                                    }
                                    cp = p;
                                }
                                c++;
                            }
                        }
                    }

                    // Find and assign total aggregation if it is a new pointer (cp.Aggregation == null)
                    if (cp.Aggregation == null)
                    {
                        cp.Aggregation = _pool.FindAggregation(cp.Attributes);
                    }

                    return(cp.Aggregation.GetValue(true, vinfo.Members));
                }
                else
                {
                    return(vinfo);
                }
            }
        }
示例#3
0
        public void Run()
        {
            if (_connection != null)
            {
                try
                {
                    if (_connection.State != ConnectionState.Open)
                    {
                        _connection.Open();
                    }
                    // Need to rename QueryAttributeMembers
                    List <Measure> measures = QueryMeasureValues();
                    if (measures.Count > 0)
                    {
                        PathFinder pf = new PathFinder(_cmd);
                        if (pf.Paths.Count > 0)
                        {
                            List <Aggregation> aggs = new List <Aggregation>();
                            // mgroups = measures grouped by fact table
                            IEnumerable <IGrouping <Table, Measure> > mgroups = measures.GroupBy(_ => _.Definition.Source.Table, _ => _);

                            Aggregate(_cmd.Permutate(false));
                            //Aggregate(_cmd.Permutate(true));

                            aggs.ForEach(_ => _.QueryTotals(_pool));

                            void Aggregate(List <Attribute[]> indices)
                            {
                                foreach (Attribute[] index in indices)
                                {
                                    Aggregation agg = _pool.FindAggregation(index);
                                    // All key columns are from the same table
                                    IEnumerable <Table> dimTables = index.Select(_ => _.Definition.KeyColumns[0].Table);
                                    foreach (IGrouping <Table, Measure> mgroup in mgroups)
                                    {
                                        Aggregator ag = new Aggregator(
                                            _connection,
                                            index,
                                            mgroup.ToArray(),
                                            pf.GetPath(dimTables, mgroup.Key)
                                            );

                                        if (agg == null)
                                        {
                                            agg = ag.Query();
                                            aggs.Add(agg);
                                            _pool.Aggregations.Add(agg);
                                        }
                                        else
                                        {
                                            if (ag.QueryMeasures(agg, agg.MergeMeasures(mgroup.ToArray())))
                                            {
                                                aggs.Add(agg);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    _connection.Close();
                }
            }
        }