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 (MyCatSchemaRow 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(MyCatConnection 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) { MyCatTrace.LogInformation(conn.ServerThread, String.Format(Resources.HardProcQuery, spName)); } } else { conn.PerfMonitor.AddSoftProcedureQuery(); if (conn.Settings.Logging) { MyCatTrace.LogInformation(conn.ServerThread, String.Format(Resources.SoftProcQuery, spName)); } } return(proc); }
private ProcedureCacheEntry GetParameters(string procName) { string procCacheKey = GetCacheKey(procName); ProcedureCacheEntry entry = Connection.ProcedureCache.GetProcedure(Connection, procName, procCacheKey); return(entry); }
/// <summary> /// Retrieves parameter information from the stored procedure specified /// in the MyCatCommand and populates the Parameters collection of the /// specified MyCatCommand object. /// This method is not currently supported since stored procedures are /// not available in MyCat. /// </summary> /// <param name="command">The MyCatCommand referencing the stored /// procedure from which the parameter information is to be derived. /// The derived parameters are added to the Parameters collection of the /// MyCatCommand.</param> /// <exception cref="InvalidOperationException">The command text is not /// a valid stored procedure name.</exception> public static void DeriveParameters(MyCatCommand 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 (MyCatSchemaRow row in entry.parameters.Rows) { MyCatParameter p = new MyCatParameter(); 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.MyCatDbType = 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.MyCatDbType == MyCatDbType.Set || p.MyCatDbType == MyCatDbType.Enum) { p.PossibleValues = GetPossibleValues(row); } command.Parameters.Add(p); } } catch (InvalidOperationException ioe) { throw new MyCatException(Resources.UnableToDeriveParameters, ioe); } }
private static ProcedureCacheEntry GetProcData(MyCatConnection 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; MyCatSchemaCollection proc = connection.GetSchemaCollection("procedures", restrictions); if (proc.Rows.Count > 1) { throw new MyCatException(Resources.ProcAndFuncSameName); } if (proc.Rows.Count == 0) { throw new MyCatException(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); MyCatSchemaCollection parameters = isp.GetProcedureParameters(rest, proc); entry.parameters = parameters; return(entry); }
private MyCatParameterCollection CheckParameters(string spName) { MyCatParameterCollection newParms = new MyCatParameterCollection(command); MyCatParameter 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 (MyCatSchemaRow param in entry.parameters.Rows) { newParms.Add(GetAndFixParameter(spName, param, realAsFloat, returnParameter)); } return(newParms); }
private ProcedureCacheEntry AddNew(MyCatConnection 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); }