merging the Mainsoft branch to the trunk
[mono.git] / mcs / class / System.Data / System.Data / DataTable.cs
index c4563dfbb4bb07146797988576384b76bb8091c0..05bf1e9eda3b0e9e501fca09363f5890157776af 100644 (file)
@@ -8,6 +8,7 @@
 //   Rodrigo Moya <rodrigo@ximian.com>\r
 //   Tim Coleman (tim@timcoleman.com)\r
 //   Ville Palo <vi64pa@koti.soon.fi>\r
+//   Sureshkumar T <tsureshkumar@novell.com>\r
 //   Konstantin Triger <kostat@mainsoft.com>\r
 //\r
 // (C) Chris Podurgiel\r
@@ -712,6 +713,10 @@ namespace System.Data {
                public void Clear () {\r
                         // Foriegn key constraints are checked in _rows.Clear method\r
                        _rows.Clear ();\r
+#if NET_2_0\r
+                        OnTableCleared (new DataTableClearEventArgs (this));\r
+#endif // NET_2_0\r
+\r
                }\r
 \r
                /// <summary>\r
@@ -991,23 +996,28 @@ namespace System.Data {
                public void ImportRow (DataRow row) \r
                {\r
                        DataRow newRow = NewNotInitializedRow();\r
-                       \r
+\r
+                       int original = -1;\r
                        if (row.HasVersion(DataRowVersion.Original)) {\r
-                               if (!newRow.HasVersion(DataRowVersion.Original)) {\r
-                                       newRow.Original = RecordCache.NewRecord();\r
-                               }                               \r
-                               int original = row.IndexFromVersion(DataRowVersion.Original);\r
+                               original = row.IndexFromVersion(DataRowVersion.Original);\r
+                               newRow.Original = RecordCache.NewRecord();\r
                                RecordCache.CopyRecord(row.Table,original,newRow.Original);\r
                        }\r
 \r
                        if (row.HasVersion(DataRowVersion.Current)) {\r
-                               if (!newRow.HasVersion(DataRowVersion.Current)) {\r
-                                       newRow.Current = RecordCache.NewRecord();\r
-                               }                               \r
                                int current = row.IndexFromVersion(DataRowVersion.Current);\r
-                               RecordCache.CopyRecord(row.Table,current,newRow.Current);\r
+                               if (current == original)\r
+                                       newRow.Current = newRow.Original;\r
+                               else {\r
+                                       newRow.Current = RecordCache.NewRecord();\r
+                                       RecordCache.CopyRecord(row.Table,current,newRow.Current);\r
+                               }\r
                        }\r
 \r
+                       if (EnforceConstraints)\r
+                               // we have to check that the new row doesn't colide with existing row\r
+                               Rows.ValidateDataRowInternal(newRow);\r
+\r
                        Rows.AddInternal(newRow);               \r
        \r
                        if (row.HasErrors) {\r
@@ -1052,17 +1062,40 @@ namespace System.Data {
                }\r
 \r
 #if NET_2_0\r
-               [MonoTODO]\r
+                /// <summary>\r
+                ///     Loads the table with the values from the reader\r
+                /// </summary>\r
                public void Load (IDataReader reader)\r
                {\r
-                       throw new NotImplementedException ();\r
+                        Load (reader, LoadOption.PreserveChanges);\r
                }\r
 \r
-               [MonoTODO]\r
+                /// <summary>\r
+                ///     Loads the table with the values from the reader and the pattern\r
+                ///     of the changes to the existing rows or the new rows are based on\r
+                ///     the LoadOption passed.\r
+                /// </summary>\r
                public void Load (IDataReader reader, LoadOption loadOption)\r
                {\r
-                       throw new NotImplementedException ();\r
-               }\r
+                        bool prevEnforceConstr = this.EnforceConstraints;\r
+                        try {\r
+                                this.EnforceConstraints = false;\r
+                                int [] mapping = DbDataAdapter.BuildSchema (reader, this, SchemaType.Mapped, \r
+                                                                            MissingSchemaAction.AddWithKey,\r
+                                                                            MissingMappingAction.Passthrough, \r
+                                                                            new DataTableMappingCollection ());\r
+                                DbDataAdapter.FillFromReader (this,\r
+                                                              reader,\r
+                                                              0, // start from\r
+                                                              0, // all records\r
+                                                              mapping,\r
+                                                              loadOption);\r
+                        } finally {\r
+                                this.EnforceConstraints = prevEnforceConstr;\r
+                        }\r
+               }\r
+\r
+                \r
 #endif\r
 \r
                /// <summary>\r
@@ -1154,10 +1187,57 @@ namespace System.Data {
                }\r
 \r
 #if NET_2_0\r
-               [MonoTODO]\r
-               public DataRow LoadDataRow (object[] values, LoadOption loadOption)\r
-               {\r
-                       throw new NotImplementedException ();\r
+                /// <summary>\r
+                ///     Loads the given values into an existing row if matches or creates\r
+                ///     the new row popluated with the values.\r
+                /// </summary>\r
+                /// <remarks>\r
+                ///     This method searches for the values using primary keys and it first\r
+                ///     searches using the original values of the rows and if not found, it\r
+                ///     searches using the current version of the row.\r
+                /// </remarks>\r
+               public DataRow LoadDataRow (object [] values, LoadOption loadOption)\r
+               {\r
+                        DataRow row  = null;\r
+                        bool new_row = false;\r
+                        \r
+                        // Find Data DataRow\r
+                        if (this.PrimaryKey.Length > 0) {\r
+                                object [] keyValues = new object [this.PrimaryKey.Length];\r
+                                for (int i = 0; i < keyValues.Length; i++)\r
+                                        keyValues [i] = values [this.PrimaryKey [i].Ordinal];\r
+                                row = this.Rows.Find (keyValues, DataRowVersion.Original );\r
+                                if (row == null) \r
+                                        row = this.Rows.Find (keyValues, DataRowVersion.Current);\r
+                        }\r
+                                \r
+                        // If not found, add new row\r
+                        if (row == null) {\r
+                                row = this.NewRow ();\r
+                                new_row = true;\r
+                        }\r
+\r
+                        bool deleted = row.RowState == DataRowState.Deleted;\r
+\r
+                        if (deleted && loadOption == LoadOption.OverwriteChanges)\r
+                                row.RejectChanges ();                        \r
+\r
+                        row.Load (values, loadOption, new_row);\r
+\r
+                        if (deleted && loadOption == LoadOption.Upsert) {\r
+                                row = this.NewRow ();\r
+                                row.Load (values, loadOption, new_row = true);\r
+                        }\r
+\r
+                        if (new_row) {\r
+                                this.Rows.Add (row);\r
+                                if (loadOption == LoadOption.OverwriteChanges ||\r
+                                    loadOption == LoadOption.PreserveChanges) {\r
+                                        row.AcceptChanges ();\r
+                                }\r
+                        }\r
+\r
+                        return row;\r
                }\r
 \r
                [MonoTODO]\r
@@ -1626,6 +1706,16 @@ namespace System.Data {
                        OnColumnChanged(e);\r
                }\r
 \r
+#if NET_2_0\r
+                /// <summary>\r
+               /// Raises TableCleared Event and delegates to subscribers\r
+               /// </summary>\r
+               protected virtual void OnTableCleared (DataTableClearEventArgs e) {\r
+                       if (TableCleared != null)\r
+                               TableCleared (this, e);\r
+               }\r
+#endif // NET_2_0\r
+\r
                /// <summary>\r
                /// Raises the ColumnChanging event.\r
                /// </summary>\r
@@ -1738,7 +1828,16 @@ namespace System.Data {
                [DataCategory ("Data")] \r
                [DataSysDescription ("Occurs when a row in the table marked for deletion. Throw an exception to cancel the deletion.")]\r
                public event DataRowChangeEventHandler RowDeleting;\r
-               \r
+\r
+#if NET_2_0\r
+               /// <summary>\r
+               /// Occurs after the Clear method is called on the datatable.\r
+               /// </summary>\r
+               [DataCategory ("Data")] \r
+               [DataSysDescription ("Occurs when the rows in a table is cleared . Throw an exception to cancel the deletion.")]\r
+               public event DataTableClearEventHandler TableCleared;\r
+#endif // NET_2_0\r
+\r
                #endregion // Events\r
 \r
                /// <summary>\r