public override MiniProfiler Load(Guid id) { // sqlite can't execute multiple result sets at once, so we need to override and run three queries MiniProfiler result = null; using (var conn = GetOpenConnection()) { var param = new { id = id }; result = conn.Query <MiniProfiler>("select * from MiniProfilerS where Id = @id", param).SingleOrDefault(); if (result != null) { // HACK: stored dates are utc, but are pulled out as local time - sqlite doesn't have dedicated datetime types, though result.Started = new DateTime(result.Started.Ticks, DateTimeKind.Utc); var timings = conn.Query <Timing>("select * from MiniProfilerTimings where MiniProfilerId = @id order by RowId", param).ToList(); var sqlTimings = conn.Query <SqlTiming>("select * from MiniProfilerSqlTimings where MiniProfilerId = @id order by RowId", param).ToList(); var sqlParameters = conn.Query <SqlTimingParameter>("select * from MiniProfilerSqlTimingParameters where MiniProfilerId = @id", param).ToList(); var clientTimingList = conn.Query <ClientTimings.ClientTiming>("select * from MiniProfilerClientTimings where MiniProfilerId = @id", param).ToList(); ClientTimings clientTimings = null; if (clientTimingList.Count > 0) { clientTimings.Timings = clientTimingList; } MapTimings(result, timings, sqlTimings, sqlParameters, clientTimings); // loading a profiler means we've viewed it conn.Execute("update MiniProfilers set HasUserViewed = 1 where Id = @id", param); } } return(result); }
/// <summary> /// load the profiler in a batch. /// </summary> /// <param name="connection">The connection.</param> /// <param name="keyParameter">The id parameter.</param> /// <returns>the mini profiler.</returns> private MiniProfiler LoadInBatch(DbConnection connection, object keyParameter) { MiniProfiler result; using (var multi = connection.QueryMultiple(LoadSqlBatch, keyParameter)) { result = multi.Read <MiniProfiler>().SingleOrDefault(); if (result != null) { var timings = multi.Read <Timing>().ToList(); var sqlTimings = multi.Read <SqlTiming>().ToList(); var sqlParameters = multi.Read <SqlTimingParameter>().ToList(); var clientTimingList = multi.Read <ClientTimings.ClientTiming>().ToList(); ClientTimings clientTimings = null; if (clientTimingList.Count > 0) { clientTimings = new ClientTimings { Timings = clientTimingList }; } MapTimings(result, timings, sqlTimings, sqlParameters, clientTimings); } } return(result); }
/// <summary> /// Loads the MiniProfiler identifed by 'id' from the database. /// </summary> public override MiniProfiler Load(Guid id) { var query = Query.EQ("_id", id.ToString()); var profilerPoco = Profilers.FindOne(query); if (profilerPoco != null) { var profiler = new MiniProfiler { Id = Guid.Parse(profilerPoco.Id), Name = profilerPoco.Name, Started = profilerPoco.Started, MachineName = profilerPoco.MachineName, User = profilerPoco.User, Level = profilerPoco.Level, HasUserViewed = profilerPoco.HasUserViewed }; if (profiler != null) //This is very similar to the Load logic in the SqlServerStorage. //Perhaps another abstraction layer(or moving some logic into the Base) which both Mongo and Sql inherit from would eliminate somewhat repetitive code. { var timings = LoadTimings(profiler.Id); var sqlTimings = LoadSqlTimings(profiler.Id); var sqlParams = LoadSqlTimingParameters(profiler.Id); var clientTimingList = LoadClientTimings(profiler.Id); ClientTimings clientTimings = null; if (clientTimingList.Count > 0) { clientTimings = new ClientTimings(); clientTimings.Timings = clientTimingList; } MapTimings(profiler, timings, sqlTimings, sqlParams, clientTimings); } profiler.OnDeserialized(new StreamingContext()); return(profiler); } return(null); }
private MiniProfiler LoadIndividually(DbConnection conn, object idParameter) { var result = LoadFor <MiniProfiler>(conn, idParameter).SingleOrDefault(); if (result != null) { var timings = LoadFor <Timing>(conn, idParameter); var sqlTimings = LoadFor <SqlTiming>(conn, idParameter); var sqlParameters = LoadFor <SqlTimingParameter>(conn, idParameter); var clientTimingList = LoadFor <ClientTimings.ClientTiming>(conn, idParameter).ToList(); ClientTimings clientTimings = null; if (clientTimingList.Count > 0) { clientTimings = new ClientTimings(); clientTimings.Timings = clientTimingList; } MapTimings(result, timings, sqlTimings, sqlParameters, clientTimings); } return(result); }
/// <summary> /// Loads the MiniProfiler identifed by 'id' from the database. /// </summary> public override MiniProfiler Load(Guid id) { var query = Query.EQ("_id", id.ToString()); var profilerPoco = Profilers.FindOne(query); if (profilerPoco != null) { var profiler = new MiniProfiler { Id = Guid.Parse(profilerPoco.Id), Name = profilerPoco.Name, Started = profilerPoco.Started, MachineName = profilerPoco.MachineName, User = profilerPoco.User, Level = profilerPoco.Level, HasUserViewed = profilerPoco.HasUserViewed }; if (profiler != null) //This is very similar to the Load logic in the SqlServerStorage. //Perhaps another abstraction layer(or moving some logic into the Base) which both Mongo and Sql inherit from would eliminate somewhat repetitive code. { var timings = LoadTimings(profiler.Id); var sqlTimings = LoadSqlTimings(profiler.Id); var mongoTimings = LoadMongoTimings(profiler.Id); var sqlParams = LoadSqlTimingParameters(profiler.Id); var clientTimingList = LoadClientTimings(profiler.Id); ClientTimings clientTimings = null; if (clientTimingList.Count > 0) { clientTimings = new ClientTimings(); clientTimings.Timings = clientTimingList; } MapTimings(profiler, timings, sqlTimings, sqlParams, clientTimings, mongoTimings); } profiler.OnDeserialized(); return profiler; } return null; }
/// <summary> /// Handles rendering a previous <c>MiniProfiler</c> session, identified by its <c>"?id=GUID"</c> on the query. /// </summary> /// <param name="context">The context.</param> /// <returns>a string containing the rendered content</returns> private static string Results(HttpContext context) { // when we're rendering as a button/popup in the corner, we'll pass ?popup=1 // if it's absent, we're rendering results as a full page for sharing var isPopup = context.Request["popup"].HasValue(); // this guid is the MiniProfiler.Id property // if this guid is not supplied, the last set of results needs to be // displayed. The home page doesn't have profiling otherwise. Guid id; try { id = new Guid(context.Request["id"]); } catch (Exception) { id = MiniProfiler.Settings.Storage.List(1).FirstOrDefault(); } if (id == default(Guid)) { return(isPopup ? NotFound(context) : NotFound(context, "text/plain", "No Guid id specified on the query string")); } MiniProfiler.Settings.EnsureStorageStrategy(); var profiler = MiniProfiler.Settings.Storage.Load(id); var provider = WebRequestProfilerProvider.Settings.UserProvider; string user = null; if (provider != null) { user = provider.GetUser(context.Request); } MiniProfiler.Settings.Storage.SetViewed(user, id); if (profiler == null) { return(isPopup ? NotFound(context) : NotFound(context, "text/plain", "No MiniProfiler results found with Id=" + id.ToString())); } bool needsSave = false; if (profiler.ClientTimings == null) { profiler.ClientTimings = ClientTimings.FromRequest(context.Request); if (profiler.ClientTimings != null) { needsSave = true; } } if (profiler.HasUserViewed == false) { profiler.HasUserViewed = true; needsSave = true; } if (needsSave) { MiniProfiler.Settings.Storage.Save(profiler); } var authorize = MiniProfiler.Settings.Results_Authorize; if (authorize != null && !authorize(context.Request)) { context.Response.ContentType = "application/json"; return("hidden".ToJson()); } return(isPopup ? ResultsJson(context, profiler) : ResultsFullPage(context, profiler)); }
/// <summary> /// Giving freshly selected collections, this method puts them in the correct /// hierarchy under the 'result' MiniProfiler. /// </summary> protected void MapTimings(MiniProfiler result, List<Timing> timings, List<SqlTiming> sqlTimings, List<SqlTimingParameter> sqlParameters, ClientTimings clientTimings) { var stack = new Stack<Timing>(); for (int i = 0; i < timings.Count; i++) { var cur = timings[i]; foreach (var sqlTiming in sqlTimings) { if (sqlTiming.ParentTimingId == cur.Id) { cur.AddSqlTiming(sqlTiming); var parameters = sqlParameters.Where(p => p.ParentSqlTimingId == sqlTiming.Id); if (parameters.Count() > 0) { sqlTiming.Parameters = parameters.ToList(); } } } if (stack.Count > 0) { Timing head; while ((head = stack.Peek()).Id != cur.ParentTimingId) { stack.Pop(); } head.AddChild(cur); } stack.Push(cur); } result.ClientTimings = clientTimings; // TODO: .Root does all the above work again, but it's used after [DataContract] deserialization; refactor it out somehow result.Root = timings.First(); }
/// <summary> /// Handles rendering a previous MiniProfiler session, identified by its "?id=GUID" on the query. /// </summary> private static string Results(HttpContext context) { // when we're rendering as a button/popup in the corner, we'll pass ?popup=1 // if it's absent, we're rendering results as a full page for sharing var isPopup = !string.IsNullOrWhiteSpace(context.Request["popup"]); // this guid is the MiniProfiler.Id property Guid id; if (!Guid.TryParse(context.Request["id"], out id)) { return(isPopup ? NotFound(context) : NotFound(context, "text/plain", "No Guid id specified on the query string")); } MiniProfiler.Settings.EnsureStorageStrategy(); var profiler = MiniProfiler.Settings.Storage.Load(id); var provider = WebRequestProfilerProvider.Settings.UserProvider; string user = null; if (provider != null) { user = provider.GetUser(context.Request); } MiniProfiler.Settings.Storage.SetViewed(user, id); if (profiler == null) { return(isPopup ? NotFound(context) : NotFound(context, "text/plain", "No MiniProfiler results found with Id=" + id.ToString())); } bool needsSave = false; if (profiler.ClientTimings == null) { profiler.ClientTimings = ClientTimings.FromRequest(context.Request); if (profiler.ClientTimings != null) { needsSave = true; } } if (profiler.HasUserViewed == false) { profiler.HasUserViewed = true; needsSave = true; } if (needsSave) { MiniProfiler.Settings.Storage.Save(profiler); } var authorize = MiniProfiler.Settings.Results_Authorize; if (authorize != null && !authorize(context.Request)) { context.Response.ContentType = "application/json"; return("hidden".ToJson()); } return(isPopup ? ResultsJson(context, profiler) : ResultsFullPage(context, profiler)); }
/// <summary> /// Giving freshly selected collections, this method puts them in the correct /// hierarchy under the 'result' MiniProfiler. /// </summary> protected void MapTimings(MiniProfiler result, List <Timing> timings, List <SqlTiming> sqlTimings, List <SqlTimingParameter> sqlParameters, ClientTimings clientTimings) { var stack = new Stack <Timing>(); for (int i = 0; i < timings.Count; i++) { var cur = timings[i]; foreach (var sqlTiming in sqlTimings) { if (sqlTiming.ParentTimingId == cur.Id) { cur.AddSqlTiming(sqlTiming); var parameters = sqlParameters.Where(p => p.ParentSqlTimingId == sqlTiming.Id); if (parameters.Count() > 0) { sqlTiming.Parameters = parameters.ToList(); } } } if (stack.Count > 0) { Timing head; while ((head = stack.Peek()).Id != cur.ParentTimingId) { stack.Pop(); } head.AddChild(cur); } stack.Push(cur); } result.ClientTimings = clientTimings; // TODO: .Root does all the above work again, but it's used after [DataContract] deserialization; refactor it out somehow result.Root = timings.First(); }