diff options
author | Rodrigo Kumpera <kumpera@gmail.com> | 2013-03-21 01:43:00 +0400 |
---|---|---|
committer | Rodrigo Kumpera <kumpera@gmail.com> | 2013-03-21 01:49:59 +0400 |
commit | 02b64abba2aa289c053007c7496181f449bd40d7 (patch) | |
tree | b76a77746c315978c42564906f81eca0355996aa /mcs/class/System.Data | |
parent | 2e6a2a4454d8aa2fbeee89c0e8152e5831910397 (diff) |
Fix multiple issues with System.Data.DataRow::SetParentRow. Fixes #7900.
* DataRow.cs: There is a total of issues been addressed here:
1) SetParentRow (null) would crash instead of setting all relation
columns to DBNull.
2)SetParentRow (parentRow, relation) did not check if both row and relation
belong to the same table.
3)SetParentRow(parentRow) when the child table has multiple relations to different
tables, we should only process those that belong to the table of parentRow.
Diffstat (limited to 'mcs/class/System.Data')
-rw-r--r-- | mcs/class/System.Data/System.Data/DataRow.cs | 13 | ||||
-rw-r--r-- | mcs/class/System.Data/Test/System.Data/DataRowTest.cs | 158 |
2 files changed, 166 insertions, 5 deletions
diff --git a/mcs/class/System.Data/System.Data/DataRow.cs b/mcs/class/System.Data/System.Data/DataRow.cs index db4ad0c29c9..c3df83b3b0c 100644 --- a/mcs/class/System.Data/System.Data/DataRow.cs +++ b/mcs/class/System.Data/System.Data/DataRow.cs @@ -1365,7 +1365,7 @@ namespace System.Data { /// </summary> public void SetParentRow (DataRow parentRow, DataRelation relation) { - if (_table == null || parentRow.Table == null) + if (_table == null || (parentRow != null && parentRow.Table == null)) 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 (parentRow != null && _table.DataSet != parentRow.Table.DataSet) @@ -1378,10 +1378,13 @@ namespace System.Data { BeginEdit(); IEnumerable relations; - if (relation == null) - relations = _table.ParentRelations; - else + if (relation != null) { + if (parentRow != null && relation.ParentColumns [0].Table != parentRow.Table) + throw new InvalidConstraintException (string.Format ("Parent belongs to table {0} but relation is for table {1}", parentRow.Table, relation.ParentColumns [0].Table)); relations = new DataRelation [] { relation }; + } else { + relations = _table.ParentRelations; + } foreach (DataRelation rel in relations) { DataColumn [] childCols = rel.ChildColumns; @@ -1390,7 +1393,7 @@ namespace System.Data { for (int i = 0; i < parentCols.Length; i++) { if (parentRow == null) { childCols [i].DataContainer [Proposed] = DBNull.Value; - } else { + } else if (parentCols [i].Table == parentRow.Table) { int defaultIdx = parentRow.IndexFromVersion (DataRowVersion.Default); childCols [i].DataContainer.CopyValue(parentCols [i].DataContainer, defaultIdx, Proposed); } diff --git a/mcs/class/System.Data/Test/System.Data/DataRowTest.cs b/mcs/class/System.Data/Test/System.Data/DataRowTest.cs index d5bbcf4586a..5b2fd8ca9f3 100644 --- a/mcs/class/System.Data/Test/System.Data/DataRowTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DataRowTest.cs @@ -1007,5 +1007,163 @@ namespace MonoTests.System.Data AssertEquals (DataRowState.Detached, dr.RowState); object o = dr ["col"]; } + + [Test] + public void SetParentRow_Null () + { + DataSet ds = new DataSet(); + + DataTable child = ds.Tables.Add("child"); + child.Columns.Add("column1"); + + DataRow r1 = child.NewRow(); + + r1.SetParentRow(null); + } + + [Test] + public void SetParentRow_DataInheritance () + { + var ds = new DataSet() ; + + var child = ds.Tables.Add("child") ; + + var childColumn1 = child.Columns.Add("column1"); + var childColumn2 = child.Columns.Add("column2"); + + var parent1 = ds.Tables.Add("parent1"); + var parent1Column1 = parent1.Columns.Add("column1"); + var parent1Column2 = parent1.Columns.Add("column2"); + + var parent2 = ds.Tables.Add("parent2"); + var parent2Column1 = parent2.Columns.Add("column1"); + var parent2Column2 = parent2.Columns.Add("column2"); + + var relation1 = ds.Relations.Add("parent1-child", parent1Column1, childColumn1); + ds.Relations.Add("parent2-child", parent2Column2, childColumn2); + + var childRow1 = child.NewRow(); + var parent1Row = parent1.NewRow(); + var parent2Row = parent2.NewRow(); + + parent1Row[parent1Column1] = "p1c1"; + parent1Row[parent1Column2] = "p1c2"; + parent2Row[parent2Column1] = "p2c1"; + parent2Row[parent2Column2] = "p2c2"; + + child.Rows.Add(childRow1); + parent1.Rows.Add(parent1Row); + parent2.Rows.Add(parent2Row); + + childRow1.SetParentRow(parent1Row); + AssertEquals ("p1c1", childRow1[childColumn1]); + AssertEquals (DBNull.Value, childRow1[childColumn2]); + + childRow1.SetParentRow(parent2Row); + AssertEquals ("p1c1", childRow1[childColumn1]); + AssertEquals ("p2c2", childRow1[childColumn2]); + + childRow1.SetParentRow(null); + AssertEquals (DBNull.Value, childRow1[childColumn1]); + AssertEquals (DBNull.Value, childRow1[childColumn2]); + + childRow1.SetParentRow(parent2Row); + AssertEquals (DBNull.Value, childRow1[childColumn1]); + AssertEquals ("p2c2", childRow1[childColumn2]); + } + + [Test] + public void SetParentRow_with_Relation () + { + var ds = new DataSet() ; + + var child = ds.Tables.Add("child") ; + + var childColumn1 = child.Columns.Add("column1"); + var childColumn2 = child.Columns.Add("column2"); + + var parent1 = ds.Tables.Add("parent1"); + var parent1Column1 = parent1.Columns.Add("column1"); + var parent1Column2 = parent1.Columns.Add("column2"); + + var parent2 = ds.Tables.Add("parent2"); + var parent2Column1 = parent2.Columns.Add("column1"); + var parent2Column2 = parent2.Columns.Add("column2"); + + var relation1 = ds.Relations.Add("parent1-child", parent1Column1, childColumn1) ; + var relation2 = ds.Relations.Add("parent2-child", parent2Column2, childColumn2) ; + + var childRow1 = child.NewRow(); + var parent1Row = parent1.NewRow(); + var parent2Row = parent2.NewRow(); + + parent1Row[parent1Column1] = "p1c1"; + parent1Row[parent1Column2] = "p1c2"; + parent2Row[parent2Column1] = "p2c1"; + parent2Row[parent2Column2] = "p2c2"; + + child.Rows.Add(childRow1); + parent1.Rows.Add(parent1Row); + parent2.Rows.Add(parent2Row); + + + childRow1.SetParentRow (null, relation2); + AssertEquals (DBNull.Value, childRow1[childColumn1]); + AssertEquals (DBNull.Value, childRow1[childColumn2]); + + try { + childRow1.SetParentRow(parent1Row, relation2); + Fail ("Must throw InvalidConstaintException"); + } catch (InvalidConstraintException e) { + } + AssertEquals (DBNull.Value, childRow1[childColumn1]); + AssertEquals (DBNull.Value, childRow1[childColumn2]); + + childRow1.SetParentRow(parent1Row, relation1); + AssertEquals ("p1c1", childRow1[childColumn1]); + AssertEquals (DBNull.Value, childRow1[childColumn2]); + + + childRow1.SetParentRow (null, relation2); + AssertEquals ("p1c1", childRow1[childColumn1]); + AssertEquals (DBNull.Value, childRow1[childColumn2]); + + childRow1.SetParentRow (null, relation1); + AssertEquals (DBNull.Value, childRow1[childColumn1]); + AssertEquals (DBNull.Value, childRow1[childColumn2]); + } + + [Test] + public void SetParent_missing_ParentRow () + { + var ds = new DataSet() ; + + var child = ds.Tables.Add("child") ; + + var childColumn1 = child.Columns.Add("column1"); + var childColumn2 = child.Columns.Add("column2"); + + var parent1 = ds.Tables.Add("parent1"); + var parentColumn1 = parent1.Columns.Add("column1"); + + var parent2 = ds.Tables.Add("parent2"); + var parentColumn2 = parent2.Columns.Add("column2"); + + ds.Relations.Add("parent1-child", parentColumn1, childColumn1); + ds.Relations.Add("parent2-child", parentColumn2, childColumn2); + + var childRow = child.NewRow(); + var parentRow = parent2.NewRow(); + + parentRow[parentColumn2] = "value"; + + child.Rows.Add(childRow); + parent2.Rows.Add(parentRow); + + childRow.SetParentRow(parentRow); + AssertEquals (DBNull.Value, childRow[childColumn1]); + AssertEquals ("value", childRow[childColumn2]); + } + } } |