Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Kumpera <kumpera@gmail.com>2013-03-21 01:43:00 +0400
committerRodrigo Kumpera <kumpera@gmail.com>2013-03-21 01:49:59 +0400
commit02b64abba2aa289c053007c7496181f449bd40d7 (patch)
treeb76a77746c315978c42564906f81eca0355996aa /mcs/class/System.Data
parent2e6a2a4454d8aa2fbeee89c0e8152e5831910397 (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.cs13
-rw-r--r--mcs/class/System.Data/Test/System.Data/DataRowTest.cs158
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]);
+ }
+
}
}