private PreparedQuery PrepareReportRollupRun(Model.Report report, StructuredQuery structuredQuery, ReportSettings reportSettings, QuerySettings nonRollupQuerySettings) { StructuredQuery rollupQuery = null; ClientAggregate clientAggregate = null; StructuredQuery optimisedQuery; QuerySettings rollupSettings; bool adhocRollup; bool reportRollup; adhocRollup = reportSettings.ReportParameters != null && reportSettings.ReportParameters.GroupAggregateRules != null; reportRollup = !adhocRollup && report.ReportColumns.Any(rc => rc.ColumnRollup.Count > 0 || rc.ColumnGrouping.Count > 0); if (adhocRollup) { clientAggregate = ApplyAdhocAggregates(reportSettings.ReportParameters.GroupAggregateRules, structuredQuery); } else if (reportRollup) { clientAggregate = new ClientAggregate(report, structuredQuery); clientAggregate.IncludeRollup = true; } else if (report.RollupGrandTotals != null || report.RollupSubTotals != null || report.RollupOptionLabels != null) { return(new PreparedQuery { ClientAggregate = new ClientAggregate( ) }); } else { return(new PreparedQuery( )); } // Clone the query, so that runs and rollups won't intefere with each others caches if they mutate the structure // In particular, calculated columns get evaluated during execution and mutate the query .. but only if the result doesn't come from cache, but this interferes with the rollup cache key. // Ideally, both calculations and optimisations would be provided in layers, and both applied, and cached, before either normal or rollup executions are run. rollupQuery = structuredQuery.DeepCopy( ); // A poor proxy for determining that this is not a pivot chart. bool isGroupedReport = !(reportSettings.ReportParameters != null && reportSettings.ReportParameters.GroupAggregateRules != null && reportSettings.ReportParameters.GroupAggregateRules.IgnoreRows); if (isGroupedReport) { ReportRollupHelper.EnsureShowTotalsHasCount(rollupQuery, clientAggregate); } // Remove unused columns bool supportQuickSearch = !string.IsNullOrWhiteSpace(reportSettings.QuickSearch); optimisedQuery = ReportRollupHelper.RemoveUnusedColumns(rollupQuery, clientAggregate, supportQuickSearch); rollupSettings = new QuerySettings { SecureQuery = nonRollupQuerySettings.SecureQuery, SupportClientAggregate = true, SupportPaging = false, QuickSearchTerm = reportSettings.QuickSearch, SupportQuickSearch = supportQuickSearch, // rollups query support quick search. ClientAggregate = clientAggregate, AdditionalOrderColumns = BuildAdditionOrderColumnDictionary(optimisedQuery, clientAggregate), FullAggregateClustering = true, Hint = "RptRollup-" + report.Id, TargetResource = nonRollupQuerySettings.TargetResource, IncludeResources = nonRollupQuerySettings.IncludeResources, ExcludeResources = nonRollupQuerySettings.ExcludeResources }; // Note : do not apply quick search filter to rollups (for scalability reasons) PreparedQuery preparedQuery = new PreparedQuery { ClientAggregate = clientAggregate, StructuredQuery = optimisedQuery, QuerySettings = rollupSettings }; return(preparedQuery); }
/// <summary> /// Applies report settings to the structured query and also builds an appropriate query settings object. /// </summary> /// <param name="structuredQuery"></param> /// <param name="queryReportSettings"></param> /// <returns></returns> private static PreparedQuery PrepareReportRun(StructuredQuery structuredQuery, ReportSettings queryReportSettings) { QuerySettings querySettings; // Build the query engine settings bool secureReports; if (!_cachedSecureReports.HasValue) { DatabaseConfiguration dbConfiguration; dbConfiguration = ConfigurationSettings.GetDatabaseConfigurationSection( ); if (dbConfiguration != null) { _cachedSecureReports = dbConfiguration.ConnectionSettings.SecureReports; } } secureReports = _cachedSecureReports.Value; // Set the time zone for the report if (queryReportSettings.Timezone != null) { structuredQuery.TimeZoneName = queryReportSettings.Timezone.StandardName; } // Update the query engine settings querySettings = new QuerySettings { SecureQuery = secureReports, SupportPaging = queryReportSettings.SupportPaging, FirstRow = queryReportSettings.InitialRow, PageSize = queryReportSettings.PageSize, QuickSearchTerm = queryReportSettings.QuickSearch, SupportQuickSearch = !string.IsNullOrWhiteSpace(queryReportSettings.QuickSearch), FullAggregateClustering = true, RefreshCachedResult = queryReportSettings.RefreshCachedResult, RefreshCachedSql = queryReportSettings.RefreshCachedSql, CpuLimitSeconds = queryReportSettings.CpuLimitSeconds }; if (queryReportSettings.ReportOnType.HasValue) { Model.IEntity typeEntity = Model.Entity.Get <Model.EntityType>(queryReportSettings.ReportOnType); if (typeEntity == null) { throw new WebArgumentException("Not a valid type"); } (( ResourceEntity )structuredQuery.RootEntity).EntityTypeId = queryReportSettings.ReportOnType.Value; } if (queryReportSettings.ReportParameters != null) { // Apply any filters for analyser if (queryReportSettings.ReportParameters.AnalyserConditions != null && queryReportSettings.ReportParameters.AnalyserConditions.Count > 0) { ApplyAnalyserConditions(structuredQuery, queryReportSettings.ReportParameters.AnalyserConditions); } // Apply any filters for sorting if (queryReportSettings.ReportParameters.SortColumns != null) { ApplySortOrder(structuredQuery, queryReportSettings.ReportParameters.SortColumns); } // Determine if main row report is to be ignored querySettings.ResultSchemaOnly = queryReportSettings.ReportParameters.GroupAggregateRules != null && queryReportSettings.ReportParameters.GroupAggregateRules.IgnoreRows; } if (queryReportSettings.ReportRelationship != null) { ApplyRelatedResourceCondition(structuredQuery, queryReportSettings.ReportRelationship, querySettings); } if (queryReportSettings.RelatedEntityFilters != null) { ApplyRelatedEntityFilters(structuredQuery, queryReportSettings.RelatedEntityFilters); } if (queryReportSettings.FilteredEntityIdentifiers != null && queryReportSettings.FilteredEntityIdentifiers.Count > 0) { ApplyFilteredEntityIdentifiers(structuredQuery, queryReportSettings.FilteredEntityIdentifiers); } PreparedQuery preparedQuery = new PreparedQuery { QuerySettings = querySettings, StructuredQuery = structuredQuery }; return(preparedQuery); }