2002-10-06 Luis Fernandez <luifer@onetel.net.uk>
authorRodrigo Moya <rodrigo@mono-cvs.ximian.com>
Sun, 6 Oct 2002 19:10:14 +0000 (19:10 -0000)
committerRodrigo Moya <rodrigo@mono-cvs.ximian.com>
Sun, 6 Oct 2002 19:10:14 +0000 (19:10 -0000)
* System.Data/Constraint.cs (AssertConstraint): added overloaded
method.

* System.Data/DataColumnCollection.cs: added constraints when needed.

* System.Data/DataRow.cs: validate UniqueConstraint's.

* System.Data/DataRowCollection.cs (ValidateDataRowInternal): new
internal method to validate a given DataRow with respect to the
DataRowCollection.

* System.Data/ForeignKeyConstraint.cs (AssertConstraint): stubs for
new overloaded method.

* System.Data/UniqueConstraint.cs: added implementation.
(AseertConstraint): implemented new overloaded method.

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

mcs/class/System.Data/ChangeLog
mcs/class/System.Data/System.Data/Constraint.cs
mcs/class/System.Data/System.Data/DataColumn.cs
mcs/class/System.Data/System.Data/DataColumnCollection.cs
mcs/class/System.Data/System.Data/DataRow.cs
mcs/class/System.Data/System.Data/DataRowCollection.cs
mcs/class/System.Data/System.Data/ForeignKeyConstraint.cs
mcs/class/System.Data/System.Data/UniqueConstraint.cs

index ea9190a429202f64c2dd195a95b2d03f6ce4d763..bbba6c5a4d4be281d955aad4324fe795e0480f28 100644 (file)
@@ -1,3 +1,22 @@
+2002-10-06  Luis Fernandez <luifer@onetel.net.uk>
+
+       * System.Data/Constraint.cs (AssertConstraint): added overloaded
+       method.
+
+       * System.Data/DataColumnCollection.cs: added constraints when needed.
+
+       * System.Data/DataRow.cs: validate UniqueConstraint's.
+
+       * System.Data/DataRowCollection.cs (ValidateDataRowInternal): new
+       internal method to validate a given DataRow with respect to the
+       DataRowCollection.
+
+       * System.Data/ForeignKeyConstraint.cs (AssertConstraint): stubs for
+       new overloaded method.
+
+       * System.Data/UniqueConstraint.cs: added implementation.
+       (AseertConstraint): implemented new overloaded method.
+       
 2002-10-01  Rodrigo Moya <rodrigo@ximian.com>
 
        * System.Data.OleDb/OleDbConnection.cs (Open): commented code from
index c8eb6e158683517006f6b302cb9edd539054f3b7..a58bd130d2122c589cea0f2b8d75c3999cd6f15f 100644 (file)
@@ -104,10 +104,8 @@ namespace System.Data
                internal virtual void RemoveFromConstraintCollectionCleanup( 
                        ConstraintCollection collection){}
 
-
-               //Call to Validate the constraint
-               //Will throw if constraint is violated
                internal virtual void AssertConstraint(){}
                
+               internal virtual void AssertConstraint(DataRow row){}
        }
 }
index 10cda87d34a516e4a987a6eb2ae9e5b994807915..cebb3b93a5ac30d9e1ddd8f11945a01ae987382f 100644 (file)
@@ -362,8 +362,7 @@ namespace System.Data
                                return unique;
                        }
                        set {
-                               //TODO: create UniqueConstraint
-                               //if Table == null then the constraint is 
+                               //if Table == null then the UniqueConstraint is
                                //created on addition to the collection
                                
                                //FIXME?: need to check if value is the same
index 5e813c6e5a33496ba61ebb4d4da1ceea7ed325d5..0d247f06d493a4ba73025b7b39f37c2749d275eb 100644 (file)
@@ -113,6 +113,7 @@ namespace System.Data
                /// Creates and adds the specified DataColumn object to the DataColumnCollection.
                /// </summary>
                /// <param name="column">The DataColumn to add.</param>
+               [MonoTODO]
                public void Add(DataColumn column)
                {       
                        //FIXME:
@@ -126,6 +127,17 @@ namespace System.Data
                                
                                column.SetTable( parentTable);
                                base.List.Add(column);
+                               
+                               //add constraints if neccesary
+
+                               if(column.Unique)
+                               {
+                                       UniqueConstraint uc = new UniqueConstraint(column);
+                                       parentTable.Constraints.Add(uc);
+                               }
+                               
+                               //TODO: add missing constraints. i.e. Primary/Foreign keys
+
                                OnCollectionChanged(e);
                                return;
                        }
index ec1b514875b3cd0c87fb2c7c8c38d623179a73a6..8f3576f02c8356e840d39c8a4a9b603a3807a981 100644 (file)
@@ -394,7 +394,11 @@ namespace System.Data
                        if (HasVersion (DataRowVersion.Proposed))
                        {
                                rowState = DataRowState.Modified;
-                               //TODO: Validate Constraints, Events
+                               
+                               //Calling next method validates UniqueConstraints
+                               //and ForeignKeys.
+                               _table.Rows.ValidateDataRowInternal(this);
+                               
                                Array.Copy (proposed, current, _table.Columns.Count);
                                
                                //FIXME: MS implementation assigns the proposed values to
index ca98c053d44e89df57eb237006cd92dba719995e..894f13d9e83d60fcee667206660ac32bbf33b700 100644 (file)
@@ -140,5 +140,22 @@ namespace System.Data
                        list.RemoveAt (index);
                }
 
+               ///<summary>
+               ///Internal method used to validate a given DataRow with respect
+               ///to the DataRowCollection
+               ///</summary>
+               [MonoTODO]
+               internal void ValidateDataRowInternal(DataRow row)
+               {
+                       //FIXME: this validates constraints in the order they appear
+                       //in the collection. Most probably we need to do it in a 
+                       //specific order like unique/primary keys first, then Foreignkeys, etc
+                       foreach(Constraint constraint in table.Constraints)
+                       {
+                               constraint.AssertConstraint(row);
+                       }
+
+               }
+
        }
 }
index 1539cc614463960cc675be1e38e7e087f1ea8ed1..0d99615c07996587bb7d806fbd303b8916a8e51a 100644 (file)
@@ -371,6 +371,13 @@ namespace System.Data
                        
                }
                
+               [MonoTODO]
+               internal override void AssertConstraint(DataRow row)
+               {
+                       //Implement: this should be used to validate ForeignKeys constraints 
+                       //when modifiying the DataRow values of a DataTable.
+               }
+               
                #endregion // Methods
        }
 
index b6f7ef80a0fef32be354237ca6a3e663c7ef8b2b..92d0c2728217b074a86fb5e3cb1d99140fa006a4 100644 (file)
@@ -312,7 +312,7 @@ namespace System.Data
                        return hash ;
                }
                
-       
+               [MonoTODO]
                internal override void AddToConstraintCollectionSetup(
                                ConstraintCollection collection)
                {
@@ -332,6 +332,9 @@ namespace System.Data
 
                        }
                                        
+                       //FIXME: ConstraintCollection calls AssertContraint() again rigth after calling
+                       //this method, so that it is executed twice. Need to investigate which
+                       // call to remove as that migth affect other parts of the classes.
                        AssertConstraint();
                }
                                        
@@ -352,9 +355,82 @@ namespace System.Data
                        //Unique?       
                        DataTable tbl = _dataTable;
 
-                       //TODO: validate no dups        
+                       //TODO: Investigate other ways of speeding up the validation work below.
+                       //FIXME: This only works when only one DataColumn has been specified.
+
+                       //validate no duplicates exists.
+                       //Only validate when there are at least 2 rows
+                       //so that a duplicate migth exist.
+                       if(tbl.Rows.Count > 1)
+                       {
+
+
+                               //get copy of rows collection first so that we do not modify the
+                               //original.
+                               ArrayList clonedDataList = (ArrayList)tbl.Rows.List.Clone();
+
+                               ArrayList newDataList = new ArrayList();
+
+                               //copy to array list only the column we are interested in.
+                               foreach (DataRow row in clonedDataList)
+                               {
+                                       newDataList.Add(row[this._dataColumns[0]]);
+                               }
+                               
+                               //sort ArrayList and check adjacent values for duplicates.
+                               newDataList.Sort();
+
+                               for( int i = 0 ; i < newDataList.Count - 1 ; i++)
+                               {
+                                       if( newDataList[i].Equals(newDataList[i+1]) )
+                                       {
+                                               string msg = "Column '" + this._dataColumns[0] + "' contains non-unique values";
+                                               throw new InvalidConstraintException( msg );
+                                       }
+                               }
+                       }
+
+
+               }
+
+               [MonoTODO]
+               internal override void AssertConstraint(DataRow row)
+               {
+
+                       if (_dataTable == null) return; //???
+                       if (_dataColumns == null) return; //???
+
+
+                       //Unique?
+                       DataTable tbl = _dataTable;
+
+                       foreach(DataRow compareRow in tbl.Rows)
+                       {
+                               //skip if it is the same row to be validated
+                               if(!row.Equals(compareRow))
+                               {
+                                       if(compareRow.HasVersion (DataRowVersion.Original))
+                                       {
+                                               //FIXME: should we compare to compareRow[DataRowVersion.Current]?
+                                               //FIXME: We need to compare to all columns the constraint is set to.
+                                               if(row[_dataColumns[0], DataRowVersion.Proposed].Equals( compareRow[_dataColumns[0], DataRowVersion.Current]))
+                                               {
+                                                       string ExceptionMessage;
+                                                       ExceptionMessage = "Column '" + _dataColumns[0].ColumnName + "' is constrained to be unique.";
+                                                       ExceptionMessage += " Value '" + row[_dataColumns[0], DataRowVersion.Proposed].ToString();
+                                                       ExceptionMessage += "' is already present.";
+
+                                                       throw new ConstraintException (ExceptionMessage);
+                                               }
+
+                                       }
 
                }
+
+                       }
+
+               }
+
                #endregion // Methods
        }
 }