X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Data%2FSystem.Data%2FDataRow.cs;h=baee5d293d2308dac165e01c5a6e30d4362f0a68;hb=c21950a927ac0f18190708b5c8d5ccd297bab68c;hp=923b5e8a1d99d705c799f193d6db156988bc53c4;hpb=398bf81fc09557b3dabf0ad91406ff20903fe777;p=mono.git diff --git a/mcs/class/System.Data/System.Data/DataRow.cs b/mcs/class/System.Data/System.Data/DataRow.cs index 923b5e8a1d9..baee5d293d2 100644 --- a/mcs/class/System.Data/System.Data/DataRow.cs +++ b/mcs/class/System.Data/System.Data/DataRow.cs @@ -42,12 +42,17 @@ using System.Data.Common; using System.Collections; using System.Globalization; using System.Xml; +#if NET_2_0 +using System.ComponentModel; +#endif namespace System.Data { /// /// Represents a row of data in a DataTable. /// +#if !NET_2_0 [Serializable] +#endif public class DataRow { #region Fields @@ -180,7 +185,6 @@ namespace System.Data { } CheckValue (value, column); - bool orginalEditing = Proposed >= 0; if (!orginalEditing) { BeginEdit (); @@ -246,9 +250,6 @@ namespace System.Data { get { if (columnIndex < 0 || columnIndex > _table.Columns.Count) throw new IndexOutOfRangeException (); - // Accessing deleted rows - if (!_inExpressionEvaluation && RowState == DataRowState.Deleted && version != DataRowVersion.Original) - throw new DeletedRowInaccessibleException ("Deleted row information cannot be accessed through the row."); DataColumn column = _table.Columns[columnIndex]; int recordIndex = IndexFromVersion(version); @@ -262,9 +263,6 @@ namespace System.Data { return column[recordIndex]; } - if (RowState == DataRowState.Detached && version == DataRowVersion.Default && Proposed < 0) - throw new RowNotInTableException("This row has been removed from a table and does not have any data. BeginEdit() will allow creation of new data in this row."); - return column[recordIndex]; } } @@ -274,17 +272,26 @@ namespace System.Data { /// public object[] ItemArray { get { - // row not in table - if (RowState == DataRowState.Detached) - throw new RowNotInTableException("This row has been removed from a table and does not have any data. BeginEdit() will allow creation of new data in this row."); // Accessing deleted rows if (RowState == DataRowState.Deleted) throw new DeletedRowInaccessibleException ("Deleted row information cannot be accessed through the row."); + + int index = 0; + if (RowState == DataRowState.Detached) + // Check if datarow is removed from the table. + if (Proposed < 0) + throw new RowNotInTableException( + "This row has been removed from a table and does not have any data." + +" BeginEdit() will allow creation of new data in this row."); + else + index = Proposed; + else + index = Current; object[] items = new object[_table.Columns.Count]; - foreach(DataColumn column in _table.Columns) { - items[column.Ordinal] = column[Current]; - } + + foreach(DataColumn column in _table.Columns) + items[column.Ordinal] = column[index]; return items; } set { @@ -322,23 +329,15 @@ namespace System.Data { public DataRowState RowState { get { //return rowState; - if ((Original == -1) && (Current == -1)) - { - return DataRowState.Detached; - } - if (Original == Current) - { - return DataRowState.Unchanged; - } - if (Original == -1) - { - return DataRowState.Added; - } - if (Current == -1) - { - return DataRowState.Deleted; - } - return DataRowState.Modified; + if ((Original == -1) && (Current == -1)) + return DataRowState.Detached; + if (Original == Current) + return DataRowState.Unchanged; + if (Original == -1) + return DataRowState.Added; + if (Current == -1) + return DataRowState.Deleted; + return DataRowState.Modified; } } @@ -592,12 +591,17 @@ namespace System.Data { return; case DataRowState.Added: case DataRowState.Modified: + int original = Original; + DataRowState oldState = RowState; if (Original >= 0) { Table.RecordCache.DisposeRecord(Original); } Original = Current; + foreach (Index index in Table.Indexes) + index.Update(this, original, DataRowVersion.Original, oldState); break; case DataRowState.Deleted: + Table.DeleteRowFromIndexes(this); _table.Rows.RemoveInternal (this); DetachRow(); break; @@ -611,6 +615,9 @@ namespace System.Data { /// /// Begins an edit operation on a DataRow object. /// +#if NET_2_0 + [EditorBrowsable (EditorBrowsableState.Advanced)] +#endif public void BeginEdit () { if (_inChangingEvent) @@ -631,6 +638,9 @@ namespace System.Data { /// /// Cancels the current edit on the row. /// +#if NET_2_0 + [EditorBrowsable (EditorBrowsableState.Advanced)] +#endif public void CancelEdit () { if (_inChangingEvent) { @@ -638,8 +648,13 @@ namespace System.Data { } if (HasVersion (DataRowVersion.Proposed)) { + int oldRecord = Proposed; + DataRowState oldState = RowState; Table.RecordCache.DisposeRecord(Proposed); Proposed = -1; + + foreach(Index index in Table.Indexes) + index.Update(this,oldRecord, DataRowVersion.Proposed, oldState); } } @@ -675,14 +690,17 @@ namespace System.Data { default: // check what to do with child rows CheckChildRows(DataRowAction.Delete); - _table.DeleteRowFromIndexes (this); break; } if (Current >= 0) { + int current = Current; + DataRowState oldState = RowState; if (Current != Original) { _table.RecordCache.DisposeRecord(Current); } Current = -1; + foreach(Index index in Table.Indexes) + index.Update(this, current, DataRowVersion.Current, oldState); } _table.DeletedDataRow(this, DataRowAction.Delete); } @@ -760,7 +778,6 @@ namespace System.Data { case DataRowAction.Rollback: { if (childRows[j].RowState != DataRowState.Unchanged) childRows[j].RejectChanges (); - break; } } @@ -817,6 +834,9 @@ namespace System.Data { /// /// Ends the edit occurring on the row. /// +#if NET_2_0 + [EditorBrowsable (EditorBrowsableState.Advanced)] +#endif public void EndEdit () { if (_inChangingEvent) @@ -839,38 +859,46 @@ namespace System.Data { _inChangingEvent = false; } - //Calling next method validates UniqueConstraints - //and ForeignKeys. - bool rowValidated = false; - try - { - if ((_table.DataSet == null || _table.DataSet.EnforceConstraints) && !_table._duringDataLoad) { - _table.Rows.ValidateDataRowInternal(this); - rowValidated = true; - } - } - catch (Exception e) - { - Table.RecordCache.DisposeRecord(Proposed); - Proposed = -1; - throw e; - } - - CheckChildRows(DataRowAction.Change); - if (Original != Current) { - Table.RecordCache.DisposeRecord(Current); - } + DataRowState oldState = RowState; + int oldRecord = Current; Current = Proposed; Proposed = -1; - if (!rowValidated) { - // keep indexes updated even if there was no need to validate row + if (!Table._duringDataLoad) { foreach(Index index in Table.Indexes) { - index.Update(this,Current); //FIXME: why Current ?! + index.Update(this,oldRecord, DataRowVersion.Current, oldState); } } + try { + AssertConstraints(); + + // restore previous state to let the cascade update to find the rows + Proposed = Current; + Current = oldRecord; + + CheckChildRows(DataRowAction.Change); + + // apply new state + Current = Proposed; + Proposed = -1; + } + catch { + int proposed = Proposed >= 0 ? Proposed : Current; + Current = oldRecord; + if (!Table._duringDataLoad) { + foreach(Index index in Table.Indexes) { + index.Update(this,proposed, DataRowVersion.Current, RowState); + } + } + throw; + } + + if (Original != oldRecord) { + Table.RecordCache.DisposeRecord(oldRecord); + } + // Note : row state must not be changed before all the job on indexes finished, // since the indexes works with recods rather than with rows and the decision // which of row records to choose depends on row state. @@ -1293,46 +1321,28 @@ namespace System.Data { throw new RowNotInTableException("This row has been removed from a table and does not have any data. BeginEdit() will allow creation of new data in this row."); // If original is null, then nothing has happened since AcceptChanges // was last called. We have no "original" to go back to. - if (HasVersion(DataRowVersion.Original)) { - if (Current >= 0 && Current != Original) { - Table.RecordCache.DisposeRecord(Current); - } - CheckChildRows(DataRowAction.Rollback); + + _table.ChangedDataRow (this, DataRowAction.Rollback); + CancelEdit (); + //TODO : Need to Verify the constraints.. + switch (RowState) { + case DataRowState.Added: + _table.DeleteRowFromIndexes (this); + _table.Rows.RemoveInternal (this); + DetachRow (); + break; + case DataRowState.Modified: + Table.RecordCache.DisposeRecord (Current); + CheckChildRows (DataRowAction.Rollback); + Table.DeleteRowFromIndexes(this); Current = Original; - - _table.ChangedDataRow (this, DataRowAction.Rollback); - CancelEdit (); - switch (RowState) - { - case DataRowState.Added: - _table.DeleteRowFromIndexes (this); - _table.Rows.RemoveInternal (this); - break; - case DataRowState.Modified: - if ((_table.DataSet == null || _table.DataSet.EnforceConstraints) && !_table._duringDataLoad) - _table.Rows.ValidateDataRowInternal(this); - break; - case DataRowState.Deleted: - if ((_table.DataSet == null || _table.DataSet.EnforceConstraints) && !_table._duringDataLoad) - _table.Rows.ValidateDataRowInternal(this); - break; - } - - } - else { - // If rows are just loaded via Xml the original values are null. - // So in this case we have to remove all columns. - // FIXME: I'm not realy sure, does this break something else, but - // if so: FIXME ;) - - if ((RowState & DataRowState.Added) > 0) - { - _table.DeleteRowFromIndexes (this); - _table.Rows.RemoveInternal (this); - // if row was in Added state we move it to Detached. - DetachRow(); - } + break; + case DataRowState.Deleted: + CheckChildRows (DataRowAction.Rollback); + Table.DeleteRowFromIndexes(this); + Current = Original; + break; } } @@ -1614,6 +1624,34 @@ namespace System.Data { } } + internal void Validate() { + Table.AddRowToIndexes(this); + AssertConstraints(); + } + + void AssertConstraints() { + if (Table == null || Table._duringDataLoad) + return; + + if (Table.DataSet != null && !Table.DataSet.EnforceConstraints) + return; + foreach(DataColumn column in Table.Columns) { + if (!column.AllowDBNull && IsNull(column)) { + throw new NoNullAllowedException(_nullConstraintMessage); + } + } + + foreach(Constraint constraint in Table.Constraints) { + try { + constraint.AssertConstraint(this); + } + catch(Exception e) { + Table.DeleteRowFromIndexes(this); + throw e; + } + } + } + internal void CheckNullConstraints() { if (_nullConstraintViolation) { @@ -1655,17 +1693,15 @@ namespace System.Data { && RowState == DataRowState.Unchanged)) { Table.ChangingDataRow (this, DataRowAction.ChangeCurrentAndOriginal); temp = Table.CreateRecord (values); + Table.DeleteRowFromIndexes(this); if (HasVersion (DataRowVersion.Original) && Current != Original) Table.RecordCache.DisposeRecord (Original); Original = temp; - // update the pk index - index = Table.GetIndex(Table.PrimaryKey,null,DataViewRowState.None,null,false); - if (index != null) - index.Update (this, temp); if (HasVersion (DataRowVersion.Current)) Table.RecordCache.DisposeRecord (Current); Current = temp; + Table.AddRowToIndexes(this); Table.ChangedDataRow (this, DataRowAction.ChangeCurrentAndOriginal); return; } @@ -1687,19 +1723,16 @@ namespace System.Data { if (RowState == DataRowState.Added || Table.CompareRecords (rindex, temp) != 0) { Table.ChangingDataRow (this, DataRowAction.Change); + Table.DeleteRowFromIndexes(this); if (HasVersion (DataRowVersion.Proposed)) { Table.RecordCache.DisposeRecord (Proposed); Proposed = -1; } - - // update the pk index - index = Table.GetIndex(Table.PrimaryKey,null,DataViewRowState.None,null,false); - if (index != null) - index.Update (this, temp); - + if (Original != Current) Table.RecordCache.DisposeRecord (Current); Current = temp; + Table.AddRowToIndexes(this); Table.ChangedDataRow (this, DataRowAction.Change); } else { Table.ChangingDataRow (this, DataRowAction.Nothing);