internal void ProcessOutputParameters(MyCatDataReader reader) { // We apparently need to always adjust our output types since the server // provided data types are not always right AdjustOutputTypes(reader); if ((reader.CommandBehavior & CommandBehavior.SchemaOnly) != 0) { return; } // now read the output parameters data row reader.Read(); string prefix = "@" + StoredProcedure.ParameterPrefix; for (int i = 0; i < reader.FieldCount; i++) { string fieldName = reader.GetName(i); if (fieldName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { fieldName = fieldName.Remove(0, prefix.Length); } MyCatParameter parameter = command.Parameters.GetParameterFlexible(fieldName, true); parameter.Value = reader.GetValue(i); } }
private void ProcessOutputParameters() { // if we are not 5.5 or later or we are not prepared then we are simulating output parameters // with user variables and they are also string so we have to work some magic with out // column types before we read the data if (!driver.SupportsOutputParameters || !command.IsPrepared) { AdjustOutputTypes(); } // now read the output parameters data row if ((commandBehavior & CommandBehavior.SchemaOnly) != 0) { return; } resultSet.NextRow(commandBehavior); string prefix = "@" + StoredProcedure.ParameterPrefix; for (int i = 0; i < FieldCount; i++) { string fieldName = GetName(i); if (fieldName.StartsWith(prefix)) { fieldName = fieldName.Remove(0, prefix.Length); } MyCatParameter parameter = command.Parameters.GetParameterFlexible(fieldName, true); parameter.Value = GetValue(i); } }
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); }
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())); } }
/// <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); }
private MyCatParameter GetAndFixParameter(string spName, MyCatSchemaRow param, bool realAsFloat, MyCatParameter returnParameter) { string mode = (string)param["PARAMETER_MODE"]; string pName = (string)param["PARAMETER_NAME"]; if (param["ORDINAL_POSITION"].Equals(0)) { if (returnParameter == null) { throw new InvalidOperationException( String.Format(Resources.RoutineRequiresReturnParameter, spName)); } pName = returnParameter.ParameterName; } // make sure the parameters given to us have an appropriate type set if it's not already MyCatParameter p = command.Parameters.GetParameterFlexible(pName, true); if (!p.TypeHasBeenSet) { string datatype = (string)param["DATA_TYPE"]; bool unsigned = GetFlags(param["DTD_IDENTIFIER"].ToString()).IndexOf("UNSIGNED") != -1; p.MyCatDbType = MetaData.NameToType(datatype, unsigned, realAsFloat, Connection); } return(p); }
internal MyCatParameter GetParameterFlexible(string parameterName, bool throwOnNotFound) { string baseName = parameterName; MyCatParameter p = GetParameterFlexibleInternal(baseName); if (p != null) { return(p); } if (parameterName.StartsWith("@", StringComparison.Ordinal) || parameterName.StartsWith("?", StringComparison.Ordinal)) { baseName = parameterName.Substring(1); } p = GetParameterFlexibleInternal(baseName); if (p != null) { return(p); } if (throwOnNotFound) { throw new ArgumentException("Parameter '" + parameterName + "' not found in the collection."); } return(null); }
private void AdjustOutputTypes() { // since MySQL likes to return user variables as strings // we reset the types of the readers internal value objects // this will allow those value objects to parse the string based // return values for (int i = 0; i < FieldCount; i++) { string fieldName = GetName(i); fieldName = fieldName.Remove(0, StoredProcedure.ParameterPrefix.Length + 1); MyCatParameter parameter = command.Parameters.GetParameterFlexible(fieldName, true); IMyCatValue v = MyCatField.GetIMyCatValue(parameter.MyCatDbType); if (v is MyCatBit) { MyCatBit bit = (MyCatBit)v; bit.ReadAsString = true; resultSet.SetValueObject(i, bit); } else { resultSet.SetValueObject(i, v); } } }
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(InstanceDescriptor)) { ConstructorInfo ci = typeof(MyCatParameter).GetConstructor( new Type[] { typeof(string), typeof(MyCatDbType), typeof(int), typeof(ParameterDirection), typeof(bool), typeof(byte), typeof(byte), typeof(string), typeof(DataRowVersion), typeof(object) }); MyCatParameter p = (MyCatParameter)value; return(new InstanceDescriptor(ci, new object[] { p.ParameterName, p.DbType, p.Size, p.Direction, p.IsNullable, p.Precision, p.Scale, p.SourceColumn, p.SourceVersion, p.Value })); } // Always call base, even if you can't convert. return(base.ConvertTo(context, culture, value, destinationType)); }
/// <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); } }
public virtual void Prepare() { // strip out names from parameter markers string text; List <string> parameter_names = PrepareCommandText(out text); // ask our connection to send the prepare command MyCatField[] paramList = null; statementId = Driver.PrepareStatement(text, ref paramList); // now we need to assign our field names since we stripped them out // for the prepare for (int i = 0; i < parameter_names.Count; i++) { //paramList[i].ColumnName = (string) parameter_names[i]; string parameterName = (string)parameter_names[i]; MyCatParameter p = Parameters.GetParameterFlexible(parameterName, false); if (p == null) { throw new InvalidOperationException( String.Format(Resources.ParameterNotFoundDuringPrepare, parameterName)); } p.Encoding = paramList[i].Encoding; parametersToSend.Add(p); } // now prepare our null map int numNullBytes = 0; if (paramList != null && paramList.Length > 0) { #if NET451 nullMap = new BitArray(paramList.Length); #else nullMap = new RtBitArray(paramList.Length); #endif numNullBytes = (nullMap.Count + 7) / 8; } packet = new MyCatPacket(Driver.Encoding); // write out some values that do not change run to run packet.WriteByte(0); packet.WriteInteger(statementId, 4); packet.WriteByte((byte)0); // flags; always 0 for 4.1 packet.WriteInteger(1, 4); // interation count; 1 for 4.1 nullMapPosition = packet.Position; packet.Position += numNullBytes; // leave room for our null map packet.WriteByte(1); // rebound flag // write out the parameter types foreach (MyCatParameter p in parametersToSend) { packet.WriteInteger(p.GetPSType(), 2); } dataPosition = packet.Position; }
internal void ParameterNameChanged(MyCatParameter p, string oldName, string newName) { int index = IndexOf(oldName); indexHashCS.Remove(oldName); indexHashCI.Remove(oldName); indexHashCS.Add(newName, index); indexHashCI.Add(newName, index); }
/// <summary> /// Inserts a MyCatParameter into the collection at the specified index. /// </summary> /// <param name="index"></param> /// <param name="value"></param> public override void Insert(int index, object value) { MyCatParameter parameter = value as MyCatParameter; if (parameter == null) { throw new MyCatException("Only MyCatParameter objects may be stored"); } InternalAdd(parameter, index); }
/// <summary> /// Gets the location of a <see cref="MyCatParameter"/> in the collection. /// </summary> /// <param name="value">The <see cref="MyCatParameter"/> object to locate. </param> /// <returns>The zero-based location of the <see cref="MyCatParameter"/> in the collection.</returns> /// <overloads>Gets the location of a <see cref="MyCatParameter"/> in the collection.</overloads> public override int IndexOf(object value) { MyCatParameter parameter = value as MyCatParameter; if (null == parameter) { throw new ArgumentException("Argument must be of type DbParameter", "value"); } return(items.IndexOf(parameter)); }
private void InternalSetParameter(string parameterName, MyCatParameter value) { int index = IndexOf(parameterName); if (index < 0) { throw new ArgumentException("Parameter '" + parameterName + "' not found in the collection."); } InternalSetParameter(index, value); }
public MyCatParameter Clone() { #if NETSTANDARD1_3 MyCatParameter clone = new MyCatParameter(paramName, mySqlDbType); #else MyCatParameter clone = new MyCatParameter(paramName, mySqlDbType, Direction, SourceColumn, SourceVersion, paramValue); #endif // if we have not had our type set yet then our clone should not either clone.inferType = inferType; return(clone); }
/// <summary> /// Adds the specified <see cref="MyCatParameter"/> object to the <see cref="MyCatParameterCollection"/>. /// </summary> /// <param name="value">The <see cref="MyCatParameter"/> to add to the collection.</param> /// <returns>The index of the new <see cref="MyCatParameter"/> object.</returns> public override int Add(object value) { MyCatParameter parameter = value as MyCatParameter; if (parameter == null) { throw new MyCatException("Only MyCatParameter objects may be stored"); } parameter = Add(parameter); return(IndexOf(parameter)); }
/// <summary> /// Removes the specified MyCatParameter from the collection. /// </summary> /// <param name="value"></param> public override void Remove(object value) { MyCatParameter p = (value as MyCatParameter); p.Collection = null; int index = IndexOf(p); items.Remove(p); indexHashCS.Remove(p.ParameterName); indexHashCI.Remove(p.ParameterName); AdjustHashes(index, false); }
public override void Execute() { // if we are not prepared, then call down to our base if (!IsPrepared) { base.Execute(); return; } //TODO: support long data here // create our null bitmap // we check this because Mono doesn't ignore the case where nullMapBytes // is zero length. // if (nullMapBytes.Length > 0) // { // byte[] bits = packet.Buffer; // nullMap.CopyTo(bits, // nullMap.CopyTo(nullMapBytes, 0); // start constructing our packet // if (Parameters.Count > 0) // nullMap.CopyTo(packet.Buffer, nullMapPosition); //if (parameters != null && parameters.Count > 0) //else // packet.WriteByte( 0 ); //TODO: only send rebound if parms change // now write out all non-null values packet.Position = dataPosition; for (int i = 0; i < parametersToSend.Count; i++) { MyCatParameter p = parametersToSend[i]; nullMap[i] = (p.Value == DBNull.Value || p.Value == null) || p.Direction == ParameterDirection.Output; if (nullMap[i]) { continue; } packet.Encoding = p.Encoding; p.Serialize(packet, true, Connection.Settings); } if (nullMap != null) { nullMap.CopyTo(packet.Buffer, nullMapPosition); } executionCount++; Driver.ExecuteStatement(packet); }
private MyCatParameter InternalAdd(MyCatParameter value, int index) { if (value == null) { throw new ArgumentException("The MyCatParameterCollection only accepts non-null MyCatParameter type objects.", "value"); } // if the parameter is unnamed, then assign a default name if (String.IsNullOrEmpty(value.ParameterName)) { value.ParameterName = String.Format("Parameter{0}", GetNextIndex()); } // make sure we don't already have a parameter with this name if (IndexOf(value.ParameterName) >= 0) { throw new MyCatException( String.Format(Resources.ParameterAlreadyDefined, value.ParameterName)); } else { string inComingName = value.ParameterName; if (inComingName[0] == '@' || inComingName[0] == '?') { inComingName = inComingName.Substring(1, inComingName.Length - 1); } if (IndexOf(inComingName) >= 0) { throw new MyCatException( String.Format(Resources.ParameterAlreadyDefined, value.ParameterName)); } } if (index == -1) { items.Add(value); index = items.Count - 1; } else { items.Insert(index, value); AdjustHashes(index, true); } indexHashCS.Add(value.ParameterName, index); indexHashCI.Add(value.ParameterName, index); value.Collection = this; return(value); }
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 void InternalSetParameter(int index, MyCatParameter value) { MyCatParameter newParameter = value as MyCatParameter; if (newParameter == null) { throw new ArgumentException(Resources.NewValueShouldBeMyCatParameter); } CheckIndex(index); MyCatParameter p = (MyCatParameter)items[index]; // first we remove the old parameter from our hashes indexHashCS.Remove(p.ParameterName); indexHashCI.Remove(p.ParameterName); // then we add in the new parameter items[index] = newParameter; indexHashCS.Add(value.ParameterName, index); indexHashCI.Add(value.ParameterName, index); }
/// <summary> /// Adds the specified <see cref="MyCatParameter"/> object to the <see cref="MyCatParameterCollection"/>. /// </summary> /// <param name="value">The <see cref="MyCatParameter"/> to add to the collection.</param> /// <returns>The newly added <see cref="MyCatParameter"/> object.</returns> public MyCatParameter Add(MyCatParameter value) { return(InternalAdd(value, -1)); }