Пример #1
0
        protected TransformResults Transform(CancellationToken cancellationToken, DataSchema dataSchema, TransformResults input,
                                             TransformStack transformStack)
        {
            if (transformStack == null || transformStack.StackIndex >= transformStack.RowTransforms.Count)
            {
                return(input);
            }
            cancellationToken.ThrowIfCancellationRequested();
            if (transformStack.Predecessor != null)
            {
                input = Transform(cancellationToken, dataSchema, input, transformStack.Predecessor);
            }
            var filter = transformStack.CurrentTransform as RowFilter;

            if (filter != null)
            {
                var filteredRows = new PivotedRows(Filter(cancellationToken, dataSchema, filter, input.PivotedRows),
                                                   input.PivotedRows.ItemProperties);
                filteredRows = Sort(cancellationToken, dataSchema, filter, filteredRows);
                return(new TransformResults(input, filter, filteredRows));
            }
            var pivotSpec = transformStack.CurrentTransform as PivotSpec;

            if (pivotSpec != null)
            {
                var pivotedRows = GroupAndTotaler.GroupAndTotal(cancellationToken, dataSchema, pivotSpec, input.PivotedRows);
                return(new TransformResults(input, pivotSpec, pivotedRows));
            }
            return(input);
        }
Пример #2
0
 public QueryResults SetPivotedRows(PivotedRows pivotedRows)
 {
     return(new QueryResults(this)
     {
         PivotedRows = pivotedRows.RowItems,
         ItemProperties = pivotedRows.ItemProperties,
     });
 }
Пример #3
0
        public static PivotedRows GroupAndTotal(CancellationToken cancellationToken, DataSchema dataSchema,
                                                PivotSpec pivotSpec, PivotedRows input)
        {
            if (pivotSpec.IsEmpty)
            {
                return(input);
            }
            var groupAndTotaller = new GroupAndTotaler(cancellationToken, dataSchema, pivotSpec, input.ItemProperties);
            var newProperties    = new List <DataPropertyDescriptor>();
            var newRows          = ImmutableList.ValueOf(groupAndTotaller.GroupAndTotal(input.RowItems, newProperties));

            return(new PivotedRows(newRows, newProperties));
        }
Пример #4
0
        public PivotedRows ExpandAndPivot(TickCounter tickCounter, IEnumerable <RowItem> rowItems)
        {
            var expandedItems = rowItems.SelectMany(rowItem => Expand(tickCounter, rowItem, 0)).ToArray();
            var pivotedItems  = expandedItems.Select(item => Pivot(tickCounter, item));
            var filteredItems = Filter(pivotedItems);
            var rows          = ImmutableList.ValueOf(filteredItems);
            var result        = new PivotedRows(rows, new PropertyDescriptorCollection(GetItemProperties(rows).ToArray()));

            if (ViewInfo.HasTotals)
            {
                result = GroupAndTotal(tickCounter, result);
            }
            return(result);
        }
Пример #5
0
        public PivotedRows ExpandAndPivot(CancellationToken cancellationToken, IEnumerable <RowItem> rowItems)
        {
            var expandedItems = rowItems.SelectMany(rowItem => Expand(cancellationToken, rowItem, 0)).ToArray();
            var pivotedItems  = expandedItems.Select(item => Pivot(cancellationToken, item));
            var filteredItems = Filter(cancellationToken, pivotedItems);
            var rows          = ImmutableList.ValueOf(filteredItems);
            var result        = new PivotedRows(rows, GetItemProperties(rows));

            if (ViewInfo.HasTotals)
            {
                result = GroupAndTotal(cancellationToken, result);
            }
            return(result);
        }
Пример #6
0
        protected PivotedRows Sort(CancellationToken cancellationToken, DataSchema dataSchema, RowFilter rowFilter,
                                   PivotedRows pivotedRows)
        {
            if (rowFilter.ColumnSorts.Count == 0)
            {
                return(pivotedRows);
            }
            var sortDescriptions = rowFilter.GetListSortDescriptionCollection(pivotedRows.ItemProperties);

            if (sortDescriptions.Count == 0)
            {
                return(pivotedRows);
            }
            return(pivotedRows.ChangeRowItems(Sort(cancellationToken, dataSchema, sortDescriptions, pivotedRows)));
        }
Пример #7
0
        protected IEnumerable <RowItem> Filter(CancellationToken cancellationToken, DataSchema dataSchema, RowFilter filter, PivotedRows pivotedRows)
        {
            if (filter.IsEmptyFilter)
            {
                return(pivotedRows.RowItems);
            }
            var properties = pivotedRows.ItemProperties;

            Predicate <object>[] columnPredicates = new Predicate <object> [properties.Count];

            for (int i = 0; i < properties.Count; i++)
            {
                columnPredicates[i] = filter.GetPredicate(dataSchema, properties[i]);
            }
            var filteredRows = new List <RowItem>();
            // toString on an enum is incredibly slow, so we cache the results in
            // in a dictionary.
            var toStringCaches = new Dictionary <object, string> [properties.Count];

            for (int i = 0; i < properties.Count; i++)
            {
                var property = properties[i];
                if (property.PropertyType.IsEnum)
                {
                    toStringCaches[i] = new Dictionary <object, string>();
                }
            }

            foreach (var row in pivotedRows.RowItems)
            {
                bool matchesText   = string.IsNullOrEmpty(filter.Text);
                bool matchesFilter = true;
                for (int iProperty = 0; iProperty < properties.Count; iProperty++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var predicate = columnPredicates[iProperty];
                    if (matchesText && null == predicate)
                    {
                        continue;
                    }
                    var property = properties[iProperty];
                    var value    = property.GetValue(row);
                    if (!matchesText && value != null)
                    {
                        var    cache = toStringCaches[iProperty];
                        string strValue;
                        if (cache == null)
                        {
                            strValue = value.ToString();
                        }
                        else
                        {
                            if (!cache.TryGetValue(value, out strValue))
                            {
                                strValue = value.ToString();
                                cache.Add(value, strValue);
                            }
                        }
                        if (filter.MatchesText(strValue))
                        {
                            matchesText = true;
                        }
                    }
                    matchesFilter = null == predicate || predicate(value);
                    if (!matchesFilter)
                    {
                        break;
                    }
                }
                if (matchesText && matchesFilter)
                {
                    filteredRows.Add(row);
                }
            }

            if (filteredRows.Count == pivotedRows.RowItems.Count)
            {
                return(pivotedRows.RowItems);
            }
            return(filteredRows);
        }
Пример #8
0
        protected IEnumerable <RowItem> Sort(CancellationToken cancellationToken, DataSchema dataSchema, ListSortDescriptionCollection sortDescriptions, PivotedRows pivotedRows)
        {
            var unsortedRows = pivotedRows.RowItems;

            if (sortDescriptions == null || sortDescriptions.Count == 0)
            {
                return(unsortedRows);
            }
            var sortRows = new SortRow[unsortedRows.Count];

            for (int iRow = 0; iRow < sortRows.Length; iRow++)
            {
                sortRows[iRow] = new SortRow(cancellationToken, dataSchema, sortDescriptions, unsortedRows[iRow], iRow);
            }
            Array.Sort(sortRows);
            return(Array.AsReadOnly(sortRows.Select(sr => sr.RowItem).ToArray()));
        }
Пример #9
0
 public PivotedRows GroupAndTotal(TickCounter tickCounter, PivotedRows pivotedRows)
 {
     IDictionary<IList<Tuple<PropertyPath, PivotKey, object>>, List<GroupedRow>> allReportRows
         = new Dictionary<IList<Tuple<PropertyPath, PivotKey, object>>, List<GroupedRow>>();
     var groupColumns = ViewInfo.DisplayColumns
         .Where(col => TotalOperation.GroupBy == col.ColumnSpec.TotalOperation)
         .Select(col => col.ColumnDescriptor)
         .ToArray();
     var pivotOnColumns = ViewInfo.DisplayColumns
         .Where(col => TotalOperation.PivotKey == col.ColumnSpec.TotalOperation)
         .Select(col => col.ColumnDescriptor)
         .ToArray();
     var allInnerPivotKeys = new HashSet<PivotKey>();
     var allPivotKeys = new Dictionary<PivotKey, PivotKey>();
     foreach (var rowItem in pivotedRows.RowItems)
     {
         allInnerPivotKeys.UnionWith(rowItem.PivotKeys);
         IList<Tuple<PropertyPath, PivotKey, object>> groupKey = new List<Tuple<PropertyPath, PivotKey, object>>();
         foreach (var column in groupColumns)
         {
             var pivotColumn = GetPivotColumn(column);
             if (null == pivotColumn)
             {
                 groupKey.Add(new Tuple<PropertyPath, PivotKey, object>(column.PropertyPath, null,
                     column.GetPropertyValue(rowItem, null)));
             }
             else
             {
                 foreach (var pivotKey in GetPivotKeys(pivotColumn.PropertyPath, new []{rowItem}))
                 {
                     if (!pivotKey.Contains(pivotColumn.PropertyPath))
                     {
                         continue;
                     }
                     groupKey.Add(new Tuple<PropertyPath, PivotKey, object>(column.PropertyPath, pivotKey, column.GetPropertyValue(rowItem, pivotKey)));
                 }
             }
         }
         groupKey = ImmutableList.ValueOf(groupKey);
         var pivotOnKeyValues = new List<KeyValuePair<PropertyPath, object>>();
         foreach (var column in pivotOnColumns)
         {
             var pivotColumn = GetPivotColumn(column);
             if (null == pivotColumn)
             {
                 pivotOnKeyValues.Add(new KeyValuePair<PropertyPath, object>(column.PropertyPath,
                     column.GetPropertyValue(rowItem, null)));
             }
             else
             {
                 Trace.TraceWarning("Unable to pivot on column {0} because it is already pivoted.", pivotColumn.PropertyPath); // Not L10N
             }
         }
         var pivotOnKey = PivotKey.GetPivotKey(allPivotKeys, pivotOnKeyValues);
         List<GroupedRow> rowGroups;
         if (!allReportRows.TryGetValue(groupKey, out rowGroups))
         {
             rowGroups = new List<GroupedRow>();
             allReportRows.Add(groupKey, rowGroups);
         }
         var rowGroup = rowGroups.FirstOrDefault(rg => !rg.ContainsKey(pivotOnKey));
         if (null == rowGroup)
         {
             rowGroup = new GroupedRow();
             rowGroups.Add(rowGroup);
         }
         rowGroup.AddInnerRow(pivotOnKey, rowItem);
     }
     var outerPivotKeys = allPivotKeys.Keys.Where(key=>key.Length == pivotOnColumns.Length).ToArray();
     var pivotKeyComparer = PivotKey.GetComparer(ViewInfo.DataSchema);
     Array.Sort(outerPivotKeys, pivotKeyComparer);
     var innerPivotKeys = allInnerPivotKeys.ToArray();
     Array.Sort(innerPivotKeys, pivotKeyComparer);
     var reportItemProperties = new List<PropertyDescriptor>();
     var propertyNames = new HashSet<string>();
     foreach (var displayColumn in ViewInfo.DisplayColumns)
     {
         if (displayColumn.ColumnSpec.Hidden)
         {
             continue;
         }
         var totalOperation = displayColumn.ColumnSpec.TotalOperation;
         if (TotalOperation.GroupBy == totalOperation)
         {
             var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor);
             if (null == pivotColumn)
             {
                 string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                 reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, null));
             }
             else
             {
                 foreach (var innerPivotKey in innerPivotKeys)
                 {
                     string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                     reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, innerPivotKey));
                 }
             }
         }
     }
     foreach (var outerPivotKey in outerPivotKeys)
     {
         foreach (var displayColumn in ViewInfo.DisplayColumns)
         {
             if (displayColumn.ColumnSpec.Hidden)
             {
                 continue;
             }
             if (TotalOperation.PivotValue == displayColumn.ColumnSpec.TotalOperation || TotalOperation.PivotKey == displayColumn.ColumnSpec.TotalOperation)
             {
                 var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor);
                 if (null == pivotColumn)
                 {
                     string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                     reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, null));
                 }
                 else
                 {
                     foreach (var innerPivotKey in allInnerPivotKeys)
                     {
                         string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                         reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, innerPivotKey));
                     }
                 }
             }
         }
     }
     return new PivotedRows(allReportRows.SelectMany(entry=>entry.Value.Select(
         reportRow=>new RowItem(reportRow))), 
         new PropertyDescriptorCollection(reportItemProperties.ToArray()));
 }
Пример #10
0
 public PivotedRows ExpandAndPivot(TickCounter tickCounter, IEnumerable<RowItem> rowItems)
 {
     var expandedItems = rowItems.SelectMany(rowItem => Expand(tickCounter, rowItem, 0)).ToArray();
     var pivotedItems = expandedItems.Select(item => Pivot(tickCounter, item));
     var filteredItems = Filter(pivotedItems);
     var rows = ImmutableList.ValueOf(filteredItems);
     var result = new PivotedRows(rows, new PropertyDescriptorCollection(GetItemProperties(rows).ToArray()));
     if (ViewInfo.HasTotals)
     {
         result = GroupAndTotal(tickCounter, result);
     }
     return result;
 }
Пример #11
0
 public QueryResults SetPivotedRows(PivotedRows pivotedRows)
 {
     return new QueryResults(this)
                {
                    PivotedRows = pivotedRows.RowItems,
                    ItemProperties = pivotedRows.ItemProperties,
                };
 }
Пример #12
0
        public PivotedRows GroupAndTotal(TickCounter tickCounter, PivotedRows pivotedRows)
        {
            IDictionary <IList <Tuple <PropertyPath, PivotKey, object> >, List <GroupedRow> > allReportRows
                = new Dictionary <IList <Tuple <PropertyPath, PivotKey, object> >, List <GroupedRow> >();
            var groupColumns = ViewInfo.DisplayColumns
                               .Where(col => TotalOperation.GroupBy == col.ColumnSpec.TotalOperation)
                               .Select(col => col.ColumnDescriptor)
                               .ToArray();
            var pivotOnColumns = ViewInfo.DisplayColumns
                                 .Where(col => TotalOperation.PivotKey == col.ColumnSpec.TotalOperation)
                                 .Select(col => col.ColumnDescriptor)
                                 .ToArray();
            var allInnerPivotKeys = new HashSet <PivotKey>();
            var allPivotKeys      = new Dictionary <PivotKey, PivotKey>();

            foreach (var rowItem in pivotedRows.RowItems)
            {
                allInnerPivotKeys.UnionWith(rowItem.PivotKeys);
                IList <Tuple <PropertyPath, PivotKey, object> > groupKey = new List <Tuple <PropertyPath, PivotKey, object> >();
                foreach (var column in groupColumns)
                {
                    var pivotColumn = GetPivotColumn(column);
                    if (null == pivotColumn)
                    {
                        groupKey.Add(new Tuple <PropertyPath, PivotKey, object>(column.PropertyPath, null,
                                                                                column.GetPropertyValue(rowItem, null)));
                    }
                    else
                    {
                        foreach (var pivotKey in GetPivotKeys(pivotColumn.PropertyPath, new [] { rowItem }))
                        {
                            if (!pivotKey.Contains(pivotColumn.PropertyPath))
                            {
                                continue;
                            }
                            groupKey.Add(new Tuple <PropertyPath, PivotKey, object>(column.PropertyPath, pivotKey, column.GetPropertyValue(rowItem, pivotKey)));
                        }
                    }
                }
                groupKey = ImmutableList.ValueOf(groupKey);
                var pivotOnKeyValues = new List <KeyValuePair <PropertyPath, object> >();
                foreach (var column in pivotOnColumns)
                {
                    var pivotColumn = GetPivotColumn(column);
                    if (null == pivotColumn)
                    {
                        pivotOnKeyValues.Add(new KeyValuePair <PropertyPath, object>(column.PropertyPath,
                                                                                     column.GetPropertyValue(rowItem, null)));
                    }
                    else
                    {
                        Trace.TraceWarning("Unable to pivot on column {0} because it is already pivoted.", pivotColumn.PropertyPath); // Not L10N
                    }
                }
                var pivotOnKey = PivotKey.GetPivotKey(allPivotKeys, pivotOnKeyValues);
                List <GroupedRow> rowGroups;
                if (!allReportRows.TryGetValue(groupKey, out rowGroups))
                {
                    rowGroups = new List <GroupedRow>();
                    allReportRows.Add(groupKey, rowGroups);
                }
                var rowGroup = rowGroups.FirstOrDefault(rg => !rg.ContainsKey(pivotOnKey));
                if (null == rowGroup)
                {
                    rowGroup = new GroupedRow();
                    rowGroups.Add(rowGroup);
                }
                rowGroup.AddInnerRow(pivotOnKey, rowItem);
            }
            var outerPivotKeys   = allPivotKeys.Keys.Where(key => key.Length == pivotOnColumns.Length).ToArray();
            var pivotKeyComparer = PivotKey.GetComparer(ViewInfo.DataSchema);

            Array.Sort(outerPivotKeys, pivotKeyComparer);
            var innerPivotKeys = allInnerPivotKeys.ToArray();

            Array.Sort(innerPivotKeys, pivotKeyComparer);
            var reportItemProperties = new List <PropertyDescriptor>();
            var propertyNames        = new HashSet <string>();

            foreach (var displayColumn in ViewInfo.DisplayColumns)
            {
                if (displayColumn.ColumnSpec.Hidden)
                {
                    continue;
                }
                var totalOperation = displayColumn.ColumnSpec.TotalOperation;
                if (TotalOperation.GroupBy == totalOperation)
                {
                    var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor);
                    if (null == pivotColumn)
                    {
                        string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                        reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, null));
                    }
                    else
                    {
                        foreach (var innerPivotKey in innerPivotKeys)
                        {
                            string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                            reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, innerPivotKey));
                        }
                    }
                }
            }
            foreach (var outerPivotKey in outerPivotKeys)
            {
                foreach (var displayColumn in ViewInfo.DisplayColumns)
                {
                    if (displayColumn.ColumnSpec.Hidden)
                    {
                        continue;
                    }
                    if (TotalOperation.PivotValue == displayColumn.ColumnSpec.TotalOperation || TotalOperation.PivotKey == displayColumn.ColumnSpec.TotalOperation)
                    {
                        var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor);
                        if (null == pivotColumn)
                        {
                            string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                            reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, null));
                        }
                        else
                        {
                            foreach (var innerPivotKey in allInnerPivotKeys)
                            {
                                string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                                reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, innerPivotKey));
                            }
                        }
                    }
                }
            }
            return(new PivotedRows(allReportRows.SelectMany(entry => entry.Value.Select(
                                                                reportRow => new RowItem(reportRow))),
                                   new PropertyDescriptorCollection(reportItemProperties.ToArray())));
        }