示例#1
0
        private List <Measure> QueryMeasureValues()
        {
            List <Measure> list = new List <Measure>();

            Measure[] measures = _cmd.Measures;
            foreach (Measure m in measures)
            {
                MeasureQuery mq   = null;
                Aggregation  root = _pool.GetRoot();
                if (root == null)
                {
                    root = new Aggregation(new Attribute[] { });
                    _pool.Aggregations.Add(root);
                }

                MeasureValues mvs = root[m];
                if (mvs == null || mvs.Values.Count == 0)
                {
                    if (mq == null)
                    {
                        mq = new MeasureQuery(Connection);
                    }
                    mq.Measure = m.Definition;

                    if (mvs == null)
                    {
                        mvs = new MeasureValues(m);
                        root.Values.Add(mvs);
                    }

                    mvs.Values.Add(mq.QueryValue());
                }
                list.Add(m);
            }
            return(list);
        }
示例#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 JoinedMembers JoinMembers(Aggregation agg, bool shouldCleanUp = false)
        {
            if (agg == null && Attributes.Length == 0)
            {
                if (Measures.Length > 0)
                {
                    Measure[]     ms     = Measures;
                    JoinedMembers result = new JoinedMembers();
                    foreach (Measure m in ms)
                    {
                        AttributeMember mm = new AttributeMember(m.Name);
                        mm.LinkedMeasure = m;
                        result.Add(new AttributeMember[] { mm });
                    }
                    return(result);
                }
                else
                {
                    return(JoinedMembers.Empty);
                }
            }
            else
            {
                RearrangedSets sets = Rearrange();
                if (shouldCleanUp)
                {
                    sets.CleanUp();
                }

                // return empty if no sets left after cleaned up
                if (sets.Count == 0)
                {
                    return(JoinedMembers.Empty);
                }

                int   depth    = sets.Count;
                int[] indices  = new int[depth];
                int[] ceilings = new int[depth];
                List <List <AttributeMember> > list = new List <List <AttributeMember> >();
                for (int i = 0; i < depth; i++)
                {
                    indices[i]  = 0;
                    ceilings[i] = sets[i].Count;
                }

                Join(0);

                void Join(int level)
                {
                    for (int i = 0; i < ceilings[level]; i++)
                    {
                        indices[level] = i;
                        if (level == depth - 1)
                        {
                            List <AttributeMember> members = new List <AttributeMember>();
                            for (int j = 0; j < depth; j++)
                            {
                                IQueryMember member = sets[j][indices[j]];
                                members.Add(member is AttributeMember ? (AttributeMember)member : ((HierarchyMember)member).Origin);
                            }

                            if (agg.GetIndex(members) > -1)
                            {
                                list.Add(members);
                            }
                        }
                        else
                        {
                            Join(level + 1);
                        }
                    }
                }

                JoinedMembers result = new JoinedMembers();
                list.ForEach(_ => result.Add(_.ToArray()));
                return(result);
            }
        }
示例#4
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();
                }
            }
        }
示例#5
0
        public Aggregation Query()
        {
            DateTime t = DateTime.Now;

            int         attrLen = Attributes.Length;
            int         ceiling = attrLen - 1;
            int         mLen    = Measures.Length;
            Aggregation agg     = new Aggregation(Attributes, Measures);

            IDataReader reader = null;

            try
            {
                int rowIndex = 0;
                reader = ExecuteReader(GetSql(null));
                while (reader.Read())
                {
                    AttributeMember[] tuple = new AttributeMember[attrLen];
                    for (int i = 0; i < attrLen; i++)
                    {
                        tuple[i] = (AttributeMember)Attributes[i].Levels[1].Members[reader[i]];
                    }
                    if (rowIndex > 0)
                    {
                        AddTotals(tuple, ref rowIndex);
                    }
                    agg.Tuples.Add(tuple);

                    int index = attrLen;
                    for (int i = 0; i < mLen; i++)
                    {
                        agg.Values[i].Values.Add(reader[index]);
                        index++;
                    }
                    rowIndex++;
                }
                AddTotals(new AttributeMember[attrLen], ref rowIndex);
                BuildIndexTree();

                agg.QueryTime = (DateTime.Now - t).TotalMilliseconds;
                return(agg);
            }
            finally
            {
                CloseReader(reader);
            }

            void AddTotals(AttributeMember[] tuple, ref int ri)
            {
                AttributeMember[] last = agg.Tuples.Last();
                for (int i = tuple.Length - 2; i >= 0; i--)
                {
                    if (tuple[i] != last[i])
                    {
                        AttributeMember[] total = (AttributeMember[])last.Clone();
                        for (int j = i + 1; j < attrLen; j++)
                        {
                            Attribute attr = last[j].Attribute;
                            //Member tm = new Member(attr.Dimension.AttributeAllMemberName);
                            //tm.IsTotal = true;
                            //tm.Attribute = attr;
                            total[j] = (AttributeMember)attr.AllMember;
                        }
                        agg.Tuples.Add(total);
                        agg.TotalIndices.Add(ri);

                        int index = attrLen;
                        for (int j = 0; j < mLen; j++)
                        {
                            agg.Values[j].Values.Add(0);
                            index++;
                        }
                        ri++;
                    }
                }
            }

            void BuildIndexTree()
            {
                IndexTreeNode[] currNodes = new IndexTreeNode[attrLen];
                for (int i = 0; i < agg.Tuples.Count; i++)
                {
                    bool changed = false;
                    for (int j = 0; j < attrLen; j++)
                    {
                        AttributeMember member = agg.Tuples[i][j];

                        // Transfers flat columns to IndexTree structure
                        // currNode == 1 => first pass
                        // currNode.Member != member => current member is different from the previous row
                        // changed => any previous columns is different from the previous row
                        IndexTreeNode currNode = currNodes[j];
                        if (currNode == null || currNode.Member != member || changed)
                        {
                            changed = true;
                            // Only leaf nodes hold row index
                            IndexTreeNode n = new IndexTreeNode(member);
                            if (j == 0)
                            {
                                agg.IndexTree.Nodes.Add(n);
                                if (attrLen == 1)
                                {
                                    n.Index = i;
                                }
                            }
                            else
                            {
                                currNodes[j - 1].Children.Add(n);
                                if (j == ceiling)
                                {
                                    n.Index = i;
                                }
                            }
                            currNodes[j] = n;
                        }
                    }
                }
            }
        }