merging the Mainsoft branch to the trunk
[mono.git] / mcs / class / System.Data / System.Data / DataColumn.cs
index d51a5f0eab1c3ea3870f9efe37cbca98d097ceba..afac3af74f378588d915bd253a3896595a841c00 100644 (file)
-//
-// System.Data.DataColumn.cs
-//
-// Author:
-//   Franklin Wise (gracenote@earthlink.net)
-//   Christopher Podurgiel (cpodurgiel@msn.com)
-//   Rodrigo Moya (rodrigo@ximian.com)
-//   Daniel Morgan (danmorg@sc.rr.com)
-//   Tim Coleman (tim@timcoleman.com)
-//
-// (C) Copyright 2002, Franklin Wise
-// (C) Chris Podurgiel
-// (C) Ximian, Inc 2002
-// Copyright (C) Tim Coleman, 2002
-// Copyright (C) Daniel Morgan, 2002, 2003
-//
-
-using System;
-using System.ComponentModel;
-using System.Reflection;
-
-namespace System.Data {
-       internal delegate void DelegateColumnValueChange(DataColumn column, DataRow row, object proposedValue);
-       
-       /// <summary>
-       /// Summary description for DataColumn.
-       /// </summary>
-
-       [DefaultMember ("Item")]
-       [DefaultProperty ("ColumnName")]
-       [DesignTimeVisible (false)]
-       public class DataColumn : MarshalByValueComponent
-       {               
-               #region Events
-               [MonoTODO]
-               //used for constraint validation
-               //if an exception is fired during this event the change should be canceled
-               internal event DelegateColumnValueChange ValidateColumnValueChange;
-
-               //used for FK Constraint Cascading rules
-               internal event DelegateColumnValueChange ColumnValueChanging;
-               #endregion //Events
-               
-               #region Fields
-
-               private bool _allowDBNull = true;
-               private bool _autoIncrement = false;
-               private long _autoIncrementSeed = 0;
-               private long _autoIncrementStep = 1;
-               private long _nextAutoIncrementValue = 0;
-               private bool dataHasBeenSet = false;
-               private string _caption = null;
-               private MappingType _columnMapping = MappingType.Element;
-               private string _columnName = null;
-               private Type _dataType = Type.GetType ("System.String");
-               private object _defaultValue = DBNull.Value;
-               private string expression = "";
-               private PropertyCollection _extendedProperties = new PropertyCollection ();
-               private int maxLength = -1; //-1 represents no length limit
-               private string nameSpace = "";
-               private int _ordinal = -1; //-1 represents not part of a collection
-               private string prefix = "";
-               private bool readOnly = false;
-               private DataTable _table = null;
-               private bool unique = false;
-
-               #endregion // Fields
-
-               #region Constructors
-
-               public DataColumn()
-               {
-               }
-
-               //TODO: Ctor init vars directly
-               public DataColumn(string columnName): this()
-               {
-                       ColumnName = columnName;
-               }
-
-               public DataColumn(string columnName, Type dataType): this(columnName)
-               {
-                       if(dataType == null) {
-                               throw new ArgumentNullException("dataType can't be null.");
-                       }
-                       
-                       DataType = dataType;
-
-               }
-
-               public DataColumn( string columnName, Type dataType, 
-                       string expr): this(columnName, dataType)
-               {
-                       Expression = expr;
-               }
-
-               public DataColumn(string columnName, Type dataType, 
-                       string expr, MappingType type): this(columnName, dataType, expr)
-               {
-                       ColumnMapping = type;
-               }
-               #endregion
-
-               #region Properties
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether null values are allowed in this column.")]
-               [DefaultValue (true)]
-               public bool AllowDBNull
-               {
-                       get {
-                               return _allowDBNull;
-                       }
-                       set {
-                               //TODO: If we are a part of the table and this value changes
-                               //we need to validate that all the existing values conform to the new setting
-
-                               if (true == value)
-                               {
-                                       _allowDBNull = true;
-                                       return;
-                               }
-                               
-                               //if Value == false case
-                               if (null != _table)
-                               {
-                                       if (_table.Rows.Count > 0)
-                                       {
-                                               bool nullsFound = false;
-                                               for(int r = 0; r < _table.Rows.Count; r++) {
-                                                       DataRow row = _table.Rows[r];
-                                                       if(row.IsNull(this)) {
-                                                               nullsFound = true;
-                                                               break;
-                                                       }
-                                               }
-                                               
-                                               //TODO: Validate no null values exist
-                                               //do we also check different versions of the row??
-                                       }
-                               }
-                                       
-                               _allowDBNull = value;
-                       }
-               }
-        
-               /// <summary>
-               /// Gets or sets a value indicating whether the column automatically increments the value of the column for new rows added to the table.
-               /// </summary>
-               /// <remarks>
-               ///             If the type of this column is not Int16, Int32, or Int64 when this property is set, 
-               ///             the DataType property is coerced to Int32. An exception is generated if this is a computed column 
-               ///             (that is, the Expression property is set.) The incremented value is used only if the row's value for this column, 
-               ///             when added to the columns collection, is equal to the default value.
-               ///     </remarks>
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether the column automatically increments itself for new rows added to the table.  The type of this column must be Int16, Int32, or Int64.")]
-               [DefaultValue (false)]
-               [RefreshProperties (RefreshProperties.All)]
-               public bool AutoIncrement
-               {
-                       get {
-                               return _autoIncrement;
-                       }
-                       set {
-                               if(value == true)
-                               {
-                                       //Can't be true if this is a computed column
-                                       if(!Expression.Equals(String.Empty))
-                                       {
-                                               throw new ArgumentException("Can not Auto Increment a computed column."); 
-                                       }
-
-                                       //If the DataType of this Column isn't an Int
-                                       //Make it an int
-                                       TypeCode typeCode = Type.GetTypeCode(_dataType);
-                                       if(typeCode != TypeCode.Int16 && 
-                                          typeCode != TypeCode.Int32 && 
-                                          typeCode != TypeCode.Int64)
-                                       {
-                                               _dataType = typeof(Int32); 
-                                       }
-                               }
-                               _autoIncrement = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the starting value for an AutoIncrement column.")]
-               [DefaultValue (0)]
-               public long AutoIncrementSeed
-               {
-                       get {
-                               return _autoIncrementSeed;
-                       }
-                       set {
-                               _autoIncrementSeed = value;
-                               _nextAutoIncrementValue = _autoIncrementSeed;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the increment used by an AutoIncrement column.")]
-               [DefaultValue (1)]
-               public long AutoIncrementStep
-               {
-                       get {
-                               return _autoIncrementStep;
-                       }
-                       set {
-                               _autoIncrementStep = value;
-                       }
-               }
-
-               internal void UpdateAutoIncrementValue (long value) 
-               {
-                       if(value > _nextAutoIncrementValue) {
-                               _nextAutoIncrementValue = value;
-                               AutoIncrementValue ();
-                       }
-               }
-
-               internal long AutoIncrementValue () 
-               {
-                       long currentValue = _nextAutoIncrementValue;
-                       _nextAutoIncrementValue += AutoIncrementStep;
-                       return currentValue;
-               }
-
-               internal bool DataHasBeenSet {
-                       get {
-                               return dataHasBeenSet;
-                       }
-                       set {
-                               dataHasBeenSet = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the default user-interface caption for this column.")]
-               public string Caption 
-               {
-                       get {
-                               if(_caption == null)
-                                       return ColumnName;
-                               else
-                                       return _caption;
-                       }
-                       set {
-                               _caption = value;
-                       }
-               }
-               [DataSysDescription ("Indicates how this column persists in XML: as an attribute, element, simple content node, or nothing.")]
-               [DefaultValue (MappingType.Element)]
-               public virtual MappingType ColumnMapping
-               {
-                       get {
-                               return _columnMapping;
-                       }
-                       set {
-                               _columnMapping = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the name used to look up this column in the Columns collection of a DataTable.")]
-               [RefreshProperties (RefreshProperties.All)]
-               public string ColumnName
-               {
-                       get {
-                               return "" + _columnName;
-                       }
-                       set {
-                               //Both are checked after the column is part of the collection
-                               //TODO: Check Name duplicate
-                               //TODO: check Name != null
-                               _columnName = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the type of data stored in this column.")]
-               [DefaultValue (typeof (string))]
-               [RefreshProperties (RefreshProperties.All)]
-               public Type DataType
-               {
-                       get {
-                               return _dataType;
-                       }
-                       set {
-                               // check if data already exists can we change the datatype
-                               if(DataHasBeenSet == true)
-                                       throw new ArgumentException("The column already has data stored.");
-
-                               // we want to check that the datatype is supported?
-                               TypeCode typeCode = Type.GetTypeCode(value);
-                               
-                               //Check AutoIncrement status, make compatible datatype
-                               if(AutoIncrement == true) {
-                                       if(typeCode != TypeCode.Int16 &&
-                                          typeCode != TypeCode.Int32 &&
-                                          typeCode != TypeCode.Int64)
-                                               throw new ArgumentException("AutoIncrement is true, but the value is set to a type unsupported by AutoIncrement.");
-                               }
-                               _dataType = value;
-                       }
-               }
-
-               /// <summary>
-               /// 
-               /// </summary>
-               /// <remarks>When AutoIncrement is set to true, there can be no default value.</remarks>
-               /// <exception cref="System.InvalidCastException"></exception>
-               /// <exception cref="System.ArgumentException"></exception>
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the default column value used when adding new rows to the table.")]
-               public object DefaultValue
-               {
-                       get {
-                               return _defaultValue;
-                       }
-                       set {
-                               
-                               //If autoIncrement == true throw
-                               if (AutoIncrement) 
-                               {
-                                       throw new ArgumentException("Can not set default value while" +
-                                                       " AutoIncrement is true on this column.");
-                               }
-                                       
-                               //Will throw invalid cast exception
-                               //if value is not the correct type
-                               //FIXME: some types can be casted
-                               if (value.GetType() != _dataType)
-                               {
-                                       throw new InvalidCastException("Default Value type is not compatible with" + 
-                                                       " column type.");
-                               }
-                                       
-                               _defaultValue = value;
-                       }
-               }
-
-               [MonoTODO]
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the value that this column computes for each row based on other columns instead of taking user input.")]
-               [DefaultValue ("")]
-               [RefreshProperties (RefreshProperties.All)]
-               public string Expression
-               {
-                       get {
-                               return expression;
-                       }
-                       set {
-                               //TODO: validation of the expression
-                               expression = value;  //Check?
-                       }
-               }
-
-               [Browsable (false)]
-               [DataCategory ("Data")]
-               [DataSysDescription ("The collection that holds custom user information.")]
-               public PropertyCollection ExtendedProperties
-               {
-                       get {
-                               return _extendedProperties;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the maximum length of the value this column allows.")]
-               [DefaultValue (-1)]
-               public int MaxLength
-               {
-                       get {
-                               //Default == -1 no max length
-                               return maxLength;
-                       }
-                       set {
-                               //only applies to string columns
-                               maxLength = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the XML uri for elements stored in this  column.")]
-               public string Namespace
-               {
-                       get {
-                               return nameSpace;
-                       }
-                       set {
-                               nameSpace = value;
-                       }
-               }
-
-               //Need a good way to set the Ordinal when the column is added to a columnCollection.
-               [Browsable (false)]
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the index of this column in the Columns collection.")]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-               public int Ordinal
-               {
-                       get {
-                               //value is -1 if not part of a collection
-                               return _ordinal;
-                       }
-               }
-
-               internal void SetOrdinal(int ordinal)
-               {
-                       _ordinal = ordinal;
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the prefix used for this DataColumn in the xml representation.")]
-               [DefaultValue ("")]
-               public string Prefix
-               {
-                       get {
-                               return prefix;
-                       }
-                       set {
-                               prefix = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether this column allows changes once a row has been added to the table.")]
-               [DefaultValue (false)]
-               public bool ReadOnly
-               {
-                       get {
-                               return readOnly;
-                       }
-                       set {
-                               readOnly = value;
-                       }
-               }
-
-               [Browsable (false)]
-               [DataCategory ("Data")]
-               [DataSysDescription ("Returns the DataTable to which this column belongs.")]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]      
-               public DataTable Table
-               {
-                       get {
-                               return _table;
-                       }
-               }
-
-               [MonoTODO]
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether this column should restrict its values in the rows of the table to be unique.")]
-               [DefaultValue (false)]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-                public bool Unique 
-               {
-                       get {
-                               return unique;
-                       }
-                       set {
-                               //if Table == null then the UniqueConstraint is
-                               //created on addition to the collection
-                               
-                               //FIXME?: need to check if value is the same
-                               //because when calling "new UniqueConstraint"
-                               //the new object tries to set "column.Unique = True"
-                               //which creates an infinite loop.
-                               if(unique != value)
-                               {
-                               unique = value;
-
-                                       if( value )
-                                       {
-                                               if( _table != null )
-                                               {
-                                                       UniqueConstraint uc = new UniqueConstraint(this);
-                                                       _table.Constraints.Add(uc);
-                                               }
-                                       }
-                                       else
-                                       {
-                                               if( _table != null )
-                                               {
-                                                       //FIXME: Add code to remove constraint from DataTable
-                                                       throw new NotImplementedException ();
-                                               }
-                                       }
-
-                               }
-                       }
-               }
-
-               #endregion // Properties
-
-               #region Methods
-               
-/* ??
-               [MonoTODO]
-               protected internal void CheckNotAllowNull() {
-               }
-
-               [MonoTODO]
-               protected void CheckUnique() {
-               }
-*/
-
-               [MonoTODO]
-               internal void AssertCanAddToCollection()
-               {
-                       //Check if Default Value is set and AutoInc is set
-               }
-               
-               [MonoTODO]
-               protected internal virtual void 
-               OnPropertyChanging (PropertyChangedEventArgs pcevent) {
-               }
-
-               [MonoTODO]
-               protected internal void RaisePropertyChanging(string name) {
-               }
-
-               /// <summary>
-               /// Gets the Expression of the column, if one exists.
-               /// </summary>
-               /// <returns>The Expression value, if the property is set; 
-               /// otherwise, the ColumnName property.</returns>
-               [MonoTODO]
-               public override string ToString()
-               {
-                       if (expression != null)
-                               return expression;
-                       
-                       return ColumnName;
-               }
-
-               [MonoTODO]
-               internal void SetTable(DataTable table) {
-                       _table = table; 
-                       // this will get called by DataTable 
-                       // and DataColumnCollection
-               }
-
-               
-               // Returns true if all the same collumns are in columnSet and compareSet
-               internal static bool AreColumnSetsTheSame(DataColumn[] columnSet, DataColumn[] compareSet)
-               {
-                       if (null == columnSet && null == compareSet) return true;
-                       if (null == columnSet || null == compareSet) return false;
-
-                       if (columnSet.Length != compareSet.Length) return false;
-                       
-                       foreach (DataColumn col in columnSet)
-                       {
-                               bool matchFound = false;
-                               foreach (DataColumn compare in compareSet)
-                               {
-                                       if (col == compare)
-                                       {
-                                               matchFound = true;                                      
-                                       }
-                               }
-                               if (! matchFound) return false;
-                       }
-                       
-                       return true;
-               }
-               
-               #endregion // Methods
-
-       }
-}
+//\r
+// System.Data.DataColumn.cs\r
+//\r
+// Author:\r
+//   Franklin Wise (gracenote@earthlink.net)\r
+//   Christopher Podurgiel (cpodurgiel@msn.com)\r
+//   Rodrigo Moya (rodrigo@ximian.com)\r
+//   Daniel Morgan (danmorg@sc.rr.com)\r
+//   Tim Coleman (tim@timcoleman.com)\r
+//\r
+// (C) Copyright 2002, Franklin Wise\r
+// (C) Chris Podurgiel\r
+// (C) Ximian, Inc 2002\r
+// Copyright (C) Tim Coleman, 2002\r
+// Copyright (C) Daniel Morgan, 2002, 2003\r
+//\r
+\r
+//\r
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+using System;\r
+using System.ComponentModel;\r
+using System.Reflection;\r
+using System.Collections;\r
+using System.Data.Common;\r
+using System.Globalization;\r
+using Mono.Data.SqlExpressions;\r
+\r
+namespace System.Data {\r
+       internal delegate void DelegateColumnValueChange(DataColumn column, DataRow row, object proposedValue);\r
+       \r
+       /// <summary>\r
+       /// Summary description for DataColumn.\r
+       /// </summary>\r
+\r
+       [Editor]\r
+       [ToolboxItem (false)]\r
+       [DefaultProperty ("ColumnName")]\r
+       [DesignTimeVisible (false)]\r
+       public class DataColumn : MarshalByValueComponent\r
+       {               \r
+               #region Events\r
+               [MonoTODO]\r
+               //used for constraint validation\r
+               //if an exception is fired during this event the change should be canceled\r
+               internal event DelegateColumnValueChange ValidateColumnValueChange;\r
+\r
+               //used for FK Constraint Cascading rules\r
+               internal event DelegateColumnValueChange ColumnValueChanging;\r
+               #endregion //Events\r
+               \r
+               #region Fields\r
+\r
+               private bool _allowDBNull = true;\r
+               private bool _autoIncrement;\r
+               private long _autoIncrementSeed;\r
+               private long _autoIncrementStep = 1;\r
+               private long _nextAutoIncrementValue;\r
+               private string _caption;\r
+               private MappingType _columnMapping;\r
+               private string _columnName = String.Empty;\r
+               private object _defaultValue = DBNull.Value;\r
+               private string _expression;\r
+               private IExpression _compiledExpression;\r
+               private PropertyCollection _extendedProperties = new PropertyCollection ();\r
+               private int _maxLength = -1; //-1 represents no length limit\r
+               private string _nameSpace;\r
+               private int _ordinal = -1; //-1 represents not part of a collection\r
+               private string _prefix = String.Empty;\r
+               private bool _readOnly;\r
+               private DataTable _table;\r
+               private bool _unique;\r
+               private AbstractDataContainer _dataContainer;\r
+\r
+               #endregion // Fields\r
+\r
+               #region Constructors\r
+\r
+               public DataColumn() : this(String.Empty, typeof (string), String.Empty, MappingType.Element)\r
+               {\r
+               }\r
+\r
+               //TODO: Ctor init vars directly\r
+               public DataColumn(string columnName): this(columnName, typeof (string), String.Empty, MappingType.Element)\r
+               {\r
+               }\r
+\r
+               public DataColumn(string columnName, Type dataType): this(columnName, dataType, String.Empty, MappingType.Element)\r
+               {\r
+               }\r
+\r
+               public DataColumn( string columnName, Type dataType, \r
+                       string expr): this(columnName, dataType, expr, MappingType.Element)\r
+               {\r
+               }\r
+\r
+               public DataColumn(string columnName, Type dataType, \r
+                       string expr, MappingType type)\r
+               {\r
+                       ColumnName = (columnName == null ? String.Empty : columnName);\r
+                       \r
+                       if(dataType == null) {\r
+                               throw new ArgumentNullException("dataType can't be null.");\r
+                       }\r
+                       \r
+                       DataType = dataType;\r
+                       Expression = expr == null ? String.Empty : expr;\r
+                       ColumnMapping = type;\r
+               }\r
+               #endregion\r
+\r
+               #region Properties\r
+\r
+               internal object this[int index] {\r
+                       get {\r
+                               return DataContainer[index];\r
+                       }\r
+                       set {\r
+                               if ( !(value == null && AutoIncrement) ) {\r
+                                       DataContainer[index] = value;\r
+                               }\r
+\r
+                               if ( AutoIncrement && !DataContainer.IsNull(index) ) {\r
+                                       long value64 = Convert.ToInt64(value);\r
+                                       UpdateAutoIncrementValue(value64);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether null values are allowed in this column.")]\r
+               [DefaultValue (true)]\r
+               public bool AllowDBNull\r
+               {\r
+                       get {\r
+                               return _allowDBNull;\r
+                       }\r
+                       set {\r
+                               //TODO: If we are a part of the table and this value changes\r
+                               //we need to validate that all the existing values conform to the new setting\r
+\r
+                               if (true == value)\r
+                               {\r
+                                       _allowDBNull = true;\r
+                                       return;\r
+                               }\r
+                               \r
+                               //if Value == false case\r
+                               if (null != _table)\r
+                               {\r
+                                       if (_table.Rows.Count > 0)\r
+                                       {\r
+                                               bool nullsFound = false;\r
+                                               for(int r = 0; r < _table.Rows.Count; r++) {\r
+                                                       DataRow row = _table.Rows[r];\r
+                                                       if(row.IsNull(this)) {\r
+                                                               nullsFound = true;\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+                                               \r
+                                               if (nullsFound)\r
+                                                       throw new DataException("Column '" + ColumnName + "' has null values in it.");\r
+                                               //TODO: Validate no null values exist\r
+                                               //do we also check different versions of the row??\r
+                                       }\r
+                               }\r
+                                       \r
+                               _allowDBNull = value;\r
+                       }\r
+               }\r
+        \r
+               /// <summary>\r
+               /// Gets or sets a value indicating whether the column automatically increments the value of the column for new rows added to the table.\r
+               /// </summary>\r
+               /// <remarks>\r
+               ///             If the type of this column is not Int16, Int32, or Int64 when this property is set, \r
+               ///             the DataType property is coerced to Int32. An exception is generated if this is a computed column \r
+               ///             (that is, the Expression property is set.) The incremented value is used only if the row's value for this column, \r
+               ///             when added to the columns collection, is equal to the default value.\r
+               ///     </remarks>\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether the column automatically increments itself for new rows added to the table.  The type of this column must be Int16, Int32, or Int64.")]\r
+               [DefaultValue (false)]\r
+               [RefreshProperties (RefreshProperties.All)]\r
+               public bool AutoIncrement\r
+               {\r
+                       get {\r
+                               return _autoIncrement;\r
+                       }\r
+                       set {\r
+                               if(value == true)\r
+                               {\r
+                                       //Can't be true if this is a computed column\r
+                                       if (Expression != string.Empty)\r
+                                       {\r
+                                               throw new ArgumentException("Can not Auto Increment a computed column."); \r
+                                       }\r
+\r
+                                       if ( DefaultValue != DBNull.Value ) {\r
+                                               throw new ArgumentException("Can not set AutoIncrement while" +\r
+                                                       " default value exists for this column.");\r
+                                       }\r
+\r
+                                       if(!CanAutoIncrement(DataType))\r
+                                       {\r
+                                               DataType = typeof(Int32); \r
+                                       }\r
+\r
+                                       if (_table != null)\r
+                                               _table.Columns.UpdateAutoIncrement(this,true);\r
+                               }\r
+                               else\r
+                               {\r
+                                       if (_table != null)\r
+                                               _table.Columns.UpdateAutoIncrement(this,false);\r
+                               }\r
+                               _autoIncrement = value;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the starting value for an AutoIncrement column.")]\r
+               [DefaultValue (0)]\r
+               public long AutoIncrementSeed\r
+               {\r
+                       get {\r
+                               return _autoIncrementSeed;\r
+                       }\r
+                       set {\r
+                               _autoIncrementSeed = value;\r
+                               _nextAutoIncrementValue = _autoIncrementSeed;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the increment used by an AutoIncrement column.")]\r
+               [DefaultValue (1)]\r
+               public long AutoIncrementStep\r
+               {\r
+                       get {\r
+                               return _autoIncrementStep;\r
+                       }\r
+                       set {\r
+                               _autoIncrementStep = value;\r
+                       }\r
+               }\r
+\r
+               internal void UpdateAutoIncrementValue(long value64)\r
+               {\r
+                       if (_autoIncrementStep > 0 ) {\r
+                               if (value64 >= _nextAutoIncrementValue) {\r
+                                       _nextAutoIncrementValue = value64;\r
+                                       AutoIncrementValue ();\r
+                               }\r
+                       }\r
+                       else if (value64 <= _nextAutoIncrementValue) {\r
+                               AutoIncrementValue ();\r
+                       }\r
+               }\r
+\r
+               internal long AutoIncrementValue () \r
+               {\r
+                       long currentValue = _nextAutoIncrementValue;\r
+                       _nextAutoIncrementValue += AutoIncrementStep;\r
+                       return currentValue;\r
+               }\r
+\r
+               internal long GetAutoIncrementValue ()\r
+               {\r
+                       return _nextAutoIncrementValue;\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the default user-interface caption for this column.")]\r
+               public string Caption \r
+               {\r
+                       get {\r
+                               if(_caption == null)\r
+                                       return ColumnName;\r
+                               else\r
+                                       return _caption;\r
+                       }\r
+                       set {\r
+                               if (value == null)\r
+                                       value = String.Empty;\r
+                                       \r
+                               _caption = value;\r
+                       }\r
+               }\r
+               [DataSysDescription ("Indicates how this column persists in XML: as an attribute, element, simple content node, or nothing.")]\r
+               [DefaultValue (MappingType.Element)]\r
+               public virtual MappingType ColumnMapping\r
+               {\r
+                       get {\r
+                               return _columnMapping;\r
+                       }\r
+                       set {\r
+                               _columnMapping = value;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the name used to look up this column in the Columns collection of a DataTable.")]\r
+               [RefreshProperties (RefreshProperties.All)]\r
+               [DefaultValue ("")]\r
+               public string ColumnName\r
+               {\r
+                       get {\r
+                               return _columnName;\r
+                       }\r
+                       set {\r
+                               if (value == null)\r
+                                       value = String.Empty;\r
+\r
+                               CultureInfo info = Table != null ? Table.Locale : CultureInfo.CurrentCulture;\r
+                               if (String.Compare(value, _columnName, true, info) != 0) {\r
+                                       if (Table != null) {\r
+                                               if (value.Length == 0)\r
+                                                       throw new ArgumentException("ColumnName is required when it is part of a DataTable.");\r
+\r
+                                               Table.Columns.RegisterName(value, this);\r
+                                               if (_columnName.Length > 0)\r
+                                                       Table.Columns.UnregisterName(_columnName);\r
+                                       }\r
+\r
+                                       RaisePropertyChanging("ColumnName");\r
+                                       _columnName = value;\r
+\r
+                                       if (Table != null)\r
+                                               Table.ResetPropertyDescriptorsCache();\r
+                               }\r
+                               else if (String.Compare(value, _columnName, false, info) != 0) {\r
+                                       RaisePropertyChanging("ColumnName");\r
+                                       _columnName = value;\r
+\r
+                                       if (Table != null)\r
+                                               Table.ResetPropertyDescriptorsCache();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the type of data stored in this column.")]\r
+               [DefaultValue (typeof (string))]\r
+               [RefreshProperties (RefreshProperties.All)]\r
+               [TypeConverterAttribute (typeof (ColumnTypeConverter))] \r
+               public Type DataType\r
+               {\r
+                       get {\r
+                               return DataContainer.Type;\r
+                       }\r
+                       set {\r
+\r
+                                if ( value == null ) \r
+                                        return;\r
+\r
+                               if ( _dataContainer != null ) {\r
+                                       if ( value == _dataContainer.Type ) \r
+                                               return;\r
+\r
+                                       // check if data already exists can we change the datatype\r
+                                       if ( _dataContainer.Capacity > 0 )\r
+                                               throw new ArgumentException("The column already has data stored.");\r
+                               }\r
+\r
+                                if (null != GetParentRelation () || null != GetChildRelation ())\r
+                                        throw new InvalidConstraintException ("Cannot change datatype, " + \r
+                                                                              "when column is part of a relation");\r
+                                \r
+                                _dataContainer = AbstractDataContainer.CreateInstance(value, this);\r
+\r
+                               //Check AutoIncrement status, make compatible datatype\r
+                               if(AutoIncrement == true) {\r
+                                       // we want to check that the datatype is supported?\r
+                                       TypeCode typeCode = Type.GetTypeCode(value);\r
+                                       \r
+                                       if(typeCode != TypeCode.Int16 &&\r
+                                          typeCode != TypeCode.Int32 &&\r
+                                          typeCode != TypeCode.Int64) {\r
+                                               AutoIncrement = false;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               /// <summary>\r
+               /// \r
+               /// </summary>\r
+               /// <remarks>When AutoIncrement is set to true, there can be no default value.</remarks>\r
+               /// <exception cref="System.InvalidCastException"></exception>\r
+               /// <exception cref="System.ArgumentException"></exception>\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the default column value used when adding new rows to the table.")]\r
+               [TypeConverterAttribute (typeof (System.Data.DefaultValueTypeConverter))]\r
+               public object DefaultValue\r
+               {\r
+                       get {\r
+                               return _defaultValue;\r
+                       }\r
+\r
+                       set {\r
+                               if (AutoIncrement) {\r
+                                       throw new ArgumentException("Can not set default value while" +\r
+                                               " AutoIncrement is true on this column.");\r
+                               }\r
+\r
+                               object tmpObj;\r
+                               if (!this._defaultValue.Equals(value)) {                \r
+                                       if (value == null) {\r
+                                               tmpObj = DBNull.Value;\r
+                                       }\r
+                                       else {\r
+                                               tmpObj = value;\r
+                                       }\r
+\r
+                                       if ((this.DataType != typeof (object))&& (tmpObj != DBNull.Value)) {\r
+                                               try {\r
+                                                       //Casting to the new type\r
+                                                       tmpObj= Convert.ChangeType(tmpObj,this.DataType);\r
+                                               }\r
+                                               catch (InvalidCastException) {\r
+                                                       throw new InvalidCastException("Default Value type is not compatible with" + \r
+                                                               " column type.");\r
+                                               }\r
+                                       }\r
+                                       _defaultValue = tmpObj;\r
+                               }\r
+\r
+                               // store default value in the table if already belongs to\r
+                               if (Table != null && Table.DefaultValuesRowIndex != -1) {\r
+                                       DataContainer[Table.DefaultValuesRowIndex] = _defaultValue;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the value that this column computes for each row based on other columns instead of taking user input.")]\r
+               [DefaultValue ("")]\r
+               [RefreshProperties (RefreshProperties.All)]\r
+               public string Expression\r
+               {\r
+                       get {\r
+                               return _expression;\r
+                       }\r
+                       set {\r
+                               if (value == null)\r
+                                       value = String.Empty;\r
+                                       \r
+                               if (value != String.Empty) \r
+                               {\r
+\r
+                                       if (AutoIncrement || Unique)\r
+                                               throw new ArgumentException("Cannot create an expression on a column that has AutoIncrement or Unique.");\r
+\r
+                                       if (Table != null)\r
+                                       {\r
+                                               for (int i = 0; i < Table.Constraints.Count; i++)\r
+                                               {\r
+                                                       if (Table.Constraints[i].IsColumnContained(this))\r
+                                                               throw new ArgumentException(String.Format("Cannot set Expression property on column {0}, because it is a part of a constraint.", ColumnName));\r
+                                               }\r
+                                       }\r
+\r
+                                       Parser parser = new Parser ();\r
+                                       IExpression compiledExpression = parser.Compile (value);\r
+\r
+                                       if (Table != null)\r
+                                       {\r
+                                               if (compiledExpression.DependsOn(this))\r
+                                                       throw new ArgumentException("Cannot set Expression property due to circular reference in the expression.");\r
+                                       }\r
+                                       \r
+                                       ReadOnly = true;\r
+                                       _compiledExpression = compiledExpression;\r
+                               }\r
+                               else\r
+                               {\r
+                                       _compiledExpression = null;\r
+                                       if (Table != null)\r
+                                       {\r
+                                               int defaultValuesRowIndex = Table.DefaultValuesRowIndex;\r
+                                               if ( defaultValuesRowIndex != -1) \r
+                                                       DataContainer.FillValues(defaultValuesRowIndex);\r
+                                       }\r
+                               }\r
+                               _expression = value;  \r
+                       }\r
+               }\r
+\r
+               internal IExpression CompiledExpression {\r
+                       get { return _compiledExpression; }\r
+               }\r
+\r
+               [Browsable (false)]\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("The collection that holds custom user information.")]\r
+               public PropertyCollection ExtendedProperties\r
+               {\r
+                       get {\r
+                               return _extendedProperties;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the maximum length of the value this column allows.")]\r
+               [DefaultValue (-1)]\r
+               public int MaxLength\r
+               {\r
+                       get {\r
+                               //Default == -1 no max length\r
+                               return _maxLength;\r
+                       }\r
+                       set {\r
+                               if (value >= 0 &&\r
+                                       _columnMapping == MappingType.SimpleContent)\r
+                                       throw new ArgumentException (String.Format ("Cannot set MaxLength property on '{0}' column which is mapped to SimpleContent.", ColumnName));\r
+                               //only applies to string columns\r
+                               _maxLength = value;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the XML uri for elements stored in this  column.")]\r
+               public string Namespace\r
+               {\r
+                       get {\r
+                               if (_nameSpace != null)\r
+                               {\r
+                                       return _nameSpace;\r
+                               }\r
+                               if ((Table != null) && (_columnMapping != MappingType.Attribute))\r
+                               {\r
+                                       return Table.Namespace;\r
+                               }\r
+                               return String.Empty;\r
+                       }\r
+                       set {\r
+                               _nameSpace = value;\r
+                       }\r
+               }\r
+\r
+               //Need a good way to set the Ordinal when the column is added to a columnCollection.\r
+               [Browsable (false)]\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the index of this column in the Columns collection.")]\r
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]\r
+               public int Ordinal\r
+               {\r
+                       get {\r
+                               //value is -1 if not part of a collection\r
+                               return _ordinal;\r
+                       }\r
+               }\r
+\r
+               internal void SetOrdinal(int ordinal)\r
+               {\r
+                       _ordinal = ordinal;\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the prefix used for this DataColumn in the xml representation.")]\r
+               [DefaultValue ("")]\r
+               public string Prefix\r
+               {\r
+                       get {\r
+                               return _prefix;\r
+                       }\r
+                       set {\r
+                               if (value == null)\r
+                                       value = String.Empty;\r
+                               _prefix = value;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether this column allows changes once a row has been added to the table.")]\r
+               [DefaultValue (false)]\r
+               public bool ReadOnly\r
+               {\r
+                       get {\r
+                               return _readOnly;\r
+                       }\r
+                       set {\r
+                               _readOnly = value;\r
+                       }\r
+               }\r
+\r
+               [Browsable (false)]\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Returns the DataTable to which this column belongs.")]\r
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]      \r
+               public DataTable Table\r
+               {\r
+                       get {\r
+                               return _table;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether this column should restrict its values in the rows of the table to be unique.")]\r
+               [DefaultValue (false)]\r
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]\r
+                public bool Unique \r
+               {\r
+                       get {\r
+                               return _unique;\r
+                       }\r
+                       set {\r
+                               //NOTE: In .NET 1.1 the Unique property\r
+                                //is left unchanged when it is added\r
+                                //to a UniqueConstraint\r
+\r
+                               if(_unique != value)\r
+                               {\r
+                                       _unique = value;\r
+\r
+                                       if( value )\r
+                                       {\r
+                                               if (Expression != null && Expression != String.Empty)\r
+                                                       throw new ArgumentException("Cannot change Unique property for the expression column.");\r
+                                               if( _table != null )\r
+                                               {\r
+                                                       UniqueConstraint uc = new UniqueConstraint(this);\r
+                                                       _table.Constraints.Add(uc);\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               if( _table != null )\r
+                                               {\r
+                                                       ConstraintCollection cc = _table.Constraints;\r
+                                                       //foreach (Constraint c in cc) \r
+                                                       for (int i = 0; i < cc.Count; i++)\r
+                                                       {\r
+                                                               Constraint c = cc[i];\r
+                                                               if (c is UniqueConstraint)\r
+                                                               {\r
+                                                                       DataColumn[] cols = ((UniqueConstraint)c).Columns;\r
+                                                                       \r
+                                                                       if (cols.Length == 1 && cols[0] == this)\r
+                                                                       {\r
+                                                                               cc.Remove(c);\r
+                                                                       }\r
+                                                                       \r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+\r
+                               }\r
+                       }\r
+               }\r
+\r
+               internal AbstractDataContainer DataContainer {\r
+                       get {\r
+                               return _dataContainer;\r
+                       }\r
+               }\r
+\r
+               internal static bool CanAutoIncrement(Type type) {\r
+                       switch (Type.GetTypeCode(type)) {\r
+                               case TypeCode.Int16:\r
+                               case TypeCode.Int32:\r
+                               case TypeCode.Int64:\r
+                               case TypeCode.Decimal:\r
+                                       return true;\r
+                       }\r
+\r
+                       return false;\r
+               }\r
+\r
+               #endregion // Properties\r
+\r
+               #region Methods\r
+               \r
+/* ??\r
+               [MonoTODO]\r
+               protected internal void CheckNotAllowNull() {\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected void CheckUnique() {\r
+               }\r
+*/\r
+               [MonoTODO]\r
+               internal DataColumn Clone() {\r
+                       DataColumn copy = new DataColumn ();\r
+\r
+                       // Copy all the properties of column\r
+                       copy._allowDBNull = _allowDBNull;\r
+                       copy._autoIncrement = _autoIncrement;\r
+                       copy._autoIncrementSeed = _autoIncrementSeed;\r
+                       copy._autoIncrementStep = _autoIncrementStep;\r
+                       copy._caption = _caption;\r
+                       copy._columnMapping = _columnMapping;\r
+                       copy._columnName = _columnName;\r
+                       //Copy.Container\r
+                       copy.DataType = DataType;\r
+                       copy._defaultValue = _defaultValue;                     \r
+                       copy._expression = _expression;\r
+                       //Copy.ExtendedProperties\r
+                       copy._maxLength = _maxLength;\r
+                       copy._nameSpace = _nameSpace;\r
+                       copy._prefix = _prefix;\r
+                       copy._readOnly = _readOnly;\r
+                       //Copy.Site\r
+                       //we do not copy the unique value - it will be copyied when copying the constraints.\r
+                       //Copy.Unique = Column.Unique;\r
+                       \r
+                       return copy;\r
+               }\r
+\r
+               /// <summary>\r
+               ///  Sets unique true whithout creating Constraint\r
+               /// </summary>\r
+               internal void SetUnique() \r
+               {\r
+                       _unique = true;\r
+               }\r
+\r
+               [MonoTODO]\r
+               internal void AssertCanAddToCollection()\r
+               {\r
+                       //Check if Default Value is set and AutoInc is set\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected internal void CheckNotAllowNull ()\r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected void CheckUnique ()\r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected internal virtual void \r
+               OnPropertyChanging (PropertyChangedEventArgs pcevent) {\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected internal void RaisePropertyChanging(string name) {\r
+               }\r
+\r
+               /// <summary>\r
+               /// Gets the Expression of the column, if one exists.\r
+               /// </summary>\r
+               /// <returns>The Expression value, if the property is set; \r
+               /// otherwise, the ColumnName property.</returns>\r
+               public override string ToString()\r
+               {\r
+                       if (_expression != string.Empty)\r
+                               return ColumnName + " + " + _expression;\r
+                       \r
+                       return ColumnName;\r
+               }\r
+\r
+               internal void SetTable(DataTable table) {\r
+                       if(_table!=null) { // serves as double check while adding to a table\r
+                    throw new ArgumentException("The column already belongs to a different table");\r
+            }\r
+            _table = table;\r
+            // this will get called by DataTable\r
+            // and DataColumnCollection\r
+            if(_unique) {\r
+                // if the DataColumn is marked as Unique and then\r
+                   // added to a DataTable , then a UniqueConstraint\r
+                   // should be created\r
+                UniqueConstraint uc = new UniqueConstraint(this);\r
+                _table.Constraints.Add(uc);\r
+            }\r
+\r
+                       // allocate space in the column data container \r
+                       DataContainer.Capacity = _table.RecordCache.CurrentCapacity;\r
+                       \r
+                       int defaultValuesRowIndex = _table.DefaultValuesRowIndex;\r
+                       if ( defaultValuesRowIndex != -1) {\r
+                               // store default value in the table\r
+                               DataContainer[defaultValuesRowIndex] = _defaultValue;\r
+                               // Set all the values in data container to default\r
+                               // it's cheaper that raise event on each row.\r
+                               DataContainer.FillValues(defaultValuesRowIndex);\r
+                       }\r
+               }\r
+               \r
+               // Returns true if all the same collumns are in columnSet and compareSet\r
+               internal static bool AreColumnSetsTheSame(DataColumn[] columnSet, DataColumn[] compareSet)\r
+               {\r
+                       if (null == columnSet && null == compareSet) {\r
+                               return true;\r
+                       }\r
+\r
+                       if (null == columnSet || null == compareSet) {\r
+                               return false;\r
+                       }\r
+\r
+                       if (columnSet.Length != compareSet.Length) { \r
+                               return false;\r
+                       }\r
+                       \r
+                       foreach (DataColumn col in columnSet) {\r
+                               bool matchFound = false;\r
+                               foreach (DataColumn compare in compareSet) {\r
+                                       if (col == compare) {\r
+                                               matchFound = true;                                      \r
+                                       }\r
+                               }\r
+                               if (! matchFound) {\r
+                                       return false;\r
+                               }\r
+                       }                       \r
+                       return true;\r
+               }\r
+\r
+               \r
+               internal int CompareValues (int index1, int index2)\r
+               {\r
+                       return DataContainer.CompareValues(index1, index2);\r
+               }\r
+\r
+                /// <summary>\r
+                ///     Returns the data relation, which contains this column.\r
+                ///     This searches in current table's parent relations.\r
+                /// <summary>\r
+                /// <returns>\r
+                ///     DataRelation if found otherwise null.\r
+                /// </returns>\r
+        private DataRelation GetParentRelation ()\r
+                {\r
+                        if (_table == null)\r
+                                return null;\r
+                        foreach (DataRelation rel in _table.ParentRelations)\r
+                                if (rel.Contains (this))\r
+                                        return rel;\r
+                        return null;\r
+                }\r
+                \r
+\r
+                /// <summary>\r
+                ///     Returns the data relation, which contains this column.\r
+                ///     This searches in current table's child relations.\r
+                /// <summary>\r
+                /// <returns>\r
+                ///     DataRelation if found otherwise null.\r
+                /// </returns>\r
+        private DataRelation GetChildRelation ()\r
+                {\r
+                        if (_table == null)\r
+                                return null;\r
+                        foreach (DataRelation rel in _table.ChildRelations)\r
+                                if (rel.Contains (this))\r
+                                        return rel;\r
+                        return null;\r
+                }\r
+                \r
+\r
+               #endregion // Methods\r
+\r
+       }\r
+}\r