if (row == null)
throw new ArgumentNullException("row", "'row' argument cannot be null.");
- if (list.IndexOf(row) != -1)
+ if (row.Table != this.table)
+ throw new ArgumentException ("This row already belongs to another table.");
+
+ // If row id is not -1, we know that it is in the collection.
+ if (row.RowID != -1)
throw new ArgumentException ("This row already belongs to this table.");
- if (table.DataSet == null || table.DataSet.EnforceConstraints)
+
+ if ((table.DataSet == null || table.DataSet.EnforceConstraints) && !table._duringDataLoad)
// we have to check that the new row doesn't colide with existing row
ValidateDataRowInternal(row);
+ row.HasParentCollection = true;
list.Add (row);
+ // Set the row id.
+ row.RowID = list.Count - 1;
row.AttachRow ();
row.Table.ChangedDataRow (row, DataRowAction.Add);
}
{
if (pos < 0)
throw new IndexOutOfRangeException ("The row insert position " + pos + " is invalid.");
+
+ if (row == null)
+ throw new ArgumentNullException("row", "'row' argument cannot be null.");
+
+ if (row.Table != this.table)
+ throw new ArgumentException ("This row already belongs to another table.");
+
+ // If row id is not -1, we know that it is in the collection.
+ if (row.RowID != -1)
+ throw new ArgumentException ("This row already belongs to this table.");
+
+ if ((table.DataSet == null || table.DataSet.EnforceConstraints) && !table._duringDataLoad)
+ // we have to check that the new row doesn't colide with existing row
+ ValidateDataRowInternal(row);
if (pos >= list.Count)
list.Add (row);
else
list.Insert (pos, row);
+
+ row.HasParentCollection = true;
+ row.AttachRow ();
+ row.Table.ChangedDataRow (row, DataRowAction.Add);
+ }
+
+ /// <summary>
+ /// Removes the specified DataRow from the internal list. Used by DataRow to commit the removing.
+ /// </summary>
+ internal void RemoveInternal (DataRow row) {
+ if (row == null) {
+ throw new IndexOutOfRangeException ("The given datarow is not in the current DataRowCollection.");
+ }
+ int index = list.IndexOf(row);
+ if (index < 0) {
+ throw new IndexOutOfRangeException ("The given datarow is not in the current DataRowCollection.");
+ }
+ list.RemoveAt(index);
}
/// <summary>
int index = list.IndexOf(row);
if (index < 0)
throw new IndexOutOfRangeException ("The given datarow is not in the current DataRowCollection.");
- RemoveAt(index);
+ row.Delete();
+ // if the row was in added state it will be in Detached state after the
+ // delete operation, so we have to check it.
+ if (row.RowState != DataRowState.Detached)
+ row.AcceptChanges();
}
/// <summary>
{
if (index < 0 || index >= list.Count)
throw new IndexOutOfRangeException ("There is no row at position " + index + ".");
-
DataRow row = (DataRow)list [index];
- if (row.RowState != DataRowState.Deleted && row.RowState != DataRowState.Added)
- row.Delete();
- list.RemoveAt (index);
- row.DetachRow();
- table.DeletedDataRow (row, DataRowAction.Delete);
+ row.Delete();
+ row.AcceptChanges();
}
///<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);
+ //first check for null violations.
+ row.CheckNullConstraints();
+ // This validates constraints in the specific order :
+ // first unique/primary keys first, then Foreignkeys, etc
+ ArrayList uniqueConstraintsDone = new ArrayList();
+ ArrayList foreignKeyConstraintsDone = new ArrayList();
+ try {
+ foreach(Constraint constraint in table.Constraints.UniqueConstraints) {
+ constraint.AssertConstraint(row);
+ uniqueConstraintsDone.Add(constraint);
+ }
+
+ foreach(Constraint constraint in table.Constraints.ForeignKeyConstraints) {
+ constraint.AssertConstraint(row);
+ foreignKeyConstraintsDone.Add(constraint);
+ }
+ }
+ // if one of the AssertConstraint failed - we need to "rollback" all the changes
+ // caused by AssertCoinstraint calls already succeeded
+ catch(ConstraintException e) {
+ RollbackAsserts(row,foreignKeyConstraintsDone,uniqueConstraintsDone);
+ throw e;
+ }
+ catch(InvalidConstraintException e) {
+ RollbackAsserts(row,foreignKeyConstraintsDone,uniqueConstraintsDone);
+ throw e;
}
-
}
-
- }
+ private void RollbackAsserts(DataRow row,ICollection foreignKeyConstraintsDone,
+ ICollection uniqueConstraintsDone)
+ {
+ // if any of constraints assert failed -
+ // we have to rollback all the asserts scceeded
+ // on order reverse to thier original execution
+ foreach(Constraint constraint in foreignKeyConstraintsDone) {
+ constraint.RollbackAssert(row);
+ }
+ foreach(Constraint constraint in uniqueConstraintsDone) {
+ constraint.RollbackAssert(row);
+ }
+ }
+ }
}