Guest User

Untitled

a guest
Jan 23rd, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.13 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Data.Common;
  5. using System.Data.SqlClient;
  6. using System.Linq;
  7. using System.Runtime.Remoting.Messaging;
  8. using System.Runtime.Remoting.Proxies;
  9. using System.Text;
  10. using System.Web;
  11. using Castle.DynamicProxy;
  12. using MvcMiniProfiler;
  13. using MvcMiniProfiler.Data;
  14. using NHibernate.AdoNet;
  15. using NHibernate.AdoNet.Util;
  16. using NHibernate.Driver;
  17. using NHibernate.Exceptions;
  18. using NHibernate.Util;
  19.  
  20. namespace Cygnus.Infrastructure
  21. {
  22. public class ProfiledSql2008ClientDriver : Sql2008ClientDriver, IEmbeddedBatcherFactoryProvider
  23. {
  24. ProxyGenerator pg = new ProxyGenerator();
  25. public override IDbCommand CreateCommand()
  26. {
  27. IDbCommand command = base.CreateCommand();
  28.  
  29. if (MiniProfiler.Current != null)
  30. command = pg.CreateInterfaceProxyWithTarget(command, new ProfileInterceptor());
  31.  
  32. return command;
  33. }
  34.  
  35. System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass
  36. {
  37. get { return typeof(ProfiledSqlClientBatchingBatcherFactory); }
  38. }
  39.  
  40. }
  41.  
  42. public class ProfiledSqlClientBatchingBatcherFactory : SqlClientBatchingBatcherFactory
  43. {
  44. public override NHibernate.Engine.IBatcher CreateBatcher(ConnectionManager connectionManager, NHibernate.IInterceptor interceptor)
  45. {
  46. return new ProfiledSqlClientBatchingBatcher(connectionManager, interceptor);
  47. }
  48. }
  49. public class ProfiledSqlClientBatchingBatcher : AbstractBatcher
  50. {
  51. private int batchSize;
  52. private int totalExpectedRowsAffected;
  53. private SqlClientSqlCommandSet currentBatch;
  54. private StringBuilder currentBatchCommandsLog;
  55. private readonly int defaultTimeout;
  56.  
  57. public ProfiledSqlClientBatchingBatcher(ConnectionManager connectionManager, NHibernate.IInterceptor interceptor)
  58. : base(connectionManager, interceptor)
  59. {
  60. batchSize = Factory.Settings.AdoBatchSize;
  61. defaultTimeout = PropertiesHelper.GetInt32(NHibernate.Cfg.Environment.CommandTimeout, NHibernate.Cfg.Environment.Properties, -1);
  62.  
  63. currentBatch = CreateConfiguredBatch();
  64. //we always create this, because we need to deal with a scenario in which
  65. //the user change the logging configuration at runtime. Trying to put this
  66. //behind an if(log.IsDebugEnabled) will cause a null reference exception
  67. //at that point.
  68. currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
  69. }
  70.  
  71. public override int BatchSize
  72. {
  73. get { return batchSize; }
  74. set { batchSize = value; }
  75. }
  76.  
  77. protected override int CountOfStatementsInCurrentBatch
  78. {
  79. get { return currentBatch.CountOfCommands; }
  80. }
  81.  
  82. public override void AddToBatch(IExpectation expectation)
  83. {
  84. totalExpectedRowsAffected += expectation.ExpectedRowCount;
  85. IDbCommand batchUpdate = CurrentCommand;
  86. Driver.AdjustCommand(batchUpdate);
  87. string lineWithParameters = null;
  88. var sqlStatementLogger = Factory.Settings.SqlStatementLogger;
  89. if (sqlStatementLogger.IsDebugEnabled || log.IsDebugEnabled)
  90. {
  91. lineWithParameters = sqlStatementLogger.GetCommandLineWithParameters(batchUpdate);
  92. var formatStyle = sqlStatementLogger.DetermineActualStyle(FormatStyle.Basic);
  93. lineWithParameters = formatStyle.Formatter.Format(lineWithParameters);
  94. currentBatchCommandsLog.Append("command ")
  95. .Append(currentBatch.CountOfCommands)
  96. .Append(":")
  97. .AppendLine(lineWithParameters);
  98. }
  99. if (log.IsDebugEnabled)
  100. {
  101. log.Debug("Adding to batch:" + lineWithParameters);
  102. }
  103. if (batchUpdate is System.Data.SqlClient.SqlCommand)
  104. currentBatch.Append((System.Data.SqlClient.SqlCommand)batchUpdate);
  105. else
  106. {
  107. var sqlCommand = new System.Data.SqlClient.SqlCommand(
  108. batchUpdate.CommandText,
  109. (SqlConnection)batchUpdate.Connection,
  110. (SqlTransaction)batchUpdate.Transaction);
  111. foreach (SqlParameter p in batchUpdate.Parameters)
  112. {
  113. sqlCommand.Parameters.Add(
  114. new SqlParameter(
  115. p.ParameterName,
  116. p.SqlDbType,
  117. p.Size,
  118. p.Direction,
  119. p.IsNullable,
  120. p.Precision,
  121. p.Scale,
  122. p.SourceColumn,
  123. p.SourceVersion,
  124. p.Value));
  125. }
  126. currentBatch.Append(sqlCommand);
  127. }
  128.  
  129. if (currentBatch.CountOfCommands >= batchSize)
  130. {
  131. ExecuteBatchWithTiming(batchUpdate);
  132. }
  133. }
  134.  
  135. protected override void DoExecuteBatch(IDbCommand ps)
  136. {
  137. log.DebugFormat("Executing batch");
  138. CheckReaders();
  139. Prepare(currentBatch.BatchCommand);
  140. if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
  141. {
  142. Factory.Settings.SqlStatementLogger.LogBatchCommand(currentBatchCommandsLog.ToString());
  143. currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
  144. }
  145.  
  146. int rowsAffected;
  147. try
  148. {
  149. rowsAffected = currentBatch.ExecuteNonQuery();
  150. }
  151. catch (DbException e)
  152. {
  153. throw ADOExceptionHelper.Convert(Factory.SQLExceptionConverter, e, "could not execute batch command.");
  154. }
  155.  
  156. Expectations.VerifyOutcomeBatched(totalExpectedRowsAffected, rowsAffected);
  157.  
  158. currentBatch.Dispose();
  159. totalExpectedRowsAffected = 0;
  160. currentBatch = CreateConfiguredBatch();
  161. }
  162.  
  163. private SqlClientSqlCommandSet CreateConfiguredBatch()
  164. {
  165. var result = new SqlClientSqlCommandSet();
  166. if (defaultTimeout > 0)
  167. {
  168. try
  169. {
  170. result.CommandTimeout = defaultTimeout;
  171. }
  172. catch (Exception e)
  173. {
  174. if (log.IsWarnEnabled)
  175. {
  176. log.Warn(e.ToString());
  177. }
  178. }
  179. }
  180.  
  181. return result;
  182. }
  183. }
  184. public class ProfileInterceptor : IInterceptor
  185. {
  186. public void Intercept(IInvocation invocation)
  187. {
  188. var profiler = MiniProfiler.Current as IDbProfiler;
  189.  
  190. var executeType = GetExecuteType(invocation);
  191. var cmd = (DbCommand) invocation.InvocationTarget;
  192. if (executeType != ExecuteType.None)
  193. profiler.ExecuteStart(cmd, executeType);
  194. invocation.Proceed();
  195. object returnValue = invocation.ReturnValue;
  196.  
  197. if (executeType == ExecuteType.Reader)
  198. returnValue = new ProfiledDbDataReader((DbDataReader)returnValue, cmd.Connection, profiler);
  199.  
  200. //IMessage returnMessage = new ReturnMessage(returnValue, invocation.Arguments, invocation.Arguments.Count(), methodMessage.LogicalCallContext, methodMessage);
  201.  
  202. if (executeType == ExecuteType.Reader)
  203. profiler.ExecuteFinish(cmd, executeType, (DbDataReader)returnValue);
  204. else if (executeType != ExecuteType.None)
  205. profiler.ExecuteFinish(cmd, executeType);
  206.  
  207. }
  208. private static ExecuteType GetExecuteType(IInvocation invocation)
  209. {
  210. switch (invocation.Method.Name)
  211. {
  212. case "ExecuteNonQuery":
  213. return ExecuteType.NonQuery;
  214. case "ExecuteReader":
  215. return ExecuteType.Reader;
  216. case "ExecuteScalar":
  217. return ExecuteType.Scalar;
  218. default:
  219. return ExecuteType.None;
  220. }
  221. }
  222.  
  223. }
  224. }
Add Comment
Please, Sign In to add comment