private SearchResponse ParseQueryResult(IReportsDataSource dataSource, IEnumerable <dynamic> queryResult, SearchRequest request, out long countResult)
        {
            var result = new SearchResponse();

            result.Data = new List <SearchResultRow>();
            countResult = 0;

            int rowIndex          = 1;
            var allColumnMappings = dataSource.GetColumnMappings(request.SelectedColumns);
            // need to preserve order
            var selectedColumnMappings = request.SelectedColumns.Select(x => allColumnMappings.First(y => y.Id == x.ColumnId)).ToList();

            foreach (dynamic doc in queryResult)
            {
                var data = new SearchResultRow();
                data.Values = new List <ResultColumnValue>();

                IDictionary <string, object> propertyValues = (IDictionary <string, object>)doc;

                foreach (var col in selectedColumnMappings)
                {
                    var columnAlias = dataSource.GetFieldAlias(col);
                    var displayName = dataSource.GetColumnDisplayName(col);

                    object value = null;

                    if (!propertyValues.ContainsKey(columnAlias))
                    {
                        result.DebugInfo.WarningMessages.Add(
                            String.Format(
                                "Cannot find the '{0}' column (column alias: '{1}') in the database query result set. It could be a column that's not allowed for this type of stats query. For example, the DateTime column can only be requested for stats queries that return timestamped data (e.g. queries with a daily temporal aggregation). Will set this value to null in the response data.",
                                displayName, columnAlias));
                    }
                    else
                    {
                        value = propertyValues[columnAlias];
                    }

                    data.Values.Add(new ResultColumnValue
                    {
                        ColumnId = col.Id,
                        Value    = value == null ? null : value.ToString(),
                        Name     = (request.DebugMode || rowIndex == 1) ? displayName : null
                    });
                }

                result.Data.Add(data);

                if (rowIndex == 1 && propertyValues.ContainsKey("_COUNT"))
                {
                    countResult = long.Parse(propertyValues["_COUNT"].ToString());
                }

                rowIndex++;
            }

            return(result);
        }
        private SearchResult GetPage(SearchRequest request, IReportsDataSource dataSource)
        {
            var page = sqlQueryExecutor.Search(dataSource, request);

            if (page != null && page.Data != null && page.Data.Any())
            {
                _renderFilterService.ApplyAllRenderFilters(dataSource, page);
            }
            return(page);
        }
Exemple #3
0
        private void ValidateQueryColumns(
            SearchRequest request,
            List <ColumnDefinition> knownColumns,
            IReportsDataSource dataSource)
        {
            var notFoundColumns = new List <SelectedColumn>();

            // check selected columns
            if (request.TextFilterColumns == null)
            {
                return;
            }

            // check if columns exist
            foreach (var selectedColumn in request.TextFilterColumns)
            {
                if (knownColumns.All(x => x.Id != selectedColumn.ColumnId))
                {
                    notFoundColumns.Add(selectedColumn);
                }
            }

            if (notFoundColumns.Any())
            {
                string errorMsg = "Requested query columns not recognised : ";
                foreach (var column in notFoundColumns)
                {
                    errorMsg += string.Format(" {0},", column.ColumnId);
                }
                errorMsg.TrimEnd(',');

                throw new Exception(errorMsg);
            }

            var columnMappings = dataSource.GetColumnMappings(request.TextFilterColumns);

            foreach (var selectedColumn in columnMappings)
            {
                if (!selectedColumn.DbType.IsStringType())
                {
                    throw new Exception("At least one of the requested text search query columns is not of type String.");
                }
            }
        }
Exemple #4
0
        public void ApplyAllRenderFilters(IReportsDataSource dataSource, SearchResult searchResult)
        {
            if (searchResult != null && searchResult.Data != null && searchResult.Data.Any())
            {
                var allFilters        = _renderFilterFactory.GetFilters();
                var selectedColumnIds = searchResult.Data.First().Values.Select(x => x.ColumnId);
                var allColumnMappings = dataSource.GetColumnProvider().GetColumnMappings(dataSource.DataSourceId, selectedColumnIds);

                foreach (var row in searchResult.Data)
                {
                    foreach (var cell in row.Values)
                    {
                        var mapping = allColumnMappings.FirstOrDefault(x => x.Id == cell.ColumnId);
                        if (mapping != null)
                        {
                            ApplyRenderFilters(allFilters, cell, mapping);
                        }
                    }
                }
            }
        }
        private List <SearchResultRow> LoadAllData(ref ReportStatus status, SearchRequest request, IReportsDataSource dataSource, LoopTimer <ReportStatus> loopTimer)
        {
            request.PageIndex = 0;
            request.GetCount  = true;

            // get the first page, with a count
            var page = GetPage(request, dataSource);

            var totalRows  = page.Summary.TotalRows;
            var totalPages = (int)Math.Ceiling((double)totalRows / request.PageSize);

            var result = page.Data;

            // getting count could have an impact on performance and is only needed for the first request
            request.GetCount = false;

            while (request.PageIndex + 1 < totalPages)
            {
                request.PageIndex++;
                page = GetPage(request, dataSource);
                if (page != null && page.Data != null && page.Data.Any())
                {
                    result.AddRange(page.Data);
                }

                status.ProgressPercentage = (int)Math.Floor(((double)100 / totalPages) * (request.PageIndex + 1) * Configuration.Exports.DataLoadPercent);

                loopTimer.Loop();
            }

            return(result);
        }
        public SearchResult Search(IReportsDataSource dataSource, SearchRequest request, bool doNotExecute = false)
        {
            var result = new SearchResult();
            var searchResultSummary = new SearchResultSummary();

            var           query         = new SqlModeller.Model.Query();
            CompiledQuery compiledQuery = null;
            string        sql           = null;

            if (request.SelectedColumns == null || !request.SelectedColumns.Any())
            {
                throw new Exception("No Columns Selected");
            }
            try
            {
                using (new QuickTimer(x => searchResultSummary.BuildQueryElapsedMilliseconds = x))
                {
                    long mapTime;
                    query = dataSource.BuildQuery(request, out mapTime);
                    searchResultSummary.MapRequestElapsedMilliseconds = mapTime;
                }

                long countResult = 0;

                using (new QuickTimer(x => searchResultSummary.CompileQueryElapsedMilliseconds = x))
                {
                    compiledQuery = query.Compile();
                }

                // add OPTION (RECOMPILE) to combat parameter sniffing slowness
                sql = compiledQuery.Sql + "\n OPTION (RECOMPILE) ";

                DynamicParameters sqlParams = null;
                if (compiledQuery.Parameters != null)
                {
                    sqlParams = new DynamicParameters();
                    foreach (var p in compiledQuery.Parameters)
                    {
                        sqlParams.Add(p.ParameterName, p.Value, p.DataType);
                    }
                }

                if (!doNotExecute)
                {
                    using (var connection = ConnectionFactory.GetOpenConnectionUsingConnectionStringName(dataSource.ConnectionStringName))
                    {
                        Debug.WriteLine(compiledQuery.ToString());
                        IEnumerable <dynamic> queryResult;

                        using (new QuickTimer(x => searchResultSummary.QueryElapsedMilliseconds = x))
                        {
                            using (var tran = connection.BeginTransaction(IsolationLevel.ReadUncommitted))
                            {
                                queryResult = connection.Query(sql, sqlParams, tran, commandTimeout: sqlCommandTimeoutSeconds);
                                tran.Commit();
                            }
                        }

                        using (new QuickTimer(x => searchResultSummary.ParseResultElapsedMilliseconds = x))
                        {
                            result = ParseQueryResult(dataSource, queryResult, request, out countResult);
                        }
                    }
                }

                searchResultSummary.TotalRows = countResult;
                result.Summary = searchResultSummary;
            }
            catch (Exception ex)
            {
                result = new SearchResponse()
                {
                    Error = new ResponseError().Load(ex)
                };
            }

            try
            {
                result.DebugInfo.SqlQuery = compiledQuery.ParameterSql + "\n\n" + sql;
            }
            catch
            {
            }

            return(result);
        }