context: // This program is free software; you can redistribute it and/or modify
  // it under the terms of the GNU Lesser General Public License as published
  // by the Free Software Foundation; version 3 of the License.
  //
  // This program is distributed in the hope that it will be useful, but
  // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
  // for more details.
  //
  // You should have received a copy of the GNU Lesser General Public License along
  // with this program; if not, write to the Free Software Foundation, Inc.,
  // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  
  using System.Data;
  using System.Text;
  
  namespace MariaDB.Data.MySqlClient
  {
      /// <summary>
      /// Helper class that makes it easier to work with the provider.
      /// </summary>
      public sealed class MySqlHelper
      {
          private enum CharClass : byte
          {
              None,
              Quote,
              Backslash
          }
  
          private static string stringOfBackslashChars = "\u005c\u00a5\u0160\u20a9\u2216\ufe68\uff3c";
  
          private static string stringOfQuoteChars =
              "\u0027\u0060\u00b4\u02b9\u02ba\u02bb\u02bc\u02c8\u02ca\u02cb\u02d9\u0300\u0301\u2018\u2019\u201a\u2032\u2035\u275b\u275c\uff07";
  
          private static CharClass[] charClassArray = makeCharClassArray();
  
          // this class provides only static methods
          private MySqlHelper() { }
  
          /// <summary>
          /// Executes a single command against a MySQL database.  The <see cref="MySqlConnection"/> is assumed to be
          /// open when the method is called and remains open after the method completes.
          /// </summary>
          /// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
          /// <param name="commandText">SQL command to be executed</param>
          /// <param name="commandParameters">Array of <see cref="MySqlParameter"/> objects to use with the command.</param>
          /// <returns></returns>
          public static int ExecuteNonQuery(MySqlConnection connection, string commandText, params MySqlParameter[] commandParameters)
          {
              //create a command and prepare it for execution
              MySqlCommand cmd = new MySqlCommand();
              cmd.Connection = connection;
              cmd.CommandText = commandText;
              cmd.CommandType = CommandType.Text;
  
              if (commandParameters != null)
                  foreach (MySqlParameter p in commandParameters)
                      cmd.Parameters.Add(p);
  
              int result = cmd.ExecuteNonQuery();
              cmd.Parameters.Clear();
  
              return result;
          }
  
          /// <summary>
          /// Executes a single command against a MySQL database.  A new <see cref="MySqlConnection"/> is created
          /// using the <see cref="MySqlConnection.ConnectionString"/> given.
          /// </summary>
          /// <param name="connectionString"><see cref="MySqlConnection.ConnectionString"/> to use</param>
          /// <param name="commandText">SQL command to be executed</param>
          /// <param name="parms">Array of <see cref="MySqlParameter"/> objects to use with the command.</param>
          /// <returns></returns>
          public static int ExecuteNonQuery(string connectionString, string commandText, params MySqlParameter[] parms)
          {
              //create & open a SqlConnection, and dispose of it after we are done.
              using (MySqlConnection cn = new MySqlConnection(connectionString))
              {
                  cn.Open();
  
                  //call the overload that takes a connection in place of the connection string
                  return ExecuteNonQuery(cn, commandText, parms);
              }
          }
  
          /// <summary>
          /// Executes a single command against a MySQL database, possibly inside an existing transaction.
          /// </summary>
          /// <param name="connection"><see cref="MySqlConnection"/> object to use for the command</param>
          /// <param name="transaction"><see cref="MySqlTransaction"/> object to use for the command</param>
          /// <param name="commandText">Command text to use</param>
          /// <param name="commandParameters">Array of <see cref="MySqlParameter"/> objects to use with the command</param>
          /// <param name="ExternalConn">True if the connection should be preserved, false if not</param>
          /// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
          private static MySqlDataReader ExecuteReader(MySqlConnection connection, MySqlTransaction transaction, string commandText, MySqlParameter[] commandParameters, bool ExternalConn)
          {
              //create a command and prepare it for execution
              MySqlCommand cmd = new MySqlCommand();
              cmd.Connection = connection;
              cmd.Transaction = transaction;
              cmd.CommandText = commandText;
              cmd.CommandType = CommandType.Text;
  
              if (commandParameters != null)
                  foreach (MySqlParameter p in commandParameters)
                      cmd.Parameters.Add(p);
  
              //create a reader
              MySqlDataReader dr;
  
              // call ExecuteReader with the appropriate CommandBehavior
              if (ExternalConn)
              {
                  dr = cmd.ExecuteReader();
              }
              else
              {
                  dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
              }
  
              // detach the SqlParameters from the command object, so they can be used again.
              cmd.Parameters.Clear();
  
              return dr;
          }
  
          /// <summary>
          /// Executes a single command against a MySQL database.
          /// </summary>
          /// <param name="connectionString">Settings to use for this command</param>
          /// <param name="commandText">Command text to use</param>
          /// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
          public static MySqlDataReader ExecuteReader(string connectionString, string commandText)
          {
              //pass through the call providing null for the set of SqlParameters
              return ExecuteReader(connectionString, commandText, (MySqlParameter[])null);
          }
  
          /// <summary>
          /// Executes a single command against a MySQL database.
          /// </summary>
          /// <param name="connection"><see cref="MySqlConnection"/> object to use for the command</param>
          /// <param name="commandText">Command text to use</param>
          /// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
          public static MySqlDataReader ExecuteReader(MySqlConnection connection, string commandText)
          {
              //pass through the call providing null for the set of SqlParameters
              return ExecuteReader(connection, null, commandText, (MySqlParameter[])null, true);
          }
  
          /// <summary>
          /// Executes a single command against a MySQL database.
          /// </summary>
          /// <param name="connectionString">Settings to use for this command</param>
          /// <param name="commandText">Command text to use</param>
          /// <param name="commandParameters">Array of <see cref="MySqlParameter"/> objects to use with the command</param>
          /// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
          public static MySqlDataReader ExecuteReader(string connectionString, string commandText, params MySqlParameter[] commandParameters)
          {
              //create & open a SqlConnection
              MySqlConnection cn = new MySqlConnection(connectionString);
              cn.Open();
  
              //call the private overload that takes an internally owned connection in place of the connection string
              return ExecuteReader(cn, null, commandText, commandParameters, false);
          }
  
          /// <summary>
          /// Executes a single command against a MySQL database.
          /// </summary>
          /// <param name="connection">Connection to use for the command</param>
          /// <param name="commandText">Command text to use</param>
          /// <param name="commandParameters">Array of <see cref="MySqlParameter"/> objects to use with the command</param>
          /// <returns><see cref="MySqlDataReader"/> object ready to read the results of the command</returns>
          public static MySqlDataReader ExecuteReader(MySqlConnection connection, string commandText, params MySqlParameter[] commandParameters)
          {
              //call the private overload that takes an internally owned connection in place of the connection string
              return ExecuteReader(connection, null, commandText, commandParameters, true);
          }
  
          /// <summary>
          /// Execute a single command against a MySQL database.
          /// </summary>
          /// <param name="connectionString">Settings to use for the update</param>
          /// <param name="commandText">Command text to use for the update</param>
          /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
          public static object ExecuteScalar(string connectionString, string commandText)
          {
              //pass through the call providing null for the set of MySqlParameters
              return ExecuteScalar(connectionString, commandText, (MySqlParameter[])null);
          }
  
          /// <summary>
          /// Execute a single command against a MySQL database.
          /// </summary>
          /// <param name="connectionString">Settings to use for the command</param>
          /// <param name="commandText">Command text to use for the command</param>
          /// <param name="commandParameters">Parameters to use for the command</param>
          /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
          public static object ExecuteScalar(string connectionString, string commandText, params MySqlParameter[] commandParameters)
          {
              //create & open a SqlConnection, and dispose of it after we are done.
              using (MySqlConnection cn = new MySqlConnection(connectionString))
              {
                  cn.Open();
  
                  //call the overload that takes a connection in place of the connection string
                  return ExecuteScalar(cn, commandText, commandParameters);
              }
          }
  
          /// <summary>
          /// Execute a single command against a MySQL database.
          /// </summary>
          /// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
          /// <param name="commandText">Command text to use for the command</param>
          /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
          public static object ExecuteScalar(MySqlConnection connection, string commandText)
          {
              //pass through the call providing null for the set of MySqlParameters
              return ExecuteScalar(connection, commandText, (MySqlParameter[])null);
          }
  
          /// <summary>
          /// Execute a single command against a MySQL database.
          /// </summary>
          /// <param name="connection"><see cref="MySqlConnection"/> object to use</param>
          /// <param name="commandText">Command text to use for the command</param>
          /// <param name="commandParameters">Parameters to use for the command</param>
          /// <returns>The first column of the first row in the result set, or a null reference if the result set is empty.</returns>
          public static object ExecuteScalar(MySqlConnection connection, string commandText, params MySqlParameter[] commandParameters)
          {
              //create a command and prepare it for execution
              MySqlCommand cmd = new MySqlCommand();
              cmd.Connection = connection;
              cmd.CommandText = commandText;
              cmd.CommandType = CommandType.Text;
  
              if (commandParameters != null)
                  foreach (MySqlParameter p in commandParameters)
                      cmd.Parameters.Add(p);
  
              //execute the command & return the results
  
gt:             object retval = cmd.ExecuteScalar();