internal string GetCacheKey(string spName, ProcedureCacheEntry proc)
        {
            string        retValue = String.Empty;
            StringBuilder key      = new StringBuilder(spName);

            key.Append("(");
            string delimiter = "";

            if (proc.parameters != null)
            {
                foreach (MySqlSchemaRow row in proc.parameters.Rows)
                {
                    if (row["ORDINAL_POSITION"].Equals(0))
                    {
                        retValue = "?=";
                    }
                    else
                    {
                        key.AppendFormat(CultureInfo.InvariantCulture, "{0}?", delimiter);
                        delimiter = ",";
                    }
                }
            }
            key.Append(")");
            return(retValue + key.ToString());
        }
        public ProcedureCacheEntry GetProcedure(MySqlConnection conn, string spName, string cacheKey)
        {
            ProcedureCacheEntry proc = null;

            if (cacheKey != null)
            {
                int hash = cacheKey.GetHashCode();

                lock (procHash)
                {
                    procHash.TryGetValue(hash, out proc);
                }
            }
            if (proc == null)
            {
                proc = AddNew(conn, spName);
                conn.PerfMonitor.AddHardProcedureQuery();
                if (conn.Settings.Logging)
                {
                    MySqlTrace.LogInformation(conn.ServerThread,
                                              String.Format(Resources.HardProcQuery, spName));
                }
            }
            else
            {
                conn.PerfMonitor.AddSoftProcedureQuery();
                if (conn.Settings.Logging)
                {
                    MySqlTrace.LogInformation(conn.ServerThread,
                                              String.Format(Resources.SoftProcQuery, spName));
                }
            }
            return(proc);
        }
Exemple #3
0
        private ProcedureCacheEntry GetParameters(string procName)
        {
            string procCacheKey       = GetCacheKey(procName);
            ProcedureCacheEntry entry = Connection.ProcedureCache.GetProcedure(Connection, procName, procCacheKey);

            return(entry);
        }
Exemple #4
0
        /// <summary>
        /// Retrieves parameter information from the stored procedure specified
        /// in the MySqlCommand and populates the Parameters collection of the
        /// specified MySqlCommand object.
        /// This method is not currently supported since stored procedures are
        /// not available in MySql.
        /// </summary>
        /// <param name="command">The MySqlCommand referencing the stored
        /// procedure from which the parameter information is to be derived.
        /// The derived parameters are added to the Parameters collection of the
        /// MySqlCommand.</param>
        /// <exception cref="InvalidOperationException">The command text is not
        /// a valid stored procedure name.</exception>
        public static void DeriveParameters(MySqlCommand command)
        {
            if (command.CommandType != CommandType.StoredProcedure)
            {
                throw new InvalidOperationException(Resources.CanNotDeriveParametersForTextCommands);
            }

            // retrieve the proc definition from the cache.
            string spName = command.CommandText;

            if (spName.IndexOf(".") == -1)
            {
                spName = command.Connection.Database + "." + spName;
            }

            try
            {
                ProcedureCacheEntry entry = command.Connection.ProcedureCache.GetProcedure(command.Connection, spName, null);
                command.Parameters.Clear();
                foreach (MySqlSchemaRow row in entry.parameters.Rows)
                {
                    MySqlParameter p = new MySqlParameter();
                    p.ParameterName = String.Format("@{0}", row["PARAMETER_NAME"]);
                    if (row["ORDINAL_POSITION"].Equals(0) && p.ParameterName == "@")
                    {
                        p.ParameterName = "@RETURN_VALUE";
                    }
                    p.Direction = GetDirection(row);
                    bool unsigned      = StoredProcedure.GetFlags(row["DTD_IDENTIFIER"].ToString()).IndexOf("UNSIGNED") != -1;
                    bool real_as_float = entry.procedure.Rows[0]["SQL_MODE"].ToString().IndexOf("REAL_AS_FLOAT") != -1;
                    p.MySqlDbType = MetaData.NameToType(row["DATA_TYPE"].ToString(),
                                                        unsigned, real_as_float, command.Connection);
                    if (row["CHARACTER_MAXIMUM_LENGTH"] != null)
                    {
                        p.Size = (int)row["CHARACTER_MAXIMUM_LENGTH"];
                    }
#if NET452 || DNX452 || NETSTANDARD1_3
                    if (row["NUMERIC_PRECISION"] != null)
                    {
                        p.Precision = Convert.ToByte(row["NUMERIC_PRECISION"]);
                    }
                    if (row["NUMERIC_SCALE"] != null)
                    {
                        p.Scale = Convert.ToByte(row["NUMERIC_SCALE"]);
                    }
#endif
                    if (p.MySqlDbType == MySqlDbType.Set || p.MySqlDbType == MySqlDbType.Enum)
                    {
                        p.PossibleValues = GetPossibleValues(row);
                    }
                    command.Parameters.Add(p);
                }
            }
            catch (InvalidOperationException ioe)
            {
                throw new MySqlException(Resources.UnableToDeriveParameters, ioe);
            }
        }
        private static ProcedureCacheEntry GetProcData(MySqlConnection connection, string spName)
        {
            string schema = String.Empty;
            string name   = spName;

            int dotIndex = spName.IndexOf(".");

            if (dotIndex != -1)
            {
                schema = spName.Substring(0, dotIndex);
                name   = spName.Substring(dotIndex + 1, spName.Length - dotIndex - 1);
            }

            string[] restrictions = new string[4];
            restrictions[1] = schema.Length > 0 ? schema : connection.CurrentDatabase();
            restrictions[2] = name;
            MySqlSchemaCollection proc = connection.GetSchemaCollection("procedures", restrictions);

            if (proc.Rows.Count > 1)
            {
                throw new MySqlException(Resources.ProcAndFuncSameName);
            }
            if (proc.Rows.Count == 0)
            {
                throw new MySqlException(String.Format(Resources.InvalidProcName, name, schema));
            }

            ProcedureCacheEntry entry = new ProcedureCacheEntry();

            entry.procedure = proc;

            // we don't use GetSchema here because that would cause another
            // query of procedures and we don't need that since we already
            // know the procedure we care about.
            ISSchemaProvider isp = new ISSchemaProvider(connection);

            string[] rest = isp.CleanRestrictions(restrictions);
            MySqlSchemaCollection parameters = isp.GetProcedureParameters(rest, proc);

            entry.parameters = parameters;

            return(entry);
        }
Exemple #6
0
        private MySqlParameterCollection CheckParameters(string spName)
        {
            MySqlParameterCollection newParms        = new MySqlParameterCollection(command);
            MySqlParameter           returnParameter = GetReturnParameter();

            ProcedureCacheEntry entry = GetParameters(spName);

            if (entry.procedure == null || entry.procedure.Rows.Count == 0)
            {
                throw new InvalidOperationException(String.Format(Resources.RoutineNotFound, spName));
            }

            bool realAsFloat = entry.procedure.Rows[0]["SQL_MODE"].ToString().IndexOf("REAL_AS_FLOAT") != -1;

            foreach (MySqlSchemaRow param in entry.parameters.Rows)
            {
                newParms.Add(GetAndFixParameter(spName, param, realAsFloat, returnParameter));
            }
            return(newParms);
        }
 internal string GetCacheKey(string spName, ProcedureCacheEntry proc)
 {
   string retValue = String.Empty;
   StringBuilder key = new StringBuilder(spName);
   key.Append("(");
   string delimiter = "";
   if (proc.parameters != null)
   {
     foreach (MySqlSchemaRow row in proc.parameters.Rows)
     {
       if (row["ORDINAL_POSITION"].Equals(0))
         retValue = "?=";
       else
       {
         key.AppendFormat(CultureInfo.InvariantCulture, "{0}?", delimiter);
         delimiter = ",";
       }
     }
   }
   key.Append(")");
   return retValue + key.ToString();
 }
        private ProcedureCacheEntry AddNew(MySqlConnection connection, string spName)
        {
            ProcedureCacheEntry procData = GetProcData(connection, spName);

            if (maxSize > 0)
            {
                string cacheKey = GetCacheKey(spName, procData);
                int    hash     = cacheKey.GetHashCode();
                lock (procHash)
                {
                    if (procHash.Keys.Count >= maxSize)
                    {
                        TrimHash();
                    }
                    if (!procHash.ContainsKey(hash))
                    {
                        procHash[hash] = procData;
                        hashQueue.Enqueue(hash);
                    }
                }
            }
            return(procData);
        }
    private static ProcedureCacheEntry GetProcData(MySqlConnection connection, string spName)
    {
      string schema = String.Empty;
      string name = spName;

      int dotIndex = spName.IndexOf(".");
      if (dotIndex != -1)
      {
        schema = spName.Substring(0, dotIndex);
        name = spName.Substring(dotIndex + 1, spName.Length - dotIndex - 1);
      }

      string[] restrictions = new string[4];
      restrictions[1] = schema.Length > 0 ? schema : connection.CurrentDatabase();
      restrictions[2] = name;
      MySqlSchemaCollection proc = connection.GetSchemaCollection("procedures", restrictions);
      if (proc.Rows.Count > 1)
        throw new MySqlException(Resources.ProcAndFuncSameName);
      if (proc.Rows.Count == 0)
        throw new MySqlException(String.Format(Resources.InvalidProcName, name, schema));

      ProcedureCacheEntry entry = new ProcedureCacheEntry();
      entry.procedure = proc;

      // we don't use GetSchema here because that would cause another
      // query of procedures and we don't need that since we already
      // know the procedure we care about.
      ISSchemaProvider isp = new ISSchemaProvider(connection);
      string[] rest = isp.CleanRestrictions(restrictions);
      MySqlSchemaCollection parameters = isp.GetProcedureParameters(rest, proc);
      entry.parameters = parameters;

      return entry;
    }