[Mono-dev] DataColumn.DefaultValue fixes

Konstantin Triger kostat at gmail.com
Fri Jun 13 09:19:24 EDT 2008


Hello all,

It was strange to me that MS perform a special check for SqlXXX types, so I
started looking what is common to them. I saw that all of them derive from
INullable. It looked interesting, so I created my type that derived from
INullable. When I tried to set it as a DataColumn type, I got an exception
stating that I must have a static property or field named "Null". When I
added it, I got its value for DataColumn.DefaultValue.

Regards,
Kosta

On Fri, Jun 13, 2008 at 7:58 AM, Atsushi Eno <atsushi at ximian.com> wrote:

> Thanks, applied.
>
> Atsushi Eno
>
> Veerapuram Varadhan wrote:
> > Hi Atsushi,
> >
> > Patch looks really good to go.
> >
> > Thanks,
> >
> > V. Varadhan
> >
> > On Fri, 2008-06-13 at 01:06 +0900, Atsushi Eno wrote:
> >> Hello,
> >>
> >> I have a fix for one of failing sys.data test in 2.0 profile. Here
> >> is description (could be used for ChangeLog):
> >>
> >> * System.Data/DataColumn.cs
> >>   DefaultValue can be non-DBNull. For SqlXxx type, it becomes
> >>   SqlXxx.Null. Also, changing DataType may change DefaultValue
> >>   to be consistent with the new type (say, having int DefaultValue
> >>   for new string DataType is wrong).
> >>
> >> * System.Data/XmlSchemaWriter.cs
> >>   This should be fixed to take non-DBNull default value into
> >>   consideration.
> >>
> >> * Test/System.Data/DataTableTest.cs, Test/System.Data/DataSetTest.cs
> >>   We could use default value as is, not in string form. This makes
> >>   comparison more strict.
> >>
> >> * Test/System.Data/DataColumnTest.cs
> >>   Added test for non-DBNull case and changing DataType case.
> >>
> >> If it looks good, I'll check in it later.
> >>
> >> Atsushi Eno
> >>
> >> plain text document attachment (column-default-value-fix.patch)
> >> Index: Test/System.Data/DataColumnTest.cs
> >> ===================================================================
> >> --- Test/System.Data/DataColumnTest.cs       (revision 105623)
> >> +++ Test/System.Data/DataColumnTest.cs       (working copy)
> >> @@ -38,6 +38,7 @@
> >>  using System;
> >>  using System.ComponentModel;
> >>  using System.Data;
> >> +using System.Data.SqlTypes;
> >>
> >>  using NUnit.Framework;
> >>
> >> @@ -326,6 +327,42 @@
> >>              }
> >>
> >>              [Test]
> >> +#if !NET_2_0
> >> +            [ExpectedException (typeof (ArgumentException))]
> >> +#endif
> >> +            public void Defaults3 ()
> >> +            {
> >> +                    DataColumn col = new DataColumn ("foo", typeof
> (SqlBoolean));
> >> +#if NET_2_0
> >> +                    Assert.AreEqual (SqlBoolean.Null, col.DefaultValue,
> "#1");
> >> +                    col.DefaultValue = SqlBoolean.True;
> >> +                    // FIXME: not working yet
> >> +                    //col.DefaultValue = true;
> >> +                    //Assert.AreEqual (SqlBoolean.True,
> col.DefaultValue, "#2"); // not bool but SqlBoolean
> >> +                    col.DefaultValue = DBNull.Value;
> >> +                    Assert.AreEqual (SqlBoolean.Null, col.DefaultValue,
> "#3"); // not DBNull
> >> +#else
> >> +                    Assert.AreEqual (DBNull.Value, col.DefaultValue,
> "#1");
> >> +                    col.DefaultValue = true;
> >> +                    Assert.AreEqual (true, col.DefaultValue, "#2");
> >> +                    col.DefaultValue = DBNull.Value; // throws. DBNull
> is not allowed!
> >> +#endif
> >> +            }
> >> +
> >> +            [Test]
> >> +#if NET_2_0
> >> +            [ExpectedException (typeof (DataException))]
> >> +#else
> >> +            [ExpectedException (typeof (ArgumentException))]
> >> +#endif
> >> +            public void ChangeTypeAfterSettingDefaultValue ()
> >> +            {
> >> +                    DataColumn col = new DataColumn ("foo", typeof
> (SqlBoolean));
> >> +                    col.DefaultValue = true;
> >> +                    col.DataType = typeof (int);
> >> +            }
> >> +
> >> +            [Test]
> >>              public void ExpressionSubstringlimits () {
> >>                      DataTable t = new DataTable ();
> >>                      t.Columns.Add ("aaa");
> >> Index: Test/System.Data/DataTableTest.cs
> >> ===================================================================
> >> --- Test/System.Data/DataTableTest.cs        (revision 105623)
> >> +++ Test/System.Data/DataTableTest.cs        (working copy)
> >> @@ -2793,7 +2793,8 @@
> >>                      Assert.AreEqual ("Element",
> column2.ColumnMapping.ToString (), "test#33");
> >>                      Assert.AreEqual ("second", column2.ColumnName,
> "test#34");
> >>                      Assert.AreEqual ("System.Data.SqlTypes.SqlGuid",
> column2.DataType.ToString (), "test#35");
> >> -                    Assert.AreEqual ("Null",
> column2.DefaultValue.ToString (), "test#36");
> >> +                    Assert.AreEqual (SqlGuid.Null,
> column2.DefaultValue, "test#36");
> >> +                    Assert.AreEqual (typeof (SqlGuid),
> column2.DefaultValue.GetType (), "test#36-2");
> >>                      Assert.IsFalse (column2.DesignMode, "test#37");
> >>                      Assert.AreEqual ("", column2.Expression,
> "test#38");
> >>                      Assert.AreEqual (-1, column2.MaxLength, "test#39");
> >> Index: Test/System.Data/DataSetTest.cs
> >> ===================================================================
> >> --- Test/System.Data/DataSetTest.cs  (revision 105623)
> >> +++ Test/System.Data/DataSetTest.cs  (working copy)
> >> @@ -133,7 +133,11 @@
> >>                      Assert.AreEqual ("Element",
> column2.ColumnMapping.ToString (), "test#33");
> >>                      Assert.AreEqual ("second", column2.ColumnName,
> "test#34");
> >>                      Assert.AreEqual ("System.Data.SqlTypes.SqlGuid",
> column2.DataType.ToString (), "test#35");
> >> -                    Assert.AreEqual ("", column2.DefaultValue.ToString
> (), "test#36");
> >> +#if NET_2_0
> >> +                    Assert.AreEqual (SqlGuid.Null,
> column2.DefaultValue, "test#36");
> >> +#else
> >> +                    Assert.AreEqual (DBNull.Value,
> column2.DefaultValue, "test#36");
> >> +#endif
> >>                      Assert.IsFalse (column2.DesignMode, "test#37");
> >>                      Assert.AreEqual ("", column2.Expression,
> "test#38");
> >>                      Assert.AreEqual (-1, column2.MaxLength, "test#39");
> >> Index: System.Data/XmlSchemaWriter.cs
> >> ===================================================================
> >> --- System.Data/XmlSchemaWriter.cs   (revision 105623)
> >> +++ System.Data/XmlSchemaWriter.cs   (working copy)
> >> @@ -678,7 +678,7 @@
> >>                                      XmlConvert.ToString
> (col.AutoIncrementStep));
> >>                      }
> >>
> >> -                    if (col.DefaultValue.ToString () != String.Empty)
> >> +                    if (!DataColumn.GetDefaultValueForType
> (col.DataType).Equals (col.DefaultValue))
> >>                              w.WriteAttributeString ("default",
> >>                                      DataSet.WriteObjectXml
> (col.DefaultValue));
> >>
> >> @@ -792,7 +792,7 @@
> >>
> >>                              if (!col.AllowDBNull)
> >>                                      w.WriteAttributeString ("use",
> "required");
> >> -                            if (col.DefaultValue.ToString () !=
> String.Empty)
> >> +                            if (col.DefaultValue !=
> DataColumn.GetDefaultValueForType (col.DataType))
> >>                                      w.WriteAttributeString ("default",
> >>                                              DataSet.WriteObjectXml
> (col.DefaultValue));
> >>
> >> Index: System.Data/DataColumn.cs
> >> ===================================================================
> >> --- System.Data/DataColumn.cs        (revision 105623)
> >> +++ System.Data/DataColumn.cs        (working copy)
> >> @@ -90,7 +90,7 @@
> >>              private string _caption;
> >>              private MappingType _columnMapping;
> >>              private string _columnName = String.Empty;
> >> -            private object _defaultValue = DBNull.Value;
> >> +            private object _defaultValue = GetDefaultValueForType
> (null);
> >>              private string _expression;
> >>              private IExpression _compiledExpression;
> >>              private PropertyCollection _extendedProperties = new
> PropertyCollection ();
> >> @@ -465,6 +465,8 @@
> >>                                          throw new
> InvalidConstraintException ("Cannot change datatype, " +
> >>
>        "when column is part of a relation");
> >>
> >> +                            Type prevType = _dataContainer != null ?
> _dataContainer.Type : null; // current
> >> +
> >>  #if NET_2_0
> >>                              if (_dataContainer != null &&
> _dataContainer.Type == typeof (DateTime))
> >>                                      _datetimeMode =
> DataSetDateTime.UnspecifiedLocal;
> >> @@ -482,6 +484,13 @@
> >>                                              AutoIncrement = false;
> >>                                      }
> >>                              }
> >> +
> >> +                            if (DefaultValue != GetDefaultValueForType
> (prevType))
> >> +                                    SetDefaultValue (DefaultValue,
> true);
> >> +#if NET_2_0
> >> +                            else
> >> +                                    _defaultValue =
> GetDefaultValueForType (DataType);
> >> +#endif
> >>                      }
> >>              }
> >>
> >> @@ -507,9 +516,15 @@
> >>                                      throw new ArgumentException("Can
> not set default value while" +
> >>                                              " AutoIncrement is true on
> this column.");
> >>                              }
> >> +                            SetDefaultValue (value, false);
> >> +                    }
> >> +            }
> >>
> >> +            void SetDefaultValue (object value, bool forcedTypeCheck)
> >> +            {
> >> +                    {
> >>                              object tmpObj;
> >> -                            if (!this._defaultValue.Equals(value)) {
> >> +                            if (forcedTypeCheck||
> !this._defaultValue.Equals(value)) {
> >>                                      if (value == null) {
> >>                                              tmpObj = DBNull.Value;
> >>                                      }
> >> @@ -517,16 +532,24 @@
> >>                                              tmpObj = value;
> >>                                      }
> >>
> >> -                                    if ((this.DataType != typeof
> (object))&& (tmpObj != DBNull.Value)) {
> >> +                                    if (!this.DataType.IsInstanceOfType
> (tmpObj) && tmpObj != DBNull.Value) {
> >>                                              try {
> >>                                                      //Casting to the
> new type
> >>                                                      tmpObj=
> Convert.ChangeType(tmpObj,this.DataType);
> >>                                              }
> >>                                              catch
> (InvalidCastException) {
> >> -                                                    throw new
> InvalidCastException("Default Value type is not compatible with" +
> >> -                                                            " column
> type.");
> >> +                                                    string msg =
> String.Format ("Default Value of type '{0}' is not compatible with column
> type '{1}'", tmpObj.GetType (), DataType);
> >> +#if NET_2_0
> >> +                                                    throw new
> DataException(msg);
> >> +#else
> >> +                                                    throw new
> ArgumentException(msg);
> >> +#endif
> >>                                              }
> >>                                      }
> >> +#if NET_2_0
> >> +                                    if (tmpObj == DBNull.Value)
> >> +                                            tmpObj =
> GetDefaultValueForType (DataType);
> >> +#endif
> >>                                      _defaultValue = tmpObj;
> >>                              }
> >>
> >> @@ -1004,6 +1027,19 @@
> >>  #endif
> >>                      return true;
> >>              }
> >> +
> >> +            internal static object GetDefaultValueForType (Type type)
> >> +            {
> >> +#if NET_2_0
> >> +                    if (type == null)
> >> +                            return DBNull.Value;
> >> +                    if (type.Namespace == "System.Data.SqlTypes" &&
> type.Assembly == typeof (DataColumn).Assembly)
> >> +                            // For SqlXxx types, set SqlXxx.Null
> instead of DBNull.Value.
> >> +                            return Activator.CreateInstance (type);
> >> +#endif
> >> +                    return DBNull.Value;
> >> +            }
> >> +
> >>              #endregion // Methods
> >>      }
> >>  }
> >
> >
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>



-- 
Regards,
Konstantin Triger
RSS: http://feeds.feedburner.com/ktriger
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080613/1fb6fe5a/attachment-0001.html 


More information about the Mono-devel-list mailing list