You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
6.7 KiB

4 years ago
  1. #if MYSQL_6_10
  2. // Copyright © 2004, 2018, Oracle and/or its affiliates. All rights reserved.
  3. //
  4. // MySQL Connector/NET is licensed under the terms of the GPLv2
  5. // <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
  6. // MySQL Connectors. There are special exceptions to the terms and
  7. // conditions of the GPLv2 as it is applied to this software, see the
  8. // FLOSS License Exception
  9. // <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
  10. //
  11. // This program is free software; you can redistribute it and/or modify
  12. // it under the terms of the GNU General Public License as published
  13. // by the Free Software Foundation; version 2 of the License.
  14. //
  15. // This program is distributed in the hope that it will be useful, but
  16. // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  18. // for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License along
  21. // with this program; if not, write to the Free Software Foundation, Inc.,
  22. // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23. using System;
  24. using System.Collections.Generic;
  25. using System.Data;
  26. using Externals.MySql.Data.MySqlClient;
  27. #if NETSTANDARD1_3
  28. namespace Externals.MySql.Data.MySqlClient.Interceptors
  29. #else
  30. namespace Externals.MySql.Data.MySqlClient
  31. #endif
  32. {
  33. /// <summary>
  34. /// BaseCommandInterceptor is the base class that should be used for all userland
  35. /// command interceptors
  36. /// </summary>
  37. internal abstract class BaseCommandInterceptor
  38. {
  39. /// <summary>
  40. /// Gets the active connection.
  41. /// </summary>
  42. protected MySqlConnection ActiveConnection { get; private set; }
  43. /// <summary>
  44. /// Executes an SQL statements that returns a scalar value such as a calculation.
  45. /// </summary>
  46. /// <param name="sql">The SQL statement to execute.</param>
  47. /// <param name="returnValue">A scalar value that represents the result returned by the execution of the SQL statement.</param>
  48. /// <returns><c>false</c>.</returns>
  49. /// <remarks>This method is intended to be overriden.</remarks>
  50. public virtual bool ExecuteScalar(string sql, ref object returnValue)
  51. {
  52. return false;
  53. }
  54. /// <summary>
  55. /// Executes an SQL statement that returns the number of affected rows.
  56. /// </summary>
  57. /// <param name="sql">The SQL statement to execute.</param>
  58. /// <param name="returnValue">The number of affected rows.</param>
  59. /// <returns><c>false</c>.</returns>
  60. /// <remarks>This method is intended to be overriden.</remarks>
  61. public virtual bool ExecuteNonQuery(string sql, ref int returnValue)
  62. {
  63. return false;
  64. }
  65. /// <summary>
  66. /// Executes an SQL statement that will return a resultset.
  67. /// </summary>
  68. /// <param name="sql">The SQL statement to execute.</param>
  69. /// <param name="behavior">A value that describes the results of the query and its effect on the database.</param>
  70. /// <param name="returnValue">A <see cref="MySqlDataReader"/> object containing the result of the statement execution.</param>
  71. /// <returns><c>false</c>.</returns>
  72. /// <remarks>This method is intended to be overriden.</remarks>
  73. public virtual bool ExecuteReader(string sql, CommandBehavior behavior, ref MySqlDataReader returnValue)
  74. {
  75. return false;
  76. }
  77. /// <summary>
  78. /// Sets the active connection.
  79. /// </summary>
  80. /// <param name="connection">The active connection.</param>
  81. public virtual void Init(MySqlConnection connection)
  82. {
  83. ActiveConnection = connection;
  84. }
  85. }
  86. /// <summary>
  87. /// CommandInterceptor is the "manager" class that keeps the list of registered interceptors
  88. /// for the given connection.
  89. /// </summary>
  90. internal sealed partial class CommandInterceptor : Interceptor
  91. {
  92. bool _insideInterceptor = false;
  93. readonly List<BaseCommandInterceptor> _interceptors = new List<BaseCommandInterceptor>();
  94. public CommandInterceptor(MySqlConnection connection)
  95. {
  96. Connection = connection;
  97. LoadInterceptors(connection.Settings.CommandInterceptors);
  98. }
  99. public bool ExecuteScalar(string sql, ref object returnValue)
  100. {
  101. if (_insideInterceptor) return false;
  102. _insideInterceptor = true;
  103. bool handled = false;
  104. foreach (BaseCommandInterceptor bci in _interceptors)
  105. handled |= bci.ExecuteScalar(sql, ref returnValue);
  106. _insideInterceptor = false;
  107. return handled;
  108. }
  109. public bool ExecuteNonQuery(string sql, ref int returnValue)
  110. {
  111. if (_insideInterceptor) return false;
  112. _insideInterceptor = true;
  113. bool handled = false;
  114. foreach (BaseCommandInterceptor bci in _interceptors)
  115. handled |= bci.ExecuteNonQuery(sql, ref returnValue);
  116. _insideInterceptor = false;
  117. return handled;
  118. }
  119. public bool ExecuteReader(string sql, CommandBehavior behavior, ref MySqlDataReader returnValue)
  120. {
  121. if (_insideInterceptor) return false;
  122. _insideInterceptor = true;
  123. bool handled = false;
  124. foreach (BaseCommandInterceptor bci in _interceptors)
  125. handled |= bci.ExecuteReader(sql, behavior, ref returnValue);
  126. _insideInterceptor = false;
  127. return handled;
  128. }
  129. protected override void AddInterceptor(object o)
  130. {
  131. if (o == null)
  132. throw new ArgumentException("Unable to instantiate CommandInterceptor");
  133. if (!(o is BaseCommandInterceptor))
  134. throw new InvalidOperationException(String.Format(Resources.TypeIsNotCommandInterceptor,
  135. o.GetType()));
  136. BaseCommandInterceptor ie = (BaseCommandInterceptor)o;
  137. ie.Init(Connection);
  138. _interceptors.Insert(0, (BaseCommandInterceptor)o);
  139. }
  140. protected override string ResolveType(string nameOrType)
  141. {
  142. #if NETSTANDARD1_3
  143. return base.ResolveType(nameOrType);
  144. #else
  145. if (MySqlConfiguration.Settings == null || MySqlConfiguration.Settings.CommandInterceptors == null)
  146. return base.ResolveType(nameOrType);
  147. foreach (InterceptorConfigurationElement e in MySqlConfiguration.Settings.CommandInterceptors)
  148. if (String.Compare(e.Name, nameOrType, true) == 0)
  149. return e.Type;
  150. return base.ResolveType(nameOrType);
  151. #endif
  152. }
  153. }
  154. }
  155. #endif