+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
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){}
}
}
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
/// 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:
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;
}
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
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);
+ }
+
+ }
+
}
}
}
+ [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
}
return hash ;
}
-
+ [MonoTODO]
internal override void AddToConstraintCollectionSetup(
ConstraintCollection collection)
{
}
+ //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();
}
//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
}
}