checking in ongoing implementation before DynamicDataRoute.
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 16 Oct 2008 19:29:07 +0000 (19:29 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 16 Oct 2008 19:29:07 +0000 (19:29 -0000)
svn path=/trunk/mcs/; revision=116032

19 files changed:
mcs/class/System.Web.DynamicData/ChangeLog
mcs/class/System.Web.DynamicData/Makefile
mcs/class/System.Web.DynamicData/System.Web.DynamicData.ModelProviders/ChangeLog
mcs/class/System.Web.DynamicData/System.Web.DynamicData.ModelProviders/ColumnProvider.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData.ModelProviders/DLinqDataModelProviders.cs [new file with mode: 0644]
mcs/class/System.Web.DynamicData/System.Web.DynamicData.ModelProviders/TableProvider.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData.dll.sources
mcs/class/System.Web.DynamicData/System.Web.DynamicData/ChangeLog
mcs/class/System.Web.DynamicData/System.Web.DynamicData/DynamicDataManager.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData/DynamicDataRoute.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData/FieldTemplateFactory.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData/MetaChildrenColumn.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData/MetaColumn.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData/MetaForeignKeyColumn.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData/MetaModel.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData/MetaTable.cs
mcs/class/System.Web.DynamicData/System.Web.DynamicData_test.dll.sources [new file with mode: 0644]
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/ChangeLog [new file with mode: 0644]
mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/MetaModelTest.cs [new file with mode: 0644]

index 300d8bf4be55aabfd4139e1a2dd1d61fccdc79f3..5485a729f41f1bbee436d77814d908e6fd1509d0 100644 (file)
@@ -1,3 +1,8 @@
+2008-10-16  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * Makefile : added -r:System.Data.
+       * System.Web.DynamicData_test.dll.sources : new file.
+
 2008-10-14  Atsushi Enomoto  <atsushi@ximian.com>
 
        * Makefile, System.Web.DynamicData.dll.sources : initial checkin.
index 924cbb4e958b2cdbb7110dee14fa8b4579e55761..2dd138d3fab2a531cc4454d1ba679d47587ba86b 100644 (file)
@@ -7,6 +7,7 @@ LIB_MCS_FLAGS = \
                /r:System.dll \
                /r:System.Core.dll \
                /r:System.ComponentModel.DataAnnotations.dll \
+               /r:System.Data.dll \
                /r:System.Data.Linq.dll \
                /r:System.Drawing.dll \
                /r:System.Web.dll \
index 71942ef15b0e03c8286bb0ac76d2c0ce359d50b9..722b5feac73265be06c52fc4fd27e4cc7bb79f84 100644 (file)
@@ -1,3 +1,8 @@
+2008-10-16  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ColumnProvider.cs, TableProvider.cs : implemented constructors.
+       * DLinqDataModelProviders.cs : new, DLinq-based implementation.
+
 2008-10-14  Atsushi Enomoto  <atsushi@ximian.com>
 
        *.cs : initial checkin. stubs.
index a87a8af36f02dd88ecd23cdc8cdc12135f6863db..e52e55755c8664526ff949c9942959d27b87e033 100644 (file)
@@ -38,10 +38,11 @@ namespace System.Web.DynamicData.ModelProviders
        [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public abstract class ColumnProvider
        {
-               [MonoTODO]
                protected ColumnProvider (TableProvider table)
                {
-                       throw new NotImplementedException ();
+                       if (table == null)
+                               throw new ArgumentNullException ("table");
+                       this.Table = table;
                }
 
                [MonoTODO]
diff --git a/mcs/class/System.Web.DynamicData/System.Web.DynamicData.ModelProviders/DLinqDataModelProviders.cs b/mcs/class/System.Web.DynamicData/System.Web.DynamicData.ModelProviders/DLinqDataModelProviders.cs
new file mode 100644 (file)
index 0000000..57a9a31
--- /dev/null
@@ -0,0 +1,140 @@
+//
+// DLinqDataModelProvider.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2008 Novell Inc. http://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.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Data.Linq;
+using System.Data.Linq.Mapping;
+using System.Linq;
+using System.Security.Permissions;
+
+using DMetaModel = System.Data.Linq.Mapping.MetaModel;
+using DMetaTable = System.Data.Linq.Mapping.MetaTable;
+
+namespace System.Web.DynamicData.ModelProviders
+{
+       class DLinqDataModelProvider : DataModelProvider
+       {
+               Func<object> factory;
+               DMetaModel model;
+
+               public DLinqDataModelProvider (Func<object> factory)
+               {
+                       this.factory = factory;
+                       Type type = CreateContext ().GetType ();
+
+                       if (!typeof (DataContext).IsAssignableFrom (type))
+                               throw new ArgumentException (String.Format ("Type '{0}' is not supported as data context factory", type));
+
+                       this.factory = factory;
+
+                       model = new AttributeMappingSource ().GetModel (type);
+                       ContextType = model.ContextType;
+
+                       var l = new List<TableProvider> ();
+                       foreach (var m in model.GetTables ())
+                               l.Add (new DLinqTableProvider (this, m));
+                       tables = new ReadOnlyCollection<TableProvider> (l);
+               }
+
+               ReadOnlyCollection<TableProvider> tables;
+
+               public override ReadOnlyCollection<TableProvider> Tables {
+                       get { return tables; }
+               }
+
+               public override object CreateContext ()
+               {
+                       return factory ();
+               }
+       }
+
+       class DLinqTableProvider : TableProvider
+       {
+               public DLinqTableProvider (DataModelProvider owner, DMetaTable meta)
+                       : base (owner)
+               {
+                       EntityType = meta.RowType.Type;
+
+                       Name = meta.TableName;
+                       int idx = Name.LastIndexOf ('.');
+                       Name = idx < 0 ? Name : Name.Substring (idx + 1);
+
+                       var l = new List<ColumnProvider> ();
+                       foreach (var c in meta.RowType.DataMembers)
+                               l.Add (new DLinqColumnProvider (this, c));
+                       columns = new ReadOnlyCollection<ColumnProvider> (l);
+               }
+
+               MetaTable table;
+               ReadOnlyCollection<ColumnProvider> columns;
+
+               public override ReadOnlyCollection<ColumnProvider> Columns {
+                       get { return columns; }
+               }
+
+               public override IQueryable GetQuery (object context)
+               {
+                       return ((DataContext) context).GetTable (EntityType);
+               }
+
+               public override string ToString ()
+               {
+                       return base.ToString ();
+               }
+       }
+
+       class DLinqColumnProvider : ColumnProvider
+       {
+               public DLinqColumnProvider (TableProvider owner, MetaDataMember meta)
+                       : base (owner)
+               {
+                       if (owner == null)
+                               throw new ArgumentNullException ("owner");
+                       if (meta == null)
+                               throw new ArgumentNullException ("meta");
+
+                       this.meta = meta;
+
+                       // FIXME: fill more
+                       Name = meta.Name;
+                       Nullable = meta.CanBeNull;
+               }
+
+               MetaDataMember meta;
+
+               [MonoTODO]
+               public override string ToString ()
+               {
+                       return base.ToString ();
+               }
+       }
+}
index 871f5bb6842b30699193bdf0ee217a11fa239201..e7d81f370fd892234e65e2624db053ed7802fd57 100644 (file)
@@ -42,9 +42,12 @@ namespace System.Web.DynamicData.ModelProviders
        {
                protected TableProvider (DataModelProvider model)
                {
-                       throw new NotImplementedException ();
+                       if (model == null)
+                               throw new ArgumentNullException ("model");
+                       DataModel = model;
                }
 
+               [MonoTODO]
                public abstract ReadOnlyCollection<ColumnProvider> Columns { get; }
                [MonoTODO]
                public DataModelProvider DataModel { get; private set; }
@@ -59,6 +62,7 @@ namespace System.Web.DynamicData.ModelProviders
                        throw new NotImplementedException ();
                }
 
+               [MonoTODO]
                public abstract IQueryable GetQuery (object context);
 
                [MonoTODO]
index 2d27f61f21ae15c434d638815f79132bb7c43a0c..5aafeb46f3b7f1a223d8480d10f382baf27f81b6 100644 (file)
@@ -5,6 +5,7 @@ Assembly/AssemblyInfo.cs
 System.Web.DynamicData.ModelProviders/AssociationDirection.cs
 System.Web.DynamicData.ModelProviders/AssociationProvider.cs
 System.Web.DynamicData.ModelProviders/ColumnProvider.cs
+System.Web.DynamicData.ModelProviders/DLinqDataModelProviders.cs
 System.Web.DynamicData.ModelProviders/DataModelProvider.cs
 System.Web.DynamicData.ModelProviders/TableProvider.cs
 System.Web.DynamicData/ContextConfiguration.cs
index 71942ef15b0e03c8286bb0ac76d2c0ce359d50b9..558c44dfb110e53f23200083e234eadd689eb88f 100644 (file)
@@ -1,3 +1,10 @@
+2008-10-16  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * DynamicDataManager.cs, DynamicDataRoute.cs,
+         FieldTemplateFactory.cs, MetaChildrenColumn.cs,
+         MetaColumn.cs, MetaForeignKeyColumn.cs, MetaModel.cs, MetaTable.cs:
+         ongoing implementation.
+
 2008-10-14  Atsushi Enomoto  <atsushi@ximian.com>
 
        *.cs : initial checkin. stubs.
index 6049e3330ddf028502434046bc68e3f9a9d20f6d..515cce70c12764aa7e8d0fada56b416b465f77ea 100644 (file)
@@ -1,5 +1,5 @@
 //
-// DynamicDataExtensions.cs
+// DynamicDataManager.cs
 //
 // Author:
 //     Atsushi Enomoto <atsushi@ximian.com>
index 7d6a761559415030c9e87b4ba4679ece01fff284..0bb4fea5e81fe6e944a60a73e77bad056397dd7d 100644 (file)
@@ -47,18 +47,17 @@ namespace System.Web.DynamicData
                public DynamicDataRoute (string url)
                        : base (url, null)
                {
-                       throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public string Action { get; set; }
-               [MonoTODO]
+
                public MetaModel Model { get; set; }
+
                [MonoTODO]
                public DynamicDataRouteHandler RouteHandler { get; set; }
-               [MonoTODO]
+
                public string Table { get; set; }
-               [MonoTODO]
+
                public string ViewName { get; set; }
 
                [MonoTODO]
index af5187373392560e48fd848163c71e573243b257..8dc3eb6fc0fdbd25d1e0bb7eee8c11e296d91113 100644 (file)
@@ -69,7 +69,10 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public virtual void Initialize (MetaModel model)
                {
-                       throw new NotImplementedException ();
+                       if (model == null)
+                               throw new ArgumentNullException ("model");
+                       Model = model;
+                       // FIXME: do something more.
                }
 
                [MonoTODO]
index 38bf673433729f75c0575f0eaa775122bef49ec9..9afd442f15abe2b4ece19cb397216d82fc14ca04 100644 (file)
@@ -43,7 +43,8 @@ namespace System.Web.DynamicData
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class MetaChildrenColumn : MetaColumn
        {
-               internal MetaChildrenColumn ()
+               internal MetaChildrenColumn (MetaTable table, ColumnProvider provider)
+                       : base (table, provider)
                {
                }
 
index cdf752ecc3e9a7b29be230faf78e2e8b366f7134..5d12304b568081603338d4089d2dd0efd03713f3 100644 (file)
@@ -46,8 +46,10 @@ namespace System.Web.DynamicData
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class MetaColumn : IFieldFormattingOptions
        {
-               internal MetaColumn ()
+               internal MetaColumn (MetaTable table, ColumnProvider provider)
                {
+                       Table = table;
+                       Provider = provider;
                }
 
                [MonoTODO]
@@ -56,8 +58,9 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public AttributeCollection Attributes { get; private set; }
 
-               [MonoTODO]
-               public Type ColumnType { get; private set; }
+               public Type ColumnType {
+                       get { return Provider.ColumnType; }
+               }
 
                [MonoTODO]
                public bool ConvertEmptyStringToNull { get; private set; }
@@ -77,8 +80,9 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public string DisplayName { get; private set; }
 
-               [MonoTODO]
-               public PropertyInfo EntityTypeProperty { get; private set; }
+               public PropertyInfo EntityTypeProperty {
+                       get { return Provider.EntityTypeProperty; }
+               }
 
                [MonoTODO]
                public bool HtmlEncode { get; private set; }
@@ -86,17 +90,20 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public bool IsBinaryData { get; private set; }
 
-               [MonoTODO]
-               public bool IsCustomProperty { get; private set; }
+               public bool IsCustomProperty {
+                       get { return Provider.IsCustomProperty; }
+               }
 
                [MonoTODO]
                public bool IsFloatingPoint { get; private set; }
 
-               [MonoTODO]
-               public bool IsForeignKeyComponent { get; private set; }
+               public bool IsForeignKeyComponent {
+                       get { return Provider.IsForeignKeyComponent; }
+               }
 
-               [MonoTODO]
-               public bool IsGenerated { get; private set; }
+               public bool IsGenerated {
+                       get { return Provider.IsGenerated; }
+               }
 
                [MonoTODO]
                public bool IsInteger { get; private set; }
@@ -104,8 +111,9 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public bool IsLongString { get; private set; }
 
-               [MonoTODO]
-               public bool IsPrimaryKey { get; private set; }
+               public bool IsPrimaryKey {
+                       get { return Provider.IsPrimaryKey; }
+               }
 
                [MonoTODO]
                public bool IsReadOnly { get; private set; }
@@ -116,19 +124,19 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public bool IsString { get; private set; }
 
-               [MonoTODO]
-               public int MaxLength { get; private set; }
+               public int MaxLength {
+                       get { return Provider.MaxLength; }
+               }
 
-               [MonoTODO]
                public MetaModel Model { get; private set; }
 
-               [MonoTODO]
-               public string Name { get; private set; }
+               public string Name {
+                       get { return Provider.Name; }
+               }
 
                [MonoTODO]
                public string NullDisplayText { get; private set; }
 
-               [MonoTODO]
                public ColumnProvider Provider { get; private set; }
 
                [MonoTODO]
@@ -140,7 +148,6 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public string SortExpression { get; private set; }
 
-               [MonoTODO]
                public MetaTable Table { get; private set; }
 
                [MonoTODO]
index cb8a630217c88cf14a64a6090d3c08a4224c8920..8b93c0cf23bdc671913682552e967e61536fb40d 100644 (file)
@@ -44,7 +44,8 @@ namespace System.Web.DynamicData
        [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class MetaForeignKeyColumn : MetaColumn
        {
-               internal MetaForeignKeyColumn ()
+               internal MetaForeignKeyColumn (MetaTable table, ColumnProvider provider)
+                       : base (table, provider)
                {
                }
 
index 010a71a0c3bbdbdc174a81471f4c8c27bc5e24aa..a70ecfb37965e637447afd441e9a42cb6b43302b 100644 (file)
@@ -46,20 +46,44 @@ namespace System.Web.DynamicData
        public class MetaModel
        {
                static MetaModel default_model;
+               static Exception registration_exception;
 
-               [MonoTODO]
                public static MetaModel Default {
-                       get { throw new NotImplementedException (); }
+                       get { return default_model; }
                        internal set { default_model = value; }
                }
 
                [MonoTODO]
+               public static MetaModel GetModel (Type contextType)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static void ResetRegistrationException ()
+               {
+                       registration_exception = null;
+               }
+
+               public MetaModel ()
+               {
+                       if (default_model == null)
+                               default_model = this;
+
+                       DynamicDataFolderVirtualPath = "~/DynamicData/";
+                       FieldTemplateFactory = new FieldTemplateFactory ();
+                       Tables = new ReadOnlyCollection<MetaTable> (new MetaTable [0]);
+                       VisibleTables = new List<MetaTable> ();
+               }
+
+               DataModelProvider provider;
+
+
                public string DynamicDataFolderVirtualPath { get; set; }
-               [MonoTODO]
+
                public IFieldTemplateFactory FieldTemplateFactory { get; set; }
-               [MonoTODO]
+
                public ReadOnlyCollection<MetaTable> Tables { get; private set; }
-               [MonoTODO]
+
                public List<MetaTable> VisibleTables { get; private set; }
 
                [MonoTODO]
@@ -68,22 +92,37 @@ namespace System.Web.DynamicData
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
-               public static MetaModel GetModel (Type contextType)
+               public bool TryGetTable (string uniqueTableName, out MetaTable table)
                {
-                       throw new NotImplementedException ();
+                       if (uniqueTableName == null)
+                               throw new ArgumentNullException ("uniqueTableName");
+                       if (provider != null)
+                               foreach (var t in Tables)
+                                       if (t.Name == uniqueTableName) {
+                                               table = t;
+                                               return true;
+                                       }
+                       table = null;
+                       return false;
                }
 
-               [MonoTODO]
                public MetaTable GetTable (string uniqueTableName)
                {
-                       throw new NotImplementedException ();
+                       MetaTable mt;
+                       if (TryGetTable (uniqueTableName, out mt))
+                               return mt;
+                       throw new ArgumentException (String.Format ("Table '{0}' does not exist in registered context", uniqueTableName));
                }
 
-               [MonoTODO]
                public MetaTable GetTable (Type entityType)
                {
-                       throw new NotImplementedException ();
+                       if (entityType == null)
+                               throw new ArgumentNullException ("entityType");
+                       if (provider != null)
+                               foreach (var t in Tables)
+                                       if (t.EntityType == entityType)
+                                               return t;
+                       throw new ArgumentException (String.Format ("Entity type '{0}' does not exist in registered context", entityType));
                }
 
                [MonoTODO]
@@ -92,52 +131,70 @@ namespace System.Web.DynamicData
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
+               void CheckRegistrationError ()
+               {
+                       if (registration_exception != null)
+                               throw new InvalidOperationException ("An error occured during context model registration", registration_exception);
+               }
+
                public void RegisterContext (Func<object> contextFactory)
                {
-                       throw new NotImplementedException ();
+                       RegisterContext (contextFactory, null);
                }
 
-               [MonoTODO]
                public void RegisterContext (Type contextType)
                {
-                       throw new NotImplementedException ();
+                       RegisterContext (contextType, null);
                }
 
-               [MonoTODO]
                public void RegisterContext (DataModelProvider dataModelProvider)
                {
-                       throw new NotImplementedException ();
+                       RegisterContext (dataModelProvider, null);
                }
 
-               [MonoTODO]
-               public void RegisterContext (Func<object> contextFactory, ContextConfiguration configuration)
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
                public void RegisterContext (Type contextType, ContextConfiguration configuration)
                {
-                       throw new NotImplementedException ();
+                       if (contextType == null)
+                               throw new ArgumentNullException ("contextType");
+                       CheckRegistrationError ();
+Activator.CreateInstance (contextType);
+                       RegisterContext (() => Activator.CreateInstance (contextType), configuration);
                }
 
-               [MonoTODO]
-               public void RegisterContext (DataModelProvider dataModelProvider, ContextConfiguration configuration)
+               public void RegisterContext (Func<object> contextFactory, ContextConfiguration configuration)
                {
-                       throw new NotImplementedException ();
+                       if (contextFactory == null)
+                               throw new ArgumentNullException ("contextFactory");
+                       CheckRegistrationError ();
+                       try {
+                               // FIXME: entity framework support is not done.
+                               RegisterContextCore (new DLinqDataModelProvider (contextFactory), configuration);
+                       } catch (Exception ex) {
+                               registration_exception = ex;
+                               throw;
+                       }
                }
 
-               [MonoTODO]
-               public static void ResetRegistrationException ()
+               public void RegisterContext (DataModelProvider dataModelProvider, ContextConfiguration configuration)
                {
-                       throw new NotImplementedException ();
+                       if (dataModelProvider == null)
+                               throw new ArgumentNullException ("dataModelProvider");
+                       CheckRegistrationError ();
+                       try {
+                               RegisterContextCore (dataModelProvider, configuration);
+                       } catch (Exception ex) {
+                               registration_exception = ex;
+                               throw;
+                       }
                }
 
-               [MonoTODO]
-               public bool TryGetTable (string uniqueTableName, out MetaTable table)
+               void RegisterContextCore (DataModelProvider dataModelProvider, ContextConfiguration configuration)
                {
-                       throw new NotImplementedException ();
+                       var l = new List<MetaTable> ();
+                       foreach (var t in dataModelProvider.Tables)
+                               l.Add (new MetaTable (this, t, configuration != null && configuration.ScaffoldAllTables));
+                       Tables = new ReadOnlyCollection<MetaTable> (l);
+                       VisibleTables = l;
                }
        }
 }
index 98bd8188f89b8944262c2d25935d6ebe187cbcd8..b56557136d0ac4f7c4d93a71e0e951786237dea4 100644 (file)
@@ -47,10 +47,23 @@ namespace System.Web.DynamicData
        [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public class MetaTable
        {
-               internal MetaTable ()
+               internal MetaTable (MetaModel model, TableProvider provider, bool scaffold)
                {
+                       this.model = model;
+                       Provider = provider;
+                       Scaffold = scaffold;
+
+                       var l = new List<MetaColumn> ();
+                       foreach (var c in provider.Columns)
+                               l.Add (new MetaColumn (this, c));
+                       Columns = new ReadOnlyCollection<MetaColumn> (l);
+
+                       DisplayName = Name;
+                       ListActionPath = String.Concat (DisplayName, "/", PageAction.List, ".aspx");
                }
 
+               MetaModel model;
+
                [MonoTODO]
                public AttributeCollection Attributes { get; private set; }
 
@@ -69,8 +82,9 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public string DisplayName { get; private set; }
 
-               [MonoTODO]
-               public Type EntityType { get; private set; }
+               public Type EntityType {
+                       get { return Provider.EntityType; }
+               }
 
                [MonoTODO]
                public string ForeignKeyColumnsNames { get; private set; }
@@ -84,19 +98,19 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public string ListActionPath { get; private set; }
 
-               [MonoTODO]
-               public MetaModel Model { get; private set; }
+               public MetaModel Model {
+                       get { return model; }
+               }
 
-               [MonoTODO]
-               public string Name { get; private set; }
+               public string Name {
+                       get { return Provider.Name; }
+               }
 
                [MonoTODO]
                public ReadOnlyCollection<MetaColumn> PrimaryKeyColumns { get; private set; }
 
-               [MonoTODO]
                public TableProvider Provider { get; private set; }
 
-               [MonoTODO]
                public bool Scaffold { get; private set; }
 
                [MonoTODO]
@@ -108,7 +122,7 @@ namespace System.Web.DynamicData
                [MonoTODO]
                public object CreateContext ()
                {
-                       throw new NotImplementedException ();
+                       return Activator.CreateInstance (EntityType);
                }
 
                [MonoTODO]
@@ -147,10 +161,12 @@ namespace System.Web.DynamicData
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public MetaColumn GetColumn (string columnName)
                {
-                       throw new NotImplementedException ();
+                       MetaColumn mc;
+                       if (TryGetColumn (columnName, out mc))
+                               return mc;
+                       throw new ArgumentException (String.Format ("Column '{0}' does not exist in the meta table '{1}'", columnName, Name));
                }
 
                [MonoTODO]
@@ -177,10 +193,9 @@ namespace System.Web.DynamicData
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public IQueryable GetQuery ()
                {
-                       throw new NotImplementedException ();
+                       return GetQuery (CreateContext ());
                }
 
                [MonoTODO]
@@ -195,10 +210,15 @@ namespace System.Web.DynamicData
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public bool TryGetColumn (string columnName, out MetaColumn column)
                {
-                       throw new NotImplementedException ();
+                       foreach (var m in Columns)
+                               if (m.Name == columnName) {
+                                       column = m;
+                                       return true;
+                               }
+                       column = null;
+                       return false;
                }
        }
 }
diff --git a/mcs/class/System.Web.DynamicData/System.Web.DynamicData_test.dll.sources b/mcs/class/System.Web.DynamicData/System.Web.DynamicData_test.dll.sources
new file mode 100644 (file)
index 0000000..71e5a25
--- /dev/null
@@ -0,0 +1 @@
+System.Web.DynamicData/MetaModelTest.cs
diff --git a/mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/ChangeLog b/mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/ChangeLog
new file mode 100644 (file)
index 0000000..ce18101
--- /dev/null
@@ -0,0 +1,3 @@
+2008-10-16  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * MetaModelTest.cs : initial checkin.
diff --git a/mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/MetaModelTest.cs b/mcs/class/System.Web.DynamicData/Test/System.Web.DynamicData/MetaModelTest.cs
new file mode 100644 (file)
index 0000000..d18a138
--- /dev/null
@@ -0,0 +1,215 @@
+//
+// MetaModelTest.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2008 Novell Inc. http://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.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Data.SqlClient;
+using System.Data.Linq;
+using System.Data.Linq.Mapping;
+using System.Globalization;
+using System.Reflection;
+using System.Security.Permissions;
+using System.Security.Principal;
+using System.Web.Caching;
+using System.Web.DynamicData;
+using System.Web.DynamicData.ModelProviders;
+using NUnit.Framework;
+
+namespace System.Web.DynamicData
+{
+       [TestFixture]
+       public class MetaModelTest
+       {
+               [Test]
+               public void Default ()
+               {
+                       Assert.IsNull (MetaModel.Default, "#1");
+                       var m = new MetaModel (); // it automatically fills Default
+                       Assert.AreEqual (m, MetaModel.Default, "#2");
+                       Assert.IsNotNull (m.Tables, "#3");
+                       Assert.IsNotNull (m.VisibleTables, "#4");
+                       Assert.IsNotNull (m.FieldTemplateFactory, "#5");
+                       Assert.AreEqual ("~/DynamicData/", m.DynamicDataFolderVirtualPath, "#6");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void GetTableNull ()
+               {
+                       new MetaModel ().GetTable ((Type) null);
+               }
+
+               [Test]
+               public void RegisterContext ()
+               {
+                       var m = new MetaModel ();
+                       try {
+                               m.RegisterContext (typeof (Foo));
+                               Assert.Fail ("#1");
+                       } catch (TargetInvocationException ex) {
+                               Assert.AreEqual ("ERROR", ex.InnerException.Message, "#2");
+                       } finally {
+                               MetaModel.ResetRegistrationException ();
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void RegisterContext2 ()
+               {
+                       try {
+                               var m = new MetaModel ();
+                               m.RegisterContext (typeof (Bar)); // not supported
+                       } finally {
+                               MetaModel.ResetRegistrationException ();
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (MissingMethodException))]
+               public void RegisterContext3 ()
+               {
+                       var m = new MetaModel ();
+                       try {
+                               // no public constructor
+                               m.RegisterContext (typeof (DataContext));
+                       } finally {
+                               MetaModel.ResetRegistrationException ();
+                       }
+               }
+
+               [Test]
+               public void RegisterContext4 ()
+               {
+                       var m = new MetaModel ();
+                       try {
+                               m.RegisterContext (typeof (MyDataContext1));
+                               Assert.AreEqual (0, m.Tables.Count, "#1-1");
+                               Assert.AreEqual (0, m.VisibleTables.Count, "#1-2");
+                       } finally {
+                               MetaModel.ResetRegistrationException ();
+                       }
+               }
+
+               [Test]
+               public void RegisterContext5 ()
+               {
+                       var m = new MetaModel ();
+                       try {
+                               m.RegisterContext (typeof (MyDataContext2));
+                               Assert.AreEqual (1, m.Tables.Count, "#1-1");
+                               // VisibleTables property somehow requires live HttpContext.
+                               //Assert.AreEqual (1, m.VisibleTables.Count, "#1-2");
+                               MetaTable t = m.Tables [0];
+                               // Those names are only the last part before '.' (i.e. without schema name).
+                               Assert.AreEqual ("FooTable", t.Name, "#2-1");
+                               Assert.AreEqual ("FooTable", t.DisplayName, "#2-2");
+                               // FIXME: test it too.
+                               //Assert.AreEqual ("FooTable", t.DataContextPropertyName, "#2-3");
+                               Assert.AreEqual ("FooTable", t.Provider.Name, "#3-1");
+                       } finally {
+                               MetaModel.ResetRegistrationException ();
+                       }
+               }
+
+               [Test]
+               public void ResetRegistrationException ()
+               {
+                       MetaModel.ResetRegistrationException ();
+
+                       var m = new MetaModel ();
+                       try {
+                               m.RegisterContext (typeof (Foo));
+                               Assert.Fail ("#1");
+                       } catch (TargetInvocationException) {
+                       }
+
+                       try {
+                               m.RegisterContext (typeof (MyDataContext1));
+                               Assert.Fail ("#2");
+                       } catch (InvalidOperationException) {
+                       } finally {
+                               MetaModel.ResetRegistrationException ();
+                       }
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void GetTableObject ()
+               {
+                       // entity type 'System.Object' not found.
+                       new MetaModel ().GetTable (typeof (object));
+               }
+       }
+
+       class MyDataContext1 : DataContext
+       {
+               public MyDataContext1 ()
+                       : base (new SqlConnection ("Data Source=localhost"))
+               {
+               }
+       }
+
+       [Database (Name = "MyDB1")]
+       class MyDataContext2 : DataContext
+       {
+               public MyDataContext2 ()
+                       : base (new SqlConnection ("Data Source=localhost"))
+               {
+               }
+
+               public Table<Foo> FooTable { get { return GetTable<Foo> (); } }
+       }
+
+       [Table (Name = "dbo...FooTable")]
+       class Foo
+       {
+               public Foo ()
+               {
+                       throw new Exception ("ERROR");
+               }
+
+               [Column (Name = "Col1")]
+               public string Column1 { get; set; }
+       }
+
+       [Table (Name = "BarTable")]
+       class Bar
+       {
+               [Column (Name = "Col1")]
+               public string Column1 { get; set; }
+
+               [Column (Name = "Col2")]
+               public string Column2 { get; set; }
+       }
+}