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:
authorSenganal T <senga@mono-cvs.ximian.com>2006-04-21 12:11:46 +0400
committerSenganal T <senga@mono-cvs.ximian.com>2006-04-21 12:11:46 +0400
commitab0191bf4b042d8851daac129996ac18a340416b (patch)
tree33f8bf7c1ce79a0c1dbcaf661b28c7b99cb770b6
parent6dcd3635ec1b1f1f5db852702b4817b59485d781 (diff)
2006-04-21 Senganal T <tsenganal@novell.com>
* Test/System.Data/DataTableTest2.cs : Test Duplicate values are handled appropriatly during table loading ( BeginLoadData , EndLoadData). Test LoadDataRow behaves appropriately if called outside BeginLoadData,EndLoadData. * System.Data/DataRowCollection.cs : - Find : If search on the table using PrimaryKey fails and if index is not being maintained (during table load), search the entire table. - Find (int) : Removed. Deadcode. - Clear : - Not necessary to delete each row from the Index. Just reset the Indexes after cleaning up the row collection. - Simplify dependency check for child tables * System.Data/DataTable.cs : - LoadDataRow : - Do not use DataRowCollection.Find to search for existing records as this wud check even newly loaded rows. Use Index.Find. - Do not add new records to Index. Update Index only if an existing record is modified. New records will be taken care by EndLoadData. svn path=/trunk/mcs/; revision=59730
-rw-r--r--mcs/class/System.Data/System.Data/ChangeLog21
-rw-r--r--mcs/class/System.Data/System.Data/DataRowCollection.cs108
-rw-r--r--mcs/class/System.Data/System.Data/DataTable.cs60
-rw-r--r--mcs/class/System.Data/Test/System.Data/ChangeLog6
-rw-r--r--mcs/class/System.Data/Test/System.Data/DataTableTest2.cs55
5 files changed, 153 insertions, 97 deletions
diff --git a/mcs/class/System.Data/System.Data/ChangeLog b/mcs/class/System.Data/System.Data/ChangeLog
index 37b7dae4529..84d3037e259 100644
--- a/mcs/class/System.Data/System.Data/ChangeLog
+++ b/mcs/class/System.Data/System.Data/ChangeLog
@@ -1,3 +1,24 @@
+2006-04-21 Senganal T <tsenganal@novell.com>
+
+ * DataRowCollection.cs :
+ - Find : If search on the table using PrimaryKey fails and if
+ index is not being maintained (during table load), search the
+ entire table.
+ - Find (int) : Removed. Deadcode.
+ - Clear :
+ - Not necessary to delete each row from the Index.
+ Just reset the Indexes after cleaning up the row
+ collection.
+ - Simplify dependency check for child tables
+ * DataTable.cs :
+ - LoadDataRow :
+ - Do not use DataRowCollection.Find to search for
+ existing records as this wud check even newly loaded rows.
+ Use Index.Find.
+ - Do not add new records to Index. Update Index only
+ if an existing record is modified. New records will be
+ taken care by EndLoadData.
+
2006-04-19 Senganal T <tsenganal@novell.com>
* XmlHelper.cs : A helper class for encoding/decoding schema names.
diff --git a/mcs/class/System.Data/System.Data/DataRowCollection.cs b/mcs/class/System.Data/System.Data/DataRowCollection.cs
index 9b8a5d1ff64..f81748de2cd 100644
--- a/mcs/class/System.Data/System.Data/DataRowCollection.cs
+++ b/mcs/class/System.Data/System.Data/DataRowCollection.cs
@@ -145,31 +145,28 @@ namespace System.Data
public void Clear ()
{
if (this.table.DataSet != null && this.table.DataSet.EnforceConstraints) {
- foreach (DataTable table in this.table.DataSet.Tables) {
- foreach (Constraint c in table.Constraints) {
- if (c is ForeignKeyConstraint) {
- ForeignKeyConstraint fk = (ForeignKeyConstraint) c;
- if (fk.RelatedTable.Equals(this.table)
- && fk.Table.Rows.Count > 0) // check does not make sense if we don't have rows
+ foreach (Constraint c in table.Constraints) {
+ UniqueConstraint uc = c as UniqueConstraint;
+ if (uc == null)
+ continue;
+ if (uc.ChildConstraint == null || uc.ChildConstraint.Table.Rows.Count == 0)
+ continue;
+
+ string err = String.Format ("Cannot clear table Parent because " +
+ "ForeignKeyConstraint {0} enforces Child.", uc.ConstraintName);
#if NET_1_1
- throw new InvalidConstraintException (String.Format ("Cannot clear table Parent" +
- " because ForeignKeyConstraint "+
- "{0} enforces Child.",
- c.ConstraintName));
+ throw new InvalidConstraintException (err);
#else
- throw new ArgumentException (String.Format ("Cannot clear table Parent because " +
- "ForeignKeyConstraint {0} enforces Child.",
- c.ConstraintName));
+ throw new ArgumentException (err);
#endif
- }
- }
}
}
- // Remove from indexes
- for (int i = 0; i < this.Count; i++)
- this.table.DeleteRowFromIndexes (this [i]);
List.Clear ();
+
+ // Remove from indexes
+ table.ResetIndexes ();
+
OnListChanged (this, new ListChangedEventArgs (ListChangedType.Reset, -1, -1));
}
@@ -196,7 +193,7 @@ namespace System.Data
/// </summary>
public DataRow Find (object key)
{
- return Find(new object[]{key});
+ return Find (new object[]{key}, DataViewRowState.CurrentRows);
}
/// <summary>
@@ -204,16 +201,7 @@ namespace System.Data
/// </summary>
public DataRow Find (object[] keys)
{
- if (table.PrimaryKey.Length == 0)
- throw new MissingPrimaryKeyException ("Table doesn't have a primary key.");
-
- if (keys == null)
- throw new ArgumentException ("Expecting " + table.PrimaryKey.Length +" value(s) for the key being indexed, but received 0 value(s).");
-
- Index index = table.GetIndex(table.PrimaryKey,null,DataViewRowState.None,null,false);
-
- int record = index.Find(keys);
- return (record != -1) ? table.RecordCache[record] : null;
+ return Find (keys, DataViewRowState.CurrentRows);
}
/// <summary>
@@ -227,45 +215,41 @@ namespace System.Data
if (keys == null)
throw new ArgumentException ("Expecting " + table.PrimaryKey.Length +" value(s) for the key being indexed, but received 0 value(s).");
-
- Index index = table.FindIndex (table.PrimaryKey, null, rowStateFilter, null);
- if (index == null)
- index = new Index (new Key (table, table.PrimaryKey, null, rowStateFilter, null));
- int record = index.Find(keys);
- return (record != -1) ? table.RecordCache[record] : null;
- }
+ Index index = table.GetIndex (table.PrimaryKey, null, rowStateFilter, null, false);
+ int record = index.Find (keys);
- internal DataRow Find(int index)
- {
- DataColumn[] primaryKey = table.PrimaryKey;
- Index primaryKeyIndex = table.FindIndex(primaryKey);
- // if we can search through index
- if (primaryKeyIndex != null) {
- // get the child rows from the index
- int record = primaryKeyIndex.Find(index);
- if ( record != -1 ) {
- return table.RecordCache[record];
- }
- }
- else {
- //loop through all collection rows
+ if (record != -1 || !table._duringDataLoad)
+ return (record != -1 ? table.RecordCache [record] : null);
+
+ // If the key is not found using Index *and* if DataTable is under BeginLoadData
+ // then, check all the DataRows for the key
+ record = table.RecordCache.NewRecord ();
+ try {
+ for (int i=0; i < table.PrimaryKey.Length; ++i)
+ table.PrimaryKey [i].DataContainer [record] = keys [i];
+
+ bool found;
foreach (DataRow row in this) {
- if (row.RowState != DataRowState.Deleted) {
- int rowIndex = row.IndexFromVersion(DataRowVersion.Default);
- bool match = true;
- for (int columnCnt = 0; columnCnt < primaryKey.Length; ++columnCnt) {
- if (primaryKey[columnCnt].DataContainer.CompareValues(rowIndex, index) != 0) {
- match = false;
- }
- }
- if ( match ) {
- return row;
- }
+
+ int rowIndex = Key.GetRecord (row, rowStateFilter);
+ if (rowIndex == -1)
+ continue;
+
+ found = true;
+ for (int columnCnt = 0; columnCnt < table.PrimaryKey.Length; ++columnCnt) {
+ if (table.PrimaryKey [columnCnt].CompareValues (rowIndex, record) == 0)
+ continue;
+ found = false;
+ break;
}
+ if (found)
+ return row;
}
+ return null;
+ } finally {
+ table.RecordCache.DisposeRecord (record);
}
- return null;
}
/// <summary>
diff --git a/mcs/class/System.Data/System.Data/DataTable.cs b/mcs/class/System.Data/System.Data/DataTable.cs
index 3d3350ce90c..3f873366ed1 100644
--- a/mcs/class/System.Data/System.Data/DataTable.cs
+++ b/mcs/class/System.Data/System.Data/DataTable.cs
@@ -1190,42 +1190,39 @@ namespace System.Data {
public DataRow LoadDataRow (object[] values, bool fAcceptChanges)
{
DataRow row = null;
- if (PrimaryKey.Length == 0) {
+ if (PrimaryKey.Length == 0)
row = Rows.Add (values);
- if (fAcceptChanges)
- row.AcceptChanges ();
- }
else {
EnsureDefaultValueRowIndex();
int newRecord = CreateRecord(values);
- int existingRecord = _primaryKeyConstraint.Index.Find(newRecord);
+ int existingRecord = _primaryKeyConstraint.Index.Find (newRecord);
if (existingRecord < 0) {
row = NewRowFromBuilder (RowBuilder);
row.Proposed = newRecord;
- AddRowToIndexes (row);
Rows.AddInternal(row);
- }
- else {
+ if (!_duringDataLoad)
+ AddRowToIndexes (row);
+ } else {
row = RecordCache[existingRecord];
row.BeginEdit();
row.ImportRecord(newRecord);
row.EndEdit();
}
-
- if (fAcceptChanges)
- row.AcceptChanges ();
}
+
+ if (fAcceptChanges)
+ row.AcceptChanges ();
return row;
}
- internal DataRow LoadDataRow(IDataRecord record, int[] mapping, int length, bool fAcceptChanges)
+ internal DataRow LoadDataRow (IDataRecord record, int[] mapping, int length, bool fAcceptChanges)
{
DataRow row = null;
- int tmpRecord = this.RecordCache.NewRecord();
- try {
- RecordCache.ReadIDataRecord(tmpRecord,record,mapping,length);
+ int tmpRecord = this.RecordCache.NewRecord ();
+ try {
+ RecordCache.ReadIDataRecord (tmpRecord,record,mapping,length);
if (PrimaryKey.Length != 0) {
bool hasPrimaryValues = true;
foreach(DataColumn col in PrimaryKey) {
@@ -1234,35 +1231,28 @@ namespace System.Data {
break;
}
}
-
+
if (hasPrimaryValues) {
- // find the row in the table.
- row = Rows.Find(tmpRecord);
+ int existingRecord = _primaryKeyConstraint.Index.Find (tmpRecord);
+ if (existingRecord != -1)
+ row = RecordCache [existingRecord];
}
}
-
- bool shouldUpdateIndex = false;
+
if (row == null) {
row = NewNotInitializedRow();
- row.ImportRecord(tmpRecord);
+ row.Proposed = tmpRecord;
Rows.AddInternal (row);
- shouldUpdateIndex = true;
- }
- else {
- // Proposed = tmpRecord
- row.ImportRecord(tmpRecord);
+ } else {
+ row.BeginEdit ();
+ row.ImportRecord (tmpRecord);
+ row.EndEdit ();
}
-
- if (fAcceptChanges) {
+
+ if (fAcceptChanges)
row.AcceptChanges();
- }
-
- if (shouldUpdateIndex && !fAcceptChanges) {
- AddRowToIndexes(row);
- }
- }
- catch(Exception e) {
+ } catch(Exception e) {
this.RecordCache.DisposeRecord(tmpRecord);
throw e;
}
diff --git a/mcs/class/System.Data/Test/System.Data/ChangeLog b/mcs/class/System.Data/Test/System.Data/ChangeLog
index 0a7e50b6340..97a1cbfe525 100644
--- a/mcs/class/System.Data/Test/System.Data/ChangeLog
+++ b/mcs/class/System.Data/Test/System.Data/ChangeLog
@@ -1,3 +1,9 @@
+2006-04-21 Senganal T <tsenganal@novell.com>
+
+ * DataTableTest2.cs : Test Duplicate values are handled appropriatly
+ during table loading ( BeginLoadData , EndLoadData). Test LoadDataRow
+ behaves appropriately if called outside BeginLoadData,EndLoadData.
+
2006-04-19 Senganal T <tsenganal@novell.com>
* DataSetTest2.cs : Test if ConstraintName with whitespace is saved
diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs
index 7c75420bfea..d63c840a956 100644
--- a/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs
+++ b/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs
@@ -423,6 +423,59 @@ namespace MonoTests_System.Data
}
[Test]
+ [ExpectedException (typeof (ConstraintException))]
+ public void LoadDataRow_DuplicateValues ()
+ {
+ DataTable table = new DataTable ();
+ table.Columns.Add ("col1", typeof (int));
+ table.Columns.Add ("col2", typeof (int));
+
+ table.PrimaryKey = new DataColumn[] {table.Columns [0]};
+
+ table.BeginLoadData ();
+ table.LoadDataRow (new object[] {1 , 1}, false);
+ table.LoadDataRow (new object[] {1 , 10}, false);
+ table.EndLoadData ();
+ }
+
+ [Test]
+ public void LoadDataRow_WithoutBeginLoadData ()
+ {
+ DataTable table = new DataTable ();
+ table.Columns.Add ("col1", typeof (int));
+ table.Columns.Add ("col2", typeof (int));
+
+ table.PrimaryKey = new DataColumn[] {table.Columns [0]};
+ table.Rows.Add (new object[] {1,1});
+ table.AcceptChanges ();
+
+ table.LoadDataRow (new object[] {10,1}, false);
+ DataRow row = table.Rows.Find (10);
+ Assert.IsNotNull (row, "#1");
+ Assert.AreEqual (1, row [1], "#2");
+ Assert.AreEqual (DataRowState.Added, row.RowState, "#3");
+ table.AcceptChanges ();
+
+ table.LoadDataRow (new object[] {10,2}, true);
+ row = table.Rows.Find (10);
+ Assert.IsNotNull (row, "#4");
+ Assert.AreEqual (2, row [1], "#5");
+ Assert.AreEqual (DataRowState.Unchanged, row.RowState, "#6");
+
+ table.LoadDataRow (new object[] {1,2}, false);
+ row = table.Rows.Find (1);
+ Assert.IsNotNull (row, "#7");
+ Assert.AreEqual (2, row [1], "#8");
+ Assert.AreEqual (DataRowState.Modified, table.Rows.Find (1).RowState, "#9");
+
+ table.LoadDataRow (new object[] {1,3}, true);
+ row = table.Rows.Find (1);
+ Assert.IsNotNull (row, "#10");
+ Assert.AreEqual (3, row [1], "#11");
+ Assert.AreEqual (DataRowState.Unchanged, table.Rows.Find (1).RowState, "#12");
+ }
+
+ [Test]
public void EndLoadData_MergeDuplcateValues ()
{
DataTable table = new DataTable ();
@@ -430,6 +483,8 @@ namespace MonoTests_System.Data
table.Columns.Add ("col2", typeof (int));
table.PrimaryKey = new DataColumn[] {table.Columns [0]};
+ table.Rows.Add (new object[] {1, 500});
+ table.AcceptChanges ();
table.BeginLoadData ();
table.LoadDataRow (new object[] {1 , 1}, false);