Procházet zdrojové kódy

2008-05-14 Atsushi Enomoto <[email protected]>

	* DataTableExtensions.cs :
	  implemented AsDataView() and CopyToDataTable().
	* EnumerableRowCollection.cs : added Table property for internal use.

	* DataTableExtensionsTest.cs : new test.

	* System.Data.DataSetExtensions.dll.sources :
	  added RowEnumerableDataReader.cs
	* System.Data.DataSetExtensions_test.dll.sources :
	  added DataTableExtensionsTest.cs.


svn path=/trunk/mcs/; revision=103171
Atsushi Eno před 17 roky
rodič
revize
b4f8a014a2

+ 7 - 0
mcs/class/System.Data.DataSetExtensions/ChangeLog

@@ -1,3 +1,10 @@
+2008-05-14  Atsushi Enomoto  <[email protected]>
+
+	* System.Data.DataSetExtensions.dll.sources :
+	  added RowEnumerableDataReader.cs
+	* System.Data.DataSetExtensions_test.dll.sources :
+	  added DataTableExtensionsTest.cs.
+
 2008-05-13  Atsushi Enomoto  <[email protected]>
 
 	* System.Data.DataSetExtensions_test.dll.sources : new.

+ 1 - 0
mcs/class/System.Data.DataSetExtensions/System.Data.DataSetExtensions.dll.sources

@@ -10,5 +10,6 @@ System.Data/EnumerableRowCollection.cs
 System.Data/EnumerableRowCollectionExtensions.cs
 System.Data/EnumerableRowCollection_1.cs
 System.Data/OrderedEnumerableRowCollection.cs
+System.Data/RowEnumerableDataReader.cs
 System.Data/TypedTableBase.cs
 System.Data/TypedTableBaseExtensions.cs

+ 1 - 0
mcs/class/System.Data.DataSetExtensions/System.Data.DataSetExtensions_test.dll.sources

@@ -1,2 +1,3 @@
 System.Data/DataRowComparerTest.cs
+System.Data/DataTableExtensionsTest.cs
 System.Data/EnumerableRowCollectionTest.cs

+ 6 - 0
mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog

@@ -1,3 +1,9 @@
+2008-05-14  Atsushi Enomoto  <[email protected]>
+
+	* DataTableExtensions.cs :
+	  implemented AsDataView() and CopyToDataTable().
+	* EnumerableRowCollection.cs : added Table property for internal use.
+
 2008-05-14  Atsushi Enomoto  <[email protected]>
 
 	* TypedTableBase.cs : serialization .ctor() does nothing here (it

+ 10 - 8
mcs/class/System.Data.DataSetExtensions/System.Data/DataTableExtensions.cs

@@ -39,17 +39,16 @@ namespace System.Data
 
 	public static class DataTableExtensions
 	{
-		[MonoTODO]
 		public static DataView AsDataView (this DataTable table)
 		{
-			return table.DefaultView;
+			return AsDataView<DataRow> (table.AsEnumerable ());
 		}
 
-		[MonoTODO]
+		[MonoTODO ("We should implement an effective DataView derivation; looks like .NET does.")]
 		public static DataView AsDataView<T> (this EnumerableRowCollection<T> source)
 			where T : DataRow
 		{
-			throw new NotImplementedException ();
+			return CopyToDataTable<T> (source).DefaultView;
 		}
 
 		public static EnumerableRowCollection<DataRow> AsEnumerable (this DataTable source)
@@ -57,27 +56,30 @@ namespace System.Data
 			return new EnumerableRowCollection<DataRow> (new DataRowEnumerable<DataRow> (source));
 		}
 
-		[MonoTODO]
 		public static DataTable CopyToDataTable<T> (this IEnumerable<T> source)
 			where T : DataRow
 		{
 			DataTable dt = new DataTable ();
+			IEnumerator<T> e = source.GetEnumerator ();
+			if (!e.MoveNext ())
+				throw new InvalidOperationException ("The source contains no DataRows");
+			foreach (DataColumn col in e.Current.Table.Columns)
+				dt.Columns.Add (new DataColumn (col.ColumnName, col.DataType, col.Expression, col.ColumnMapping));
 			CopyToDataTable<T> (source, dt, LoadOption.PreserveChanges);
 			return dt;
 		}
 
-		[MonoTODO]
 		public static void CopyToDataTable<T> (this IEnumerable<T> source, DataTable table, LoadOption options)
 			where T : DataRow
 		{
 			CopyToDataTable<T> (source, table, options, null);
 		}
 
-		[MonoTODO]
 		public static void CopyToDataTable<T> (this IEnumerable<T> source, DataTable table, LoadOption options, FillErrorEventHandler errorHandler)
 			where T : DataRow
 		{
-			throw new NotImplementedException ();
+			var reader = new RowEnumerableDataReader (source, 0);
+			table.Load (reader, options, errorHandler);
 		}
 	}
 

+ 13 - 0
mcs/class/System.Data.DataSetExtensions/System.Data/EnumerableRowCollection.cs

@@ -36,10 +36,23 @@ namespace System.Data
 {
 	public abstract class EnumerableRowCollection : IEnumerable
 	{
+		DataTable table;
+
 		internal EnumerableRowCollection ()
 		{
 		}
 
+		internal DataTable Table {
+			get {
+				if (table == null)
+					foreach (DataRow r in this) {
+						table = r.Table;
+						break;
+					}
+				return table;
+			}
+		}
+
 		IEnumerator IEnumerable.GetEnumerator ()
 		{
 			// it is the documented behavior.

+ 235 - 0
mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs

@@ -0,0 +1,235 @@
+//
+// RowEnumerableDataReader.cs
+//
+// Author:
+//   Atsushi Enomoto  <[email protected]>
+//
+// Copyright (C) 2008 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.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Data
+{
+	internal class RowEnumerableDataReader : IDataReader
+	{
+		EnumerableRowCollection source;
+		IEnumerator e;
+		int depth;
+
+		public RowEnumerableDataReader (IEnumerable source, int depth)
+		{
+			this.source = source as EnumerableRowCollection;
+			if (source == null)
+				source = new EnumerableRowCollection<DataRow> ((IEnumerable<DataRow>) source);
+			this.depth = depth;
+		}
+
+		public DataRow Current {
+			get { return e != null ? (DataRow) e.Current : null; }
+		}
+
+		public int Depth {
+			get { return depth; }
+		}
+
+		public bool IsClosed {
+			get { return e == null; }
+		}
+
+		public int RecordsAffected {
+			get { return -1; }
+		}
+
+		public void Close ()
+		{
+			e = null;
+		}
+
+		public DataTable GetSchemaTable ()
+		{
+			return new DataTableReader (source.Table).GetSchemaTable ();
+		}
+
+		public bool NextResult ()
+		{
+			return e.MoveNext ();
+		}
+
+		public bool Read ()
+		{
+			if (e == null)
+				e = ((IEnumerable) source).GetEnumerator ();
+			return NextResult ();
+		}
+
+		// IDisposable
+		public void Dispose ()
+		{
+			Close ();
+		}
+
+		// IDataRecord
+
+		DataTable GetTable ()
+		{
+			DataRow r = Current;
+			if (r == null)
+				foreach (DataRow rr in source) {
+					r = rr;
+					break;
+				}
+			return r.Table;
+		}
+
+		public int FieldCount {
+			get { return GetTable ().Columns.Count; }
+		}
+
+		public object this [int i] {
+			get { return Current [i]; }
+		}
+
+		public object this [string name] {
+			get { return Current [name]; }
+		}
+
+		public string GetDataTypeName (int i)
+		{
+			return GetFieldType (i).Name;
+		}
+
+		public Type GetFieldType (int i)
+		{
+			return GetTable ().Columns [i].DataType;
+		}
+
+		public string GetName (int i)
+		{
+			return GetTable ().Columns [i].ColumnName;
+		}
+
+		public int GetOrdinal (string name)
+		{
+			return GetTable ().Columns [name].Ordinal;
+		}
+
+		public long GetBytes (int i, long fieldOffset, byte [] buffer, int bufferoffset, int length)
+		{
+			// FIXME: do we need it?
+			throw new NotSupportedException ();
+		}
+
+		public long GetChars (int i, long fieldOffset, char [] buffer, int bufferoffset, int length)
+		{
+			// FIXME: do we need it?
+			throw new NotSupportedException ();
+		}
+
+		public IDataReader GetData (int i)
+		{
+			// FIXME: do we need it?
+			throw new NotSupportedException ();
+		}
+
+		public int GetValues (object [] values)
+		{
+			// FIXME: do we need it?
+			throw new NotSupportedException ();
+		}
+
+		public bool IsDBNull (int i)
+		{
+			return Current.IsNull (i);
+		}
+
+		public bool GetBoolean (int i)
+		{
+			return (bool) Current [i];
+		}
+
+		public byte GetByte (int i)
+		{
+			return (byte) Current [i];
+		}
+
+		public char GetChar (int i)
+		{
+			return (char) Current [i];
+		}
+
+		public DateTime GetDateTime (int i)
+		{
+			return (DateTime) Current [i];
+		}
+
+		public decimal GetDecimal (int i)
+		{
+			return (decimal) Current [i];
+		}
+
+		public double GetDouble (int i)
+		{
+			return (double) Current [i];
+		}
+
+		public float GetFloat (int i)
+		{
+			return (float) Current [i];
+		}
+
+		public Guid GetGuid (int i)
+		{
+			return (Guid) Current [i];
+		}
+
+		public short GetInt16 (int i)
+		{
+			return (short) Current [i];
+		}
+
+		public int GetInt32 (int i)
+		{
+			return (int) Current [i];
+		}
+
+		public long GetInt64 (int i)
+		{
+			return (long) Current [i];
+		}
+
+		public string GetString (int i)
+		{
+			return (string) Current [i];
+		}
+
+		public object GetValue (int i)
+		{
+			return Current [i];
+		}
+	}
+}

+ 4 - 0
mcs/class/System.Data.DataSetExtensions/Test/System.Data/ChangeLog

@@ -1,3 +1,7 @@
+2008-05-14  Atsushi Enomoto  <[email protected]>
+
+	* DataTableExtensionsTest.cs : new test.
+
 2008-05-14  Atsushi Enomoto  <[email protected]>
 
 	* EnumerableRowCollectionTest.cs : added tests for thenby (again

+ 86 - 0
mcs/class/System.Data.DataSetExtensions/Test/System.Data/DataTableExtensionsTest.cs

@@ -0,0 +1,86 @@
+//
+// DataTableExtensionsTest.cs
+//
+// Author:
+//   Atsushi Enomoto  <[email protected]>
+//
+// Copyright (C) 2008 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.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using NUnit.Framework;
+
+namespace MonoTests.System.Data
+{
+	[TestFixture]
+	public class DataTableExtensionsTest
+	{
+		[Test]
+		[ExpectedException (typeof (InvalidOperationException))] // for no rows
+		public void CopyToDataTableNoArgNoRows ()
+		{
+			DataTable dt = new DataTable ();
+			dt.Columns.Add ("CID", typeof (int));
+			dt.Columns.Add ("CName", typeof (string));
+			dt.AsEnumerable ().CopyToDataTable<DataRow> ();
+		}
+
+		[Test]
+		public void CopyToDataTableNoArg ()
+		{
+			DataTable dt = new DataTable ();
+			dt.Columns.Add ("CID", typeof (int));
+			dt.Columns.Add ("CName", typeof (string));
+			dt.Rows.Add (new object [] {1, "foo"});
+			DataTable dst = dt.AsEnumerable ().CopyToDataTable<DataRow> ();
+			Assert.AreEqual (1, dst.Rows.Count, "#1");
+			Assert.AreEqual ("foo", dst.Rows [0] ["CName"], "#2");
+		}
+
+		[Test]
+		// no error for empty table this time.
+		[Category ("NotWorking")] // some DataTableReader internal issues
+		public void CopyToDataTableTableArgNoRows ()
+		{
+			DataTable dt = new DataTable ();
+			dt.Columns.Add ("CID", typeof (int));
+			dt.Columns.Add ("CName", typeof (string));
+			DataTable dst = new DataTable ();
+			dt.AsEnumerable ().CopyToDataTable<DataRow> (dst, LoadOption.PreserveChanges);
+		}
+
+		[Test]
+		public void AsDataView ()
+		{
+			DataSet ds = new DataSet ();
+			ds.ReadXml ("Test/System.Data/testdataset1.xml");
+			DataTable dt = ds.Tables [0];
+			var dv = dt.AsEnumerable ().Where<DataRow> ((DataRow r) => (int) r ["Score"] > 60).AsDataView<DataRow> ();
+			Assert.AreEqual (1, dv [0] ["ID"], "#1");
+			Assert.AreEqual (4, dv [1] ["ID"], "#2");
+		}
+	}
+}