2005-04-27 Sureshkumar T <tsureshkumar@novell.com>
authorSureshkumar T <suresh@mono-cvs.ximian.com>
Wed, 27 Apr 2005 12:39:14 +0000 (12:39 -0000)
committerSureshkumar T <suresh@mono-cvs.ximian.com>
Wed, 27 Apr 2005 12:39:14 +0000 (12:39 -0000)
* System.Data/DataTableReader.cs: Implemented most of the TODO.
* Test/System.Data/DataTableReaderTest.cs: Added Tests for DataTableReader class.
* System.Data.Common/DbDataReader.cs: Added static method to construct the schema
           table with default schema. Could be reused in many places.
* System.Data_test.dll.sources: Added DataTableReaderTest.cs

svn path=/trunk/mcs/; revision=43650

mcs/class/System.Data/ChangeLog
mcs/class/System.Data/System.Data.Common/ChangeLog
mcs/class/System.Data/System.Data.Common/DbDataReader.cs
mcs/class/System.Data/System.Data/ChangeLog
mcs/class/System.Data/System.Data/DataTableReader.cs
mcs/class/System.Data/System.Data_test.dll.sources
mcs/class/System.Data/Test/System.Data/ChangeLog
mcs/class/System.Data/Test/System.Data/DataTableReaderTest.cs [new file with mode: 0755]

index fb65b7175fc5f0757bb8d033a2bcabeb69b20799..c7e8d5da560d1081d4b3d9cff72c1dd532e92076 100644 (file)
@@ -1,3 +1,7 @@
+2005-04-27  Sureshkumar T  <tsureshkumar@novell.com>
+
+       * System.Data_test.dll.sources: Added DataTableReaderTest.cs
+
 2005-04-22  Sureshkumar T  <tsureshkumar@novell.com>
 
        * System.Data_test.dll.sources: Added DataTableLoadRowTest.cs.
index c0ee834b35b27c0f158d8f6a4d595f5c2e98ac52..b145a8ff96221b0dcaf083415bab82a4e575cf1a 100755 (executable)
@@ -1,3 +1,8 @@
+2005-04-27  Sureshkumar T  <tsureshkumar@novell.com>
+
+       * DbDataReader.cs: Added static method to construct the schema
+       table with default schema. Could be reused in many places.
+
 2005-04-22  Sureshkumar T  <tsureshkumar@novell.com>
 
        * DbDataAdapter.cs: Moved FillTable and BuildSchema as static
index ba0d2fab0c5d39127507db1fd6c66b50a33fee0c..6dd3f1733cb5871b36e2557e25aa1f4f89e1f753 100644 (file)
@@ -105,6 +105,42 @@ namespace System.Data.Common {
                public abstract bool NextResult ();
                public abstract bool Read ();
 
+                internal static DataTable GetSchemaTableTemplate ()
+               {
+                       Type booleanType        = Type.GetType ("System.Boolean");
+                       Type stringType         = Type.GetType ("System.String");
+                       Type intType            = Type.GetType ("System.Int32");
+                       Type typeType           = Type.GetType ("System.Type");
+                       Type shortType          = Type.GetType ("System.Int16");
+
+                       DataTable schemaTable = new DataTable ("SchemaTable");
+                       schemaTable.Columns.Add ("ColumnName",          stringType);
+                       schemaTable.Columns.Add ("ColumnOrdinal",       intType);
+                       schemaTable.Columns.Add ("ColumnSize",          intType);
+                       schemaTable.Columns.Add ("NumericPrecision",    shortType);
+                       schemaTable.Columns.Add ("NumericScale",        shortType);
+                       schemaTable.Columns.Add ("IsUnique",            booleanType);
+                       schemaTable.Columns.Add ("IsKey",               booleanType);
+                       schemaTable.Columns.Add ("BaseServerName",      stringType);
+                       schemaTable.Columns.Add ("BaseCatalogName",     stringType);
+                       schemaTable.Columns.Add ("BaseColumnName",      stringType);
+                       schemaTable.Columns.Add ("BaseSchemaName",      stringType);
+                       schemaTable.Columns.Add ("BaseTableName",       stringType);
+                       schemaTable.Columns.Add ("DataType",            typeType);
+                       schemaTable.Columns.Add ("AllowDBNull",         booleanType);
+                       schemaTable.Columns.Add ("ProviderType",        intType);
+                       schemaTable.Columns.Add ("IsAliased",           booleanType);
+                       schemaTable.Columns.Add ("IsExpression",        booleanType);
+                       schemaTable.Columns.Add ("IsIdentity",          booleanType);
+                       schemaTable.Columns.Add ("IsAutoIncrement",     booleanType);
+                       schemaTable.Columns.Add ("IsRowVersion",        booleanType);
+                       schemaTable.Columns.Add ("IsHidden",            booleanType);
+                       schemaTable.Columns.Add ("IsLong",              booleanType);
+                       schemaTable.Columns.Add ("IsReadOnly",          booleanType);
+
+                       return schemaTable;
+               }
+
                #endregion // Methods
        }
 }
index becadf74d6e9d50662b0a943b8cf3220f8135ae4..a541095e4555fad3b29a3c3964a59f72f02952d0 100644 (file)
@@ -1,3 +1,7 @@
+2005-04-27  Sureshkumar T  <tsureshkumar@novell.com>
+
+       * DataTableReader.cs: Implemented most of the TODO.
+
 2005-04-22  Sureshkumar T  <tsureshkumar@novell.com>
 
        * LoadOption.cs: Changed the enums. Keeping old values for
index ddd0bb17b1f16779078b1536c995a8a77040c924..304dccc27deffdd11fb2d2f159cded9c7621caba 100644 (file)
@@ -2,7 +2,8 @@
 // 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
 //
@@ -36,254 +37,319 @@ using System.Collections;
 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
index cd37280dec060e31788296439968f661f58ea1d2..9fe26b6cb462728a2fbfc9d8358100be1127df1a 100644 (file)
@@ -28,6 +28,7 @@ System.Data/DataSetReadXmlSchemaTest.cs
 System.Data/DataSetInferXmlSchemaTest.cs
 System.Data/DataTableTest.cs
 System.Data/DataTableLoadRowTest.cs
+System.Data/DataTableReaderTest.cs
 System.Data/DataViewManagerTest.cs
 System.Data/DataViewTest.cs
 System.Data/ForeignKeyConstraintTest.cs
index 027a7a8d9f6aecf956ae2b39328ab88940719c5e..4e18922698e5f04411b72183f4f338838d431aa8 100644 (file)
@@ -1,3 +1,7 @@
+2005-04-27  Sureshkumar T  <tsureshkumar@novell.com>
+
+       * DataTableReaderTest.cs: Added Tests for DataTableReader class.
+
 2005-04-22  Sureshkumar T  <tsureshkumar@novell.com>
 
        * DataTableLoadRowTest.cs: Added. A test case for testing
diff --git a/mcs/class/System.Data/Test/System.Data/DataTableReaderTest.cs b/mcs/class/System.Data/Test/System.Data/DataTableReaderTest.cs
new file mode 100755 (executable)
index 0000000..c0e0dcd
--- /dev/null
@@ -0,0 +1,213 @@
+
+// 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