123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- using System;
- using System.Collections.Generic;
- namespace FastReport.AdvMatrix
- {
- internal class AggregateExpressionPairList : List<AggregateExpressionPair>
- {
- private AdvMatrixObject matrix;
- public AggregateExpressionPair Find(string aggregateName, string expression)
- {
- foreach (AggregateExpressionPair item in this)
- {
- if (item.AggregateName == aggregateName && item.Expression == expression)
- return item;
- }
- return null;
- }
- public AggregateExpressionPair Add(string aggregateName, string expression)
- {
- AggregateExpressionPair result = new AggregateExpressionPair(matrix, aggregateName, expression);
- Add(result);
- return result;
- }
- public AggregateExpressionPair AddUnique(string aggregateName, string expression)
- {
- AggregateExpressionPair result = Find(aggregateName, expression);
- if (result != null)
- return result;
- return Add(aggregateName, expression);
- }
- public AggregateExpressionPair AddUnique(AggregateExpressionPair ag)
- {
- AggregateExpressionPair result = Find(ag.AggregateName, ag.Expression);
- if (result != null)
- return result;
- Add(ag);
- return ag;
- }
- public AggregateExpressionPairList(AdvMatrixObject matrix)
- {
- this.matrix = matrix;
- }
- }
- internal class AggregateExpressionPair
- {
- private AdvMatrixObject matrix;
- private CellDataStorage storage;
- public string AggregateName { get; private set; }
- public string Expression { get; private set; }
- private string ToStringLiteral(string text)
- {
- return "\"" + text.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";
- }
- public string ToAggregateCall()
- {
- return matrix.Name + ".Data.Context.GetAggregate(" + ToStringLiteral(AggregateName) + ", " + ToStringLiteral(Expression) + ")";
- }
- public override string ToString()
- {
- return AggregateName + "(" + Expression + ")";
- }
- public void ProcessDataRow(int columnIndex, int rowIndex, object value)
- {
- storage.AddValue(columnIndex, rowIndex, value);
- }
- public object GetValue(int columnIndex, int rowIndex)
- {
- object value = storage.GetValue(columnIndex, rowIndex);
- if (value != null && storage.AggregateType == typeof(UserAggregate))
- value = matrix.Report.InvokeMethod(AggregateName, new object[] { value });
- return value;
- }
- public void Merge(int sourceColumnIndex, int sourceRowIndex, int targetColumnIndex, int targetRowIndex)
- {
- storage.Merge(sourceColumnIndex, sourceRowIndex, targetColumnIndex, targetRowIndex);
- }
- public void ClearData()
- {
- storage.Clear();
- }
- public AggregateExpressionPair(AdvMatrixObject matrix, string aggregateName, string expression)
- {
- this.matrix = matrix;
- AggregateName = aggregateName;
- Expression = expression;
- Type aggregateType = Aggregates.Find(aggregateName);
- if (aggregateType == null)
- aggregateType = typeof(UserAggregate);
- storage = new CellDataStorage(aggregateType);
- }
- private class CellDataStorage
- {
- // array of array: the simplest and most efficient way to store dense matrix data
- private List<List<AggregateBase>> rows;
- internal Type AggregateType { get; private set; }
- private AggregateBase GetCell(int columnIndex, int rowIndex, bool create)
- {
- if (rowIndex >= rows.Count)
- {
- if (!create)
- return null;
- // append rows if row index is out of bounds
- int delta = rowIndex - rows.Count + 1;
- for (int i = 0; i < delta; i++)
- {
- rows.Add(new List<AggregateBase>());
- }
- }
- List<AggregateBase> row = rows[rowIndex];
- if (columnIndex >= row.Count)
- {
- if (!create)
- return null;
- // append columns if column index is out of bounds
- int delta = columnIndex - row.Count + 1;
- for (int i = 0; i < delta; i++)
- {
- row.Add(null);
- }
- }
- AggregateBase aggregate = row[columnIndex];
- if (aggregate == null)
- {
- if (!create)
- return null;
- // initial state - the cell is empty. Create aggregate instance
- aggregate = Activator.CreateInstance(AggregateType) as AggregateBase;
- row[columnIndex] = aggregate;
- }
- return aggregate;
- }
- public void Clear()
- {
- rows.Clear();
- }
- public void AddValue(int columnIndex, int rowIndex, object value)
- {
- // do not put null values to the matrix!
- if (value == null || value == DBNull.Value)
- return;
- AggregateBase aggregate = GetCell(columnIndex, rowIndex, true);
- aggregate.AddValue(value);
- }
- public object GetValue(int columnIndex, int rowIndex)
- {
- AggregateBase aggregate = GetCell(columnIndex, rowIndex, false);
- if (aggregate == null)
- return null;
- return aggregate.GetValue();
- }
- public void Merge(int sourceColumnIndex, int sourceRowIndex, int targetColumnIndex, int targetRowIndex)
- {
- AggregateBase sourceAggr = GetCell(sourceColumnIndex, sourceRowIndex, false);
- AggregateBase targetAggr = GetCell(targetColumnIndex, targetRowIndex, true);
- targetAggr.Merge(sourceAggr);
- }
- public CellDataStorage(Type aggregateType)
- {
- AggregateType = aggregateType;
- rows = new List<List<AggregateBase>>();
- }
- }
- }
- }
|