Hello Suresh
There some things that looks unclear for me in the last patch... Can you explain the points below ?

Thanks,
Boris

suresh <[EMAIL PROTECTED]> wrote:

Author: suresh
Date: 2005-05-25 06:57:45 -0400 (Wed, 25 May 2005)
New Revision: 44988

Modified:
  trunk/mcs/class/System.Data/System.Data/ChangeLog
  trunk/mcs/class/System.Data/System.Data/DataRow.cs
  trunk/mcs/class/System.Data/System.Data/DataTable.cs
  trunk/mcs/class/System.Data/Test/System.Data/ChangeLog
  trunk/mcs/class/System.Data/Test/System.Data/DataTableLoadRowTest.cs
Log:
        * System.Data/DataTable.cs: Reworked DataTable.LoadDataRow method after
          regressions caused by Index redesign.
        * System.Data/DataRow.cs: Load : reworked.

        * Test/System.Data/DataTableLoadRowTest.cs: Added  additional cases for
          AutoIncrementTest to gauge any side effect with auto
          incrementing in case of upsert.



Modified: trunk/mcs/class/System.Data/System.Data/ChangeLog
===================================================================
--- trunk/mcs/class/System.Data/System.Data/ChangeLog   2005-05-25 09:55:24 UTC 
(rev 44987)
+++ trunk/mcs/class/System.Data/System.Data/ChangeLog   2005-05-25 10:57:45 UTC 
(rev 44988)
@@ -1,3 +1,9 @@
+2005-05-25  Sureshkumar T  <[EMAIL PROTECTED]>
+
+       * DataTable.cs: Reworked DataTable.LoadDataRow method after
+       regressions caused by Index redesign.
+       * DataRow.cs: Load : reworked.
+
2005-05-25 Konstantin Triger <[EMAIL PROTECTED]>

        * ISafeDataRecord.cs: Added GetDateTimeSafe method, the interface was 
made derived from IDataRecord

Modified: trunk/mcs/class/System.Data/System.Data/DataRow.cs
===================================================================
--- trunk/mcs/class/System.Data/System.Data/DataRow.cs  2005-05-25 09:55:24 UTC 
(rev 44987)
+++ trunk/mcs/class/System.Data/System.Data/DataRow.cs  2005-05-25 10:57:45 UTC 
(rev 44988)
@@ -590,14 +590,14 @@
                        _table.ChangingDataRow (this, DataRowAction.Commit);
                        CheckChildRows(DataRowAction.Commit);
                        switch (RowState) {
-                               case DataRowState.Unchanged:
+                        case DataRowState.Unchanged:
                                        return;
                        case DataRowState.Added:
                        case DataRowState.Modified:
-                                       if (Original >= 0) {
-                                               
Table.RecordCache.DisposeRecord(Original);
-                                       }
-                                       Original = Current;
+                                if (Original >= 0) {
+                                        
Table.RecordCache.DisposeRecord(Original);
+                                }
+                                Original = Current;
                                break;
                        case DataRowState.Deleted:
                                _table.Rows.RemoveInternal (this);
@@ -1566,57 +1566,65 @@
                ///    mentioned in the DataTable.Load (IDataReader, 
LoadOption) method.
                /// </summary>
                [MonoTODO ("Raise necessary Events")]
-                internal void Load (object [] values, LoadOption loadOption, 
bool is_new)
+                internal void Load (object [] values, LoadOption loadOption)
                {
+                        Index index = null;
                        DataRowAction action = DataRowAction.Change;

-                        int temp = Table.RecordCache.NewRecord ();
-                        for (int i = 0 ; i < Table.Columns.Count; i++)
-                                SetValue (i, values [i], temp);
+                        int temp = -1;

-                        if (is_new) { // new row
-                                if (HasVersion (DataRowVersion.Proposed) || 
RowState == DataRowState.Detached)
-                                        Proposed = temp;
-                                else
-                                        Current = temp;
-                                return;
-                        }
-
if (loadOption == LoadOption.OverwriteChanges || (loadOption == LoadOption.PreserveChanges
                                && RowState == DataRowState.Unchanged)) {
+                               temp = Table.CreateRecord (values);
+                                if (HasVersion (DataRowVersion.Original) && 
Current != Original)
+                                        Table.RecordCache.DisposeRecord 
(Original);
                                Original = temp;
-                                if (HasVersion (DataRowVersion.Proposed))
-                                        Proposed = temp;
-                                else
-                                        Current = 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;
Is there some special reason for first updating Original version, then updating an index, and then updating the Current version? Since index built on RowState.None, it uses Default (and not updated) value in index update.

                                action = DataRowAction.ChangeCurrentAndOriginal;
                                return;
                        }

                        if (loadOption == LoadOption.PreserveChanges) {
-                                if (RowState != DataRowState.Deleted) {
-                                        Original = temp;
-                                        action   = 
DataRowAction.ChangeOriginal;
-                                }
+                               if (RowState == DataRowState.Deleted)
+                                       return;
+                               temp = Table.CreateRecord (values);
+                               if (HasVersion (DataRowVersion.Original) && 
Current != Original)
+                                       Table.RecordCache.DisposeRecord 
(Original);
+                               Original = temp;
+                               action   = DataRowAction.ChangeOriginal;
                                return;
                        }
- bool not_used = true;
                        // Upsert
The following code runs also for loadOption other that Upset ( PreserveCurrentValues for example). Is this correct?

                        if (RowState != DataRowState.Deleted) {
-                                int index = HasVersion 
(DataRowVersion.Proposed) ? _proposed : _current;
-                                if (Table.CompareRecords (index, temp) != 0) {
-                                        if (HasVersion 
(DataRowVersion.Proposed))
-                                                Proposed = temp;
-                                        else
-                                                Current = temp;
-                                        not_used = false;
-                                }
+                                int rindex = HasVersion 
(DataRowVersion.Proposed) ? Proposed : Current;
+                               temp = Table.CreateRecord (values);
+                               if (Table.CompareRecords (rindex, temp) != 0) {
+                                        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;
+                                } else
+                                       Table.RecordCache.DisposeRecord (temp);
                        }
- - if (not_used)
-                                Table.RecordCache.DisposeRecord (temp);
+
                }
#endif // NET_2_0
        }

Modified: trunk/mcs/class/System.Data/System.Data/DataTable.cs
===================================================================
--- trunk/mcs/class/System.Data/System.Data/DataTable.cs        2005-05-25 
09:55:24 UTC (rev 44987)
+++ trunk/mcs/class/System.Data/System.Data/DataTable.cs        2005-05-25 
10:57:45 UTC (rev 44988)
@@ -1199,31 +1199,45 @@
                public DataRow LoadDataRow (object [] values, LoadOption 
loadOption)
                {
                        DataRow row  = null;
-                        bool new_row = false;
// Find Data DataRow
                        if (this.PrimaryKey.Length > 0) {
-                               int newRecord = CreateRecord(values);
-                               try {
-                                       Index index = 
GetIndex(PrimaryKey,null,DataViewRowState.OriginalRows,null,false);
-                                       int existingRecord = 
index.Find(newRecord);
+                                Index index = FindIndex 
(PrimaryKey,null,DataViewRowState.OriginalRows,null);
+                               if (index == null)
+                                       index = new Index (new Key(this, 
PrimaryKey,null,DataViewRowState.OriginalRows,null));
This index is used only for lookup - am I right?

+
+                               object [] keys = new object [PrimaryKey.Length];
+                               for (int i=0; i < PrimaryKey.Length; i++)
+                                       keys [i] = values [PrimaryKey 
[i].Ordinal];
This assignment will raise an exception if PrimaryKey[i].Ordinal exeeds values.Length. Should probably check for this and raise the corresponding exception (the row can not be added if not all the primary keya values exists and the missing PK columns are not autoincrement).

+
+                               int existingRecord = index.Find(keys);
+                               if (existingRecord >= 0)
+                                       row = RecordCache[existingRecord];
+ else { + existingRecord = _primaryKeyConstraint.Index.Find(keys);
                                        if (existingRecord >= 0)
                                                row = 
RecordCache[existingRecord];
-                                       else {
-                                               existingRecord = 
_primaryKeyConstraint.Index.Find(newRecord);
-                                               if (existingRecord >= 0)
-                                                       row = 
RecordCache[existingRecord];
-                                       }
                                }
-                               finally {
-                                       RecordCache.DisposeRecord(newRecord);
-                               }
                        }
// If not found, add new row
-                        if (row == null) {
-                                row = this.NewRow ();
-                                new_row = true;
+ if (row == null + || (row.RowState == DataRowState.Deleted
+                                && loadOption == LoadOption.Upsert)) {
According to MSDN Upsert should preserve an Original version. Are you shure Deleted row always misses an Originlal version? If no, it should be preserved.

+                                row = NewNotInitializedRow ();
+                                row.ImportRecord (CreateRecord(values));
+
+ if (EnforceConstraints) + // we have to check that the new row doesn't colide with existing row
+                                        Rows.ValidateDataRowInternal(row); // 
this adds to index ;-)
+ + Rows.AddInternal(row);
+       
+                                if (loadOption == LoadOption.OverwriteChanges 
||
+                                    loadOption == LoadOption.PreserveChanges) {
+                                        row.AcceptChanges ();
+                                }
+                                return row;
                        }

                        bool deleted = row.RowState == DataRowState.Deleted;
@@ -1231,21 +1245,8 @@
                        if (deleted && loadOption == 
LoadOption.OverwriteChanges)
row.RejectChanges ();
-                        row.Load (values, loadOption, new_row);
+                        row.Load (values, loadOption);

-                        if (deleted && loadOption == LoadOption.Upsert) {
-                                row = this.NewRow ();
-                                row.Load (values, loadOption, new_row = true);
-                        }
-
-                        if (new_row) {
-                                this.Rows.Add (row);
-                                if (loadOption == LoadOption.OverwriteChanges 
||
-                                    loadOption == LoadOption.PreserveChanges) {
-                                        row.AcceptChanges ();
-                                }
-                        }
-
                        return row;
                }


Modified: trunk/mcs/class/System.Data/Test/System.Data/ChangeLog
===================================================================
--- trunk/mcs/class/System.Data/Test/System.Data/ChangeLog      2005-05-25 
09:55:24 UTC (rev 44987)
+++ trunk/mcs/class/System.Data/Test/System.Data/ChangeLog      2005-05-25 
10:57:45 UTC (rev 44988)
@@ -1,3 +1,9 @@
+2005-05-25  Sureshkumar T  <[EMAIL PROTECTED]>
+
+       * DataTableLoadRowTest.cs: Added  additional cases for
+       AutoIncrementTest to gauge any side effect with auto
+       incrementing in case of upsert.
+
2005-05-20  Sureshkumar T  <[EMAIL PROTECTED]>

        * DataRowCollectionTest.cs: Added a test to check Rows.Add (values

Modified: trunk/mcs/class/System.Data/Test/System.Data/DataTableLoadRowTest.cs
===================================================================
--- trunk/mcs/class/System.Data/Test/System.Data/DataTableLoadRowTest.cs        
2005-05-25 09:55:24 UTC (rev 44987)
+++ trunk/mcs/class/System.Data/Test/System.Data/DataTableLoadRowTest.cs        
2005-05-25 10:57:45 UTC (rev 44988)
@@ -271,6 +271,16 @@
                        Assert.AreEqual (25, dt.Rows [3] [0], "#2 current should be 
ai");
                        Assert.AreEqual (25, dt.Rows [3] [0, DataRowVersion.Original], 
"#3 original should be ai");

+                       dt.LoadDataRow (new object [] {25, 20, "mono test"}, 
LoadOption.Upsert);
+                       dt.LoadDataRow (new object [] {25, 20, "mono test 2"}, 
LoadOption.Upsert);
+                       dt.LoadDataRow (new object [] {null, 20, "mono test 
aaa"}, LoadOption.Upsert);
+                       
+                       Assert.AreEqual (5, dt.Rows.Count, "#4 has not added a new 
row");
+                       Assert.AreEqual (25, dt.Rows [3] [0], "#5 current should be 
ai");
+                       Assert.AreEqual (25, dt.Rows [3] [0, DataRowVersion.Original], 
"#6 original should be ai");
+
+                       Assert.AreEqual (30, dt.Rows [4] [0], "#7 current should be 
ai");
+
                }
        }
}

_______________________________________________
Mono-patches maillist  -  Mono-patches@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-patches
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to