/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show(FormCollection BuggsForm, int id) { using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString() + "(BuggId=" + id + ")", bCreateNewLog: true)) { // Handle 'CopyToJira' button int BuggIDToBeAddedToJira = 0; foreach (var Entry in BuggsForm) { if (Entry.ToString().Contains(Bugg.JiraSubmitName)) { int.TryParse(Entry.ToString().Substring(Bugg.JiraSubmitName.Length), out BuggIDToBeAddedToJira); break; } } BuggRepository Buggs = new BuggRepository(); // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if (BuggsForm["DisplayModuleNames"] == "true") { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if (BuggsForm["DisplayFunctionNames"] == "true") { DisplayFunctionNames = true; } bool DisplayFileNames = false; if (BuggsForm["DisplayFileNames"] == "true") { DisplayFileNames = true; } bool DisplayFilePathNames = false; if (BuggsForm["DisplayFilePathNames"] == "true") { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if (BuggsForm["DisplayUnformattedCallStack"] == "true") { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List <Crash> Crashes = null; BuggViewModel Model = new BuggViewModel(); Bugg NewBugg = Buggs.GetBugg(id); if (NewBugg == null) { return(RedirectToAction("")); } Crashes = NewBugg.GetCrashes(); using (FAutoScopedLogTimer GetCrashesTimer = new FAutoScopedLogTimer("Bugg.PrepareBuggForJira")) { if (Crashes.Count > 0) { NewBugg.PrepareBuggForJira(Crashes); if (BuggIDToBeAddedToJira != 0) { NewBugg.CopyToJira(); } } } using (FAutoScopedLogTimer JiraResultsTimer = new FAutoScopedLogTimer("Bugg.GrabJira")) { var JC = JiraConnection.Get(); bool bValidJira = false; // Verify valid JiraID, this may be still a TTP if (!string.IsNullOrEmpty(NewBugg.Jira)) { int TTPID = 0; int.TryParse(NewBugg.Jira, out TTPID); if (TTPID == 0) { //AddBuggJiraMapping( NewBugg, ref FoundJiras, ref JiraIDtoBugg ); bValidJira = true; } } if (JC.CanBeUsed() && bValidJira) { // Grab the data form JIRA. string JiraSearchQuery = "key = " + NewBugg.Jira; var JiraResults = JC.SearchJiraTickets( JiraSearchQuery, new string[] { "key", // string "summary", // string "components", // System.Collections.ArrayList, Dictionary<string,object>, name "resolution", // System.Collections.Generic.Dictionary`2[System.String,System.Object], name "fixVersions", // System.Collections.ArrayList, Dictionary<string,object>, name "customfield_11200" // string }); // Jira Key, Summary, Components, Resolution, Fix version, Fix changelist foreach (var Jira in JiraResults) { string JiraID = Jira.Key; string Summary = (string)Jira.Value["summary"]; string ComponentsText = ""; System.Collections.ArrayList Components = (System.Collections.ArrayList)Jira.Value["components"]; foreach (Dictionary <string, object> Component in Components) { ComponentsText += (string)Component["name"]; ComponentsText += " "; } Dictionary <string, object> ResolutionFields = (Dictionary <string, object>)Jira.Value["resolution"]; string Resolution = ResolutionFields != null ? (string)ResolutionFields["name"] : ""; string FixVersionsText = ""; System.Collections.ArrayList FixVersions = (System.Collections.ArrayList)Jira.Value["fixVersions"]; foreach (Dictionary <string, object> FixVersion in FixVersions) { FixVersionsText += (string)FixVersion["name"]; FixVersionsText += " "; } int FixCL = Jira.Value["customfield_11200"] != null ? (int)(decimal)Jira.Value["customfield_11200"] : 0; NewBugg.JiraSummary = Summary; NewBugg.JiraComponentsText = ComponentsText; NewBugg.JiraResolution = Resolution; NewBugg.JiraFixVersionsText = FixVersionsText; if (FixCL != 0) { NewBugg.JiraFixCL = FixCL.ToString(); } break; } } } // Apply any user settings if (BuggsForm.Count > 0) { if (!string.IsNullOrEmpty(BuggsForm["SetStatus"])) { NewBugg.Status = BuggsForm["SetStatus"]; Buggs.SetBuggStatus(NewBugg.Status, id); } if (!string.IsNullOrEmpty(BuggsForm["SetFixedIn"])) { NewBugg.FixedChangeList = BuggsForm["SetFixedIn"]; Buggs.SetBuggFixedChangeList(NewBugg.FixedChangeList, id); } if (!string.IsNullOrEmpty(BuggsForm["SetTTP"])) { NewBugg.Jira = BuggsForm["SetTTP"]; Buggs.SetJIRAForBuggAndCrashes(NewBugg.Jira, id); } // <STATUS> } // Set up the view model with the crash data Model.Bugg = NewBugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if (NewCrash != null) { using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("CallstackTrimming")) { CallStackContainer CallStack = new CallStackContainer(NewCrash); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; // Shorten very long function names. foreach (CallStackEntry Entry in Model.CallStack.CallStackEntries) { Entry.FunctionName = Entry.GetTrimmedFunctionName(128); } Model.SourceContext = NewCrash.SourceContext; } Model.Bugg.LatestCrashSummary = NewCrash.Summary; } Model.GenerationTime = LogTimer.GetElapsedSeconds().ToString("F2"); return(View("Show", Model)); } }
/// <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> /// Sort the container of Buggs by the requested criteria. /// </summary> /// <param name="Results">A container of unsorted Buggs.</param> /// <param name="SortTerm">The term to sort by.</param> /// <param name="bSortDescending">Whether to sort by descending or ascending.</param> /// <param name="DateFrom">The date of the earliest Bugg to examine.</param> /// <param name="DateTo">The date of the most recent Bugg to examine.</param> /// <param name="UserGroup">The user group name to filter by.</param> /// <returns>A sorted container of Buggs.</returns> public IEnumerable <Bugg> GetSortedResults(IEnumerable <Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo, string UserGroup) { using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString())) { try { // Get the group id and grab all buggs for the specified group. int NumResults = Results.Count(); HashSet <string> UserNamesForUserGroup = GetUserNamesFromUserGroups(UserGroup); // Simplified query. var BuggIdToCountMapGroup = new Dictionary <int, int>(); var BuggIdToCountMapRest = new Dictionary <int, int>(); var BuggIdToMachineSet = new Dictionary <int, HashSet <string> >(); Dictionary <string, int> MachineIdToCountMap = new Dictionary <string, int>(); List <Buggs_Crash> BuggsFromDate = null; Dictionary <int, string> CrashToUser = null; Dictionary <int, string> CrashToMachine = null; // Get all buggs from the date range. using (FScopedLogTimer LogTimer1 = new FScopedLogTimer("BuggRepository.GetSortedResults.BuggsFromDate SQL")) { BuggsFromDate = ( from BuggCrash in Context.Buggs_Crashes where BuggCrash.Crash.TimeOfCrash >= DateFrom && BuggCrash.Crash.TimeOfCrash <= AddOneDayToDate(DateTo) select BuggCrash ).AsEnumerable().ToList(); var CrashesWithIdUserMachine = ( from Crash in Context.Crashes where Crash.TimeOfCrash >= DateFrom && Crash.TimeOfCrash <= AddOneDayToDate(DateTo) select new { Id = Crash.Id, UserName = Crash.UserName, MachineId = Crash.ComputerName } ); CrashToUser = CrashesWithIdUserMachine.ToDictionary(x => x.Id, y => y.UserName); CrashToMachine = CrashesWithIdUserMachine.ToDictionary(x => x.Id, y => y.MachineId); } using (FScopedLogTimer LogTimer0 = new FScopedLogTimer("BuggRepository.GetSortedResults.Filtering")) { // This calculates total crashes for selected group and all groups. foreach (Buggs_Crash BuggCrash in BuggsFromDate) { string MachineId; CrashToMachine.TryGetValue(BuggCrash.CrashId, out MachineId); string UserName = CrashToUser[BuggCrash.CrashId]; bool bValidForGroup = UserNamesForUserGroup.Contains(UserName); if (!bValidForGroup) { int CountRest = 0; bool bFoundRestKey = BuggIdToCountMapRest.TryGetValue(BuggCrash.BuggId, out CountRest); if (bFoundRestKey) { BuggIdToCountMapRest[BuggCrash.BuggId]++; } else { BuggIdToCountMapRest.Add(BuggCrash.BuggId, 1); } continue; } int Count = 0; bool bFoundKey = BuggIdToCountMapGroup.TryGetValue(BuggCrash.BuggId, out Count); if (bFoundKey) { BuggIdToCountMapGroup[BuggCrash.BuggId]++; } else { BuggIdToCountMapGroup.Add(BuggCrash.BuggId, 1); } if (MachineId != null && MachineId.Length > 0) { HashSet <string> MachineSet = null; bool bFoundMachineKey = BuggIdToMachineSet.TryGetValue(BuggCrash.BuggId, out MachineSet); if (!bFoundMachineKey) { BuggIdToMachineSet.Add(BuggCrash.BuggId, new HashSet <string>()); } BuggIdToMachineSet[BuggCrash.BuggId].Add(MachineId); } } } using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("BuggRepository.GetSortedResults.CrashesInTimeFrame")) { foreach (var Result in Results) { int GroupCount = 0; BuggIdToCountMapGroup.TryGetValue(Result.Id, out GroupCount); Result.CrashesInTimeFrameGroup = GroupCount; int GroupRest = 0; BuggIdToCountMapRest.TryGetValue(Result.Id, out GroupRest); Result.CrashesInTimeFrameAll = GroupCount + GroupRest; } } using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("BuggRepository.GetSortedResults.UniqueMachineCrashesInTimeFrame")) { foreach (var Result in Results) { HashSet <string> MachineSet = null; bool bFoundKey = BuggIdToMachineSet.TryGetValue(Result.Id, out MachineSet); if (bFoundKey) { Result.NumberOfUniqueMachines = MachineSet.Count; } else { Result.NumberOfUniqueMachines = 0; } } } var IntermediateQueryable = Results.AsQueryable(); switch (SortTerm) { case "CrashesInTimeFrameGroup": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameGroup, bSortDescending); break; case "CrashesInTimeFrameAll": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameAll, bSortDescending); break; case "Id": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Id, bSortDescending); break; case "BuildVersion": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.BuildVersion, bSortDescending); break; case "LatestCrash": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfLastCrash, bSortDescending); break; case "FirstCrash": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfFirstCrash, bSortDescending); break; case "NumberOfCrashes": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfCrashes, bSortDescending); break; case "NumberOfUsers": { Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfUniqueMachines, bSortDescending); } break; case "Pattern": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Pattern, bSortDescending); break; case "CrashType": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashType, bSortDescending); break; case "Status": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Status, bSortDescending); break; case "FixedChangeList": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.FixedChangeList, bSortDescending); break; case "TTPID": Results = CrashRepository.OrderBy(IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TTPID, bSortDescending); break; } return(Results); } catch (Exception Ex) { Debug.WriteLine("Exception in GetSortedResults: " + Ex.ToString()); } return(Results); } }
/// <summary> /// Sort the container of Buggs by the requested criteria. /// </summary> /// <param name="Results">A container of unsorted Buggs.</param> /// <param name="SortTerm">The term to sort by.</param> /// <param name="bSortDescending">Whether to sort by descending or ascending.</param> /// <param name="DateFrom">The date of the earliest Bugg to examine.</param> /// <param name="DateTo">The date of the most recent Bugg to examine.</param> /// <returns>A sorted container of Buggs.</returns> public IQueryable<Bugg> GetSortedResults( IQueryable<Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo ) { using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() ) ) { try { var IntermediateResults = ( from BuggCrashDetail in BuggsDataContext.Buggs_Crashes where BuggCrashDetail.Crash.TimeOfCrash >= DateFrom && BuggCrashDetail.Crash.TimeOfCrash <= AddOneDayToDate( DateTo ) group BuggCrashDetail by BuggCrashDetail.BuggId into CrashesGrouped join BuggDetail in Results on CrashesGrouped.Key equals BuggDetail.Id select new { Bugg = BuggDetail, Count = CrashesGrouped.Count() } ); using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggRepository.GetSortedResults.CrashesInTimeFrame" ) ) { foreach( var Result in IntermediateResults ) { Result.Bugg.CrashesInTimeFrame = Result.Count; } } switch( SortTerm ) { case "CrashesInTimeFrame": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Count, bSortDescending ); break; case "Id": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Id, bSortDescending ); break; case "BuildVersion": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.BuildVersion, bSortDescending ); break; case "LatestCrash": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfLastCrash, bSortDescending ); break; case "FirstCrash": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfFirstCrash, bSortDescending ); break; case "NumberOfCrashes": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfCrashes, bSortDescending ); break; case "NumberOfUsers": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfUsers, bSortDescending ); break; case "Pattern": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Pattern, bSortDescending ); break; case "Status": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Status, bSortDescending ); break; case "FixedChangeList": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.FixedChangeList, bSortDescending ); break; case "TTPID": IntermediateResults = CrashRepository.OrderBy( IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TTPID, bSortDescending ); break; } return IntermediateResults.Select( x => x.Bugg ); } catch( Exception Ex ) { Debug.WriteLine( "Exception in GetSortedResults: " + Ex.ToString() ); } return Results; } }
/// <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, }); } }
/// <summary> /// Sort the container of Buggs by the requested criteria. /// </summary> /// <param name="Results">A container of unsorted Buggs.</param> /// <param name="SortTerm">The term to sort by.</param> /// <param name="bSortDescending">Whether to sort by descending or ascending.</param> /// <param name="DateFrom">The date of the earliest Bugg to examine.</param> /// <param name="DateTo">The date of the most recent Bugg to examine.</param> /// <param name="UserGroup">The user group name to filter by.</param> /// <returns>A sorted container of Buggs.</returns> public IEnumerable<Bugg> GetSortedResults( IEnumerable<Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo, string UserGroup ) { using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() ) ) { try { // Get the group id and grab all buggs for the specified group. int NumResults = Results.Count(); HashSet<string> UserNamesForUserGroup = GetUserNamesFromUserGroups( UserGroup ); // Simplified query. var BuggIdToCountMapGroup = new Dictionary<int, int>(); var BuggIdToCountMapRest = new Dictionary<int, int>(); var BuggIdToMachineSet = new Dictionary<int, HashSet<string>>(); Dictionary<string, int> MachineIdToCountMap = new Dictionary<string, int>(); List<Buggs_Crash> BuggsFromDate = null; Dictionary<int, string> CrashToUser = null; Dictionary<int, string> CrashToMachine = null; // Get all buggs from the date range. using( FScopedLogTimer LogTimer1 = new FScopedLogTimer( "BuggRepository.GetSortedResults.BuggsFromDate SQL" ) ) { BuggsFromDate = ( from BuggCrash in Context.Buggs_Crashes where BuggCrash.Crash.TimeOfCrash >= DateFrom && BuggCrash.Crash.TimeOfCrash <= AddOneDayToDate( DateTo ) select BuggCrash ).AsEnumerable().ToList(); var CrashesWithIdUserMachine = ( from Crash in Context.Crashes where Crash.TimeOfCrash >= DateFrom && Crash.TimeOfCrash <= AddOneDayToDate( DateTo ) select new { Id = Crash.Id, UserName = Crash.UserName, MachineId = Crash.ComputerName } ); CrashToUser = CrashesWithIdUserMachine.ToDictionary( x => x.Id, y => y.UserName ); CrashToMachine = CrashesWithIdUserMachine.ToDictionary( x => x.Id, y => y.MachineId ); } using( FScopedLogTimer LogTimer0 = new FScopedLogTimer( "BuggRepository.GetSortedResults.Filtering" ) ) { // This calculates total crashes for selected group and all groups. foreach( Buggs_Crash BuggCrash in BuggsFromDate ) { string MachineId; CrashToMachine.TryGetValue( BuggCrash.CrashId, out MachineId ); string UserName = CrashToUser[BuggCrash.CrashId]; bool bValidForGroup = UserNamesForUserGroup.Contains( UserName ); if( !bValidForGroup ) { int CountRest = 0; bool bFoundRestKey = BuggIdToCountMapRest.TryGetValue( BuggCrash.BuggId, out CountRest ); if( bFoundRestKey ) { BuggIdToCountMapRest[BuggCrash.BuggId]++; } else { BuggIdToCountMapRest.Add( BuggCrash.BuggId, 1 ); } continue; } int Count = 0; bool bFoundKey = BuggIdToCountMapGroup.TryGetValue( BuggCrash.BuggId, out Count ); if( bFoundKey ) { BuggIdToCountMapGroup[BuggCrash.BuggId]++; } else { BuggIdToCountMapGroup.Add( BuggCrash.BuggId, 1 ); } if( MachineId != null && MachineId.Length > 0 ) { HashSet<string> MachineSet = null; bool bFoundMachineKey = BuggIdToMachineSet.TryGetValue( BuggCrash.BuggId, out MachineSet ); if( !bFoundMachineKey ) { BuggIdToMachineSet.Add( BuggCrash.BuggId, new HashSet<string>() ); } BuggIdToMachineSet[BuggCrash.BuggId].Add( MachineId ); } } } using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggRepository.GetSortedResults.CrashesInTimeFrame" ) ) { foreach( var Result in Results ) { int GroupCount = 0; BuggIdToCountMapGroup.TryGetValue( Result.Id, out GroupCount ); Result.CrashesInTimeFrameGroup = GroupCount; int GroupRest = 0; BuggIdToCountMapRest.TryGetValue( Result.Id, out GroupRest ); Result.CrashesInTimeFrameAll = GroupCount + GroupRest; } } using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggRepository.GetSortedResults.UniqueMachineCrashesInTimeFrame" ) ) { foreach( var Result in Results ) { HashSet<string> MachineSet = null; bool bFoundKey = BuggIdToMachineSet.TryGetValue( Result.Id, out MachineSet ); if( bFoundKey ) { Result.NumberOfUniqueMachines = MachineSet.Count; } else { Result.NumberOfUniqueMachines = 0; } } } var IntermediateQueryable = Results.AsQueryable(); switch( SortTerm ) { case "CrashesInTimeFrameGroup": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameGroup, bSortDescending ); break; case "CrashesInTimeFrameAll": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashesInTimeFrameAll, bSortDescending ); break; case "Id": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Id, bSortDescending ); break; case "BuildVersion": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.BuildVersion, bSortDescending ); break; case "LatestCrash": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfLastCrash, bSortDescending ); break; case "FirstCrash": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TimeOfFirstCrash, bSortDescending ); break; case "NumberOfCrashes": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfCrashes, bSortDescending ); break; case "NumberOfUsers": { Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.NumberOfUniqueMachines, bSortDescending ); } break; case "Pattern": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Pattern, bSortDescending ); break; case "CrashType": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.CrashType, bSortDescending ); break; case "Status": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.Status, bSortDescending ); break; case "FixedChangeList": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.FixedChangeList, bSortDescending ); break; case "TTPID": Results = CrashRepository.OrderBy( IntermediateQueryable, BuggCrashInstance => BuggCrashInstance.TTPID, bSortDescending ); break; } return Results; } catch( Exception Ex ) { Debug.WriteLine( "Exception in GetSortedResults: " + Ex.ToString() ); } return Results; } }
/// <summary> /// Sort the container of Buggs by the requested criteria. /// </summary> /// <param name="Results">A container of unsorted Buggs.</param> /// <param name="SortTerm">The term to sort by.</param> /// <param name="bSortDescending">Whether to sort by descending or ascending.</param> /// <param name="DateFrom">The date of the earliest Bugg to examine.</param> /// <param name="DateTo">The date of the most recent Bugg to examine.</param> /// <returns>A sorted container of Buggs.</returns> public IQueryable <Bugg> GetSortedResults(IQueryable <Bugg> Results, string SortTerm, bool bSortDescending, DateTime DateFrom, DateTime DateTo) { using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString())) { try { var IntermediateResults = ( from BuggCrashDetail in BuggsDataContext.Buggs_Crashes where BuggCrashDetail.Crash.TimeOfCrash >= DateFrom && BuggCrashDetail.Crash.TimeOfCrash <= AddOneDayToDate(DateTo) group BuggCrashDetail by BuggCrashDetail.BuggId into CrashesGrouped join BuggDetail in Results on CrashesGrouped.Key equals BuggDetail.Id select new { Bugg = BuggDetail, Count = CrashesGrouped.Count() } ); using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("BuggRepository.GetSortedResults.CrashesInTimeFrame")) { foreach (var Result in IntermediateResults) { Result.Bugg.CrashesInTimeFrame = Result.Count; } } switch (SortTerm) { case "CrashesInTimeFrame": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Count, bSortDescending); break; case "Id": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Id, bSortDescending); break; case "BuildVersion": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.BuildVersion, bSortDescending); break; case "LatestCrash": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfLastCrash, bSortDescending); break; case "FirstCrash": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TimeOfFirstCrash, bSortDescending); break; case "NumberOfCrashes": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfCrashes, bSortDescending); break; case "NumberOfUsers": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.NumberOfUsers, bSortDescending); break; case "Pattern": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Pattern, bSortDescending); break; case "Status": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.Status, bSortDescending); break; case "FixedChangeList": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.FixedChangeList, bSortDescending); break; case "TTPID": IntermediateResults = CrashRepository.OrderBy(IntermediateResults, BuggCrashInstance => BuggCrashInstance.Bugg.TTPID, bSortDescending); break; } return(IntermediateResults.Select(x => x.Bugg)); } catch (Exception Ex) { Debug.WriteLine("Exception in GetSortedResults: " + Ex.ToString()); } return(Results); } }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show(FormCollection BuggsForm, int id) { using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString() + "(BuggId=" + id + ")")) { // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if (BuggsForm["DisplayModuleNames"] == "true") { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if (BuggsForm["DisplayFunctionNames"] == "true") { DisplayFunctionNames = true; } bool DisplayFileNames = false; if (BuggsForm["DisplayFileNames"] == "true") { DisplayFileNames = true; } bool DisplayFilePathNames = false; if (BuggsForm["DisplayFilePathNames"] == "true") { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if (BuggsForm["DisplayUnformattedCallStack"] == "true") { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List <Crash> Crashes = null; Bugg Bugg = new Bugg(); BuggViewModel Model = new BuggViewModel(); Bugg = LocalBuggRepository.GetBugg(id); if (Bugg == null) { return(RedirectToAction("")); } Crashes = Bugg.GetCrashes().ToList(); // Apply any user settings if (BuggsForm.Count > 0) { if (!string.IsNullOrEmpty(BuggsForm["SetStatus"])) { Bugg.Status = BuggsForm["SetStatus"]; LocalCrashRepository.SetBuggStatus(Bugg.Status, id); } if (!string.IsNullOrEmpty(BuggsForm["SetFixedIn"])) { Bugg.FixedChangeList = BuggsForm["SetFixedIn"]; LocalCrashRepository.SetBuggFixedChangeList(Bugg.FixedChangeList, id); } if (!string.IsNullOrEmpty(BuggsForm["SetTTP"])) { Bugg.TTPID = BuggsForm["SetTTP"]; LocalCrashRepository.SetBuggTTPID(Bugg.TTPID, id); } if (!string.IsNullOrEmpty(BuggsForm["Description"])) { Bugg.Description = BuggsForm["Description"]; } // <STATUS> } // Set up the view model with the crash data Model.Bugg = Bugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if (NewCrash != null) { CallStackContainer CallStack = new CallStackContainer(NewCrash); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; NewCrash.CallStackContainer = NewCrash.GetCallStack(); } using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("BuggsController.Show.PopulateUserInfo" + "(id=" + id + ")")) { // Add in the users for each crash in the Bugg foreach (Crash CrashInstance in Model.Crashes) { LocalCrashRepository.PopulateUserInfo(CrashInstance); } } return(View("Show", Model)); } }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show( FormCollection BuggsForm, int id ) { using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() + "(BuggId=" + id + ")" ) ) { // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if( BuggsForm["DisplayModuleNames"] == "true" ) { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if( BuggsForm["DisplayFunctionNames"] == "true" ) { DisplayFunctionNames = true; } bool DisplayFileNames = false; if( BuggsForm["DisplayFileNames"] == "true" ) { DisplayFileNames = true; } bool DisplayFilePathNames = false; if( BuggsForm["DisplayFilePathNames"] == "true" ) { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if( BuggsForm["DisplayUnformattedCallStack"] == "true" ) { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List<Crash> Crashes = null; Bugg Bugg = new Bugg(); BuggViewModel Model = new BuggViewModel(); Bugg = LocalBuggRepository.GetBugg( id ); if( Bugg == null ) { return RedirectToAction( "" ); } // @TODO yrx 2015-02-17 JIRA using( FAutoScopedLogTimer GetCrashesTimer = new FAutoScopedLogTimer( "Bugg.GetCrashes().ToList" ) ) { Crashes = Bugg.GetCrashes(); Bugg.AffectedVersions = new SortedSet<string>(); HashSet<string> MachineIds = new HashSet<string>(); foreach( Crash Crash in Crashes ) { MachineIds.Add( Crash.ComputerName ); // Ignore bad build versions. if( Crash.BuildVersion.StartsWith( "4." ) ) { Bugg.AffectedVersions.Add( Crash.BuildVersion ); } if( Crash.User == null ) { //?? } } Bugg.NumberOfUniqueMachines = MachineIds.Count; } // Apply any user settings if( BuggsForm.Count > 0 ) { if( !string.IsNullOrEmpty( BuggsForm["SetStatus"] ) ) { Bugg.Status = BuggsForm["SetStatus"]; LocalCrashRepository.SetBuggStatus( Bugg.Status, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetFixedIn"] ) ) { Bugg.FixedChangeList = BuggsForm["SetFixedIn"]; LocalCrashRepository.SetBuggFixedChangeList( Bugg.FixedChangeList, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetTTP"] ) ) { Bugg.TTPID = BuggsForm["SetTTP"]; BuggRepository.SetJIRAForBuggAndCrashes( Bugg.TTPID, id ); } if( !string.IsNullOrEmpty( BuggsForm["Description"] ) ) { Bugg.Description = BuggsForm["Description"]; } // <STATUS> } // Set up the view model with the crash data Model.Bugg = Bugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if( NewCrash != null ) { using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "CallstackTrimming" ) ) { CallStackContainer CallStack = new CallStackContainer( NewCrash ); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; // Shorten very long function names. foreach( CallStackEntry Entry in Model.CallStack.CallStackEntries ) { Entry.FunctionName = Entry.GetTrimmedFunctionName( 128 ); } Model.SourceContext = NewCrash.SourceContext; } } /*using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggsController.Show.PopulateUserInfo" + "(id=" + id + ")" ) ) { // Add in the users for each crash in the Bugg foreach( Crash CrashInstance in Model.Crashes ) { LocalCrashRepository.PopulateUserInfo( CrashInstance ); } }*/ return View( "Show", Model ); } }
private IQueryable <Crash> ConstructQuery(FormHelper FormData) { var results = ListAll(); // Grab Results if (!string.IsNullOrEmpty(FormData.SearchQuery)) { if (!string.IsNullOrEmpty(FormData.UsernameQuery)) { //We only use SearchQuery now for CallStack searching - if there's a searchquery value and a Username value, we need to get rid of the //Username so that we can create a broader search range FormData.UsernameQuery = ""; } string DecodedQuery = HttpUtility.HtmlDecode(FormData.SearchQuery).ToLower(); using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("CrashRepository.GetResults.FindUserFromQuery" + "(Query=" + DecodedQuery + ")")) { results = results.Where(item => item.RawCallStack.Contains(FormData.SearchQuery)); } } // 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; } } if (!string.IsNullOrEmpty(FormData.UsernameQuery)) { results = ( from CrashDetail in results where CrashDetail.UserName.Equals(FormData.UsernameQuery) select CrashDetail ); } // Start Filtering the results if (!string.IsNullOrEmpty(FormData.EpicIdQuery)) { var DecodedQuery = HttpUtility.HtmlDecode(FormData.EpicIdQuery).ToLower(); results = ( from CrashDetail in results where CrashDetail.EpicAccountId.Equals(FormData.EpicIdQuery) select CrashDetail ); } if (!string.IsNullOrEmpty(FormData.MachineIdQuery)) { var DecodedQuery = HttpUtility.HtmlDecode(FormData.MachineIdQuery).ToLower(); results = ( from CrashDetail in results where CrashDetail.ComputerName.Equals(FormData.MachineIdQuery) select CrashDetail ); } if (!string.IsNullOrEmpty(FormData.JiraQuery)) { var DecodedQuery = HttpUtility.HtmlDecode(FormData.JiraQuery).ToLower(); results = ( from CrashDetail in results where CrashDetail.TTPID.Equals(FormData.JiraQuery) select CrashDetail ); } // 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.Equals(FormData.BranchName) select CrashDetail ); } } else { results = ( from CrashDetail in results where !CrashDetail.Branch.Equals("UE4-UT-Releases") && !CrashDetail.Branch.Equals("UE4-UT") 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 ); } } if (!string.IsNullOrEmpty(FormData.MessageQuery)) { results = ( from CrashDetail in results where SqlMethods.Like(CrashDetail.Summary, "%" + FormData.MessageQuery + "%") select CrashDetail ); } if (!string.IsNullOrEmpty(FormData.DescriptionQuery)) { results = ( from CrashDetail in results where SqlMethods.Like(CrashDetail.Description, "%" + FormData.DescriptionQuery + "%") select CrashDetail ); } if (!string.IsNullOrEmpty(FormData.SearchQuery)) { results = ( from CrashDetail in results where SqlMethods.Like(CrashDetail.RawCallStack, "%" + FormData.SearchQuery + "%") select CrashDetail ); } return(results); }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show( FormCollection BuggsForm, int id ) { using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() + "(BuggId=" + id + ")" ) ) { // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if( BuggsForm["DisplayModuleNames"] == "true" ) { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if( BuggsForm["DisplayFunctionNames"] == "true" ) { DisplayFunctionNames = true; } bool DisplayFileNames = false; if( BuggsForm["DisplayFileNames"] == "true" ) { DisplayFileNames = true; } bool DisplayFilePathNames = false; if( BuggsForm["DisplayFilePathNames"] == "true" ) { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if( BuggsForm["DisplayUnformattedCallStack"] == "true" ) { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List<Crash> Crashes = null; Bugg Bugg = new Bugg(); BuggViewModel Model = new BuggViewModel(); Bugg = LocalBuggRepository.GetBugg( id ); if( Bugg == null ) { return RedirectToAction( "" ); } Crashes = Bugg.GetCrashes().ToList(); // Apply any user settings if( BuggsForm.Count > 0 ) { if( !string.IsNullOrEmpty( BuggsForm["SetStatus"] ) ) { Bugg.Status = BuggsForm["SetStatus"]; LocalCrashRepository.SetBuggStatus( Bugg.Status, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetFixedIn"] ) ) { Bugg.FixedChangeList = BuggsForm["SetFixedIn"]; LocalCrashRepository.SetBuggFixedChangeList( Bugg.FixedChangeList, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetTTP"] ) ) { Bugg.TTPID = BuggsForm["SetTTP"]; LocalCrashRepository.SetBuggTTPID( Bugg.TTPID, id ); } if( !string.IsNullOrEmpty( BuggsForm["Description"] ) ) { Bugg.Description = BuggsForm["Description"]; } // <STATUS> } // Set up the view model with the crash data Model.Bugg = Bugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if( NewCrash != null ) { CallStackContainer CallStack = new CallStackContainer( NewCrash ); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; NewCrash.CallStackContainer = NewCrash.GetCallStack(); } using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggsController.Show.PopulateUserInfo" + "(id=" + id + ")" ) ) { // Add in the users for each crash in the Bugg foreach( Crash CrashInstance in Model.Crashes ) { LocalCrashRepository.PopulateUserInfo( CrashInstance ); } } return View( "Show", Model ); } }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show(FormCollection BuggsForm, int id) { using (FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer(this.GetType().ToString() + "(BuggId=" + id + ")")) { // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if (BuggsForm["DisplayModuleNames"] == "true") { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if (BuggsForm["DisplayFunctionNames"] == "true") { DisplayFunctionNames = true; } bool DisplayFileNames = false; if (BuggsForm["DisplayFileNames"] == "true") { DisplayFileNames = true; } bool DisplayFilePathNames = false; if (BuggsForm["DisplayFilePathNames"] == "true") { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if (BuggsForm["DisplayUnformattedCallStack"] == "true") { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List <Crash> Crashes = null; Bugg Bugg = new Bugg(); BuggViewModel Model = new BuggViewModel(); Bugg = LocalBuggRepository.GetBugg(id); if (Bugg == null) { return(RedirectToAction("")); } // @TODO yrx 2015-02-17 JIRA using (FAutoScopedLogTimer GetCrashesTimer = new FAutoScopedLogTimer("Bugg.GetCrashes().ToList")) { Crashes = Bugg.GetCrashes(); Bugg.AffectedVersions = new SortedSet <string>(); HashSet <string> MachineIds = new HashSet <string>(); foreach (Crash Crash in Crashes) { MachineIds.Add(Crash.ComputerName); // Ignore bad build versions. if (Crash.BuildVersion.StartsWith("4.")) { Bugg.AffectedVersions.Add(Crash.BuildVersion); } if (Crash.User == null) { //?? } } Bugg.NumberOfUniqueMachines = MachineIds.Count; } // Apply any user settings if (BuggsForm.Count > 0) { if (!string.IsNullOrEmpty(BuggsForm["SetStatus"])) { Bugg.Status = BuggsForm["SetStatus"]; LocalCrashRepository.SetBuggStatus(Bugg.Status, id); } if (!string.IsNullOrEmpty(BuggsForm["SetFixedIn"])) { Bugg.FixedChangeList = BuggsForm["SetFixedIn"]; LocalCrashRepository.SetBuggFixedChangeList(Bugg.FixedChangeList, id); } if (!string.IsNullOrEmpty(BuggsForm["SetTTP"])) { Bugg.TTPID = BuggsForm["SetTTP"]; BuggRepository.SetJIRAForBuggAndCrashes(Bugg.TTPID, id); } if (!string.IsNullOrEmpty(BuggsForm["Description"])) { Bugg.Description = BuggsForm["Description"]; } // <STATUS> } // Set up the view model with the crash data Model.Bugg = Bugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if (NewCrash != null) { using (FScopedLogTimer LogTimer2 = new FScopedLogTimer("CallstackTrimming")) { CallStackContainer CallStack = new CallStackContainer(NewCrash); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; // Shorten very long function names. foreach (CallStackEntry Entry in Model.CallStack.CallStackEntries) { Entry.FunctionName = Entry.GetTrimmedFunctionName(128); } Model.SourceContext = NewCrash.SourceContext; } } /*using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "BuggsController.Show.PopulateUserInfo" + "(id=" + id + ")" ) ) * { * // Add in the users for each crash in the Bugg * foreach( Crash CrashInstance in Model.Crashes ) * { * LocalCrashRepository.PopulateUserInfo( CrashInstance ); * } * }*/ return(View("Show", Model)); } }
/// <summary> /// The Show action. /// </summary> /// <param name="BuggsForm">The form of user data passed up from the client.</param> /// <param name="id">The unique id of the Bugg.</param> /// <returns>The view to display a Bugg on the client.</returns> public ActionResult Show( FormCollection BuggsForm, int id ) { using( FAutoScopedLogTimer LogTimer = new FAutoScopedLogTimer( this.GetType().ToString() + "(BuggId=" + id + ")", bCreateNewLog: true ) ) { // Handle 'CopyToJira' button int BuggIDToBeAddedToJira = 0; foreach( var Entry in BuggsForm ) { if( Entry.ToString().Contains( Bugg.JiraSubmitName ) ) { int.TryParse( Entry.ToString().Substring( Bugg.JiraSubmitName.Length ), out BuggIDToBeAddedToJira ); break; } } BuggRepository Buggs = new BuggRepository(); // Set the display properties based on the radio buttons bool DisplayModuleNames = false; if( BuggsForm["DisplayModuleNames"] == "true" ) { DisplayModuleNames = true; } bool DisplayFunctionNames = false; if( BuggsForm["DisplayFunctionNames"] == "true" ) { DisplayFunctionNames = true; } bool DisplayFileNames = false; if( BuggsForm["DisplayFileNames"] == "true" ) { DisplayFileNames = true; } bool DisplayFilePathNames = false; if( BuggsForm["DisplayFilePathNames"] == "true" ) { DisplayFilePathNames = true; DisplayFileNames = false; } bool DisplayUnformattedCallStack = false; if( BuggsForm["DisplayUnformattedCallStack"] == "true" ) { DisplayUnformattedCallStack = true; } // Create a new view and populate with crashes List<Crash> Crashes = null; BuggViewModel Model = new BuggViewModel(); Bugg NewBugg = Buggs.GetBugg( id ); if( NewBugg == null ) { return RedirectToAction( "" ); } Crashes = NewBugg.GetCrashes(); using (FAutoScopedLogTimer GetCrashesTimer = new FAutoScopedLogTimer( "Bugg.PrepareBuggForJira" )) { if (Crashes.Count > 0) { NewBugg.PrepareBuggForJira( Crashes ); if (BuggIDToBeAddedToJira != 0) { NewBugg.CopyToJira(); } } } using( FAutoScopedLogTimer JiraResultsTimer = new FAutoScopedLogTimer( "Bugg.GrabJira" ) ) { var JC = JiraConnection.Get(); bool bValidJira = false; // Verify valid JiraID, this may be still a TTP if( !string.IsNullOrEmpty( NewBugg.Jira ) ) { int TTPID = 0; int.TryParse( NewBugg.Jira, out TTPID ); if( TTPID == 0 ) { //AddBuggJiraMapping( NewBugg, ref FoundJiras, ref JiraIDtoBugg ); bValidJira = true; } } if( JC.CanBeUsed() && bValidJira ) { // Grab the data form JIRA. string JiraSearchQuery = "key = " + NewBugg.Jira; var JiraResults = JC.SearchJiraTickets( JiraSearchQuery, new string[] { "key", // string "summary", // string "components", // System.Collections.ArrayList, Dictionary<string,object>, name "resolution", // System.Collections.Generic.Dictionary`2[System.String,System.Object], name "fixVersions", // System.Collections.ArrayList, Dictionary<string,object>, name "customfield_11200" // string } ); // Jira Key, Summary, Components, Resolution, Fix version, Fix changelist foreach( var Jira in JiraResults ) { string JiraID = Jira.Key; string Summary = (string)Jira.Value["summary"]; string ComponentsText = ""; System.Collections.ArrayList Components = (System.Collections.ArrayList)Jira.Value["components"]; foreach( Dictionary<string, object> Component in Components ) { ComponentsText += (string)Component["name"]; ComponentsText += " "; } Dictionary<string, object> ResolutionFields = (Dictionary<string, object>)Jira.Value["resolution"]; string Resolution = ResolutionFields != null ? (string)ResolutionFields["name"] : ""; string FixVersionsText = ""; System.Collections.ArrayList FixVersions = (System.Collections.ArrayList)Jira.Value["fixVersions"]; foreach( Dictionary<string, object> FixVersion in FixVersions ) { FixVersionsText += (string)FixVersion["name"]; FixVersionsText += " "; } int FixCL = Jira.Value["customfield_11200"] != null ? (int)(decimal)Jira.Value["customfield_11200"] : 0; NewBugg.JiraSummary = Summary; NewBugg.JiraComponentsText = ComponentsText; NewBugg.JiraResolution = Resolution; NewBugg.JiraFixVersionsText = FixVersionsText; if( FixCL != 0 ) { NewBugg.JiraFixCL = FixCL.ToString(); } break; } } } // Apply any user settings if( BuggsForm.Count > 0 ) { if( !string.IsNullOrEmpty( BuggsForm["SetStatus"] ) ) { NewBugg.Status = BuggsForm["SetStatus"]; Buggs.SetBuggStatus( NewBugg.Status, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetFixedIn"] ) ) { NewBugg.FixedChangeList = BuggsForm["SetFixedIn"]; Buggs.SetBuggFixedChangeList( NewBugg.FixedChangeList, id ); } if( !string.IsNullOrEmpty( BuggsForm["SetTTP"] ) ) { NewBugg.Jira = BuggsForm["SetTTP"]; Buggs.SetJIRAForBuggAndCrashes( NewBugg.Jira, id ); } // <STATUS> } // Set up the view model with the crash data Model.Bugg = NewBugg; Model.Crashes = Crashes; Crash NewCrash = Model.Crashes.FirstOrDefault(); if( NewCrash != null ) { using( FScopedLogTimer LogTimer2 = new FScopedLogTimer( "CallstackTrimming" ) ) { CallStackContainer CallStack = new CallStackContainer( NewCrash ); // Set callstack properties CallStack.bDisplayModuleNames = DisplayModuleNames; CallStack.bDisplayFunctionNames = DisplayFunctionNames; CallStack.bDisplayFileNames = DisplayFileNames; CallStack.bDisplayFilePathNames = DisplayFilePathNames; CallStack.bDisplayUnformattedCallStack = DisplayUnformattedCallStack; Model.CallStack = CallStack; // Shorten very long function names. foreach( CallStackEntry Entry in Model.CallStack.CallStackEntries ) { Entry.FunctionName = Entry.GetTrimmedFunctionName( 128 ); } Model.SourceContext = NewCrash.SourceContext; } Model.Bugg.LatestCrashSummary = NewCrash.Summary; } Model.GenerationTime = LogTimer.GetElapsedSeconds().ToString( "F2" ); return View( "Show", Model ); } }