[Mono-dev] DataColumn.DefaultValue fixes
Veerapuram Varadhan
vvaradhan at novell.com
Thu Jun 12 12:31:18 EDT 2008
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
> }
> }
More information about the Mono-devel-list
mailing list