diff options
author | Senganal T <senga@mono-cvs.ximian.com> | 2006-04-21 12:11:46 +0400 |
---|---|---|
committer | Senganal T <senga@mono-cvs.ximian.com> | 2006-04-21 12:11:46 +0400 |
commit | ab0191bf4b042d8851daac129996ac18a340416b (patch) | |
tree | 33f8bf7c1ce79a0c1dbcaf661b28c7b99cb770b6 | |
parent | 6dcd3635ec1b1f1f5db852702b4817b59485d781 (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/ChangeLog | 21 | ||||
-rw-r--r-- | mcs/class/System.Data/System.Data/DataRowCollection.cs | 108 | ||||
-rw-r--r-- | mcs/class/System.Data/System.Data/DataTable.cs | 60 | ||||
-rw-r--r-- | mcs/class/System.Data/Test/System.Data/ChangeLog | 6 | ||||
-rw-r--r-- | mcs/class/System.Data/Test/System.Data/DataTableTest2.cs | 55 |
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); |