/// <summary> /// Return a view model containing a sorted list of crashes based on the user input. /// </summary> /// <param name="FormData">The user input from the client.</param> /// <returns>A view model to use to display a list of crashes.</returns> /// <remarks>The filtering mechanism works by generating a fluent query to describe the set of crashes we wish to view. Basically, 'Select.Where().Where().Where().Where()' etc. /// The filtering is applied in the following order: /// 1. Get all crashes. /// 2. Filter between the start and end dates. /// 3. Apply the search query. /// 4. Filter by the branch. /// 5. Filter by the game name. /// 6. Filter by the type of reports to view. /// 7. Filter by the user group. /// 8. Sort the results by the sort term. /// 9. Take one page of results.</remarks> public CrashesViewModel GetResults(FormHelper FormData) { using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString())) { UsersMapping UniqueUser = null; IEnumerable <Crash> Results = null; int Skip = (FormData.Page - 1) * FormData.PageSize; int Take = FormData.PageSize; var ResultsAll = ConstructQueryForFiltering(FormData); // Filter by data and get as enumerable. Results = FilterByDate(ResultsAll, FormData.DateFrom, FormData.DateTo); // Filter by BuggId if (!string.IsNullOrEmpty(FormData.BuggId)) { int BuggId = 0; bool bValid = int.TryParse(FormData.BuggId, out BuggId); if (bValid) { BuggRepository Buggs = new BuggRepository(); Bugg NewBugg = Buggs.GetBugg(BuggId); if (NewBugg != null) { List <Crash> Crashes = NewBugg.GetCrashes(); var NewResult = Results.Intersect(Crashes, new CrashComparer()); Results = NewResult; } } } // Get UserGroup ResultCounts Dictionary <string, int> GroupCounts = GetCountsByGroupFromCrashes(Results); // Filter by user group if present int UserGroupId; if (!string.IsNullOrEmpty(FormData.UserGroup)) { UserGroupId = FRepository.Get(this).FindOrAddGroup(FormData.UserGroup); } else { UserGroupId = 1; } HashSet <int> UserIdsForGroup = FRepository.Get(this).GetUserIdsFromUserGroupId(UserGroupId); using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.Results.Users")) { List <Crash> NewResults = new List <Crash>(); foreach (Crash Crash in Results) { if (UserIdsForGroup.Contains(Crash.UserNameId.Value)) { NewResults.Add(Crash); } } Results = NewResults; } // Pass in the results and return them sorted properly Results = GetSortedResults(Results, FormData.SortTerm, (FormData.SortOrder == "Descending")); // Get the Count for pagination int ResultCount = 0; using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.Results.Users")) { ResultCount = Results.Count(); } // Grab just the results we want to display on this page Results = Results.Skip(Skip).Take(Take); using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.GetResults.GetCallstacks")) { // Process call stack for display foreach (Crash CrashInstance in Results) { // Put callstacks into an list so we can access them line by line in the view CrashInstance.CallStackContainer = GetCallStack(CrashInstance); } } return(new CrashesViewModel { Results = Results, PagingInfo = new PagingInfo { CurrentPage = FormData.Page, PageSize = FormData.PageSize, TotalResults = ResultCount }, SortOrder = FormData.SortOrder, SortTerm = FormData.SortTerm, UserGroup = FormData.UserGroup, CrashType = FormData.CrashType, SearchQuery = FormData.SearchQuery, UsernameQuery = FormData.UsernameQuery, EpicIdOrMachineQuery = FormData.EpicIdOrMachineQuery, MessageQuery = FormData.MessageQuery, BuiltFromCL = FormData.BuiltFromCL, BuggId = FormData.BuggId, JiraQuery = FormData.JiraQuery, DateFrom = (long)(FormData.DateFrom - CrashesViewModel.Epoch).TotalMilliseconds, DateTo = (long)(FormData.DateTo - CrashesViewModel.Epoch).TotalMilliseconds, BranchName = FormData.BranchName, VersionName = FormData.VersionName, PlatformName = FormData.PlatformName, GameName = FormData.GameName, GroupCounts = GroupCounts, RealUserName = UniqueUser != null?UniqueUser.ToString() : null, }); } }
/// <summary> /// Return a view model containing a sorted list of crashes based on the user input. /// </summary> /// <param name="FormData">The user input from the client.</param> /// <returns>A view model to use to display a list of crashes.</returns> /// <remarks>The filtering mechanism works by generating a fluent query to describe the set of crashes we wish to view. Basically, 'Select.Where().Where().Where().Where()' etc. /// The filtering is applied in the following order: /// 1. Get all crashes. /// 2. Filter between the start and end dates. /// 3. Apply the search query. /// 4. Filter by the branch. /// 5. Filter by the game name. /// 6. Filter by the type of reports to view. /// 7. Filter by the user group. /// 8. Sort the results by the sort term. /// 9. Take one page of results.</remarks> public CrashesViewModel GetResults(FormHelper FormData) { using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString())) { UsersMapping UniqueUser = null; IQueryable <Crash> Results = null; int Skip = (FormData.Page - 1) * FormData.PageSize; int Take = FormData.PageSize; Results = ListAll(); Results = FilterByDate(Results, FormData.DateFrom, FormData.DateTo); // Grab Results if (!string.IsNullOrEmpty(FormData.SearchQuery)) { string DecodedQuery = HttpUtility.HtmlDecode(FormData.SearchQuery).ToLower(); using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("CrashRepository.GetResults.FindUserFromQuery" + "(Query=" + DecodedQuery + ")")) { if (!string.IsNullOrEmpty(DecodedQuery)) { // Check if we are looking for user name. string[] Params = DecodedQuery.Split(new string[] { "user:"******"SELECT * FROM [analyticsdb-01.dmz.epicgames.net].[CrashReport].[dbo].[UsersMapping] WHERE lower(UserName) = {0} OR lower(UserEmail) = {0}", Params[1]); foreach (UsersMapping TheUser in FoundUsers) { UniqueUser = TheUser; break; } if (UniqueUser != null) { Results = Results.Where(CrashInstance => CrashInstance.EpicAccountId == UniqueUser.EpicAccountId); } else { Results = Results.Where(CrashInstance => CrashInstance.EpicAccountId == "SomeValueThatIsNotPresentInTheDatabase"); } } else { Results = Search(Results, DecodedQuery); } } } } // Start Filtering the results // Filter by BranchName if (!string.IsNullOrEmpty(FormData.BranchName)) { if (FormData.BranchName.StartsWith("-")) { Results = ( from CrashDetail in Results where !CrashDetail.Branch.Contains(FormData.BranchName.Substring(1)) select CrashDetail ); } else { Results = ( from CrashDetail in Results where CrashDetail.Branch.Contains(FormData.BranchName) select CrashDetail ); } } // Filter by GameName if (!string.IsNullOrEmpty(FormData.GameName)) { if (FormData.GameName.StartsWith("-")) { Results = ( from CrashDetail in Results where !CrashDetail.GameName.Contains(FormData.GameName.Substring(1)) select CrashDetail ); } else { Results = ( from CrashDetail in Results where CrashDetail.GameName.Contains(FormData.GameName) select CrashDetail ); } } // Filter by Crash Type if (FormData.CrashType != "All") { switch (FormData.CrashType) { case "Crashes": Results = Results.Where(CrashInstance => CrashInstance.CrashType == 1); break; case "Assert": Results = Results.Where(CrashInstance => CrashInstance.CrashType == 2); break; case "Ensure": Results = Results.Where(CrashInstance => CrashInstance.CrashType == 3); break; case "CrashesAsserts": Results = Results.Where(CrashInstance => CrashInstance.CrashType == 1 || CrashInstance.CrashType == 2); break; } } // Get UserGroup ResultCounts Dictionary <string, int> GroupCounts = GetCountsByGroupFromCrashes(Results); // Filter by user group if present int UserGroupId; if (!string.IsNullOrEmpty(FormData.UserGroup)) { UserGroupId = FindOrAddUserGroup(FormData.UserGroup); } else { UserGroupId = 1; } Results = ( from CrashDetail in Results from UserDetail in CrashRepositoryDataContext.Users where UserDetail.UserGroupId == UserGroupId && (CrashDetail.UserNameId == UserDetail.Id || CrashDetail.UserName == UserDetail.UserName) select CrashDetail ); // Pass in the results and return them sorted properly Results = GetSortedResults(Results, FormData.SortTerm, (FormData.SortOrder == "Descending")); // Get the Count for pagination int ResultCount = Results.Count(); // Grab just the results we want to display on this page Results = Results.Skip(Skip).Take(Take); using (FScopedLogTimer LogTimer3 = new FScopedLogTimer("CrashRepository.GetResults.GetCallstacks")) { // Process call stack for display foreach (Crash CrashInstance in Results) { // Put callstacks into an list so we can access them line by line in the view CrashInstance.CallStackContainer = GetCallStack(CrashInstance); } } return(new CrashesViewModel { Results = Results, PagingInfo = new PagingInfo { CurrentPage = FormData.Page, PageSize = FormData.PageSize, TotalResults = ResultCount }, SortOrder = FormData.SortOrder, SortTerm = FormData.SortTerm, UserGroup = FormData.UserGroup, CrashType = FormData.CrashType, SearchQuery = FormData.SearchQuery, DateFrom = (long)(FormData.DateFrom - CrashesViewModel.Epoch).TotalMilliseconds, DateTo = (long)(FormData.DateTo - CrashesViewModel.Epoch).TotalMilliseconds, BranchName = FormData.BranchName, GameName = FormData.GameName, GroupCounts = GroupCounts, RealUserName = UniqueUser != null?UniqueUser.ToString() : null, }); } }