2008-05-13 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Tue, 13 May 2008 16:48:55 +0000 (16:48 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Tue, 13 May 2008 16:48:55 +0000 (16:48 -0000)
* DataTableExtensions.cs, EnumerableRowCollection.cs,
  EnumerableRowCollectionExtensions.cs, EnumerableRowCollection_1.cs,
  OrderedEnumerableRowCollection.cs, TypedTableBase.cs,
  TypedTableBaseExtensions.cs : lots of significant refactoring to
  make collection/enumerable things unified.
  Implemented OrderBy() and OrderByDescending().

* EnumerableRowCollectionTest.cs : added tests for orderby (though
  commented out; they do not compile).

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

mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog
mcs/class/System.Data.DataSetExtensions/System.Data/DataTableExtensions.cs
mcs/class/System.Data.DataSetExtensions/System.Data/EnumerableRowCollection.cs
mcs/class/System.Data.DataSetExtensions/System.Data/EnumerableRowCollectionExtensions.cs
mcs/class/System.Data.DataSetExtensions/System.Data/EnumerableRowCollection_1.cs
mcs/class/System.Data.DataSetExtensions/System.Data/OrderedEnumerableRowCollection.cs
mcs/class/System.Data.DataSetExtensions/System.Data/TypedTableBase.cs
mcs/class/System.Data.DataSetExtensions/System.Data/TypedTableBaseExtensions.cs
mcs/class/System.Data.DataSetExtensions/Test/System.Data/ChangeLog
mcs/class/System.Data.DataSetExtensions/Test/System.Data/EnumerableRowCollectionTest.cs

index 24ef33b47a8d9cf2b36c05f2e35a751fc201b33f..05d7273bc741053661297499687e4ee08fd241f6 100644 (file)
@@ -1,3 +1,12 @@
+2008-05-13  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * DataTableExtensions.cs, EnumerableRowCollection.cs,
+         EnumerableRowCollectionExtensions.cs, EnumerableRowCollection_1.cs,
+         OrderedEnumerableRowCollection.cs, TypedTableBase.cs,
+         TypedTableBaseExtensions.cs : lots of significant refactoring to
+         make collection/enumerable things unified.
+         Implemented OrderBy() and OrderByDescending().
+
 2008-05-13  Marek Habersack  <mhabersack@novell.com>
 
        * DataRowComparer_1.cs: implemented GetHashCode and Equals.
index 3ff7e9fc88169c5dc8854af8ad4b878b20b48c74..5e9aaf7d8cefec6f38a7bad99a0df119c40cedfc 100644 (file)
@@ -29,6 +29,7 @@
 //
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 
@@ -53,7 +54,7 @@ namespace System.Data
 
                public static EnumerableRowCollection<DataRow> AsEnumerable (this DataTable source)
                {
-                       return new EnumerableRowCollection<DataRow> (source);
+                       return new EnumerableRowCollection<DataRow> (new DataRowEnumerable<DataRow> (source));
                }
 
                [MonoTODO]
@@ -79,4 +80,25 @@ namespace System.Data
                        throw new NotImplementedException ();
                }
        }
+
+       class DataRowEnumerable<TRow> : IEnumerable<TRow>
+       {
+               DataTable source;
+
+               public DataRowEnumerable (DataTable source)
+               {
+                       this.source = source;
+               }
+
+               public IEnumerator<TRow> GetEnumerator ()
+               {
+                       foreach (TRow row in source.Rows)
+                               yield return row;
+               }
+
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       return GetEnumerator ();
+               }
+       }
 }
index ee50a74f6153aed7aa0ff0538a5dead2f0eff8ef..b712c5e1f52e3a93fc4f6b0e8b24bdf4bef8427f 100644 (file)
 
 using System;
 using System.Collections;
+using System.Collections.Generic;
 
 namespace System.Data
 {
        public abstract class EnumerableRowCollection : IEnumerable
        {
+               internal static IEnumerable<TResult> Cast<TResult> (IEnumerable source)
+               {
+                       foreach (object o in source)
+                               yield return (TResult) o;
+               }
+
+               internal static IEnumerable<S> Select<TRow, S> (IEnumerable<TRow> source, Func<TRow, S> selector)
+               {
+                       foreach (TRow row in source)
+                               yield return selector (row);
+               }
+
+               internal static IEnumerable<TRow> Where<TRow> (IEnumerable<TRow> source, Func<TRow, bool> predicate)
+               {
+                       foreach (TRow row in source)
+                               if (predicate (row))
+                                       yield return row;
+               }
+
                internal EnumerableRowCollection ()
                {
                }
index cac96d18edfe568daf6280d6bf4151c3391d00c4..fa21bd393be4d361c6fb3ba1182971e16fadacdc 100644 (file)
@@ -35,45 +35,34 @@ namespace System.Data
 {
        public static class EnumerableRowCollectionExtensions
        {
-               [MonoTODO]
                public static EnumerableRowCollection<TResult> Cast<TResult> (this EnumerableRowCollection source)
                {
-                       throw new NotImplementedException ();
+                       return new EnumerableRowCollection<TResult> (EnumerableRowCollection.Cast<TResult> (source));
                }
 
-               [MonoTODO]
                public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector)
                {
                        return OrderBy<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
                }
 
-               [MonoTODO]
                public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
                {
-                       throw new NotImplementedException ();
+                       return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, false);
                }
 
-               [MonoTODO]
                public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector)
                {
                        return OrderByDescending<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
                }
 
-               [MonoTODO]
                public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this EnumerableRowCollection<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
                {
-                       throw new NotImplementedException ();
+                       return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, true);
                }
 
                public static EnumerableRowCollection<S> Select<TRow, S> (this EnumerableRowCollection<TRow> source, Func<TRow, S> selector)
                {
-                       return new EnumerableRowCollection<S> (RunSelect<TRow, S> (source, selector));
-               }
-
-               static IEnumerable<S> RunSelect<TRow, S> (this EnumerableRowCollection<TRow> source, Func<TRow, S> selector)
-               {
-                       foreach (TRow row in source)
-                               yield return selector (row);
+                       return new EnumerableRowCollection<S> (EnumerableRowCollection.Select<TRow, S> (source, selector));
                }
 
                [MonoTODO]
@@ -102,14 +91,7 @@ namespace System.Data
 
                public static EnumerableRowCollection<TRow> Where<TRow> (this EnumerableRowCollection<TRow> source, Func<TRow, bool> predicate)
                {
-                       return new EnumerableRowCollection<TRow> (RunWhere<TRow> (source, predicate));
-               }
-
-               static IEnumerable<TRow> RunWhere<TRow> (EnumerableRowCollection<TRow> source, Func<TRow, bool> predicate)
-               {
-                       foreach (TRow row in source)
-                               if (predicate (row))
-                                       yield return row;
+                       return new EnumerableRowCollection<TRow> (EnumerableRowCollection.Where<TRow> (source, predicate));
                }
        }
 }
index 31f32a7a5189703eb4ffb8a3104c78d2f92ba613..bc2ddcc171fc28ef0904652573d158065d4ca57a 100644 (file)
@@ -38,11 +38,6 @@ namespace System.Data
        {
                IEnumerable<TRow> source;
 
-               internal EnumerableRowCollection (DataTable source)
-                       : this (new DataRowGenericCollection (source))
-               {
-               }
-
                internal EnumerableRowCollection (IEnumerable<TRow> source)
                {
                        this.source = source;
@@ -58,26 +53,5 @@ namespace System.Data
                {
                        return GetEnumerator ();
                }
-
-               class DataRowGenericCollection : IEnumerable<TRow>
-               {
-                       DataTable source;
-
-                       public DataRowGenericCollection (DataTable source)
-                       {
-                               this.source = source;
-                       }
-
-                       public IEnumerator<TRow> GetEnumerator ()
-                       {
-                               foreach (TRow row in source.Rows)
-                                       yield return row;
-                       }
-
-                       IEnumerator IEnumerable.GetEnumerator ()
-                       {
-                               return GetEnumerator ();
-                       }
-               }
        }
 }
index 0a41a95058baa38abf96409a98603c094c0b5c3c..c97fdc7a19169d158f5036cbfd978de7f7b8bb48 100644 (file)
 //
 
 using System;
+using System.Collections;
+using System.Collections.Generic;
 
 namespace System.Data
 {
        public sealed class OrderedEnumerableRowCollection<TRow>
                : EnumerableRowCollection<TRow>
        {
-               internal OrderedEnumerableRowCollection (DataTable source)
-                       : this (source)
+               internal static OrderedEnumerableRowCollection<TRow> Create<TRow, TKey> (IEnumerable<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer, bool descending)
                {
+                       return new OrderedEnumerableRowCollection<TRow> (new Sorter<TRow, TKey> (source, keySelector, comparer, descending));
+               }
+
+               OrderedEnumerableRowCollection (IEnumerable<TRow> source)
+                       : base (source)
+               {
+               }
+       }
+
+       class Sorter<TRow, TKey> : IEnumerable<TRow>
+       {
+               IEnumerable<TRow> source;
+               Func<TRow, TKey> key_selector;
+               IComparer<TKey> comparer;
+               bool descending;
+
+               public Sorter (IEnumerable<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer, bool descending)
+               {
+                       if (keySelector == null)
+                               throw new ArgumentNullException ("keySelector");
+                       if (comparer == null)
+                               comparer = Comparer<TKey>.Default;
+                       this.source = source;
+                       this.key_selector = keySelector;
+                       this.comparer = comparer;
+                       this.descending = descending;
+               }
+
+               public IEnumerator<TRow> GetEnumerator ()
+               {
+                       var list = new List<TRow> ();
+                       foreach (TRow row in source)
+                               list.Add (row);
+                       list.Sort (delegate (TRow r1, TRow r2) {
+                               return comparer.Compare (key_selector (r1), key_selector (r2));
+                               });
+                       if (descending)
+                               for (int i = list.Count - 1; i >= 0; i--)
+                                       yield return list [i];
+                       else
+                               for (int i = 0, c = list.Count; i < c; i++)
+                                       yield return list [i];
+               }
+
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       return GetEnumerator ();
                }
        }
 }
index 64e8bf1e3508e172daeba02475ba4286ad5bea62..daef62180c60bf5ad80696715fadc7cef1680996 100644 (file)
@@ -50,22 +50,20 @@ namespace System.Data
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public EnumerableRowCollection<TResult> Cast<TResult> ()
                {
-                       throw new NotImplementedException ();
+                       return new EnumerableRowCollection<TResult> (EnumerableRowCollection.Cast<TResult> (this));
                }
 
-               [MonoTODO]
                public IEnumerator<T> GetEnumerator ()
                {
-                       throw new NotImplementedException ();
+                       foreach (object o in Rows)
+                               yield return (T) o;
                }
 
-               [MonoTODO]
                IEnumerator IEnumerable.GetEnumerator ()
                {
-                       return (IEnumerator) GetEnumerator ();
+                       return GetEnumerator ();
                }
        }
 }
index cdc01b40dba37b9133d1ecd50cba9dfe7c7d0a4b..7502caefdb6b1fbdf62df08c257ffee0fe566979 100644 (file)
@@ -36,10 +36,9 @@ namespace System.Data
        public static class TypedTableBaseExtensions
        {
 
-               [MonoTODO]
                public static EnumerableRowCollection<TRow> AsEnumerable<TRow> (this TypedTableBase<TRow> source) where TRow : DataRow
                {
-                       throw new NotImplementedException ();
+                       return new EnumerableRowCollection<TRow> (source);
                }
 
                public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector)
@@ -48,11 +47,10 @@ namespace System.Data
                        return OrderBy<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
                }
 
-               [MonoTODO]
                public static OrderedEnumerableRowCollection<TRow> OrderBy<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
                        where TRow : DataRow
                {
-                       throw new NotImplementedException ();
+                       return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, false);
                }
 
                public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector)
@@ -61,25 +59,22 @@ namespace System.Data
                        return OrderByDescending<TRow, TKey> (source, keySelector, Comparer<TKey>.Default);
                }
 
-               [MonoTODO]
                public static OrderedEnumerableRowCollection<TRow> OrderByDescending<TRow, TKey> (this TypedTableBase<TRow> source, Func<TRow, TKey> keySelector, IComparer<TKey> comparer)
                        where TRow : DataRow
                {
-                       throw new NotImplementedException ();
+                       return OrderedEnumerableRowCollection<TRow>.Create<TRow, TKey> (source, keySelector, comparer, true);
                }
 
-               [MonoTODO]
                public static EnumerableRowCollection<S> Select<TRow, S> (this TypedTableBase<TRow> source, Func<TRow, S> selector)
                        where TRow : DataRow
                {
-                       throw new NotImplementedException ();
+                       return new EnumerableRowCollection<S> (EnumerableRowCollection.Select<TRow, S> (source, selector));
                }
 
-               [MonoTODO]
                public static EnumerableRowCollection<TRow> Where<TRow> (this TypedTableBase<TRow> source, Func<TRow, bool> predicate)
                        where TRow : DataRow
                {
-                       throw new NotImplementedException ();
+                       return new EnumerableRowCollection<TRow> (EnumerableRowCollection.Where<TRow> (source, predicate));
                }
        }
 }
index 9c99feb6f24f203631e5c554dce1658401988f20..99d759bf2ba2c7941aa846ec90f420ee34dc33c5 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-13  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * EnumerableRowCollectionTest.cs : added tests for orderby (though
+         commented out; they do not compile).
+
 2008-05-13  Atsushi Enomoto  <atsushi@ximian.com>
 
        * DataRowComparerTest.cs, EnumerableRowCollectionTest.cs,
index 46e9fb9ba0b44900658ac9c6e087c467b435f81d..6aa4d27ef35544023ec3129a3586e40bc120176c 100644 (file)
@@ -85,6 +85,64 @@ namespace MonoTests.System.Data
                                iterated = true;
                        }
                }
+
+               [Test]
+               public void QueryWhereSelectOrderBy ()
+               {
+                       var ds = new DataSet ();
+                       ds.ReadXml ("Test/System.Data/testdataset1.xml");
+                       var table = ds.Tables [0];
+                       var q = from line in table.AsEnumerable ()
+                               where line.Field<int> ("Score") >= 80
+                               orderby line.Field<int> ("ID")
+                               select new {
+                                       StudentID = line.Field<int> ("ID"),
+                                       StudentName = line.Field<string> ("Name"),
+                                       StudentScore = line.Field<int> ("Score") };
+                       int prevID = -1;
+                       foreach (var ql in q) {
+                               switch (prevID) {
+                               case -1:
+                                       Assert.AreEqual (4, ql.StudentID, "#1");
+                                       break;
+                               case 4:
+                                       Assert.AreEqual (1, ql.StudentID, "#2");
+                                       break;
+                               default:
+                                       Assert.Fail ("should match only one raw");
+                               }
+                               prevID = ql.StudentID;
+                       }
+               }
+
+               [Test]
+               public void QueryWhereSelectOrderByDescending ()
+               {
+                       var ds = new DataSet ();
+                       ds.ReadXml ("Test/System.Data/testdataset1.xml");
+                       var table = ds.Tables [0];
+                       var q = from line in table.AsEnumerable ()
+                               where line.Field<int> ("Score") >= 80
+                               orderby line.Field<int> ("ID") descending
+                               select new {
+                                       StudentID = line.Field<int> ("ID"),
+                                       StudentName = line.Field<string> ("Name"),
+                                       StudentScore = line.Field<int> ("Score") };
+                       int prevID = -1;
+                       foreach (var ql in q) {
+                               switch (prevID) {
+                               case -1:
+                                       Assert.AreEqual (1, ql.StudentID, "#1");
+                                       break;
+                               case 4:
+                                       Assert.AreEqual (4, ql.StudentID, "#2");
+                                       break;
+                               default:
+                                       Assert.Fail ("should match only one raw");
+                               }
+                               prevID = ql.StudentID;
+                       }
+               }
                */
        }
 }