Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / System.Data / System.Data.Common / DataAdapter.cs
1 //
2 // System.Data.Common.DataAdapter
3 //
4 // Author:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Tim Coleman (tim@timcoleman.com)
7 //
8 // (C) Ximian, Inc
9 // Copyright (C) Tim Coleman, 2002-2003
10 //
11
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.Data;
37 using System.Collections;
38 using System.ComponentModel;
39
40 namespace System.Data.Common
41 {
42         /// <summary>
43         /// Represents a set of data commands and a database connection that are used to fill the DataSet and update the data source.
44         /// </summary>
45         public
46 #if ONLY_1_1
47         abstract
48 #endif
49         class DataAdapter : Component, IDataAdapter
50         {
51                 #region Fields
52
53                 private bool acceptChangesDuringFill;
54                 private bool continueUpdateOnError;
55                 private MissingMappingAction missingMappingAction;
56                 private MissingSchemaAction missingSchemaAction;
57                 private DataTableMappingCollection tableMappings;
58                 private const string DefaultSourceTableName = "Table";
59                 private const string DefaultSourceColumnName = "Column";
60
61 #if NET_2_0
62                 private bool acceptChangesDuringUpdate;
63                 private LoadOption fillLoadOption;
64                 private bool returnProviderSpecificTypes;
65 #endif
66                 #endregion
67
68                 #region Constructors
69
70                 protected DataAdapter () 
71                 {
72                         acceptChangesDuringFill = true;
73                         continueUpdateOnError = false;
74                         missingMappingAction = MissingMappingAction.Passthrough;
75                         missingSchemaAction = MissingSchemaAction.Add;
76                         tableMappings = new DataTableMappingCollection ();
77 #if NET_2_0
78                         acceptChangesDuringUpdate = true;
79                         fillLoadOption = LoadOption.OverwriteChanges;
80                         returnProviderSpecificTypes = false;
81 #endif 
82                 }
83
84                 protected DataAdapter (DataAdapter from)
85                 {
86                         AcceptChangesDuringFill = from.AcceptChangesDuringFill;
87                         ContinueUpdateOnError = from.ContinueUpdateOnError;
88                         MissingMappingAction = from.MissingMappingAction;
89                         MissingSchemaAction = from.MissingSchemaAction;
90
91                         if (from.tableMappings != null)
92                                 foreach (ICloneable cloneable in from.TableMappings)
93                                         TableMappings.Add (cloneable.Clone ());
94 #if NET_2_0
95                         acceptChangesDuringUpdate = from.AcceptChangesDuringUpdate;
96                         fillLoadOption = from.FillLoadOption;
97                         returnProviderSpecificTypes = from.ReturnProviderSpecificTypes;
98 #endif 
99                 }
100
101                 #endregion
102
103                 #region Properties
104
105                 [DataCategory ("Fill")]
106 #if !NET_2_0
107                 [DataSysDescription ("Whether or not Fill will call DataRow.AcceptChanges.")]
108 #endif
109                 [DefaultValue (true)]
110                 public bool AcceptChangesDuringFill {
111                         get { return acceptChangesDuringFill; }
112                         set { acceptChangesDuringFill = value; }
113                 }
114
115 #if NET_2_0
116                 [DefaultValue (true)]
117                 public bool AcceptChangesDuringUpdate {
118                         get { return acceptChangesDuringUpdate; }
119                         set { acceptChangesDuringUpdate = value; }
120                 }
121 #endif
122
123                 [DataCategory ("Update")]
124 #if !NET_2_0
125                 [DataSysDescription ("Whether or not to continue to the next DataRow when the Update events, RowUpdating and RowUpdated, Status is UpdateStatus.ErrorsOccurred.")]
126 #endif
127                 [DefaultValue (false)]
128                 public bool ContinueUpdateOnError {
129                         get { return continueUpdateOnError; }
130                         set { continueUpdateOnError = value; }
131                 }
132
133 #if NET_2_0
134                 [RefreshProperties (RefreshProperties.All)]
135                 public LoadOption FillLoadOption {
136                         get { return fillLoadOption; }
137                         set {
138                                 ExceptionHelper.CheckEnumValue (typeof (LoadOption), value);
139                                 fillLoadOption = value;
140                 }
141                 }
142 #endif
143
144                 ITableMappingCollection IDataAdapter.TableMappings {
145                         get { return TableMappings; }
146                 }
147
148                 [DataCategory ("Mapping")]
149 #if !NET_2_0
150                 [DataSysDescription ("The action taken when a table or column in the TableMappings is missing.")]
151 #endif
152                 [DefaultValue (MissingMappingAction.Passthrough)]
153                 public MissingMappingAction MissingMappingAction {
154                         get { return missingMappingAction; }
155                         set {
156                                 ExceptionHelper.CheckEnumValue (typeof (MissingMappingAction), value);
157                                 missingMappingAction = value;
158                         }
159                 }
160
161                 [DataCategory ("Mapping")]
162 #if !NET_2_0
163                 [DataSysDescription ("The action taken when a table or column in the DataSet is missing.")]
164 #endif
165                 [DefaultValue (MissingSchemaAction.Add)]
166                 public MissingSchemaAction MissingSchemaAction {
167                         get { return missingSchemaAction; }
168                         set {
169                                 ExceptionHelper.CheckEnumValue (typeof (MissingSchemaAction), value);
170                                 missingSchemaAction = value; 
171                         }
172                 }
173
174 #if NET_2_0
175                 [DefaultValue (false)]
176                 public virtual bool ReturnProviderSpecificTypes {
177                         get { return returnProviderSpecificTypes; }
178                         set { returnProviderSpecificTypes = value; }
179                 }
180 #endif
181
182                 [DataCategory ("Mapping")]
183 #if !NET_2_0
184                 [DataSysDescription ("How to map source table to DataSet table.")]
185 #endif
186                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
187                 public DataTableMappingCollection TableMappings {
188                         get { return tableMappings; }
189                 }
190
191                 #endregion
192
193                 #region Events
194
195 #if NET_2_0
196                 public event FillErrorEventHandler FillError;
197 #endif
198
199                 #endregion
200
201                 #region Methods
202
203                 [Obsolete ("Use the protected constructor instead")]
204                 [MonoTODO]
205                 protected virtual DataAdapter CloneInternals ()
206                 {
207                         throw new NotImplementedException ();
208                 }
209
210                 protected virtual DataTableMappingCollection CreateTableMappings ()
211                 {
212                         return new DataTableMappingCollection ();
213                 }
214
215                 [MonoTODO]
216                 protected override void Dispose (bool disposing)
217                 {
218                         throw new NotImplementedException ();
219                 }
220
221                 protected virtual bool ShouldSerializeTableMappings ()
222                 {
223                         return true;
224                 }
225
226
227                 internal int FillInternal (DataTable dataTable, IDataReader dataReader)
228                 {
229                         if (dataReader.FieldCount == 0) {
230                                 dataReader.Close ();
231                                 return 0;
232                         }
233                         
234                         int count = 0;
235
236                         try {
237                                 string tableName = SetupSchema (SchemaType.Mapped, dataTable.TableName);
238                                 if (tableName != null) {
239                                         dataTable.TableName = tableName;
240                                         FillTable (dataTable, dataReader, 0, 0, ref count);
241                                 }
242                         } finally {
243                                 dataReader.Close ();
244                         }
245
246                         return count;
247                 }
248
249                 // this method builds the schema for a given datatable. it returns a int array with 
250                 // "array[ordinal of datatable column] == index of source column in data reader".
251                 // each column in the datatable has a mapping to a specific column in the datareader,
252                 // the int array represents this match.
253                 internal int[] BuildSchema (IDataReader reader, DataTable table, SchemaType schemaType)
254                 {
255                         return BuildSchema (reader, table, schemaType, MissingSchemaAction,
256                                             MissingMappingAction, TableMappings);
257                 }
258
259                 /// <summary>
260                 ///     Creates or Modifies the schema of the given DataTable based on the schema of
261                 ///     the reader and the arguments passed.
262                 /// </summary>
263                 internal static int[] BuildSchema (IDataReader reader, DataTable table,
264                                                    SchemaType schemaType,
265                                                    MissingSchemaAction missingSchAction,
266                                                    MissingMappingAction missingMapAction,
267                                                    DataTableMappingCollection dtMapping
268                                                    )
269                 {
270                         int readerIndex = 0;
271                         // FIXME : this fails if query has fewer columns than a table
272                         int[] mapping = new int[table.Columns.Count]; // mapping the reader indexes to the datatable indexes
273                         
274                         for(int i=0; i < mapping.Length; i++) {
275                                 mapping[i] = -1;
276                         }
277                         
278                         ArrayList primaryKey = new ArrayList ();
279                         ArrayList sourceColumns = new ArrayList ();
280                         bool createPrimaryKey = true;
281                         
282                         DataTable schemaTable = reader.GetSchemaTable ();
283
284                         DataColumn ColumnNameCol =  schemaTable.Columns["ColumnName"];
285                         DataColumn DataTypeCol = schemaTable.Columns["DataType"];
286                         DataColumn IsAutoIncrementCol = schemaTable.Columns["IsAutoIncrement"];
287                         DataColumn AllowDBNullCol = schemaTable.Columns["AllowDBNull"];
288                         DataColumn IsReadOnlyCol = schemaTable.Columns["IsReadOnly"];
289                         DataColumn IsKeyCol = schemaTable.Columns["IsKey"];
290                         DataColumn IsUniqueCol = schemaTable.Columns["IsUnique"];
291                         DataColumn ColumnSizeCol = schemaTable.Columns["ColumnSize"];
292
293                         foreach (DataRow schemaRow in schemaTable.Rows) {
294                                 // generate a unique column name in the source table.
295                                 string sourceColumnName;
296                                 string realSourceColumnName ;
297                                 if (ColumnNameCol == null || schemaRow.IsNull(ColumnNameCol) ||
298                                     (string)schemaRow [ColumnNameCol] == String.Empty) {
299                                         sourceColumnName = DefaultSourceColumnName;
300                                         realSourceColumnName = DefaultSourceColumnName + "1";
301                                 } else {
302                                         sourceColumnName = (string) schemaRow [ColumnNameCol];
303                                         realSourceColumnName = sourceColumnName;
304                                 }
305
306                                 for (int i = 1; sourceColumns.Contains (realSourceColumnName); i += 1)
307                                         realSourceColumnName = String.Format ("{0}{1}", sourceColumnName, i);
308                                 sourceColumns.Add(realSourceColumnName);
309
310                                 // generate DataSetColumnName from DataTableMapping, if any
311                                 DataTableMapping tableMapping = null;
312
313                                 //FIXME : The sourcetable name shud get passed as a parameter.. 
314                                 int index = dtMapping.IndexOfDataSetTable (table.TableName);
315                                 string srcTable = (index != -1 ? dtMapping[index].SourceTable : table.TableName);
316                                 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (dtMapping, srcTable, table.TableName, missingMapAction); 
317                                 if (tableMapping != null) {
318                                         table.TableName = tableMapping.DataSetTable;
319                                         // check to see if the column mapping exists
320                                         DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction(tableMapping.ColumnMappings, realSourceColumnName, missingMapAction);
321                                         if (columnMapping != null) {
322                                                 Type columnType = schemaRow[DataTypeCol] as Type;
323                                                 DataColumn col = columnType != null ? columnMapping.GetDataColumnBySchemaAction(
324                                                                                                                                 table ,
325                                                                                                                                 columnType,
326                                                                                                                                 missingSchAction) : null;
327
328                                                 if (col != null) {
329                                                         // if the column is not in the table - add it.
330                                                         if (table.Columns.IndexOf(col) == -1) {
331                                                                 if (missingSchAction == MissingSchemaAction.Add 
332                                                                     || missingSchAction == MissingSchemaAction.AddWithKey)
333                                                                         table.Columns.Add(col);
334
335                                                                 int[] tmp = new int[mapping.Length + 1];
336                                                                 Array.Copy(mapping,0,tmp,0,col.Ordinal);
337                                                                 Array.Copy(mapping,col.Ordinal,tmp,col.Ordinal + 1,mapping.Length - col.Ordinal);
338                                                                 mapping = tmp;
339                                                         }
340
341                                                         if (missingSchAction == MissingSchemaAction.AddWithKey) {
342                                                                 object value = (AllowDBNullCol != null) ? schemaRow[AllowDBNullCol] : null;
343                                                                 bool allowDBNull = value is bool ? (bool)value : true;
344
345                                                                 value = (IsKeyCol != null) ? schemaRow[IsKeyCol] : null;
346                                                                 bool isKey = value is bool ? (bool)value : false;
347
348                                                                 value = (IsAutoIncrementCol != null) ? schemaRow[IsAutoIncrementCol] : null;
349                                                                 bool isAutoIncrement = value is bool ? (bool)value : false;
350
351                                                                 value = (IsReadOnlyCol != null) ? schemaRow[IsReadOnlyCol] : null;
352                                                                 bool isReadOnly = value is bool ? (bool)value : false;
353
354                                                                 value = (IsUniqueCol != null) ? schemaRow[IsUniqueCol] : null;
355                                                                 bool isUnique = value is bool ? (bool)value : false;
356                                                                 
357                                                                 col.AllowDBNull = allowDBNull;
358                                                                 // fill woth key info
359                                                                 if (isAutoIncrement && DataColumn.CanAutoIncrement(columnType)) {
360                                                                         col.AutoIncrement = true;
361                                                                         if (!allowDBNull)
362                                                                                 col.AllowDBNull = false;
363                                                                 }
364
365                                                                 if (columnType == DbTypes.TypeOfString) {
366                                                                         col.MaxLength = (ColumnSizeCol != null) ? (int)schemaRow[ColumnSizeCol] : 0;
367                                                                 }
368
369                                                                 if (isReadOnly)
370                                                                         col.ReadOnly = true;
371                                                                         
372                                                                 if (!allowDBNull && (!isReadOnly || isKey))
373                                                                         col.AllowDBNull = false;
374                                                                 if (isUnique && !isKey && !columnType.IsArray) {
375                                                                         col.Unique = true;
376                                                                         if (!allowDBNull)
377                                                                                 col.AllowDBNull = false;
378                                                                 }
379                                                                 
380                                                                 // This might not be set by all DataProviders
381                                                                 bool isHidden = false;
382                                                                 if (schemaTable.Columns.Contains ("IsHidden")) {
383                                                                         value = schemaRow["IsHidden"];
384                                                                         isHidden = ((value is bool) ? (bool)value : false);
385                                                                 }
386
387                                                                 if (isKey && !isHidden) {
388                                                                         primaryKey.Add (col);
389                                                                         if (allowDBNull)
390                                                                                 createPrimaryKey = false;
391                                                                 }
392                                                         }
393                                                         // add the ordinal of the column as a key and the index of the column in the datareader as a value.
394                                                         mapping[col.Ordinal] = readerIndex++;
395                                                 }
396                                         }
397                                 }
398                         }
399                         if (primaryKey.Count > 0) {
400                                 DataColumn[] colKey = (DataColumn[])(primaryKey.ToArray(typeof (DataColumn)));
401                                 if (createPrimaryKey)
402                                         table.PrimaryKey = colKey;
403                                 else {
404                                         UniqueConstraint uConstraint = new UniqueConstraint(colKey);
405                                         for (int i = 0; i < table.Constraints.Count; i++) {
406                                                 if (table.Constraints[i].Equals(uConstraint)) {
407                                                         uConstraint = null;
408                                                         break;
409                                                 }
410                                         }
411
412                                         if (uConstraint != null)
413                                                 table.Constraints.Add(uConstraint);
414                                 }
415                         }
416                         return mapping;
417                 }
418
419                 internal bool FillTable (DataTable dataTable, IDataReader dataReader, int startRecord, int maxRecords, ref int counter)
420                 {
421                         if (dataReader.FieldCount == 0)
422                                 return false;
423
424                         int counterStart = counter;
425
426                         int[] mapping = BuildSchema (dataReader, dataTable, SchemaType.Mapped);
427                         
428                         int [] sortedMapping = new int [mapping.Length];
429                         int length = sortedMapping.Length;
430                         for (int i = 0; i < sortedMapping.Length; i++) {
431                                 if (mapping [i] >= 0)
432                                         sortedMapping [mapping [i]] = i;
433                                 else
434                                         sortedMapping [--length] = i;
435                         }
436
437                         for (int i = 0; i < startRecord; i++) {
438                                 dataReader.Read ();
439                         }
440
441                         dataTable.BeginLoadData ();
442                         while (dataReader.Read () && (maxRecords == 0 || (counter - counterStart) < maxRecords)) {
443                                 try {
444                                         dataTable.LoadDataRow (dataReader, sortedMapping, length, AcceptChangesDuringFill);
445                                         counter++;
446                                 }
447                                 catch (Exception e) {
448                                         object[] readerArray = new object [dataReader.FieldCount];
449                                         object[] tableArray = new object [mapping.Length];
450                                         // we get the values from the datareader
451                                         dataReader.GetValues (readerArray);
452                                         // copy from datareader columns to table columns according to given mapping
453                                         for (int i = 0; i < mapping.Length; i++) {
454                                                 if (mapping [i] >= 0) {
455                                                         tableArray [i] = readerArray [mapping [i]];
456                                                 }
457                                         }
458                                         FillErrorEventArgs args = CreateFillErrorEvent (dataTable, tableArray, e);
459                                         OnFillErrorInternal (args);
460
461                                         // if args.Continue is not set to true or if a handler is not set, rethrow the error..
462                                         if(!args.Continue)
463                                                 throw e;
464                                 }
465                         }
466                         dataTable.EndLoadData ();
467                         return true;
468                 }
469
470                 internal virtual void OnFillErrorInternal (FillErrorEventArgs value)
471                 {
472 #if NET_2_0
473                         OnFillError (value);
474 #endif
475                 }
476
477                 internal FillErrorEventArgs CreateFillErrorEvent (DataTable dataTable, object[] values, Exception e)
478                 {
479                         FillErrorEventArgs args = new FillErrorEventArgs (dataTable, values);
480                         args.Errors = e;
481                         args.Continue = false;
482                         return args;
483                 }
484
485                 internal string SetupSchema (SchemaType schemaType, string sourceTableName)
486                 {
487                         DataTableMapping tableMapping = null;
488
489                         if (schemaType == SchemaType.Mapped) {
490                                 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (TableMappings, sourceTableName, sourceTableName, MissingMappingAction);
491                                 if (tableMapping != null)
492                                         return tableMapping.DataSetTable;
493                                 return null;
494                         } else
495                                 return sourceTableName;
496                 }
497
498                 internal int FillInternal (DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords)
499                 {
500                         if (dataSet == null)
501                                 throw new ArgumentNullException ("DataSet");
502
503                         if (startRecord < 0)
504                                 throw new ArgumentException ("The startRecord parameter was less than 0.");
505                         if (maxRecords < 0)
506                                 throw new ArgumentException ("The maxRecords parameter was less than 0.");
507
508                         DataTable dataTable = null;
509                         int resultIndex = 0;
510                         int count = 0;
511                         
512                         try {
513                                 string tableName = srcTable;
514                                 do {
515                                         // Non-resultset queries like insert, delete or update aren't processed.
516                                         if (dataReader.FieldCount != -1) {
517                                                 tableName = SetupSchema (SchemaType.Mapped, tableName);
518                                                 if (tableName != null) {
519                                                         
520                                                         // check if the table exists in the dataset
521                                                         if (dataSet.Tables.Contains (tableName))
522                                                                 // get the table from the dataset
523                                                                 dataTable = dataSet.Tables [tableName];
524                                                         else {
525                                                                 // Do not create schema if MissingSchemAction is set to Ignore
526                                                                 if (this.MissingSchemaAction == MissingSchemaAction.Ignore)
527                                                                         continue;
528                                                                 dataTable = dataSet.Tables.Add (tableName);
529                                                         }
530         
531                                                         if (!FillTable (dataTable, dataReader, startRecord, maxRecords, ref count))
532                                                                 continue;
533         
534                                                         tableName = String.Format ("{0}{1}", srcTable, ++resultIndex);
535         
536                                                         startRecord = 0;
537                                                         maxRecords = 0;
538                                                 }
539                                         }
540                                 } while (dataReader.NextResult ());
541                         } finally {
542                                 dataReader.Close ();
543                         }
544
545                         return count;
546                 }
547
548 #if NET_2_0
549                 public virtual int Fill (DataSet dataSet)
550                 {
551                         throw new NotSupportedException();
552                 }
553
554                 protected virtual int Fill (DataTable dataTable, IDataReader dataReader)
555                 {
556                         return FillInternal (dataTable, dataReader);
557                 }
558
559                 protected virtual int Fill (DataTable[] dataTables, IDataReader dataReader, int startRecord, int maxRecords)
560                 {
561                         int count = 0;
562                         if (dataReader.IsClosed)
563                                 return 0;
564
565                         if (startRecord < 0)
566                                 throw new ArgumentException ("The startRecord parameter was less than 0.");
567                         if (maxRecords < 0)
568                                 throw new ArgumentException ("The maxRecords parameter was less than 0.");
569
570                         try {
571                                 foreach (DataTable dataTable in dataTables) {
572                                         string tableName = SetupSchema (SchemaType.Mapped, dataTable.TableName);
573                                         if (tableName != null) {
574                                                 dataTable.TableName = tableName;
575                                                 FillTable (dataTable, dataReader, 0, 0, ref count);
576                                         }
577                                 }
578                         } finally {
579                                 dataReader.Close ();
580                         }
581
582                         return count;
583                 }
584
585                 protected virtual int Fill (DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords)
586                 {
587                         return FillInternal (dataSet, srcTable, dataReader, startRecord, maxRecords);
588                 }
589
590                 [MonoTODO]
591                 protected virtual DataTable FillSchema (DataTable dataTable, SchemaType schemaType, IDataReader dataReader)
592                 {
593                         throw new NotImplementedException ();
594                 }
595
596                 [MonoTODO]
597                 protected virtual DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType, string srcTable, IDataReader dataReader)
598                 {
599                         throw new NotImplementedException ();
600                 }
601
602                 public virtual DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType)
603                 {
604                         throw new NotSupportedException ();
605                 }
606
607                 [MonoTODO]
608                 [EditorBrowsable (EditorBrowsableState.Advanced)]
609                 public virtual IDataParameter[] GetFillParameters ()
610                 {
611                         throw new NotImplementedException ();
612                 }
613
614                 protected bool HasTableMappings ()
615                 {
616                         return (TableMappings.Count != 0);
617                 }
618
619                 protected virtual void OnFillError (FillErrorEventArgs value)
620                 {
621                         if (FillError != null)
622                                 FillError (this, value);
623                 }
624
625                 [EditorBrowsable (EditorBrowsableState.Never)]
626                 public void ResetFillLoadOption ()
627                 {
628                         //FIXME: what else ??
629                         FillLoadOption = LoadOption.OverwriteChanges;
630                 }
631
632                 [EditorBrowsable (EditorBrowsableState.Never)]
633                 public virtual bool ShouldSerializeAcceptChangesDuringFill ()
634                 {
635                         return true;
636                 }
637
638                 [EditorBrowsable (EditorBrowsableState.Never)]
639                 public virtual bool ShouldSerializeFillLoadOption ()
640                 {
641                         return false;
642                 }
643
644                 [MonoTODO]
645                 public virtual int Update (DataSet dataSet)
646                 {
647                         throw new NotImplementedException ();
648                 }
649 #else
650                 public abstract int Fill (DataSet dataSet);
651                 public abstract DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType);
652                 public abstract IDataParameter[] GetFillParameters ();
653                 public abstract int Update (DataSet dataSet);
654 #endif
655
656                 #endregion
657                 
658         }
659 }