From: Date: October 23 2006 6:57pm Subject: Connector/NET commit: r428 - in trunk: . TestSuite mysqlclient List-Archive: http://lists.mysql.com/commits/14200 X-Bug: 23538 Message-Id: <200610231657.k9NGvTbB023134@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: trunk/CHANGES trunk/TestSuite/DataReaderTests.cs trunk/mysqlclient/datareader.cs Log: Bug #23538 Exception thrown when GetSchemaTable is called and "fields" is null. Modified: trunk/CHANGES =================================================================== --- trunk/CHANGES 2006-10-23 15:44:57 UTC (rev 427) +++ trunk/CHANGES 2006-10-23 16:57:27 UTC (rev 428) @@ -3,6 +3,7 @@ Bugs fixed ---------- Bug #23268 System.FormatException when invoking procedure with ENUM input parameter + Bug #23538 Exception thrown when GetSchemaTable is called and "fields" is null. Other changes ------------- Modified: trunk/TestSuite/DataReaderTests.cs =================================================================== --- trunk/TestSuite/DataReaderTests.cs 2006-10-23 15:44:57 UTC (rev 427) +++ trunk/TestSuite/DataReaderTests.cs 2006-10-23 16:57:27 UTC (rev 428) @@ -840,5 +840,23 @@ reader.Close(); } } + + /// + /// Bug #23538 Exception thrown when GetSchemaTable is called and "fields" is null. + /// + [Category("5.0")] + [Test] + public void GetSchemaTableOnEmptyResultset() + { + execSQL("CREATE PROCEDURE spTest() BEGIN END"); + + MySqlCommand cmd = new MySqlCommand("spTest", conn); + cmd.CommandType = CommandType.StoredProcedure; + using (MySqlDataReader reader = cmd.ExecuteReader()) + { + DataTable dt = reader.GetSchemaTable(); + Assert.IsNull(dt); + } + } } } Modified: trunk/mysqlclient/datareader.cs =================================================================== --- trunk/mysqlclient/datareader.cs 2006-10-23 15:44:57 UTC (rev 427) +++ trunk/mysqlclient/datareader.cs 2006-10-23 16:57:27 UTC (rev 428) @@ -31,24 +31,24 @@ public sealed class MySqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord { // The DataReader should always be open when returned to the user. - private bool isOpen = true; + private bool isOpen = true; // Keep track of the results and position // within the resultset (starts prior to first record). private MySqlField[] fields; - internal IMySqlValue[] values; - private CommandBehavior commandBehavior; + internal IMySqlValue[] values; + private CommandBehavior commandBehavior; private MySqlCommand command; private bool canRead; private bool hasRows; - private long affectedRows; + private long affectedRows; private bool[] uaFieldsUsed; - private Driver driver; - private long lastInsertId; - private PreparableStatement statement; - private int seqIndex; - private bool hasRead; - private bool nextResultDone; + private Driver driver; + private long lastInsertId; + private PreparableStatement statement; + private int seqIndex; + private bool hasRead; + private bool nextResultDone; /* * Keep track of the connection in order to implement the @@ -67,121 +67,121 @@ this.command = cmd; connection = (MySqlConnection)command.Connection; commandBehavior = behavior; - driver = connection.driver; - affectedRows = -1; - this.statement = statement; - nextResultDone = false; - } + driver = connection.driver; + affectedRows = -1; + this.statement = statement; + nextResultDone = false; + } - #region Properties + #region Properties - internal long InsertedId - { - get { return this.lastInsertId; } - } + internal long InsertedId + { + get { return this.lastInsertId; } + } - internal CommandBehavior Behavior + internal CommandBehavior Behavior { get { return commandBehavior; } } - /// - /// Gets a value indicating the depth of nesting for the current row. This method is not - /// supported currently and always returns 0. - /// - public override int Depth - { - get { return 0; } - } + /// + /// Gets a value indicating the depth of nesting for the current row. This method is not + /// supported currently and always returns 0. + /// + public override int Depth + { + get { return 0; } + } - /// - /// Gets the number of columns in the current row. - /// - public override int FieldCount - { - // Return the count of the number of columns, which in - // this case is the size of the column metadata - // array. - get - { - if (fields != null) - return fields.Length; - return 0; - } - } + /// + /// Gets the number of columns in the current row. + /// + public override int FieldCount + { + // Return the count of the number of columns, which in + // this case is the size of the column metadata + // array. + get + { + if (fields != null) + return fields.Length; + return 0; + } + } - /// - /// Gets a value indicating whether the MySqlDataReader contains one or more rows. - /// - public override bool HasRows - { - get { return hasRows; } - } + /// + /// Gets a value indicating whether the MySqlDataReader contains one or more rows. + /// + public override bool HasRows + { + get { return hasRows; } + } - /// + /// /// Gets a value indicating whether the data reader is closed. /// public override bool IsClosed { - get { return ! isOpen; } + get { return !isOpen; } } - /// - /// Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. - /// - public override int RecordsAffected - { - // RecordsAffected returns the number of rows affected in batch - // statments from insert/delete/update statments. This property - // is not completely accurate until .Close() has been called. - get { return (int)affectedRows; } - } + /// + /// Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. + /// + public override int RecordsAffected + { + // RecordsAffected returns the number of rows affected in batch + // statments from insert/delete/update statments. This property + // is not completely accurate until .Close() has been called. + get { return (int)affectedRows; } + } - /// - /// Overloaded. Gets the value of a column in its native format. - /// In C#, this property is the indexer for the MySqlDataReader class. - /// - public override object this[int i] - { - get { return GetValue(i); } - } + /// + /// Overloaded. Gets the value of a column in its native format. + /// In C#, this property is the indexer for the MySqlDataReader class. + /// + public override object this[int i] + { + get { return GetValue(i); } + } - /// - /// Gets the value of a column in its native format. - /// [C#] In C#, this property is the indexer for the MySqlDataReader class. - /// - public override object this[String name] - { - // Look up the ordinal and return - // the value at that position. - get { return this[GetOrdinal(name)]; } - } + /// + /// Gets the value of a column in its native format. + /// [C#] In C#, this property is the indexer for the MySqlDataReader class. + /// + public override object this[String name] + { + // Look up the ordinal and return + // the value at that position. + get { return this[GetOrdinal(name)]; } + } - #endregion + #endregion /// /// Closes the MySqlDataReader object. /// public override void Close() { - if (! isOpen) return; + if (!isOpen) return; - bool shouldCloseConnection = (commandBehavior & CommandBehavior.CloseConnection) != 0; - commandBehavior = CommandBehavior.Default; + bool shouldCloseConnection = (commandBehavior & CommandBehavior.CloseConnection) != 0; + commandBehavior = CommandBehavior.Default; connection.Reader = null; - // we set the nextResultDone var to true inside NextResult when - // it returns false. This allows us to avoid calling NextResult - // here unnecessarily. Calling NextResult here will work but this - // is just an optimization. - if (!nextResultDone) - while (NextResult()) { } + // we set the nextResultDone var to true inside NextResult when + // it returns false. This allows us to avoid calling NextResult + // here unnecessarily. Calling NextResult here will work but this + // is just an optimization. + if (!nextResultDone) + while (NextResult()) { } - // we now give the command a chance to terminate. In the case of - // stored procedures it needs to update out and inout parameters - command.Close(); + // we now give the command a chance to terminate. In the case of + // stored procedures it needs to update out and inout parameters + command.Close(); - if (shouldCloseConnection) + if (shouldCloseConnection) connection.Close(); isOpen = false; @@ -189,10 +189,10 @@ #region TypeSafe Accessors - public bool GetBoolean(string name) - { - return GetBoolean(GetOrdinal(name)); - } + public bool GetBoolean(string name) + { + return GetBoolean(GetOrdinal(name)); + } /// /// Gets the value of the specified column as a Boolean. @@ -204,10 +204,10 @@ return Convert.ToBoolean(GetValue(i)); } - public byte GetByte(string name) - { - return GetByte(GetOrdinal(name)); - } + public byte GetByte(string name) + { + return GetByte(GetOrdinal(name)); + } /// /// Gets the value of the specified column as a byte. @@ -235,43 +235,43 @@ /// public override long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex, int length) { - if (i >= fields.Length) + if (i >= fields.Length) throw new IndexOutOfRangeException(); IMySqlValue val = GetFieldValue(i, false); - if (! (val is MySqlBinary)) + if (!(val is MySqlBinary)) throw new MySqlException("GetBytes can only be called on binary columns"); MySqlBinary binary = (MySqlBinary)val; - if (buffer == null) + if (buffer == null) return (long)binary.Value.Length; if (bufferIndex >= buffer.Length || bufferIndex < 0) throw new IndexOutOfRangeException("Buffer index must be a valid index in buffer"); if (buffer.Length < (bufferIndex + length)) - throw new ArgumentException( "Buffer is not large enough to hold the requested data" ); - if (dataIndex < 0 || + throw new ArgumentException("Buffer is not large enough to hold the requested data"); + if (dataIndex < 0 || ((ulong)dataIndex >= (ulong)binary.Value.Length && (ulong)binary.Value.Length > 0)) - throw new IndexOutOfRangeException( "Data index must be a valid index in the field" ); + throw new IndexOutOfRangeException("Data index must be a valid index in the field"); - byte[] bytes = (byte[])binary.Value; + byte[] bytes = (byte[])binary.Value; // adjust the length so we don't run off the end - if ( (ulong)binary.Value.Length < (ulong)(dataIndex+length)) + if ((ulong)binary.Value.Length < (ulong)(dataIndex + length)) { length = (int)((ulong)binary.Value.Length - (ulong)dataIndex); } - Array.Copy( bytes, (int)dataIndex, buffer, (int)bufferIndex, (int)length ); + Array.Copy(bytes, (int)dataIndex, buffer, (int)bufferIndex, (int)length); return length; } - public char GetChar(string name) - { - return GetChar(GetOrdinal(name)); - } + public char GetChar(string name) + { + return GetChar(GetOrdinal(name)); + } /// /// Gets the value of the specified column as a single character. @@ -295,7 +295,7 @@ /// public override long GetChars(int i, long fieldOffset, char[] buffer, int bufferoffset, int length) { - if (i >= fields.Length) + if (i >= fields.Length) throw new IndexOutOfRangeException(); string valAsString = GetString(i); @@ -305,13 +305,13 @@ if (bufferoffset >= buffer.Length || bufferoffset < 0) throw new IndexOutOfRangeException("Buffer index must be a valid index in buffer"); if (buffer.Length < (bufferoffset + length)) - throw new ArgumentException( "Buffer is not large enough to hold the requested data" ); - if (fieldOffset < 0 || fieldOffset >= valAsString.Length ) - throw new IndexOutOfRangeException( "Field offset must be a valid index in the field" ); - + throw new ArgumentException("Buffer is not large enough to hold the requested data"); + if (fieldOffset < 0 || fieldOffset >= valAsString.Length) + throw new IndexOutOfRangeException("Field offset must be a valid index in the field"); + if (valAsString.Length < length) length = valAsString.Length; - valAsString.CopyTo( (int)fieldOffset, buffer, bufferoffset, length ); + valAsString.CopyTo((int)fieldOffset, buffer, bufferoffset, length); return length; } @@ -322,43 +322,43 @@ /// public override String GetDataTypeName(int i) { - if (! isOpen) throw new Exception("No current query in data reader"); + if (!isOpen) throw new Exception("No current query in data reader"); if (i >= fields.Length) throw new IndexOutOfRangeException(); // return the name of the type used on the backend return values[i].MySqlTypeName; } - public MySqlDateTime GetMySqlDateTime(string name) - { - return GetMySqlDateTime(GetOrdinal(name)); - } - + public MySqlDateTime GetMySqlDateTime(string name) + { + return GetMySqlDateTime(GetOrdinal(name)); + } + /// public MySqlDateTime GetMySqlDateTime(int index) { return (MySqlDateTime)GetFieldValue(index, true); } - public DateTime GetDateTime(string name) - { - return GetDateTime(GetOrdinal(name)); - } + public DateTime GetDateTime(string name) + { + return GetDateTime(GetOrdinal(name)); + } /// public override DateTime GetDateTime(int index) { IMySqlValue val = GetFieldValue(index, true); - MySqlDateTime dt; + MySqlDateTime dt; - // we need to do this because functions like date_add return string - if (val is MySqlString) - { - string s = ((MySqlString)val).Value; - dt = MySqlDateTime.Parse(s, this.connection.driver.Version); - } - else - dt = (MySqlDateTime)val; + // we need to do this because functions like date_add return string + if (val is MySqlString) + { + string s = ((MySqlString)val).Value; + dt = MySqlDateTime.Parse(s, this.connection.driver.Version); + } + else + dt = (MySqlDateTime)val; if (connection.Settings.ConvertZeroDateTime && !dt.IsValidDateTime) return DateTime.MinValue; @@ -366,30 +366,30 @@ return dt.GetDateTime(); } - public Decimal GetDecimal(string name) - { - return GetDecimal(GetOrdinal(name)); - } + public Decimal GetDecimal(string name) + { + return GetDecimal(GetOrdinal(name)); + } /// public override Decimal GetDecimal(int index) { - IMySqlValue v = GetFieldValue(index, true); - if (v is MySqlDecimal) + IMySqlValue v = GetFieldValue(index, true); + if (v is MySqlDecimal) return ((MySqlDecimal)v).Value; return Convert.ToDecimal(v.Value); } - public double GetDouble(string name) - { - return GetDouble(GetOrdinal(name)); - } + public double GetDouble(string name) + { + return GetDouble(GetOrdinal(name)); + } /// public override double GetDouble(int index) { - IMySqlValue v = GetFieldValue(index, true); - if (v is MySqlDouble) + IMySqlValue v = GetFieldValue(index, true); + if (v is MySqlDouble) return ((MySqlDouble)v).Value; return Convert.ToDouble(v.Value); } @@ -401,36 +401,36 @@ /// public override Type GetFieldType(int i) { - if (! isOpen) throw new Exception("No current query in data reader"); + if (!isOpen) throw new Exception("No current query in data reader"); if (i >= fields.Length) throw new IndexOutOfRangeException(); if (values[i] is MySqlDateTime) - { - if (!connection.Settings.AllowZeroDateTime) - return typeof(DateTime); - return typeof(MySqlDateTime); - } + { + if (!connection.Settings.AllowZeroDateTime) + return typeof(DateTime); + return typeof(MySqlDateTime); + } return values[i].SystemType; } - public float GetFloat(string name) - { - return GetFloat(GetOrdinal(name)); - } + public float GetFloat(string name) + { + return GetFloat(GetOrdinal(name)); + } /// public override float GetFloat(int index) { - IMySqlValue v = GetFieldValue(index, true); - if (v is MySqlSingle) + IMySqlValue v = GetFieldValue(index, true); + if (v is MySqlSingle) return ((MySqlSingle)v).Value; return Convert.ToSingle(v.Value); } - public Guid GetGuid(string name) - { - return GetGuid(GetOrdinal(name)); - } + public Guid GetGuid(string name) + { + return GetGuid(GetOrdinal(name)); + } /// public override Guid GetGuid(int index) @@ -438,55 +438,55 @@ return new Guid(GetString(index)); } - public Int16 GetInt16(string name) - { - return GetInt16(GetOrdinal(name)); - } + public Int16 GetInt16(string name) + { + return GetInt16(GetOrdinal(name)); + } /// public override Int16 GetInt16(int index) { - IMySqlValue v = GetFieldValue(index, true); - if (v is MySqlInt16) + IMySqlValue v = GetFieldValue(index, true); + if (v is MySqlInt16) return ((MySqlInt16)v).Value; - - connection.UsageAdvisor.Converting(command.CommandText, - fields[index].ColumnName, v.MySqlTypeName, "Int16"); + + connection.UsageAdvisor.Converting(command.CommandText, + fields[index].ColumnName, v.MySqlTypeName, "Int16"); return ((IConvertible)v.Value).ToInt16(null); } - public Int32 GetInt32(string name) - { - return GetInt32(GetOrdinal(name)); - } + public Int32 GetInt32(string name) + { + return GetInt32(GetOrdinal(name)); + } /// public override Int32 GetInt32(int index) { - IMySqlValue v = GetFieldValue(index, true); - if (v is MySqlInt32) + IMySqlValue v = GetFieldValue(index, true); + if (v is MySqlInt32) return ((MySqlInt32)v).Value; - - connection.UsageAdvisor.Converting(command.CommandText, - fields[index].ColumnName, v.MySqlTypeName, "Int32"); - return ((IConvertible)v.Value).ToInt32(null); + + connection.UsageAdvisor.Converting(command.CommandText, + fields[index].ColumnName, v.MySqlTypeName, "Int32"); + return ((IConvertible)v.Value).ToInt32(null); } - public Int64 GetInt64(string name) - { - return GetInt64(GetOrdinal(name)); - } + public Int64 GetInt64(string name) + { + return GetInt64(GetOrdinal(name)); + } /// public override Int64 GetInt64(int index) { - IMySqlValue v = GetFieldValue(index, true); + IMySqlValue v = GetFieldValue(index, true); if (v is MySqlInt64) return ((MySqlInt64)v).Value; - connection.UsageAdvisor.Converting(command.CommandText, - fields[index].ColumnName, v.MySqlTypeName, "Int64"); - return ((IConvertible)v.Value).ToInt64(null); + connection.UsageAdvisor.Converting(command.CommandText, + fields[index].ColumnName, v.MySqlTypeName, "Int64"); + return ((IConvertible)v.Value).ToInt64(null); } /// @@ -506,11 +506,11 @@ /// public override int GetOrdinal(string name) { - if (! isOpen) + if (!isOpen) throw new Exception("No current query in data reader"); name = name.ToLower(System.Globalization.CultureInfo.InvariantCulture); - for (int i=0; i < fields.Length; i ++) + for (int i = 0; i < fields.Length; i++) { if (fields[i].ColumnName.ToLower(System.Globalization.CultureInfo.InvariantCulture) == name) return i; @@ -529,44 +529,43 @@ // Only Results from SQL SELECT Queries // get a DataTable for schema of the result // otherwise, DataTable is null reference - if (fields.Length == 0) return null; + if (fields == null || fields.Length == 0) return null; - DataTable dataTableSchema = new DataTable ("SchemaTable"); - - dataTableSchema.Columns.Add ("ColumnName", typeof (string)); - dataTableSchema.Columns.Add ("ColumnOrdinal", typeof (int)); - dataTableSchema.Columns.Add ("ColumnSize", typeof (int)); - dataTableSchema.Columns.Add ("NumericPrecision", typeof (int)); - dataTableSchema.Columns.Add ("NumericScale", typeof (int)); - dataTableSchema.Columns.Add ("IsUnique", typeof (bool)); - dataTableSchema.Columns.Add ("IsKey", typeof (bool)); + DataTable dataTableSchema = new DataTable("SchemaTable"); + + dataTableSchema.Columns.Add("ColumnName", typeof(string)); + dataTableSchema.Columns.Add("ColumnOrdinal", typeof(int)); + dataTableSchema.Columns.Add("ColumnSize", typeof(int)); + dataTableSchema.Columns.Add("NumericPrecision", typeof(int)); + dataTableSchema.Columns.Add("NumericScale", typeof(int)); + dataTableSchema.Columns.Add("IsUnique", typeof(bool)); + dataTableSchema.Columns.Add("IsKey", typeof(bool)); DataColumn dc = dataTableSchema.Columns["IsKey"]; dc.AllowDBNull = true; // IsKey can have a DBNull - dataTableSchema.Columns.Add ("BaseCatalogName", typeof (string)); - dataTableSchema.Columns.Add ("BaseColumnName", typeof (string)); - dataTableSchema.Columns.Add ("BaseSchemaName", typeof (string)); - dataTableSchema.Columns.Add ("BaseTableName", typeof (string)); - dataTableSchema.Columns.Add ("DataType", typeof(Type)); - dataTableSchema.Columns.Add ("AllowDBNull", typeof (bool)); - dataTableSchema.Columns.Add ("ProviderType", typeof (int)); - dataTableSchema.Columns.Add ("IsAliased", typeof (bool)); - dataTableSchema.Columns.Add ("IsExpression", typeof (bool)); - dataTableSchema.Columns.Add ("IsIdentity", typeof (bool)); - dataTableSchema.Columns.Add ("IsAutoIncrement", typeof (bool)); - dataTableSchema.Columns.Add ("IsRowVersion", typeof (bool)); - dataTableSchema.Columns.Add ("IsHidden", typeof (bool)); - dataTableSchema.Columns.Add ("IsLong", typeof (bool)); - dataTableSchema.Columns.Add ("IsReadOnly", typeof (bool)); + dataTableSchema.Columns.Add("BaseCatalogName", typeof(string)); + dataTableSchema.Columns.Add("BaseColumnName", typeof(string)); + dataTableSchema.Columns.Add("BaseSchemaName", typeof(string)); + dataTableSchema.Columns.Add("BaseTableName", typeof(string)); + dataTableSchema.Columns.Add("DataType", typeof(Type)); + dataTableSchema.Columns.Add("AllowDBNull", typeof(bool)); + dataTableSchema.Columns.Add("ProviderType", typeof(int)); + dataTableSchema.Columns.Add("IsAliased", typeof(bool)); + dataTableSchema.Columns.Add("IsExpression", typeof(bool)); + dataTableSchema.Columns.Add("IsIdentity", typeof(bool)); + dataTableSchema.Columns.Add("IsAutoIncrement", typeof(bool)); + dataTableSchema.Columns.Add("IsRowVersion", typeof(bool)); + dataTableSchema.Columns.Add("IsHidden", typeof(bool)); + dataTableSchema.Columns.Add("IsLong", typeof(bool)); + dataTableSchema.Columns.Add("IsReadOnly", typeof(bool)); int ord = 1; - for (int i=0; i < fields.Length; i++) + for (int i = 0; i < fields.Length; i++) { MySqlField f = fields[i]; DataRow r = dataTableSchema.NewRow(); r["ColumnName"] = f.ColumnName; r["ColumnOrdinal"] = ord++; - int maxByteCount = f.Encoding.GetMaxByteCount(1) >> 1; - r["ColumnSize"] = f.IsTextField ? f.ColumnLength / maxByteCount : f.ColumnLength; + r["ColumnSize"] = f.IsTextField ? f.ColumnLength / f.MaxLength : f.ColumnLength; int prec = f.Precision; int pscale = f.Scale; if (prec != -1) @@ -574,7 +573,7 @@ if (pscale != -1) r["NumericScale"] = (short)pscale; r["DataType"] = GetFieldType(i); - r["ProviderType"] = (int)f.Type; + r["ProviderType"] = (int)f.Type; r["IsLong"] = f.IsBlob && f.ColumnLength > 255; r["AllowDBNull"] = f.AllowsNull; r["IsReadOnly"] = false; @@ -583,20 +582,20 @@ r["IsKey"] = f.IsPrimaryKey; r["IsAutoIncrement"] = f.IsAutoIncrement; r["BaseSchemaName"] = f.DatabaseName; - r["BaseCatalogName"] = null; + r["BaseCatalogName"] = null; r["BaseTableName"] = f.RealTableName; r["BaseColumnName"] = f.OriginalColumnName; - dataTableSchema.Rows.Add( r ); + dataTableSchema.Rows.Add(r); } return dataTableSchema; } - public string GetString(string name) - { - return GetString(GetOrdinal(name)); - } + public string GetString(string name) + { + return GetString(GetOrdinal(name)); + } /// public override String GetString(int index) @@ -612,17 +611,17 @@ return val.Value.ToString(); } - public TimeSpan GetTimeSpan(string name) - { - return GetTimeSpan(GetOrdinal(name)); - } + public TimeSpan GetTimeSpan(string name) + { + return GetTimeSpan(GetOrdinal(name)); + } /// public TimeSpan GetTimeSpan(int index) { - IMySqlValue val = GetFieldValue(index, true); + IMySqlValue val = GetFieldValue(index, true); - MySqlTimeSpan ts = (MySqlTimeSpan)val; + MySqlTimeSpan ts = (MySqlTimeSpan)val; return ts.Value; } @@ -633,21 +632,21 @@ /// public override object GetValue(int i) { - if (! isOpen) throw new Exception("No current query in data reader"); + if (!isOpen) throw new Exception("No current query in data reader"); if (i >= fields.Length) throw new IndexOutOfRangeException(); IMySqlValue val = GetFieldValue(i, false); - if (val.IsNull) - return DBNull.Value; + if (val.IsNull) + return DBNull.Value; // if the column is a date/time, then we return a MySqlDateTime // so .ToString() will print '0000-00-00' correctly - if (val is MySqlDateTime) + if (val is MySqlDateTime) { - MySqlDateTime dt = (MySqlDateTime)val; - if (! dt.IsValidDateTime && connection.Settings.ConvertZeroDateTime) + MySqlDateTime dt = (MySqlDateTime)val; + if (!dt.IsValidDateTime && connection.Settings.ConvertZeroDateTime) return DateTime.MinValue; - else if (connection.Settings.AllowZeroDateTime) + else if (connection.Settings.AllowZeroDateTime) return val; else return dt.GetDateTime(); @@ -663,18 +662,18 @@ /// public override int GetValues(object[] values) { - if (! hasRead) return 0; - int numCols = Math.Min( values.Length, fields.Length ); - for (int i=0; i < numCols; i ++) + if (!hasRead) return 0; + int numCols = Math.Min(values.Length, fields.Length); + for (int i = 0; i < numCols; i++) values[i] = GetValue(i); return numCols; } - public UInt16 GetUInt16(string name) - { - return GetUInt16(GetOrdinal(name)); - } + public UInt16 GetUInt16(string name) + { + return GetUInt16(GetOrdinal(name)); + } /// public UInt16 GetUInt16(int index) @@ -683,32 +682,32 @@ if (v is MySqlUInt16) return ((MySqlUInt16)v).Value; - connection.UsageAdvisor.Converting(command.CommandText, - fields[index].ColumnName, v.MySqlTypeName, "UInt16"); - return Convert.ToUInt16(v.Value); + connection.UsageAdvisor.Converting(command.CommandText, + fields[index].ColumnName, v.MySqlTypeName, "UInt16"); + return Convert.ToUInt16(v.Value); } - public UInt32 GetUInt32(string name) - { - return GetUInt32(GetOrdinal(name)); - } + public UInt32 GetUInt32(string name) + { + return GetUInt32(GetOrdinal(name)); + } - /// + /// public UInt32 GetUInt32(int index) { IMySqlValue v = GetFieldValue(index, true); if (v is MySqlUInt32) return ((MySqlUInt32)v).Value; - connection.UsageAdvisor.Converting(command.CommandText, - fields[index].ColumnName, v.MySqlTypeName, "UInt32"); - return Convert.ToUInt32(v.Value); + connection.UsageAdvisor.Converting(command.CommandText, + fields[index].ColumnName, v.MySqlTypeName, "UInt32"); + return Convert.ToUInt32(v.Value); } - public UInt64 GetUInt64(string name) - { - return GetUInt64(GetOrdinal(name)); - } + public UInt64 GetUInt64(string name) + { + return GetUInt64(GetOrdinal(name)); + } /// public UInt64 GetUInt64(int index) @@ -717,9 +716,9 @@ if (v is MySqlUInt64) return ((MySqlUInt64)v).Value; - connection.UsageAdvisor.Converting(command.CommandText, - fields[index].ColumnName, v.MySqlTypeName, "UInt64"); - return Convert.ToUInt64(v.Value); + connection.UsageAdvisor.Converting(command.CommandText, + fields[index].ColumnName, v.MySqlTypeName, "UInt64"); + return Convert.ToUInt64(v.Value); } @@ -740,35 +739,35 @@ return DBNull.Value == GetValue(i); } - /// - /// GetResultSet is the core resultset processing method. It gets called by NextResult - /// and will loop until it finds a select resultset at which point it will return the - /// number of columns in that result. It will _not_ return for non-select resultsets instead - /// just updating the internal lastInsertId and affectedRows variables. - /// - /// -1 if no more results exist, >= 0 for select results - private long GetResultSet() - { - while (true) - { - ulong affectedRowsTemp = 0; - long fieldCount = driver.ReadResult(ref affectedRowsTemp, ref lastInsertId); - if (fieldCount > 0) - return fieldCount; - else if (fieldCount == 0) - { - command.lastInsertedId = lastInsertId; - if (affectedRows == -1) - affectedRows = (long)affectedRowsTemp; - else - affectedRows += (long)affectedRowsTemp; - } - else if (fieldCount == -1) - if (!statement.ExecuteNext()) - break; - } - return -1; - } + /// + /// GetResultSet is the core resultset processing method. It gets called by NextResult + /// and will loop until it finds a select resultset at which point it will return the + /// number of columns in that result. It will _not_ return for non-select resultsets instead + /// just updating the internal lastInsertId and affectedRows variables. + /// + /// -1 if no more results exist, >= 0 for select results + private long GetResultSet() + { + while (true) + { + ulong affectedRowsTemp = 0; + long fieldCount = driver.ReadResult(ref affectedRowsTemp, ref lastInsertId); + if (fieldCount > 0) + return fieldCount; + else if (fieldCount == 0) + { + command.lastInsertedId = lastInsertId; + if (affectedRows == -1) + affectedRows = (long)affectedRowsTemp; + else + affectedRows += (long)affectedRowsTemp; + } + else if (fieldCount == -1) + if (!statement.ExecuteNext()) + break; + } + return -1; + } /// /// Advances the data reader to the next result, when reading the results of batch SQL statements. @@ -776,56 +775,56 @@ /// public override bool NextResult() { - if (! isOpen) + if (!isOpen) throw new MySqlException("Invalid attempt to NextResult when reader is closed."); - bool firstResult = fields == null; - if (fields != null) - { - ClearCurrentResultset(); - fields = null; - } + bool firstResult = fields == null; + if (fields != null) + { + ClearCurrentResultset(); + fields = null; + } - // single result means we only return a single resultset. If we have already - // returned one, then we return false; - if (!firstResult && (commandBehavior & CommandBehavior.SingleResult) != 0) - return false; + // single result means we only return a single resultset. If we have already + // returned one, then we return false; + if (!firstResult && (commandBehavior & CommandBehavior.SingleResult) != 0) + return false; // tell our command to continue execution of the SQL batch until it its // another resultset - try + try { - long fieldCount = GetResultSet(); - if (fieldCount == -1) - { - nextResultDone = true; - hasRows = canRead = false; - return false; - } + long fieldCount = GetResultSet(); + if (fieldCount == -1) + { + nextResultDone = true; + hasRows = canRead = false; + return false; + } // issue any requested UA warnings - if (connection.Settings.UseUsageAdvisor) + if (connection.Settings.UseUsageAdvisor) { if ((connection.driver.ServerStatus & ServerStatusFlags.NoIndex) != 0) - connection.UsageAdvisor.UsingNoIndex( command.CommandText ); + connection.UsageAdvisor.UsingNoIndex(command.CommandText); if ((connection.driver.ServerStatus & ServerStatusFlags.BadIndex) != 0) - connection.UsageAdvisor.UsingBadIndex( command.CommandText ); + connection.UsageAdvisor.UsingBadIndex(command.CommandText); } - fields = driver.ReadColumnMetadata((int)fieldCount); - values = new IMySqlValue[fields.Length]; - for (int i = 0; i < fields.Length; i++) - values[i] = fields[i].GetValueObject(); - hasRead = false; + fields = driver.ReadColumnMetadata((int)fieldCount); + values = new IMySqlValue[fields.Length]; + for (int i = 0; i < fields.Length; i++) + values[i] = fields[i].GetValueObject(); + hasRead = false; - uaFieldsUsed = new bool[fields.Length]; - hasRows = canRead = driver.FetchDataRow(statement.StatementId, 0, fields.Length); - return true; - } - catch (MySqlException ex) + uaFieldsUsed = new bool[fields.Length]; + hasRows = canRead = driver.FetchDataRow(statement.StatementId, 0, fields.Length); + return true; + } + catch (MySqlException ex) { - if (ex.IsFatal) - connection.Abort(); + if (ex.IsFatal) + connection.Abort(); throw; } @@ -837,72 +836,72 @@ /// public override bool Read() { - if (! isOpen) + if (!isOpen) throw new MySqlException("Invalid attempt to Read when reader is closed."); - if (! canRead) - return false; + if (!canRead) + return false; - if (Behavior == CommandBehavior.SingleRow && hasRead) - return false; + if (Behavior == CommandBehavior.SingleRow && hasRead) + return false; - try + try { bool isSequential = (Behavior & CommandBehavior.SequentialAccess) != 0; - seqIndex = -1; - if (hasRead) - canRead = driver.FetchDataRow(statement.StatementId, 0, fields.Length); - hasRead = true; - if (canRead && !isSequential) - for (int i = 0; i < fields.Length; i++) - values[i] = driver.ReadColumnValue(i, fields[i], values[i]); + seqIndex = -1; + if (hasRead) + canRead = driver.FetchDataRow(statement.StatementId, 0, fields.Length); + hasRead = true; + if (canRead && !isSequential) + for (int i = 0; i < fields.Length; i++) + values[i] = driver.ReadColumnValue(i, fields[i], values[i]); - return canRead; + return canRead; } - catch (MySqlException ex) + catch (MySqlException ex) { - if (ex.IsFatal) - connection.Abort(); + if (ex.IsFatal) + connection.Abort(); throw; } } - private IMySqlValue GetFieldValue(int index, bool checkNull) + private IMySqlValue GetFieldValue(int index, bool checkNull) { - if (index < 0 || index >= fields.Length) - throw new ArgumentException( "You have specified an invalid column ordinal." ); + if (index < 0 || index >= fields.Length) + throw new ArgumentException("You have specified an invalid column ordinal."); - if (! hasRead) + if (!hasRead) throw new MySqlException("Invalid attempt to access a field before calling Read()"); // keep count of how many columns we have left to access this.uaFieldsUsed[index] = true; - if ((this.commandBehavior & CommandBehavior.SequentialAccess) != 0 && - index != seqIndex) - { - if (index < seqIndex) - throw new MySqlException("Invalid attempt to read a prior column using SequentialAccess"); - while (seqIndex < (index-1)) - driver.SkipColumnValue(values[++seqIndex]); - values[index] = driver.ReadColumnValue(index, fields[index], values[index]); - seqIndex = index; - } + if ((this.commandBehavior & CommandBehavior.SequentialAccess) != 0 && + index != seqIndex) + { + if (index < seqIndex) + throw new MySqlException("Invalid attempt to read a prior column using SequentialAccess"); + while (seqIndex < (index - 1)) + driver.SkipColumnValue(values[++seqIndex]); + values[index] = driver.ReadColumnValue(index, fields[index], values[index]); + seqIndex = index; + } - IMySqlValue v = values[index]; - if (checkNull && v.IsNull) - throw new SqlNullValueException(); + IMySqlValue v = values[index]; + if (checkNull && v.IsNull) + throw new SqlNullValueException(); - return v; + return v; } - private void ClearCurrentResultset() + private void ClearCurrentResultset() { - if (!canRead) return; - while (driver.SkipDataRow()) - { - } + if (!canRead) return; + while (driver.SkipDataRow()) + { + } if (!connection.Settings.UseUsageAdvisor) return; @@ -914,13 +913,13 @@ bool readAll = true; foreach (bool b in this.uaFieldsUsed) readAll &= b; - if (! readAll) + if (!readAll) connection.UsageAdvisor.ReadPartialRowSet(command.CommandText, uaFieldsUsed, fields); } #region IEnumerator - public override IEnumerator GetEnumerator() + public override IEnumerator GetEnumerator() { return new DbEnumerator(this); }