using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Reflection; using Glimpse.Ado.Message; using Glimpse.Core.Message; namespace Glimpse.Ado.AlternateType { public static class Support { public static DbProviderFactory TryGetProviderFactory(this DbConnection connection) { // If we can pull it out quickly and easily var profiledConnection = connection as GlimpseDbConnection; if (profiledConnection != null) { return profiledConnection.InnerProviderFactory; } #if (NET45) return DbProviderFactories.GetFactory(connection); #else return connection.GetType().GetProperty("ProviderFactory", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(connection, null) as DbProviderFactory; #endif } public static DbProviderFactory TryGetProfiledProviderFactory(this DbConnection connection) { var factory = connection.TryGetProviderFactory(); if (factory != null) { if (!(factory is GlimpseDbProviderFactory)) { factory = factory.WrapProviderFactory(); } } else { throw new NotSupportedException(string.Format(Resources.DbFactoryNotFoundInDbConnection, connection.GetType().FullName)); } return factory; } public static DbProviderFactory WrapProviderFactory(this DbProviderFactory factory) { if (!(factory is GlimpseDbProviderFactory)) { var factoryType = typeof(GlimpseDbProviderFactory<>).MakeGenericType(factory.GetType()); return (DbProviderFactory)factoryType.GetField("Instance").GetValue(null); } return factory; } public static DataTable FindDbProviderFactoryTable() { var providerFactories = typeof(DbProviderFactories); var providerField = providerFactories.GetField("_configTable", BindingFlags.NonPublic | BindingFlags.Static) ?? providerFactories.GetField("_providerTable", BindingFlags.NonPublic | BindingFlags.Static); var registrations = providerField.GetValue(null); return registrations is DataSet ? ((DataSet)registrations).Tables["DbProviderFactories"] : (DataTable)registrations; } public static object GetParameterValue(IDataParameter parameter) { if (parameter.Value == DBNull.Value) { return "NULL"; } if (parameter.Value is byte[]) { var blob = parameter.Value as byte[]; return "BLOB" + (blob != null ? string.Format(" {0} bytes", blob.Length) : string.Empty); } return parameter.Value; } public static TimeSpan LogCommandSeed(this GlimpseDbCommand command) { return command.TimerStrategy != null ? command.TimerStrategy.Start() : TimeSpan.Zero; } public static void LogCommandStart(this GlimpseDbCommand command, Guid commandId, TimeSpan timerTimeSpan) { command.LogCommandStart(commandId, timerTimeSpan, false); } public static void LogCommandStart(this GlimpseDbCommand command, Guid commandId, TimeSpan timerTimeSpan, bool isAsync) { if (command.MessageBroker != null) { IList<CommandExecutedParamater> parameters = null; if (command.Parameters.Count > 0) { parameters = new List<CommandExecutedParamater>(); foreach (IDbDataParameter parameter in command.Parameters) { var parameterName = parameter.ParameterName; if (!parameterName.StartsWith("@")) { parameterName = "@" + parameterName; } parameters.Add(new CommandExecutedParamater { Name = parameterName, Value = GetParameterValue(parameter), Type = parameter.DbType.ToString(), Size = parameter.Size }); } } command.MessageBroker.Publish( new CommandExecutedMessage(command.InnerConnection.ConnectionId, commandId, command.InnerCommand.CommandText, parameters, command.InnerCommand.Transaction != null, isAsync) .AsTimedMessage(timerTimeSpan)); } } public static void LogCommandEnd(this GlimpseDbCommand command, Guid commandId, TimeSpan timer, int? recordsAffected, string type) { command.LogCommandEnd(commandId, timer, recordsAffected, type, false); } public static void LogCommandEnd(this GlimpseDbCommand command, Guid commandId, TimeSpan timer, int? recordsAffected, string type, bool isAsync) { if (command.MessageBroker != null && command.TimerStrategy != null) { command.MessageBroker.Publish( new CommandDurationAndRowCountMessage(command.InnerConnection.ConnectionId, commandId, recordsAffected) .AsTimedMessage(command.TimerStrategy.Stop(timer)) .AsTimelineMessage("Command: Executed", AdoTimelineCategory.Command, type)); } } public static void LogCommandError(this GlimpseDbCommand command, Guid commandId, TimeSpan timer, Exception exception, string type) { command.LogCommandError(commandId, timer, exception, type, false); } public static void LogCommandError(this GlimpseDbCommand command, Guid commandId, TimeSpan timer, Exception exception, string type, bool isAsync) { if (command.MessageBroker != null && command.TimerStrategy != null) { command.MessageBroker.Publish( new CommandErrorMessage(command.InnerConnection.ConnectionId, commandId, exception) .AsTimedMessage(command.TimerStrategy.Stop(timer)) .AsTimelineMessage("Command: Error", AdoTimelineCategory.Command, type)); } } } }