/// <summary> /// Serializes the given parameter to the given memory stream /// </summary> /// <remarks> /// <para>This method is called by PrepareSqlBuffers to convert the given /// parameter to bytes and write those bytes to the given memory stream. /// </para> /// </remarks> /// <returns>True if the parameter was successfully serialized, false otherwise.</returns> private bool SerializeParameter(MyCatParameterCollection parameters, MyCatPacket packet, string parmName, int parameterIndex) { MyCatParameter parameter = null; if (!parameters.containsUnnamedParameters) { parameter = parameters.GetParameterFlexible(parmName, false); } else { if (parameterIndex <= parameters.Count) { parameter = parameters[parameterIndex]; } else { throw new MyCatException(Resources.ParameterIndexNotFound); } } if (parameter == null) { // if we are allowing user variables and the parameter name starts with @ // then we can't throw an exception if (parmName.StartsWith("@", StringComparison.Ordinal) && ShouldIgnoreMissingParameter(parmName)) { return(false); } throw new MyCatException( String.Format(Resources.ParameterMustBeDefined, parmName)); } parameter.Serialize(packet, false, Connection.Settings); return(true); }
public override void Resolve(bool preparing) { // check to see if we are already resolved if (resolvedCommandText != null) { return; } serverProvidingOutputParameters = Driver.SupportsOutputParameters && preparing; // first retrieve the procedure definition from our // procedure cache string spName = commandText; if (spName.IndexOf(".") == -1 && !String.IsNullOrEmpty(Connection.Database)) { spName = Connection.Database + "." + spName; } spName = FixProcedureName(spName); MyCatParameter returnParameter = GetReturnParameter(); MyCatParameterCollection parms = command.Connection.Settings.CheckParameters ? CheckParameters(spName) : Parameters; string setSql = SetUserVariables(parms, preparing); string callSql = CreateCallStatement(spName, returnParameter, parms); string outSql = CreateOutputSelect(parms, preparing); resolvedCommandText = String.Format("{0}{1}{2}", setSql, callSql, outSql); }
/// <include file='docs/mysqlcommand.xml' path='docs/ctor1/*'/> public MyCatCommand() { cmdType = CommandType.Text; parameters = new MyCatParameterCollection(this); cmdText = String.Empty; useDefaultTimeout = true; Constructor(); }
protected virtual void BindParameters() { MyCatParameterCollection parameters = command.Parameters; int index = 0; while (true) { InternalBindParameters(ResolvedCommandText, parameters, null); // if we are not batching, then we are done. This is only really relevant the // first time through if (command.Batch == null) { return; } while (index < command.Batch.Count) { MyCatCommand batchedCmd = command.Batch[index++]; MyCatPacket packet = (MyCatPacket)buffers[buffers.Count - 1]; // now we make a guess if this statement will fit in our current stream long estimatedCmdSize = batchedCmd.EstimatedSize(); if (((packet.Length - 4) + estimatedCmdSize) > Connection.driver.MaxPacketSize) { // it won't, so we setup to start a new run from here parameters = batchedCmd.Parameters; break; } // looks like we might have room for it so we remember the current end of the stream buffers.RemoveAt(buffers.Count - 1); //long originalLength = packet.Length - 4; // and attempt to stream the next command string text = ResolvedCommandText; if (text.StartsWith("(", StringComparison.Ordinal)) { packet.WriteStringNoNull(", "); } else { packet.WriteStringNoNull("; "); } InternalBindParameters(text, batchedCmd.Parameters, packet); if ((packet.Length - 4) > Connection.driver.MaxPacketSize) { //TODO //stream.InternalBuffer.SetLength(originalLength); parameters = batchedCmd.Parameters; break; } } if (index == command.Batch.Count) { return; } } }
private void InternalBindParameters(string sql, MyCatParameterCollection parameters, MyCatPacket packet) { bool sqlServerMode = command.Connection.Settings.SqlServerMode; if (packet == null) { packet = new MyCatPacket(Driver.Encoding); packet.Version = Driver.Version; packet.WriteByte(0); } MyCatTokenizer tokenizer = new MyCatTokenizer(sql); tokenizer.ReturnComments = true; tokenizer.SqlServerMode = sqlServerMode; int pos = 0; string token = tokenizer.NextToken(); int parameterCount = 0; while (token != null) { // serialize everything that came before the token (i.e. whitespace) packet.WriteStringNoNull(sql.Substring(pos, tokenizer.StartIndex - pos)); pos = tokenizer.StopIndex; if (MyCatTokenizer.IsParameter(token)) { if ((!parameters.containsUnnamedParameters && token.Length == 1 && parameterCount > 0) || parameters.containsUnnamedParameters && token.Length > 1) { throw new MyCatException(Resources.MixedParameterNamingNotAllowed); } parameters.containsUnnamedParameters = token.Length == 1; if (SerializeParameter(parameters, packet, token, parameterCount)) { token = null; } parameterCount++; } if (token != null) { if (sqlServerMode && tokenizer.Quoted && token.StartsWith("[", StringComparison.Ordinal)) { token = String.Format("`{0}`", token.Substring(1, token.Length - 2)); } packet.WriteStringNoNull(token); } token = tokenizer.NextToken(); } buffers.Add(packet); }
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 string SetUserVariables(MyCatParameterCollection parms, bool preparing) { StringBuilder setSql = new StringBuilder(); if (serverProvidingOutputParameters) { return(setSql.ToString()); } string delimiter = String.Empty; foreach (MyCatParameter p in parms) { if (p.Direction != ParameterDirection.InputOutput) { continue; } string pName = "@" + p.BaseName; string uName = "@" + ParameterPrefix + p.BaseName; string sql = String.Format("SET {0}={1}", uName, pName); if (command.Connection.Settings.AllowBatch && !preparing) { setSql.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", delimiter, sql); delimiter = "; "; } else { MyCatCommand cmd = new MyCatCommand(sql, command.Connection); cmd.Parameters.Add(p); cmd.ExecuteNonQuery(); } } if (setSql.Length > 0) { setSql.Append("; "); } return(setSql.ToString()); }
private string CreateOutputSelect(MyCatParameterCollection parms, bool preparing) { StringBuilder outSql = new StringBuilder(); string delimiter = String.Empty; foreach (MyCatParameter p in parms) { if (p.Direction == ParameterDirection.Input) { continue; } if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Output) && serverProvidingOutputParameters) { continue; } string pName = "@" + p.BaseName; string uName = "@" + ParameterPrefix + p.BaseName; outSql.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", delimiter, uName); delimiter = ", "; } if (outSql.Length == 0) { return(String.Empty); } if (command.Connection.Settings.AllowBatch && !preparing) { return(String.Format(";SELECT {0}", outSql.ToString())); } outSelect = String.Format("SELECT {0}", outSql.ToString()); return(String.Empty); }
private string CreateCallStatement(string spName, MyCatParameter returnParameter, MyCatParameterCollection parms) { StringBuilder callSql = new StringBuilder(); string delimiter = String.Empty; foreach (MyCatParameter p in parms) { if (p.Direction == ParameterDirection.ReturnValue) { continue; } string pName = "@" + p.BaseName; string uName = "@" + ParameterPrefix + p.BaseName; bool useRealVar = p.Direction == ParameterDirection.Input || serverProvidingOutputParameters; callSql.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", delimiter, useRealVar ? pName : uName); delimiter = ", "; } if (returnParameter == null) { return(String.Format("CALL {0}({1})", spName, callSql.ToString())); } else { return(String.Format("SET @{0}{1}={2}({3})", ParameterPrefix, returnParameter.BaseName, spName, callSql.ToString())); } }