Merge pull request #1542 from ninjarobot/UriTemplateMatchException
[mono.git] / mcs / class / System.Data / System.Data.Common / DbDataAdapter.cs
index 7df8f5992d66b721104816f55f574abbb1028b4e..918da04f502013c941a25eccf00e34355621c468 100644 (file)
@@ -5,13 +5,14 @@
 //   Rodrigo Moya (rodrigo@ximian.com)
 //   Tim Coleman (tim@timcoleman.com)
 //   Sureshkumar T <tsureshkumar@novell.com>
+//   Veerapuram Varadhan  <vvaradhan@novell.com>
 //
 // (C) Ximian, Inc
 // Copyright (C) Tim Coleman, 2002-2003
 //
 
 //
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004, 2009 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -42,11 +43,7 @@ using System.Runtime.InteropServices;
 
 namespace System.Data.Common
 {
-#if NET_2_0
        public abstract class DbDataAdapter : DataAdapter, IDbDataAdapter, IDataAdapter, ICloneable
-#else
-       public abstract class DbDataAdapter : DataAdapter, ICloneable
-#endif
        {
                #region Fields
 
@@ -54,12 +51,10 @@ namespace System.Data.Common
                const string DefaultSourceColumnName = "Column";
                CommandBehavior _behavior = CommandBehavior.Default;
 
-#if NET_2_0
                IDbCommand _selectCommand;
                IDbCommand _updateCommand;
                IDbCommand _deleteCommand;
                IDbCommand _insertCommand;
-#endif
 
                #endregion // Fields
                
@@ -77,58 +72,89 @@ namespace System.Data.Common
 
                #region Properties
 
-#if NET_2_0
                protected internal CommandBehavior FillCommandBehavior {
                        get { return _behavior; }
                        set { _behavior = value; }
                }
 
                IDbCommand IDbDataAdapter.SelectCommand {
-                       get { return _selectCommand; }
-                       set { _selectCommand = value; }
+                   get { return ((DbDataAdapter)this).SelectCommand; }
+                   set { ((DbDataAdapter)this).SelectCommand = (DbCommand)value; }
                }
 
                IDbCommand IDbDataAdapter.UpdateCommand{
-                       get { return _updateCommand; }
-                       set { _updateCommand = value; }
+                   get { return ((DbDataAdapter)this).UpdateCommand; }
+                   set { ((DbDataAdapter)this).UpdateCommand = (DbCommand)value; }
                }
-
+               
                IDbCommand IDbDataAdapter.DeleteCommand{
-                       get { return _deleteCommand; }
-                       set { _deleteCommand = value; }
+                   get { return ((DbDataAdapter)this).DeleteCommand; }
+                   set { ((DbDataAdapter)this).DeleteCommand = (DbCommand)value; }
                }
 
                IDbCommand IDbDataAdapter.InsertCommand{
-                       get { return _insertCommand; }
-                       set { _insertCommand = value; }
+                   get { return ((DbDataAdapter)this).InsertCommand; }
+                   set { ((DbDataAdapter)this).InsertCommand = (DbCommand)value; }
                }
                
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public DbCommand SelectCommand {
-                       get { return (DbCommand) ((IDbDataAdapter) this).SelectCommand; }
-                       set { ((IDbDataAdapter) this).SelectCommand = value; }
+                   get {
+                                       return (DbCommand) _selectCommand;
+                                       //return (DbCommand) ((IDbDataAdapter)this).SelectCommand; 
+                       }
+                   set {
+                                       if (_selectCommand != value) {
+                                               _selectCommand = value;
+                                               ((IDbDataAdapter)this).SelectCommand = value; 
+                                       }
+                       }
                }
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public DbCommand DeleteCommand {
-                       get { return (DbCommand) ((IDbDataAdapter) this).DeleteCommand; }
-                       set { ((IDbDataAdapter) this).DeleteCommand = value; }
+                   get {
+                                       return (DbCommand) _deleteCommand;
+                                       //return (DbCommand) ((IDbDataAdapter)this).DeleteCommand; 
+                       }
+                   set {
+                                       if (_deleteCommand != value) {
+                                               _deleteCommand = value;
+                                               ((IDbDataAdapter)this).DeleteCommand = value; 
+                                       }
+                       }
                }
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public DbCommand InsertCommand {
-                       get { return (DbCommand) ((IDbDataAdapter) this).InsertCommand; }
-                       set { ((IDbDataAdapter) this).InsertCommand = value; }
+                   get {
+                                       return (DbCommand) _insertCommand;
+                                       //return (DbCommand) ((IDbDataAdapter)this).InsertCommand; 
+                       }
+                   set {
+                                       if (_insertCommand != value) {
+                                               _insertCommand = value;
+                                               ((IDbDataAdapter)this).InsertCommand = value; 
+                                       }
+                       }
                }
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public DbCommand UpdateCommand {
-                       get { return (DbCommand) ((IDbDataAdapter) this).UpdateCommand; }
-                       set { ((IDbDataAdapter) this).UpdateCommand = value; }
+                   get {
+                                       return (DbCommand) _updateCommand;
+                                       //return (DbCommand) ((IDbDataAdapter)this).DeleteCommand; 
+                       }
+                   set {
+                                       if (_updateCommand != value) {
+                                               _updateCommand = value;
+                                               ((IDbDataAdapter)this).UpdateCommand = value; 
+                                       }
+                       }
                }
 
                [DefaultValue (1)]
@@ -139,27 +165,11 @@ namespace System.Data.Common
                                        throw new NotSupportedException ();
                        }
                }
-#else
-               IDbCommand SelectCommand {
-                       get { return ((IDbDataAdapter) this).SelectCommand; }
-               }
-#endif
 
                #endregion // Properties
                
-               #region Events
-
-#if ONLY_1_0 || ONLY_1_1
-               [DataCategory ("Fill")]
-               [DataSysDescription ("Event triggered when a recoverable error occurs during Fill.")]
-               public event FillErrorEventHandler FillError;
-
-#endif
-               #endregion // Events
-
                #region Methods
 
-#if NET_2_0
                protected virtual RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command,
                                                                             StatementType statementType,
                                                                             DataTableMapping tableMapping)
@@ -195,18 +205,6 @@ namespace System.Data.Common
                                }
                        }
                }
-#else
-               protected abstract RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command,
-                                                                            StatementType statementType,
-                                                                            DataTableMapping tableMapping);
-
-               protected abstract RowUpdatingEventArgs CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command,
-                                                                              StatementType statementType,
-                                                                              DataTableMapping tableMapping);
-
-               protected abstract void OnRowUpdated (RowUpdatedEventArgs value);
-               protected abstract void OnRowUpdating (RowUpdatingEventArgs value);
-#endif
 
                protected override void Dispose (bool disposing)
                {
@@ -249,12 +247,6 @@ namespace System.Data.Common
                        return Fill (dataSet, 0, 0, srcTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
                }
 
-#if !NET_2_0
-               protected virtual int Fill (DataTable dataTable, IDataReader dataReader)
-               {
-                       return base.FillInternal (dataTable, dataReader);
-               }
-#endif
 
                protected virtual int Fill (DataTable dataTable, IDbCommand command, CommandBehavior behavior)
                {
@@ -273,7 +265,6 @@ namespace System.Data.Common
                        return this.Fill (dataSet, startRecord, maxRecords, srcTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
                }
 
-#if NET_2_0
                [MonoTODO]
                public int Fill (int startRecord, int maxRecords, params DataTable[] dataTables)
                {
@@ -285,12 +276,6 @@ namespace System.Data.Common
                {
                        throw new NotImplementedException ();
                }
-#else
-               protected virtual int Fill (DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords)
-               {
-                       return base.FillInternal (dataSet, srcTable, dataReader, startRecord, maxRecords);
-               }
-#endif
 
                protected virtual int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior)
                {
@@ -309,7 +294,6 @@ namespace System.Data.Common
                                startRecord, maxRecords);
                }
 
-#if NET_2_0
                /// <summary>
                /// Fills the given datatable using values from reader. if a value 
                /// for a column is  null, that will be filled with default value. 
@@ -378,7 +362,6 @@ namespace System.Data.Common
                        }
                        return counter;
                }
-#endif // NET_2_0
 
                public override DataTable [] FillSchema (DataSet dataSet, SchemaType schemaType)
                {
@@ -477,8 +460,9 @@ namespace System.Data.Common
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                public override IDataParameter[] GetFillParameters ()
                {
-                       IDataParameter[] parameters = new IDataParameter [SelectCommand.Parameters.Count];
-                       SelectCommand.Parameters.CopyTo (parameters, 0);
+                       IDbCommand selectCmd = ((IDbDataAdapter) this).SelectCommand;
+                       IDataParameter[] parameters = new IDataParameter [selectCmd.Parameters.Count];
+                       selectCmd.Parameters.CopyTo (parameters, 0);
                        return parameters;
                }
                
@@ -629,7 +613,7 @@ namespace System.Data.Common
                                }
 
                                RowUpdatingEventArgs argsUpdating = CreateRowUpdatingEvent (row, command, statementType, tableMapping);
-                               row.RowError = null;
+                               row.RowError = String.Empty;
                                OnRowUpdating (argsUpdating);
                                switch (argsUpdating.Status) {
                                case UpdateStatus.Continue :
@@ -654,28 +638,31 @@ namespace System.Data.Common
                                try {
                                        if (command != null) {
                                                DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
-                                               IDataParameter nullCheckParam = null;
                                                foreach (IDataParameter parameter in command.Parameters) {
-                                                       if ((parameter.Direction & ParameterDirection.Input) != 0) {
-                                                               string dsColumnName = parameter.SourceColumn;
-                                                               if (columnMappings.Contains(parameter.SourceColumn))
-                                                                       dsColumnName = columnMappings [parameter.SourceColumn].DataSetColumn;
-                                                               if (dsColumnName == null || dsColumnName.Length <= 0) {
-                                                                       nullCheckParam = parameter;
-                                                                       continue;
-                                                               }
+                                                       if ((parameter.Direction & ParameterDirection.Input) == 0)
+                                                               continue;
 
-                                                               DataRowVersion rowVersion = parameter.SourceVersion;
-                                                               // Parameter version is ignored for non-update commands
-                                                               if (statementType == StatementType.Delete) 
-                                                                       rowVersion = DataRowVersion.Original;
+                                                       DataRowVersion rowVersion = parameter.SourceVersion;
+                                                       // Parameter version is ignored for non-update commands
+                                                       if (statementType == StatementType.Delete)
+                                                               rowVersion = DataRowVersion.Original;
 
+                                                       string dsColumnName = parameter.SourceColumn;
+                                                       if (columnMappings.Contains(dsColumnName)) {
+                                                               dsColumnName = columnMappings [dsColumnName].DataSetColumn;
                                                                parameter.Value = row [dsColumnName, rowVersion];
-                                                               if (nullCheckParam != null && (parameter.Value != null
-                                                                       && parameter.Value != DBNull.Value)) {
+                                                       } else {
+                                                               parameter.Value = null;
+                                                       }
+
+                                                       DbParameter nullCheckParam = parameter as DbParameter;
+
+                                                       if (nullCheckParam != null && nullCheckParam.SourceColumnNullMapping) {
+                                                               if (parameter.Value != null && parameter.Value != DBNull.Value)
                                                                        nullCheckParam.Value = 0;
-                                                                       nullCheckParam = null;
-                                                               }
+                                                               else
+                                                                       nullCheckParam.Value = 1;
+                                                               nullCheckParam = null;
                                                        }
                                                }
                                        }
@@ -737,7 +724,8 @@ namespace System.Data.Common
                                        // if the execute does not effect any rows we throw an exception.
                                        if (tmp == 0)
                                                throw new DBConcurrencyException("Concurrency violation: the " + 
-                                                       commandName +"Command affected 0 records.");
+                                                       commandName +"Command affected 0 records.", null,
+                                                       new DataRow [] { row });
                                        updateCount += tmp;
 
                                        if (command.UpdatedRowSource == UpdateRowSource.Both ||
@@ -785,10 +773,8 @@ namespace System.Data.Common
                                        case UpdateStatus.SkipAllRemainingRows:
                                                return updateCount;
                                        }
-#if NET_2_0
                                        if (!AcceptChangesDuringUpdate)
                                                continue;
-#endif
                                        row.AcceptChanges ();
                                } catch (Exception e) {
                                        row.RowError = e.Message;
@@ -815,10 +801,31 @@ namespace System.Data.Common
                        if (dataTable == null)
                                throw new ArgumentException (String.Format ("Missing table {0}",
                                                                            srcTable));
+
+                       /** Copied from another Update function **/
+                       if (tableMapping != null) {
+                               foreach (DataColumn col in dataTable.Columns) {
+                                       if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
+                                               continue;
+                                       DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
+                                       if (columnMapping == null)
+                                               columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
+                                       tableMapping.ColumnMappings.Add (columnMapping);
+                               }
+                       } else {
+                               ArrayList cmc = new ArrayList ();
+                               foreach (DataColumn col in dataTable.Columns)
+                                       cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
+                               tableMapping =
+                                       new DataTableMapping (
+                                                             dataTable.TableName,
+                                                             dataTable.TableName,
+                                                             cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
+                       }
+                       /**end insert from another update**/
                        return Update (dataTable, tableMapping);
                }
 
-#if NET_2_0
                // All the batch methods, should be implemented, if supported,
                // by individual providers
 
@@ -863,18 +870,6 @@ namespace System.Data.Common
                {
                        return new NotSupportedException ("Method is not supported.");
                }
-#else
-               internal override void OnFillErrorInternal (FillErrorEventArgs value)
-               {
-                       OnFillError (value);
-               }
-
-               protected virtual void OnFillError (FillErrorEventArgs value)
-               {
-                       if (FillError != null)
-                               FillError (this, value);
-               }
-#endif
                #endregion // Methods
        }
 }