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();
}
}
+
+ /// <summary>
+ /// Bug #23538 Exception thrown when GetSchemaTable is called and "fields" is null.
+ /// </summary>
+ [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; }
}
- /// <summary>
- /// Gets a value indicating the depth of nesting for the current row. This
method is not
- /// supported currently and always returns 0.
- /// </summary>
- public override int Depth
- {
- get { return 0; }
- }
+ /// <summary>
+ /// Gets a value indicating the depth of nesting for the current row. This method is
not
+ /// supported currently and always returns 0.
+ /// </summary>
+ public override int Depth
+ {
+ get { return 0; }
+ }
- /// <summary>
- /// Gets the number of columns in the current row.
- /// </summary>
- 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;
- }
- }
+ /// <summary>
+ /// Gets the number of columns in the current row.
+ /// </summary>
+ 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;
+ }
+ }
- /// <summary>
- /// Gets a value indicating whether the MySqlDataReader contains one or more
rows.
- /// </summary>
- public override bool HasRows
- {
- get { return hasRows; }
- }
+ /// <summary>
+ /// Gets a value indicating whether the MySqlDataReader contains one or more rows.
+ /// </summary>
+ public override bool HasRows
+ {
+ get { return hasRows; }
+ }
- /// <summary>
+ /// <summary>
/// Gets a value indicating whether the data reader is closed.
/// </summary>
public override bool IsClosed
{
- get { return ! isOpen; }
+ get { return !isOpen; }
}
- /// <summary>
- /// Gets the number of rows changed, inserted, or deleted by execution of the SQL
statement.
- /// </summary>
- 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; }
- }
+ /// <summary>
+ /// Gets the number of rows changed, inserted, or deleted by execution of the SQL
statement.
+ /// </summary>
+ 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; }
+ }
- /// <summary>
- /// Overloaded. Gets the value of a column in its native format.
- /// In C#, this property is the indexer for the MySqlDataReader class.
- /// </summary>
- public override object this[int i]
- {
- get { return GetValue(i); }
- }
+ /// <summary>
+ /// Overloaded. Gets the value of a column in its native format.
+ /// In C#, this property is the indexer for the MySqlDataReader class.
+ /// </summary>
+ public override object this[int i]
+ {
+ get { return GetValue(i); }
+ }
- /// <summary>
- /// Gets the value of a column in its native format.
- /// [C#] In C#, this property is the indexer for the MySqlDataReader class.
- /// </summary>
- public override object this[String name]
- {
- // Look up the ordinal and return
- // the value at that position.
- get { return this[GetOrdinal(name)]; }
- }
+ /// <summary>
+ /// Gets the value of a column in its native format.
+ /// [C#] In C#, this property is the indexer for the MySqlDataReader class.
+ /// </summary>
+ public override object this[String name]
+ {
+ // Look up the ordinal and return
+ // the value at that position.
+ get { return this[GetOrdinal(name)]; }
+ }
- #endregion
+ #endregion
/// <summary>
/// Closes the MySqlDataReader object.
/// </summary>
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));
+ }
/// <summary>
/// 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));
+ }
/// <summary>
/// Gets the value of the specified column as a byte.
@@ -235,43 +235,43 @@
/// <include file='docs/MySqlDataReader.xml'
path='MyDocs/MyMembers[@name="GetBytes"]/*'/>
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));
+ }
/// <summary>
/// Gets the value of the specified column as a single character.
@@ -295,7 +295,7 @@
/// <returns></returns>
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 @@
/// <returns></returns>
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));
+ }
+
/// <include file='docs/MySqlDataReader.xml' path='docs/GetMySqlDateTime/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDateTime/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDecimal/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDouble/*'/>
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 @@
/// <returns></returns>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetFloat/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetGuid/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt16/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt32/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetInt64/*'/>
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);
}
/// <summary>
@@ -506,11 +506,11 @@
/// <returns></returns>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetString/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetTimeSpan/*'/>
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 @@
/// <returns></returns>
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 @@
/// <returns></returns>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt16/*'/>
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));
+ }
- /// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt32/*'/>
+ /// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt32/*'/>
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));
+ }
/// <include file='docs/MySqlDataReader.xml' path='docs/GetUInt64/*'/>
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);
}
- /// <summary>
- /// 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.
- /// </summary>
- /// <returns>-1 if no more results exist, >= 0 for select
results</returns>
- 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;
- }
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <returns>-1 if no more results exist, >= 0 for select
results</returns>
+ 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;
+ }
/// <summary>
/// Advances the data reader to the next result, when reading the results of batch SQL
statements.
@@ -776,56 +775,56 @@
/// <returns></returns>
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 @@
/// <returns></returns>
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);
}
| Thread |
|---|
| • Connector/NET commit: r428 - in trunk: . TestSuite mysqlclient | rburnett | 23 Oct |