// System.Data.DataTableReader.cs
//
// Author:
-// Tim Coleman (tim@timcoleman.com)
+// Sureshkumar T <tsureshkumar@novell.com>
+// Tim Coleman (tim@timcoleman.com)
//
// Copyright (C) Tim Coleman, 2003
//
using System.Data.Common;
namespace System.Data {
- public sealed class DataTableReader : DbDataReader
- {
- bool closed;
- DataTable[] dataTables;
- int index;
-
- #region Constructors
-
- [MonoTODO]
- public DataTableReader (DataTable dt)
- : this (new DataTable[] {dt})
- {
- }
-
- [MonoTODO]
- public DataTableReader (DataTable[] dataTables)
- {
- this.dataTables = dataTables;
- closed = false;
- index = 0;
- }
-
- #endregion // Constructors
-
- #region Properties
-
- public override int Depth {
- get { return 0; }
- }
-
- public override int FieldCount {
- get { return dataTables [index].Columns.Count; }
- }
-
- public override bool HasRows {
- get { return dataTables [index].Rows.Count > 0; }
- }
-
- public override bool IsClosed {
- get { return closed; }
- }
-
- [MonoTODO]
- public override object this [int index] {
- get { throw new NotImplementedException (); }
- }
-
- [MonoTODO]
- public override object this [string name] {
- get { throw new NotImplementedException (); }
- }
-
- [MonoTODO]
- public override int RecordsAffected {
- get { throw new NotImplementedException (); }
- }
-
- [MonoTODO]
- public override int VisibleFieldCount {
- get { throw new NotImplementedException (); }
- }
-
- #endregion // Properties
-
- #region Methods
-
- [MonoTODO]
- public override void Close ()
- {
- closed = true;
- }
-
- [MonoTODO]
- public override void Dispose ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override bool GetBoolean (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override byte GetByte (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override char GetChar (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override string GetDataTypeName (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override DateTime GetDateTime (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override decimal GetDecimal (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override double GetDouble (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override IEnumerator GetEnumerator ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override Type GetFieldProviderSpecificType (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override Type GetFieldType (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override float GetFloat (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override Guid GetGuid (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override short GetInt16 (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override int GetInt32 (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override long GetInt64 (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override string GetName (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override int GetOrdinal (string name)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override object GetProviderSpecificValue (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override int GetProviderSpecificValues (object[] values)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override DataTable GetSchemaTable ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override string GetString (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override object GetValue (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override int GetValues (object[] values)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override bool IsDBNull (int i)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override bool NextResult ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public override bool Read ()
- {
- throw new NotImplementedException ();
- }
-
- #endregion // Methods
- }
+ public sealed class DataTableReader : DbDataReader
+ {
+ bool _closed;
+ DataTable [] _tables;
+ IEnumerator _enumerator;
+ bool _first = true;
+ int _current = 0;
+ int _index;
+ DataTable _schemaTable;
+
+ #region Constructors
+
+
+ public DataTableReader (DataTable dt)
+ : this (new DataTable[] {dt})
+ {
+ }
+
+ public DataTableReader (DataTable[] dataTables)
+ {
+ if (dataTables == null
+ || dataTables.Length <= 0)
+ throw new ArgumentException ("Cannot Create DataTable. Argument Empty!");
+
+ this._tables = dataTables;
+ _closed = false;
+ _index = 0;
+ _current = 0;
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ public override int Depth {
+ get { return 0; }
+ }
+
+ public override int FieldCount {
+ get { return _tables [_index].Columns.Count; }
+ }
+
+ public override bool HasRows {
+ get { return _tables [_index].Rows.Count > 0; }
+ }
+
+ public override bool IsClosed {
+ get { return _closed; }
+ }
+
+ public override object this [int index] {
+ get {
+ Validate ();
+ DataRow row = CurrentRow;
+ if (row.RowState == DataRowState.Deleted)
+ throw new InvalidOperationException ("Deleted Row's information cannot be accessed!");
+ return row [index];
+ }
+ }
+
+ private DataTable CurrentTable
+ {
+ get { return _tables [_index]; }
+ }
+
+ private DataRow CurrentRow
+ {
+ get { return (DataRow) CurrentTable.Rows [_current]; }
+ }
+
+
+ public override object this [string name] {
+ get {
+ Validate ();
+ DataRow row = CurrentRow;
+ if (row.RowState == DataRowState.Deleted)
+ throw new InvalidOperationException ("Deleted Row's information cannot be accessed!");
+ return row [name];
+ }
+ }
+
+ public override int RecordsAffected {
+ get { return 0; }
+ }
+
+ public override int VisibleFieldCount {
+ get { return CurrentTable.Columns.Count; }
+ }
+
+ #endregion // Properties
+
+ #region Methods
+
+ public override void Close ()
+ {
+ _closed = true;
+ }
+
+ public override void Dispose ()
+ {
+ Close ();
+ }
+
+ public override bool GetBoolean (int i)
+ {
+ return (bool) GetValue (i);
+ }
+
+ public override byte GetByte (int i)
+ {
+ return (byte) GetValue (i);
+ }
+
+ [MonoTODO]
+ public override long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override char GetChar (int i)
+ {
+ return (char) GetValue (i);
+ }
+
+ [MonoTODO]
+ public override long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override string GetDataTypeName (int i)
+ {
+ return GetFieldType (i).ToString ();
+ }
+
+ public override DateTime GetDateTime (int i)
+ {
+ return (DateTime) GetValue (i);
+ }
+
+ public override decimal GetDecimal (int i)
+ {
+ return (decimal) GetValue (i);
+ }
+
+ public override double GetDouble (int i)
+ {
+ return (double) GetValue (i);
+ }
+
+ [MonoTODO]
+ public override IEnumerator GetEnumerator ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override Type GetFieldProviderSpecificType (int i)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Type GetFieldType (int i)
+ {
+ Validate ();
+ return CurrentTable.Columns [i].DataType;
+ }
+
+ public override float GetFloat (int i)
+ {
+ return (float) GetValue (i);
+ }
+
+ public override Guid GetGuid (int i)
+ {
+ return (Guid) GetValue (i);
+ }
+
+ public override short GetInt16 (int i)
+ {
+ return (short) GetValue (i);
+ }
+
+ public override int GetInt32 (int i)
+ {
+ return (int) GetValue (i);
+ }
+
+ public override long GetInt64 (int i)
+ {
+ return (long) GetValue (i);
+ }
+
+ public override string GetName (int i)
+ {
+ return (string) GetValue (i);
+ }
+
+ public override int GetOrdinal (string name)
+ {
+ Validate ();
+ DataColumn column = CurrentTable.Columns [name];
+ if (column == null)
+ throw new ArgumentException (String.Format ("Column {0} is not found in the schema",
+ name));
+ return column.Ordinal;
+ }
+
+ [MonoTODO]
+ public override object GetProviderSpecificValue (int i)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public override int GetProviderSpecificValues (object[] values)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override string GetString (int i)
+ {
+ return (string) GetValue (i);
+ }
+
+ public override object GetValue (int i)
+ {
+ return this [i];
+ }
+
+ [MonoTODO]
+ public override int GetValues (object[] values)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool IsDBNull (int i)
+ {
+ return GetValue (i) is DBNull;
+ }
+
+ public override DataTable GetSchemaTable ()
+ {
+ if (_schemaTable != null)
+ return _schemaTable;
+
+ DataTable dt = DbDataReader.GetSchemaTableTemplate ();
+ foreach (DataColumn column in CurrentTable.Columns) {
+ DataRow row = dt.NewRow ();
+
+ row ["ColumnName"] = column.ColumnName;
+ row ["ColumnOrdinal"] = column.Ordinal;
+ row ["ColumnSize"] = column.MaxLength;
+ row ["NumericPrecision"]= DBNull.Value;
+ row ["NumericScale"] = DBNull.Value;
+ row ["IsUnique"] = DBNull.Value;
+ row ["IsKey"] = DBNull.Value;
+ row ["DataType"] = column.DataType.ToString ();
+ row ["AllowDBNull"] = column.AllowDBNull;
+ row ["IsAliased"] = DBNull.Value;
+ row ["IsExpression"] = DBNull.Value;
+ row ["IsIdentity"] = DBNull.Value;
+ row ["IsAutoIncrement"] = DBNull.Value;
+ row ["IsRowVersion"] = DBNull.Value;
+ row ["IsHidden"] = DBNull.Value;
+ row ["IsLong"] = DBNull.Value;
+ row ["IsReadOnly"] = column.ReadOnly;
+
+ dt.Rows.Add (row);
+ }
+ return _schemaTable = dt;
+ }
+
+ private void Validate ()
+ {
+ if (IsClosed)
+ throw new InvalidOperationException ("Invalid attempt to read when " +
+ "the reader is closed");
+ }
+
+ private bool MoveNext ()
+ {
+ do {
+ _current++;
+ } while (_current < CurrentTable.Rows.Count
+ && CurrentRow.RowState == DataRowState.Deleted);
+ return _current < CurrentTable.Rows.Count;
+ }
+
+ public override bool NextResult ()
+ {
+ _current = 0;
+ _index++;
+ _first = true;
+ _schemaTable = null; // force to create fresh
+ return _index < _tables.Length;
+ }
+
+ public override bool Read ()
+ {
+ Validate ();
+ if (_first) {
+ _first = false;
+ if (! HasRows)
+ return false;
+ if (CurrentRow.RowState != DataRowState.Deleted)
+ return true;
+ }
+ return MoveNext ();
+ }
+
+ #endregion // Methods
+ }
}
#endif // NET_2_0
--- /dev/null
+
+// DataTableReaderTest.cs - NUnit Test Cases for testing the DataTableReader
+//
+// Authors:
+// Sureshkumar T <tsureshkumar@novell.com>
+//
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+
+using System;
+using System.Data;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.Data.SqlClient
+{
+ [TestFixture]
+ public class DataTableReaderTest
+ {
+ DataTable dt;
+
+ [SetUp]
+ public void Setup ()
+ {
+ dt = new DataTable ("test");
+ dt.Columns.Add ("id", typeof (int));
+ dt.Columns.Add ("name", typeof (string));
+ dt.PrimaryKey = new DataColumn [] { dt.Columns ["id"] };
+
+ dt.Rows.Add (new object [] { 1, "mono 1" });
+ dt.Rows.Add (new object [] { 2, "mono 2" });
+ dt.Rows.Add (new object [] { 3, "mono 3" });
+
+ dt.AcceptChanges ();
+
+ }
+
+ #region Positive Tests
+ [Test]
+ public void CtorTest ()
+ {
+
+ dt.Rows [1].Delete ();
+
+ int i = 0;
+
+ DataTableReader reader = new DataTableReader (dt);
+ while (reader.Read ())
+ i++;
+ reader.Close ();
+
+ Assert.AreEqual (2, i, "no. of rows iterated is wrong");
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void RowInAccessibleTest ()
+ {
+
+ DataTableReader reader = new DataTableReader (dt);
+ reader.Read ();
+ reader.Read (); // 2nd row
+ dt.Rows [1].Delete ();
+ string value = reader [1].ToString ();
+ }
+
+ [Test]
+ public void IgnoreDeletedRowsDynamicTest ()
+ {
+
+ DataTableReader reader = new DataTableReader (dt);
+ reader.Read (); // first row
+ dt.Rows [1].Delete ();
+ reader.Read (); // it should be 3rd row
+ string value = reader [0].ToString ();
+ Assert.AreEqual ("3", value, "#1 reader should have moved to 3rd row");
+ }
+
+ [Test]
+ public void SeeTheModifiedTest ()
+ {
+ DataTableReader reader = new DataTableReader (dt);
+ reader.Read (); // first row
+ dt.Rows [1] ["name"] = "mono changed";
+ reader.Read ();
+ string value = reader [1].ToString ();
+ Assert.AreEqual ("mono changed", value, "#2 reader should have moved to 3rd row");
+ }
+
+ [Test]
+ public void SchemaTest ()
+ {
+ DataTable another = new DataTable ("another");
+ another.Columns.Add ("x", typeof (string));
+
+ another.Rows.Add (new object [] {"test 1" });
+ another.Rows.Add (new object [] {"test 2" });
+ another.Rows.Add (new object [] {"test 3" });
+
+ DataTableReader reader = new DataTableReader (new DataTable [] { dt, another });
+ DataTable schema = reader.GetSchemaTable ();
+
+ Assert.AreEqual (dt.Columns.Count, schema.Rows.Count, "#1 should be same");
+ Assert.AreEqual (dt.Columns [1].DataType.ToString (), schema.Rows [1] ["DataType"].ToString (), "#2 data type should match");
+
+ reader.NextResult (); //schema should change here
+ schema = reader.GetSchemaTable ();
+
+ Assert.AreEqual (another.Columns.Count, schema.Rows.Count, "#3 should be same");
+ Assert.AreEqual (another.Columns [0].DataType.ToString (), schema.Rows [0] ["DataType"].ToString (), "#4 data type should match");
+
+ }
+
+ [Test]
+ public void MultipleResultSetsTest ()
+ {
+ DataTable dt1 = new DataTable ("test2");
+ dt1.Columns.Add ("x", typeof (string));
+ dt1.Rows.Add (new object [] {"test"} );
+ dt1.Rows.Add (new object [] {"test1"} );
+ dt1.AcceptChanges ();
+
+ DataTable [] collection = new DataTable [] { dt, dt1 } ;
+
+ DataTableReader reader = new DataTableReader (collection);
+ int i = 0;
+ do {
+ while (reader.Read ())
+ i++;
+ } while (reader.NextResult ());
+
+ Assert.AreEqual (5, i, "#1 rows should be of both the tables");
+ }
+
+ [Test]
+ public void GetTest ()
+ {
+ dt.Columns.Add ("nullint", typeof (int));
+ dt.Rows [0] ["nullint"] = 333;
+
+ DataTableReader reader = new DataTableReader (dt);
+ reader.Read ();
+
+ int ordinal = reader.GetOrdinal ("nullint");
+ // Get by name
+ Assert.AreEqual (1, (int) reader ["id"], "#1 should be able to get by name");
+ Assert.AreEqual (333, reader.GetInt32 (ordinal), "#2 should get int32");
+ Assert.AreEqual ("System.Int32", reader.GetDataTypeName (ordinal), "#3 data type should match");
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void CloseTest ()
+ {
+ DataTableReader reader = new DataTableReader (dt);
+ int i = 0;
+ while (reader.Read () && i < 1)
+ i++;
+ reader.Close ();
+ reader.Read ();
+ }
+ #endregion // Positive Tests
+
+ #region Negative Tests
+ [Test]
+ public void NoRowsTest ()
+ {
+ dt.Rows.Clear ();
+ dt.AcceptChanges ();
+
+ DataTableReader reader = new DataTableReader (dt);
+
+ Assert.AreEqual (false, reader.Read (), "#1 there are no rows");
+ Assert.AreEqual (false, reader.NextResult (), "#2 there are no further resultsets");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void NoTablesTest ()
+ {
+ DataTableReader reader = new DataTableReader (new DataTable [] {});
+ reader.Read ();
+ }
+ #endregion // Negative Tests
+
+ }
+}
+
+#endif // NET_2_0