/// <summary> /// Executes & profiles the execution of the specified <see cref="IDbCommand"/>. /// </summary> /// <param name="executeType">The <see cref="DbExecuteType"/>.</param> /// <param name="command">The <see cref="IDbCommand"/> to be executed & profiled.</param> /// <param name="execute"> /// The execute handler, /// which should return the <see cref="IDataReader"/> instance if it is an ExecuteReader operation. /// If it is not ExecuteReader, it should return null. /// </param> /// <param name="tags">The tags of the <see cref="DbTiming"/> which will be created internally.</param> public virtual void ExecuteDbCommand(DbExecuteType executeType, IDbCommand command, Func <IDataReader> execute, TagCollection tags) { if (execute == null) { return; } if (command == null) { execute(); return; } var dbTiming = new DbTiming(_profiler, executeType, command) { Tags = tags }; var dataReader = execute(); if (dataReader == null) { // if not executing reader, stop the sql timing right after execute() dbTiming.Stop(); return; } dbTiming.FirstFetch(); var reader = dataReader as ProfiledDbDataReader ?? new ProfiledDbDataReader(dataReader, this); _inProgressDataReaders[reader] = dbTiming; }
/// <summary> /// Executes & profiles the execution of the specified <see cref="IDbCommand"/>. /// </summary> /// <param name="executeType">The <see cref="DbExecuteType"/>.</param> /// <param name="command">The <see cref="IDbCommand"/> to be executed & profiled.</param> /// <param name="execute"> /// The execute handler, /// which should return the <see cref="DbDataReader"/> instance if it is an ExecuteReader operation. /// </param> /// <param name="tags">The tags of the <see cref="DbTiming"/> which will be created internally.</param> public virtual Task <DbDataReader> ExecuteDbDataReaderCommandAsync(DbExecuteType executeType, IDbCommand command, Func <Task <DbDataReader> > execute, TagCollection tags) { if (command == null) { return(execute()); } var dbTiming = new DbTiming(_profiler, executeType, command) { Tags = tags }; return(execute().ContinueWith <DbDataReader>(r => { var dataReader = r.Result; if (dataReader == null) { // if not executing reader, stop the sql timing right after execute() dbTiming.Stop(); return null; } dbTiming.FirstFetch(); var reader = dataReader as ProfiledDbDataReader ?? new ProfiledDbDataReader(dataReader, this); _inProgressDataReaders[reader] = dbTiming; return reader; })); }
/// <summary> /// Executes & profiles the execution of the specified <see cref="IDbCommand"/>. /// </summary> /// <param name="executeType">The <see cref="DbExecuteType"/>.</param> /// <param name="command">The <see cref="IDbCommand"/> to be executed & profiled.</param> /// <param name="execute"> /// The execute handler /// </param> /// <param name="tags">The tags of the <see cref="DbTiming"/> which will be created internally.</param> public virtual async Task <object> ExecuteCommandAsync(DbExecuteType executeType, IDbCommand command, Func <Task <object> > execute, TagCollection tags) { if (command == null) { return(execute()); } var dbTiming = new DbTiming(_profiler, executeType, command) { Tags = tags }; var result = await execute(); var dataReader = result as DbDataReader; if (dataReader == null) { // if not executing reader, stop the sql timing right after execute() dbTiming.Stop(); return(result); } dbTiming.FirstFetch(); var reader = dataReader as ProfiledDbDataReader ?? new ProfiledDbDataReader(dataReader, this); _inProgressDataReaders[reader] = dbTiming; return(reader); }
public void TestDbTiming() { var stepId = Guid.NewGuid(); ProfilingSession.ProfilingSessionContainer.CurrentSessionStepId = stepId; var profilerDurationMilliseconds = 10; var mockProfiler = new Mock<IProfiler>(); mockProfiler.Setup(profiler => profiler.DurationMilliseconds).Returns(() => profilerDurationMilliseconds++); var executeType = DbExecuteType.Reader; var commandString = "test sql"; var mockParameters = new Mock<IDataParameterCollection>(); mockParameters.Setup(p => p.GetEnumerator()).Returns(new IDataParameter[0].GetEnumerator()); var mockCommand = new Mock<IDbCommand>(); mockCommand.Setup(cmd => cmd.CommandText).Returns(commandString); mockCommand.Setup(cmd => cmd.Parameters).Returns(mockParameters.Object); var target = new DbTiming(mockProfiler.Object, executeType, mockCommand.Object); target.FirstFetch(); var profilerAddCustomTimingCalled = false; mockProfiler.Setup(profiler => profiler.AddCustomTiming(It.IsAny<DbTiming>())) .Callback<CustomTiming>(a => { Assert.AreEqual(target, a); profilerAddCustomTimingCalled = true; }); target.Stop(); Assert.AreNotEqual(default(Guid), target.Id); Assert.AreEqual(stepId, target.ParentId); Assert.AreEqual(executeType, target.DbExecuteType); Assert.AreEqual(commandString, target.Name); Assert.IsTrue(target.Parameters != null); Assert.AreEqual(10, target.StartMilliseconds); Assert.AreEqual(1, target.OutputStartMilliseconds); Assert.AreEqual(2, target.DurationMilliseconds); Assert.IsTrue(profilerAddCustomTimingCalled); // when firstFetchDurationMilliseconds is not set and stoppped is called, // the value of firstFetchDurationMilliseconds should be copied from durationmilliseconds target.OutputStartMilliseconds = null; target.Stop(); Assert.AreEqual(target.DurationMilliseconds, target.OutputStartMilliseconds); }
/// <summary> /// Executes & profiles the execution of the specified <see cref="IDbCommand"/>. /// </summary> /// <param name="executeType">The <see cref="DbExecuteType"/>.</param> /// <param name="command">The <see cref="IDbCommand"/> to be executed & profiled.</param> /// <param name="execute"> /// The execute handler, /// which should return the <see cref="IDataReader"/> instance if it is an ExecuteReader operation. /// If it is not ExecuteReader, it should return null. /// </param> /// <param name="tags">The tags of the <see cref="DbTiming"/> which will be created internally.</param> public virtual void ExecuteDbCommand(DbExecuteType executeType, IDbCommand command, Func<IDataReader> execute, IEnumerable<string> tags) { if (execute == null) { return; } if (command == null) { execute(); return; } var dbTiming = new DbTiming(_profiler, executeType, command); if (tags != null && tags.Any()) { dbTiming.Tags = new TagCollection(tags); } var dataReader = execute(); if (dataReader == null) { // if not executing reader, stop the sql timing right after execute() dbTiming.Stop(); return; } dbTiming.FirstFetch(); var reader = dataReader as ProfiledDbDataReader ?? new ProfiledDbDataReader(dataReader, this); _inProgressDataReaders[reader] = dbTiming; }