[runtime] Overwrite stacktrace for exception on re-throw. Fixes #1856.
[mono.git] / mcs / class / System.Data / System.Data.OleDb / OleDbDataReader.cs
1 //
2 // System.Data.OleDb.OleDbDataReader
3 //
4 // Author:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Tim Coleman (tim@timcoleman.com)
7 //
8 // Copyright (C) Rodrigo Moya, 2002
9 // Copyright (C) Tim Coleman, 2002
10 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections;
33 using System.ComponentModel;
34 using System.Data.Common;
35 using System.Runtime.InteropServices;
36
37 namespace System.Data.OleDb
38 {
39         public sealed class OleDbDataReader : DbDataReader, IDisposable
40         {
41                 #region Fields
42                 
43                 private OleDbCommand command;
44                 private bool open;
45                 private ArrayList gdaResults;
46                 private int currentResult;
47                 private int currentRow;
48                 private bool disposed;
49
50                 #endregion
51
52                 #region Constructors
53
54                 internal OleDbDataReader (OleDbCommand command, ArrayList results) 
55                 {
56                         this.command = command;
57                         open = true;
58                         if (results != null)
59                                 gdaResults = results;
60                         else
61                                 gdaResults = new ArrayList ();
62                         currentResult = -1;
63                         currentRow = -1;
64                 }
65
66                 #endregion
67
68                 #region Properties
69
70                 public
71                 override
72                 int Depth {
73                         get {
74                                 return 0; // no nested selects supported
75                         }
76                 }
77
78                 public
79                 override
80                 int FieldCount {
81                         get {
82                                 if (currentResult < 0 || currentResult >= gdaResults.Count)
83                                         return 0;
84
85                                 return libgda.gda_data_model_get_n_columns (
86                                         (IntPtr) gdaResults[currentResult]);
87                         }
88                 }
89
90                 public
91                 override
92                 bool IsClosed {
93                         get {
94                                 return !open;
95                         }
96                 }
97
98                 public
99                 override
100                 object this[string name] {
101                         get {
102                                 int pos;
103
104                                 if (currentResult == -1)
105                                         throw new InvalidOperationException ();
106
107                                 pos = libgda.gda_data_model_get_column_position (
108                                         (IntPtr) gdaResults[currentResult],
109                                         name);
110                                 if (pos == -1)
111                                         throw new IndexOutOfRangeException ();
112
113                                 return this[pos];
114                         }
115                 }
116
117                 public
118                 override
119                 object this[int index] {
120                         get {
121                                 return (object) GetValue (index);
122                         }
123                 }
124
125                 public
126                 override
127                 int RecordsAffected {
128                         get {
129                                 int total_rows;
130                                 
131                                 if (currentResult < 0 || currentResult >= gdaResults.Count)
132                                         return 0;
133
134                                 total_rows = libgda.gda_data_model_get_n_rows (
135                                         (IntPtr) gdaResults[currentResult]);
136                                 if (total_rows > 0) {
137                                         if (FieldCount > 0) {
138                                                 // It's a SELECT statement
139                                                 return -1;
140                                         }
141                                 }
142
143                                 return FieldCount > 0 ? -1 : total_rows;
144                         }
145                 }
146                 
147                 [MonoTODO]
148                 public
149                 override
150                 bool HasRows {
151                         get {
152                                 throw new NotImplementedException ();
153                         }
154                 }
155
156                 [MonoTODO]
157                 public override int VisibleFieldCount {
158                         get {
159                                 throw new NotImplementedException ();
160                         }
161                 }
162
163                 #endregion
164
165                 #region Methods
166
167                 public
168                 override
169                 void Close ()
170                 {
171                         for (int i = 0; i < gdaResults.Count; i++) {
172                                 IntPtr obj = (IntPtr) gdaResults[i];
173                                 libgda.FreeObject (obj);
174                         }
175
176                         gdaResults.Clear ();
177                         gdaResults = null;
178                         
179                         open = false;
180                         currentResult = -1;
181                         currentRow = -1;
182                 }
183
184                 public
185                 override
186                 bool GetBoolean (int ordinal)
187                 {
188                         IntPtr value;
189
190                         if (currentResult == -1)
191                                 throw new InvalidCastException ();
192
193                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
194                                                                     ordinal, currentRow);
195                         if (value == IntPtr.Zero)
196                                 throw new InvalidCastException ();
197                         
198                         if (libgda.gda_value_get_type (value) != GdaValueType.Boolean)
199                                 throw new InvalidCastException ();
200                         return libgda.gda_value_get_boolean (value);
201                 }
202
203                 public
204                 override
205                 byte GetByte (int ordinal)
206                 {
207                         IntPtr value;
208
209                         if (currentResult == -1)
210                                 throw new InvalidCastException ();
211
212                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
213                                                                     ordinal, currentRow);
214                         if (value == IntPtr.Zero)
215                                 throw new InvalidCastException ();
216                         
217                         if (libgda.gda_value_get_type (value) != GdaValueType.Tinyint)
218                                 throw new InvalidCastException ();
219                         return libgda.gda_value_get_tinyint (value);
220                 }
221
222                 [MonoTODO]
223                 public
224                 override
225                 long GetBytes (int ordinal, long dataIndex, byte[] buffer, int bufferIndex, int length)
226                 {
227                         throw new NotImplementedException ();
228                 }
229                 
230                 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
231                 public
232                 override
233                 char GetChar (int ordinal)
234                 {
235                         IntPtr value;
236
237                         if (currentResult == -1)
238                                 throw new InvalidCastException ();
239
240                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
241                                 ordinal, currentRow);
242                         if (value == IntPtr.Zero)
243                                 throw new InvalidCastException ();
244                         
245                         if (libgda.gda_value_get_type (value) != GdaValueType.Tinyint)
246                                 throw new InvalidCastException ();
247                         return (char) libgda.gda_value_get_tinyint (value);
248                 }
249
250                 [MonoTODO]
251                 public
252                 override
253                 long GetChars (int ordinal, long dataIndex, char[] buffer, int bufferIndex, int length)
254                 {
255                         throw new NotImplementedException ();
256                 }
257
258                 [MonoTODO]
259                 [EditorBrowsable (EditorBrowsableState.Advanced)]
260                 public new OleDbDataReader GetData (int ordinal)
261                 {
262                         throw new NotImplementedException ();
263                 }
264
265                 protected override DbDataReader GetDbDataReader (int ordinal)
266                 {
267                         return this.GetData (ordinal);
268                 }
269
270                 public
271                 override
272                 string GetDataTypeName (int index)
273                 {
274                         IntPtr attrs;
275                         GdaValueType type;
276
277                         if (currentResult == -1)
278                                 return "unknown";
279
280                         
281                         attrs = libgda.gda_data_model_describe_column ((IntPtr) gdaResults[currentResult],
282                                 index);
283                         if (attrs == IntPtr.Zero)
284                                 return "unknown";
285
286                         type = libgda.gda_field_attributes_get_gdatype (attrs);
287                         libgda.gda_field_attributes_free (attrs);
288                         
289                         return libgda.gda_type_to_string (type);
290                 }
291
292                 public
293                 override
294                 DateTime GetDateTime (int ordinal)
295                 {
296                         IntPtr value;
297
298                         if (currentResult == -1)
299                                 throw new InvalidCastException ();
300
301                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
302                                 ordinal, currentRow);
303                         if (value == IntPtr.Zero)
304                                 throw new InvalidCastException ();
305                         
306                         if (libgda.gda_value_get_type (value) == GdaValueType.Date) {
307                                 GdaDate gdt;
308
309                                 gdt = (GdaDate) Marshal.PtrToStructure (libgda.gda_value_get_date (value),
310                                                                         typeof (GdaDate));
311                                 return new DateTime ((int) gdt.year, (int) gdt.month, (int) gdt.day);
312                         } else if (libgda.gda_value_get_type (value) == GdaValueType.Time) {
313                                 GdaTime gdt;
314
315                                 gdt = (GdaTime) Marshal.PtrToStructure (libgda.gda_value_get_time (value),
316                                                                         typeof (GdaTime));
317                                 return new DateTime (0, 0, 0, (int) gdt.hour, (int) gdt.minute, (int) gdt.second, 0);
318                         } else if (libgda.gda_value_get_type (value) == GdaValueType.Timestamp) {
319                                 GdaTimestamp gdt;
320                                 
321                                 gdt = (GdaTimestamp) Marshal.PtrToStructure (libgda.gda_value_get_timestamp (value),
322                                         typeof (GdaTimestamp));
323
324                                 return new DateTime ((int) gdt.year, (int) gdt.month, (int) gdt.day,
325                                         (int) gdt.hour, (int) gdt.minute, (int) gdt.second,
326                                         (int) gdt.fraction);
327                         }
328
329                         throw new InvalidCastException ();
330                 }
331
332                 [MonoTODO]
333                 public
334                 override
335                 decimal GetDecimal (int ordinal)
336                 {
337                         throw new NotImplementedException ();
338                 }
339
340                 public
341                 override
342                 double GetDouble (int ordinal)
343                 {
344                         IntPtr value;
345
346                         if (currentResult == -1)
347                                 throw new InvalidCastException ();
348
349                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
350                                                                     ordinal, currentRow);
351                         if (value == IntPtr.Zero)
352                                 throw new InvalidCastException ();
353                         
354                         if (libgda.gda_value_get_type (value) != GdaValueType.Double)
355                                 throw new InvalidCastException ();
356                         return libgda.gda_value_get_double (value);
357                 }
358
359                 public
360                 override
361                 Type GetFieldType (int index)
362                 {
363                         IntPtr value;
364                         GdaValueType type;
365
366                         if (currentResult == -1)
367                                 throw new IndexOutOfRangeException ();
368
369                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
370                                 index, currentRow);
371                         if (value == IntPtr.Zero)
372                                 throw new IndexOutOfRangeException ();
373
374                         type = libgda.gda_value_get_type (value);
375                         switch (type) {
376                         case GdaValueType.Bigint : return typeof (long);
377                         case GdaValueType.Boolean : return typeof (bool);
378                         case GdaValueType.Date : return typeof (DateTime);
379                         case GdaValueType.Double : return typeof (double);
380                         case GdaValueType.Integer : return typeof (int);
381                         case GdaValueType.Single : return typeof (float);
382                         case GdaValueType.Smallint : return typeof (byte);
383                         case GdaValueType.String : return typeof (string);
384                         case GdaValueType.Time : return typeof (DateTime);
385                         case GdaValueType.Timestamp : return typeof (DateTime);
386                         case GdaValueType.Tinyint : return typeof (byte);
387                         }
388
389                         return typeof(string); // default
390                 }
391
392                 public
393                 override
394                 float GetFloat (int ordinal)
395                 {
396                         IntPtr value;
397
398                         if (currentResult == -1)
399                                 throw new InvalidCastException ();
400
401                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
402                                 ordinal, currentRow);
403                         if (value == IntPtr.Zero)
404                                 throw new InvalidCastException ();
405                         
406                         if (libgda.gda_value_get_type (value) != GdaValueType.Single)
407                                 throw new InvalidCastException ();
408                         return libgda.gda_value_get_single (value);
409                 }
410
411                 [MonoTODO]
412                 public
413                 override
414                 Guid GetGuid (int ordinal)
415                 {
416                         throw new NotImplementedException ();
417                 }
418
419                 public
420                 override
421                 short GetInt16 (int ordinal)
422                 {
423                         IntPtr value;
424
425                         if (currentResult == -1)
426                                 throw new InvalidCastException ();
427
428                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
429                                 ordinal, currentRow);
430                         if (value == IntPtr.Zero)
431                                 throw new InvalidCastException ();
432                         
433                         if (libgda.gda_value_get_type (value) != GdaValueType.Smallint)
434                                 throw new InvalidCastException ();
435                         return (short) libgda.gda_value_get_smallint (value);
436                 }
437
438                 public
439                 override
440                 int GetInt32 (int ordinal)
441                 {
442                         IntPtr value;
443
444                         if (currentResult == -1)
445                                 throw new InvalidCastException ();
446
447                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
448                                 ordinal, currentRow);
449                         if (value == IntPtr.Zero)
450                                 throw new InvalidCastException ();
451                         
452                         if (libgda.gda_value_get_type (value) != GdaValueType.Integer)
453                                 throw new InvalidCastException ();
454                         return libgda.gda_value_get_integer (value);
455                 }
456
457                 public
458                 override
459                 long GetInt64 (int ordinal)
460                 {
461                         IntPtr value;
462
463                         if (currentResult == -1)
464                                 throw new InvalidCastException ();
465
466                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
467                                 ordinal, currentRow);
468                         if (value == IntPtr.Zero)
469                                 throw new InvalidCastException ();
470                         
471                         if (libgda.gda_value_get_type (value) != GdaValueType.Bigint)
472                                 throw new InvalidCastException ();
473                         return libgda.gda_value_get_bigint (value);
474                 }
475
476                 public
477                 override
478                 string GetName (int index)
479                 {
480                         if (currentResult == -1)
481                                 return null;
482
483                         return libgda.gda_data_model_get_column_title (
484                                 (IntPtr) gdaResults[currentResult], index);
485                 }
486
487                 public
488                 override
489                 int GetOrdinal (string name)
490                 {
491                         if (currentResult == -1)
492                                 throw new IndexOutOfRangeException ();
493
494                         for (int i = 0; i < FieldCount; i++) {
495                                 if (GetName (i) == name)
496                                         return i;
497                         }
498
499                         throw new IndexOutOfRangeException ();
500                 }
501
502                 public
503                 override
504                 DataTable GetSchemaTable ()
505                 {
506                         DataTable dataTableSchema = null;
507                         // Only Results from SQL SELECT Queries 
508                         // get a DataTable for schema of the result
509                         // otherwise, DataTable is null reference
510                         if(this.FieldCount > 0) {
511
512                                 IntPtr attrs;
513                                 GdaValueType gdaType;
514                                 long columnSize = 0;
515
516                                 if (currentResult == -1) {
517                                         // FIXME: throw an exception?
518 #if DEBUG_OleDbDataReader
519                                         Console.WriteLine("Error: current result -1");
520 #endif
521                                         return null;
522                                 }
523                                                 
524                                 dataTableSchema = new DataTable ();
525                                 
526                                 dataTableSchema.Columns.Add ("ColumnName", typeof (string));
527                                 dataTableSchema.Columns.Add ("ColumnOrdinal", typeof (int));
528                                 dataTableSchema.Columns.Add ("ColumnSize", typeof (int));
529                                 dataTableSchema.Columns.Add ("NumericPrecision", typeof (int));
530                                 dataTableSchema.Columns.Add ("NumericScale", typeof (int));
531                                 dataTableSchema.Columns.Add ("IsUnique", typeof (bool));
532                                 dataTableSchema.Columns.Add ("IsKey", typeof (bool));
533                                 DataColumn dc = dataTableSchema.Columns["IsKey"];
534                                 dc.AllowDBNull = true; // IsKey can have a DBNull
535                                 dataTableSchema.Columns.Add ("BaseCatalogName", typeof (string));
536                                 dataTableSchema.Columns.Add ("BaseColumnName", typeof (string));
537                                 dataTableSchema.Columns.Add ("BaseSchemaName", typeof (string));
538                                 dataTableSchema.Columns.Add ("BaseTableName", typeof (string));
539                                 dataTableSchema.Columns.Add ("DataType", typeof(Type));
540                                 dataTableSchema.Columns.Add ("AllowDBNull", typeof (bool));
541                                 dataTableSchema.Columns.Add ("ProviderType", typeof (int));
542                                 dataTableSchema.Columns.Add ("IsAliased", typeof (bool));
543                                 dataTableSchema.Columns.Add ("IsExpression", typeof (bool));
544                                 dataTableSchema.Columns.Add ("IsIdentity", typeof (bool));
545                                 dataTableSchema.Columns.Add ("IsAutoIncrement", typeof (bool));
546                                 dataTableSchema.Columns.Add ("IsRowVersion", typeof (bool));
547                                 dataTableSchema.Columns.Add ("IsHidden", typeof (bool));
548                                 dataTableSchema.Columns.Add ("IsLong", typeof (bool));
549                                 dataTableSchema.Columns.Add ("IsReadOnly", typeof (bool));
550
551                                 DataRow schemaRow;
552
553                                 for (int i = 0; i < this.FieldCount; i += 1 ) {
554                                         
555                                         schemaRow = dataTableSchema.NewRow ();
556
557                                         attrs = libgda.gda_data_model_describe_column ((IntPtr) gdaResults[currentResult],
558                                                 i);
559                                         if (attrs == IntPtr.Zero){
560                                                 // FIXME: throw exception
561 #if DEBUG_OleDbDataReader
562                                                 Console.WriteLine("Error: attrs null");
563 #endif
564                                                 return null;
565                                         }
566
567                                         gdaType = libgda.gda_field_attributes_get_gdatype (attrs);
568                                         columnSize = libgda.gda_field_attributes_get_defined_size (attrs);
569                                         libgda.gda_field_attributes_free (attrs);
570                                         
571                                         schemaRow["ColumnName"] = this.GetName(i);
572                                         schemaRow["ColumnOrdinal"] = i + 1;
573                                         
574                                         schemaRow["ColumnSize"] = (int) columnSize;
575                                         schemaRow["NumericPrecision"] = 0;
576                                         schemaRow["NumericScale"] = 0;
577                                         // TODO: need to get KeyInfo
578                                         //if((cmdBehavior & CommandBehavior.KeyInfo) == CommandBehavior.KeyInfo) {
579                                                 // bool IsUnique, IsKey;
580                                                 // GetKeyInfo(field[i].Name, out IsUnique, out IsKey);
581                                         //}
582                                         //else {
583                                                 schemaRow["IsUnique"] = false;
584                                                 schemaRow["IsKey"] = DBNull.Value;
585                                         //}
586                                         schemaRow["BaseCatalogName"] = "";
587                                         
588                                         schemaRow["BaseColumnName"] = this.GetName(i);
589                                         schemaRow["BaseSchemaName"] = "";
590                                         schemaRow["BaseTableName"] = "";
591
592                                         schemaRow["DataType"] = this.GetFieldType(i);
593
594                                         schemaRow["AllowDBNull"] = false;
595                                         
596                                         schemaRow["ProviderType"] = (int) gdaType;
597                                         schemaRow["IsAliased"] = false;
598                                         schemaRow["IsExpression"] = false;
599                                         schemaRow["IsIdentity"] = false;
600                                         schemaRow["IsAutoIncrement"] = false;
601                                         schemaRow["IsRowVersion"] = false;
602                                         schemaRow["IsHidden"] = false;
603                                         schemaRow["IsLong"] = false;
604                                         schemaRow["IsReadOnly"] = false;
605                                         
606                                         schemaRow.AcceptChanges();
607                                         
608                                         dataTableSchema.Rows.Add (schemaRow);
609                                 }
610                                 
611 #if DEBUG_OleDbDataReader
612                                 Console.WriteLine("********** DEBUG Table Schema BEGIN ************");
613                                 foreach (DataRow myRow in dataTableSchema.Rows) {
614                                         foreach (DataColumn myCol in dataTableSchema.Columns)
615                                                 Console.WriteLine(myCol.ColumnName + " = " + myRow[myCol]);
616                                         Console.WriteLine();
617                                 }
618                                 Console.WriteLine("********** DEBUG Table Schema END ************");
619 #endif // DEBUG_OleDbDataReader
620
621                         }
622                         
623                         return dataTableSchema;
624                 }
625
626                 public
627                 override
628                 string GetString (int ordinal)
629                 {
630                         IntPtr value;
631
632                         if (currentResult == -1)
633                                 throw new InvalidCastException ();
634
635                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
636                                 ordinal, currentRow);
637                         if (value == IntPtr.Zero)
638                                 throw new InvalidCastException ();
639                         
640                         if (libgda.gda_value_get_type (value) != GdaValueType.String)
641                                 throw new InvalidCastException ();
642                         return libgda.gda_value_get_string (value);
643                 }
644
645                 [MonoTODO]
646                 public TimeSpan GetTimeSpan (int ordinal)
647                 {
648                         throw new NotImplementedException ();
649                 }
650
651                 public
652                 override
653                 object GetValue (int ordinal)
654                 {
655                         IntPtr value;
656                         GdaValueType type;
657
658                         if (currentResult == -1)
659                                 throw new IndexOutOfRangeException ();
660
661                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
662                                 ordinal, currentRow);
663                         if (value == IntPtr.Zero)
664                                 throw new IndexOutOfRangeException ();
665
666                         type = libgda.gda_value_get_type (value);
667                         switch (type) {
668                         case GdaValueType.Bigint : return GetInt64 (ordinal);
669                         case GdaValueType.Boolean : return GetBoolean (ordinal);
670                         case GdaValueType.Date : return GetDateTime (ordinal);
671                         case GdaValueType.Double : return GetDouble (ordinal);
672                         case GdaValueType.Integer : return GetInt32 (ordinal);
673                         case GdaValueType.Single : return GetFloat (ordinal);
674                         case GdaValueType.Smallint : return GetByte (ordinal);
675                         case GdaValueType.String : return GetString (ordinal);
676                         case GdaValueType.Time : return GetDateTime (ordinal);
677                         case GdaValueType.Timestamp : return GetDateTime (ordinal);
678                         case GdaValueType.Tinyint : return GetByte (ordinal);
679                         }
680
681                         return (object) libgda.gda_value_stringify (value);
682                 }
683
684                 [MonoTODO]
685                 public
686                 override
687                 int GetValues (object[] values)
688                 {
689                         throw new NotImplementedException ();
690                 }
691
692
693                 public override IEnumerator GetEnumerator()
694                 {
695                         return new DbEnumerator(this);
696                 }
697
698                 public
699                 override
700                 bool IsDBNull (int ordinal)
701                 {
702                         IntPtr value;
703
704                         if (currentResult == -1)
705                                 throw new IndexOutOfRangeException ();
706
707                         value = libgda.gda_data_model_get_value_at ((IntPtr) gdaResults[currentResult],
708                                 ordinal, currentRow);
709                         if (value == IntPtr.Zero)
710                                 throw new IndexOutOfRangeException ();
711
712                         return libgda.gda_value_is_null (value);
713                 }
714
715                 public
716                 override
717                 bool NextResult ()
718                 {
719                         int i = currentResult + 1;
720                         if (i >= 0 && i < gdaResults.Count) {
721                                 currentResult++;
722                                 return true;
723                         }
724
725                         return false;
726                 }
727
728                 public
729                 override
730                 bool Read ()
731                 {
732                         if (currentResult < 0 || currentResult >= gdaResults.Count)
733                                 return false;
734
735                         currentRow++;
736                         if (currentRow < libgda.gda_data_model_get_n_rows ((IntPtr) gdaResults[currentResult]))
737                                 return true;
738
739                         return false;
740                 }
741
742                 #endregion
743
744                 #region Destructors
745
746                 private new void Dispose (bool disposing)
747                 {
748                         if (!this.disposed) {
749                                 if (disposing) {
750                                         // release any managed resources
751                                         command = null;
752                                         GC.SuppressFinalize (this);
753                                 }
754                                 // release any unmanaged resources
755                                 if (gdaResults != null) {
756                                         gdaResults.Clear ();
757                                         gdaResults = null;
758                                 }
759
760                                 // close any handles
761                                 if (open)
762                                         Close ();
763
764                                 this.disposed = true;
765                         }
766                 }
767
768                 void IDisposable.Dispose() {
769                         Dispose (true);
770                 }
771
772                 #endregion // Destructors
773         }
774 }