2002-05-18 Daniel Morgan <danmorg@sc.rr.com>
[mono.git] / mcs / class / System.Data / System.Data.SqlClient / SqlDataReader.cs
1 //
2 // System.Data.SqlClient.SqlDataReader.cs
3 //
4 // Author:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Daniel Morgan (danmorg@sc.rr.com)
7 //
8 // (C) Ximian, Inc 2002
9 // (C) Daniel Morgan 2002
10 //
11 // Credits:
12 //    SQL and concepts were used from libgda 0.8.190 (GNOME Data Access)\r
13 //    http://www.gnome-db.org/\r
14 //    with permission from the authors of the\r
15 //    PostgreSQL provider in libgda:\r
16 //        Michael Lausch <michael@lausch.at>
17 //        Rodrigo Moya <rodrigo@gnome-db.org>
18 //        Vivien Malerba <malerba@gnome-db.org>
19 //        Gonzalo Paniagua Javier <gonzalo@gnome-db.org>
20 //
21
22 // *** uncomment #define to get debug messages, comment for production ***
23 //#define DEBUG_SqlDataReader
24
25
26 using System;
27 using System.Collections;
28 using System.ComponentModel;
29 using System.Data;
30
31 namespace System.Data.SqlClient {
32         /// <summary>
33         /// Provides a means of reading one or more forward-only streams
34         /// of result sets obtained by executing a command 
35         /// at a SQL database.
36         /// </summary>
37         //public sealed class SqlDataReader : MarshalByRefObject,
38         //      IEnumerable, IDataReader, IDisposable, IDataRecord
39         public sealed class SqlDataReader : IEnumerable, 
40                 IDataReader, IDataRecord {
41                 #region Fields
42
43                 private SqlCommand cmd;
44                 private DataTable table = null;
45
46                 // columns in a row
47                 private object[] fields; // data value in a .NET type
48                 private string[] types; // PostgreSQL Type
49                 private bool[] isNull; // is NULL?
50                 private int[] actualLength; // ActualLength of data
51                 private DbType[] dbTypes; // DB data type
52                 // actucalLength = -1 is variable-length
53                                 
54                 private bool open = false;
55                 IntPtr pgResult; // PGresult
56                 private int rows;
57                 private int cols;
58
59                 private int currentRow = -1; // no Read() has been done yet
60
61                 #endregion // Fields
62
63                 #region Constructors
64
65                 internal SqlDataReader (SqlCommand sqlCmd) {
66
67                         cmd = sqlCmd;
68                         open = true;
69                 }
70
71                 #endregion
72
73                 #region Public Methods
74
75                 [MonoTODO]
76                 public void Close() {
77                         open = false;
78                         
79                         // free SqlDataReader resources in SqlCommand
80                         // and allow SqlConnection to be used again
81                         cmd.CloseReader();
82
83                         // TODO: get parameters from result
84
85                         // clear unmanaged PostgreSQL result set
86                         PostgresLibrary.PQclear (pgResult);
87                         pgResult = IntPtr.Zero;
88                 }
89
90                 [MonoTODO]
91                 public DataTable GetSchemaTable() {
92                         return table;
93                 }
94
95                 [MonoTODO]
96                 public bool NextResult() {
97                         SqlResult res;
98                         currentRow = -1;
99                         
100                         res = cmd.NextResult();
101
102                         if(res.ResultReturned == true) {
103                                 table = res.Table;
104                                 pgResult = res.PgResult;
105                                 rows = res.RowCount;
106                                 cols = res.FieldCount;
107                                 types = res.PgTypes;
108                         }
109
110                         return res.ResultReturned;
111                 }
112
113                 [MonoTODO]
114                 public bool Read() {
115                         
116                         string dataValue;
117                         int c = 0;
118                         
119                         if(currentRow < rows - 1)  {
120                                 
121                                 currentRow++;
122                         
123                                 // re-init row
124                                 fields = new object[cols];
125                                 //dbTypes = new DbType[cols];
126                                 actualLength = new int[cols];
127                                 isNull = new bool[cols];
128                         
129                                 for(c = 0; c < cols; c++) {
130
131                                         // get data value
132                                         dataValue = PostgresLibrary.
133                                                 PQgetvalue(
134                                                 pgResult,
135                                                 currentRow, c);
136
137                                         // is column NULL?
138                                         //isNull[c] = PostgresLibrary.
139                                         //      PQgetisnull(pgResult,
140                                         //      currentRow, c);
141
142                                         // get Actual Length
143                                         actualLength[c] = PostgresLibrary.
144                                                 PQgetlength(pgResult,
145                                                 currentRow, c);
146
147                                         DbType dbType;  
148                                         dbType = PostgresHelper.
149                                                 TypnameToSqlDbType(types[c]);
150
151                                         if(dataValue == null) {
152                                                 fields[c] = null;
153                                                 isNull[c] = true;
154                                         }
155                                         else if(dataValue.Equals("")) {
156                                                 fields[c] = null;
157                                                 isNull[c] = true;
158                                         }
159                                         else {
160                                                 isNull[c] = false;
161                                                 fields[c] = PostgresHelper.
162                                                         ConvertDbTypeToSystem (
163                                                         dbType,
164                                                         dataValue);
165                                         }
166                                 }
167                                 return true;
168                         }
169                         return false; // EOF
170                 }
171
172                 [MonoTODO]
173                 public byte GetByte(int i) {
174                         throw new NotImplementedException ();
175                 }
176
177                 [MonoTODO]
178                 public long GetBytes(int i, long fieldOffset, 
179                         byte[] buffer, int bufferOffset, 
180                         int length) {
181                         throw new NotImplementedException ();
182                 }
183
184                 [MonoTODO]
185                 public char GetChar(int i) {
186                         throw new NotImplementedException ();
187                 }
188
189                 [MonoTODO]
190                 public long GetChars(int i, long fieldOffset, 
191                         char[] buffer, int bufferOffset, 
192                         int length) {
193                         throw new NotImplementedException ();
194                 }
195
196                 [MonoTODO]
197                 public IDataReader GetData(int i) {
198                         throw new NotImplementedException ();
199                 }
200
201                 [MonoTODO]
202                 public string GetDataTypeName(int i) {
203                         return types[i];
204                 }
205
206                 [MonoTODO]
207                 public DateTime GetDateTime(int i) {
208                         return (DateTime) fields[i];
209                 }
210
211                 [MonoTODO]
212                 public decimal GetDecimal(int i) {
213                         return (decimal) fields[i];
214                 }
215
216                 [MonoTODO]
217                 public double GetDouble(int i) {
218                         return (double) fields[i];
219                 }
220
221                 [MonoTODO]
222                 public Type GetFieldType(int i) {
223
224                         return table.Columns[i].DataType;
225                 }
226
227                 [MonoTODO]
228                 public float GetFloat(int i) {
229                         return (float) fields[i];
230                 }
231
232                 [MonoTODO]
233                 public Guid GetGuid(int i) {
234                         throw new NotImplementedException ();
235                 }
236
237                 [MonoTODO]
238                 public short GetInt16(int i) {
239                         return (short) fields[i];
240                 }
241
242                 [MonoTODO]
243                 public int GetInt32(int i) {
244                         return (int) fields[i];
245                 }
246
247                 [MonoTODO]
248                 public long GetInt64(int i) {
249                         return (long) fields[i];
250                 }
251
252                 [MonoTODO]
253                 public string GetName(int i) {
254                         return table.Columns[i].ColumnName;
255                 }
256
257                 [MonoTODO]
258                 public int GetOrdinal(string name) {
259                         int i;
260                         for(i = 0; i < cols; i ++) {
261                                 if(table.Columns[i].ColumnName.Equals(name)) {
262                                         return i;
263                                 }
264
265                         }
266         
267                         for(i = 0; i < cols; i++) {
268                                 string ta;
269                                 string n;
270                                                 
271                                 ta = table.Columns[i].ColumnName.ToUpper();
272                                 n = name.ToUpper();
273                                                 
274                                 if(ta.Equals(n)) {
275                                         return i;
276                                 }
277                         }
278                         
279                         throw new MissingFieldException("Missing field: " + name);
280                 }
281
282                 [MonoTODO]
283                 public string GetString(int i) {
284                         return (string) fields[i];
285                 }
286
287                 [MonoTODO]
288                 public object GetValue(int i) {
289                         return fields[i];
290                 }
291
292                 [MonoTODO]
293                 public int GetValues(object[] values) 
294                 {
295                         Array.Copy (fields, values, fields.Length);
296                         return fields.Length;
297                 }
298
299                 [MonoTODO]
300                 public bool IsDBNull(int i) {
301                         return isNull[i];
302                 }
303
304                 [MonoTODO]
305                 public bool GetBoolean(int i) {
306                         return (bool) fields[i];
307                 }
308
309                 [MonoTODO]
310                 public IEnumerator GetEnumerator() {
311                         throw new NotImplementedException ();
312                 }
313
314                 #endregion // Public Methods
315
316                 #region Destructors
317
318                 [MonoTODO]
319                 public void Dispose () {
320                 }
321
322                 [MonoTODO]
323                 ~SqlDataReader() {
324                 }
325
326                 #endregion // Destructors
327
328                 #region Properties
329
330                 public int Depth {
331                         [MonoTODO]
332                         get { 
333                                 throw new NotImplementedException (); 
334                         }
335                 }
336
337                 public bool IsClosed {
338                         [MonoTODO]
339                         get {
340                                 if(open == false)
341                                         return true;
342                                 else
343                                         return false;
344                         }
345                 }
346
347                 public int RecordsAffected {
348                         [MonoTODO]
349                         get { 
350                                 throw new NotImplementedException (); 
351                         }
352                 }
353         
354                 public int FieldCount {
355                         [MonoTODO]
356                         get { 
357                                 return cols;
358                         }
359                 }
360
361                 public object this[string name] {
362                         [MonoTODO]
363                         get { 
364                                 int i;
365                                 for(i = 0; i < cols; i ++) {
366                                         if(table.Columns[i].ColumnName.Equals(name)) {
367                                                 return fields[i];
368                                         }
369
370                                 }
371         
372                                 for(i = 0; i < cols; i++) {
373                                         string ta;
374                                         string n;
375                                                 
376                                         ta = table.Columns[i].ColumnName.ToUpper();
377                                         n = name.ToUpper();
378                                                 
379                                         if(ta.Equals(n)) {
380                                                 return fields[i];
381                                         }
382                                 }
383                         
384                                 throw new MissingFieldException("Missing field: " + name);
385                         }
386                 }
387
388                 public object this[int i] {
389                         [MonoTODO]
390                         get { 
391                                 return fields[i];
392                         }
393                 }
394
395                 #endregion // Properties
396         }
397 }