4 // Part of the Mono class libraries at
5 // mcs/class/System.Data.OracleClient/System.Data.OracleClient
7 // Assembly: System.Data.OracleClient.dll
8 // Namespace: System.Data.OracleClient
10 // Authors: Tim Coleman <tim@timcoleman.com>
11 // Daniel Morgan <danmorg@sc.rr.com>
13 // Copyright (C) Tim Coleman, 2003
14 // Copyright (C) Daniel Morgan, 2003, 2005
16 // Licensed under the MIT/X11 License.
20 using System.Collections;
21 using System.ComponentModel;
23 using System.Data.Common;
24 using System.Data.OracleClient.Oci;
25 using System.Globalization;
26 using System.Runtime.InteropServices;
29 namespace System.Data.OracleClient {
30 public sealed class OracleDataReader : MarshalByRefObject, IDataReader, IDisposable, IDataRecord, IEnumerable
34 OracleCommand command;
35 ArrayList dataTypeNames;
36 bool disposed = false;
39 DataTable schemaTable;
41 int recordsAffected = -1;
42 OciStatementType statementType;
43 OciStatementHandle statement;
49 internal OracleDataReader (OracleCommand command, OciStatementHandle statement)
51 this.command = command;
53 this.isClosed = false;
54 this.schemaTable = ConstructSchemaTable ();
55 this.statement = statement;
56 this.statementType = statement.GetStatementType ();
59 internal OracleDataReader (OracleCommand command, OciStatementHandle statement, bool extHasRows )
61 this.command = command;
62 this.hasRows = extHasRows;
63 this.isClosed = false;
64 this.schemaTable = ConstructSchemaTable ();
65 this.statement = statement;
66 this.statementType = statement.GetStatementType ();
75 #endregion // Constructors
83 public int FieldCount {
84 get { return statement.ColumnCount; }
88 get { return hasRows; }
91 public bool IsClosed {
92 get { return isClosed; }
95 public object this [string name] {
96 get { return GetValue (GetOrdinal (name)); }
99 public object this [int i] {
100 get { return GetValue (i); }
103 public int RecordsAffected {
105 if (statementType == OciStatementType.Select)
108 return GetRecordsAffected ();
112 #endregion // Properties
120 command.CloseDataReader ();
124 private static DataTable ConstructSchemaTable ()
126 Type booleanType = Type.GetType ("System.Boolean");
127 Type stringType = Type.GetType ("System.String");
128 Type intType = Type.GetType ("System.Int32");
129 Type typeType = Type.GetType ("System.Type");
130 Type shortType = Type.GetType ("System.Int16");
132 DataTable schemaTable = new DataTable ("SchemaTable");
133 schemaTable.Columns.Add ("ColumnName", stringType);
134 schemaTable.Columns.Add ("ColumnOrdinal", intType);
135 schemaTable.Columns.Add ("ColumnSize", intType);
136 schemaTable.Columns.Add ("NumericPrecision", shortType);
137 schemaTable.Columns.Add ("NumericScale", shortType);
138 schemaTable.Columns.Add ("DataType", typeType);
139 schemaTable.Columns.Add ("IsLong", booleanType);
140 schemaTable.Columns.Add ("AllowDBNull", booleanType);
141 schemaTable.Columns.Add ("IsUnique", booleanType);
142 schemaTable.Columns.Add ("IsKey", booleanType);
143 schemaTable.Columns.Add ("IsReadOnly", booleanType);
144 schemaTable.Columns.Add ("BaseSchemaTable", stringType);
145 schemaTable.Columns.Add ("BaseCatalogName", stringType);
146 schemaTable.Columns.Add ("BaseTableName", stringType);
147 schemaTable.Columns.Add ("BaseColumnName", stringType);
148 schemaTable.Columns.Add ("BaseSchemaName", stringType);
153 private void Dispose (bool disposing)
157 schemaTable.Dispose ();
164 public void Dispose ()
167 GC.SuppressFinalize (this);
170 public bool GetBoolean (int i)
172 throw new NotSupportedException ();
175 public byte GetByte (int i)
177 throw new NotSupportedException ();
180 public long GetBytes (int i, long fieldOffset, byte[] buffer2, int bufferoffset, int length)
182 object value = GetValue (i);
183 if (!(value is byte[]))
184 throw new InvalidCastException ();
186 if ( buffer2 == null )
187 return ((byte []) value).Length; // Return length of data
189 // Copy data into buffer
190 long lobLength = ((byte []) value).Length;
191 if ( (lobLength - fieldOffset) < length)
192 length = (int) (lobLength - fieldOffset);
193 Array.Copy ( (byte[]) value, (int) fieldOffset, buffer2, bufferoffset, length);
194 return length; // return actual read count
197 public char GetChar (int i)
199 throw new NotSupportedException ();
202 public long GetChars (int i, long fieldOffset, char[] buffer2, int bufferoffset, int length)
204 object value = GetValue (i);
205 if (!(value is char[]))
206 throw new InvalidCastException ();
207 Array.Copy ((char[]) value, (int) fieldOffset, buffer2, bufferoffset, length);
208 return ((char[]) value).Length - fieldOffset;
212 public IDataReader GetData (int i)
214 throw new NotImplementedException ();
217 public string GetDataTypeName (int i)
219 return dataTypeNames [i].ToString ().ToUpper ();
222 public DateTime GetDateTime (int i)
224 IConvertible c = (IConvertible) GetValue (i);
225 return c.ToDateTime (CultureInfo.CurrentCulture);
228 public decimal GetDecimal (int i)
230 IConvertible c = (IConvertible) GetValue (i);
231 return c.ToDecimal (CultureInfo.CurrentCulture);
234 public double GetDouble (int i)
236 IConvertible c = (IConvertible) GetValue (i);
237 return c.ToDouble (CultureInfo.CurrentCulture);
240 public Type GetFieldType (int i)
242 OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
243 return defineHandle.FieldType;
246 public float GetFloat (int i)
248 IConvertible c = (IConvertible) GetValue (i);
249 return c.ToSingle (CultureInfo.CurrentCulture);
252 public Guid GetGuid (int i)
254 throw new NotSupportedException ();
257 public short GetInt16 (int i)
259 throw new NotSupportedException ();
262 public int GetInt32 (int i)
264 IConvertible c = (IConvertible) GetValue (i);
265 return c.ToInt32 (CultureInfo.CurrentCulture);
268 public long GetInt64 (int i)
270 IConvertible c = (IConvertible) GetValue (i);
271 return c.ToInt64 (CultureInfo.CurrentCulture);
274 public string GetName (int i)
276 return statement.GetParameter (i).GetName ();
280 public OracleBFile GetOracleBFile (int i)
282 throw new NotImplementedException ();
286 public OracleBinary GetOracleBinary (int i)
289 throw new InvalidOperationException("The value is null");
291 return new OracleBinary ((byte[]) GetValue (i));
294 public OracleLob GetOracleLob (int i)
297 throw new InvalidOperationException("The value is null");
299 OracleLob output = (OracleLob) ((OciDefineHandle) statement.Values [i]).GetValue();
300 output.connection = command.Connection;
304 public OracleNumber GetOracleNumber (int i)
307 throw new InvalidOperationException("The value is null");
309 return new OracleNumber (GetDecimal (i));
312 public OracleDateTime GetOracleDateTime (int i)
315 throw new InvalidOperationException("The value is null");
317 return new OracleDateTime (GetDateTime (i));
321 public OracleMonthSpan GetOracleMonthSpan (int i)
323 throw new NotImplementedException ();
326 public OracleString GetOracleString (int i)
329 throw new InvalidOperationException("The value is null");
331 return new OracleString (GetString (i));
334 public object GetOracleValue (int i)
336 OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
338 switch (defineHandle.DataType) {
339 case OciDataType.Raw:
340 return GetOracleBinary (i);
341 case OciDataType.Date:
342 return GetOracleDateTime (i);
343 case OciDataType.Clob:
344 case OciDataType.Blob:
345 return GetOracleLob (i);
346 case OciDataType.Integer:
347 case OciDataType.Number:
348 case OciDataType.Float:
349 return GetOracleNumber (i);
350 case OciDataType.VarChar2:
351 case OciDataType.String:
352 case OciDataType.VarChar:
353 case OciDataType.Char:
354 case OciDataType.CharZ:
355 case OciDataType.OciString:
356 case OciDataType.LongVarChar:
357 case OciDataType.Long:
358 case OciDataType.RowIdDescriptor:
359 return GetOracleString (i);
361 throw new NotImplementedException ();
365 public int GetOracleValues (object[] values)
367 int len = values.Length;
368 int count = statement.ColumnCount;
376 for (int i = 0; i < retval; i += 1)
377 values [i] = GetOracleValue (i);
383 public OracleTimeSpan GetOracleTimeSpan (int i)
385 return new OracleTimeSpan (GetTimeSpan (i));
388 public int GetOrdinal (string name)
392 for (i = 0; i < statement.ColumnCount; i += 1) {
393 if (String.Compare (statement.GetParameter(i).GetName(), name, false) == 0)
397 for (i = 0; i < statement.ColumnCount; i += 1) {
398 if (String.Compare (statement.GetParameter(i).GetName(), name, true) == 0)
402 throw new IndexOutOfRangeException ();
405 private int GetRecordsAffected ()
407 if (recordsAffected == -1)
408 recordsAffected = statement.GetAttributeInt32 (OciAttributeType.RowCount, command.ErrorHandle);
409 return recordsAffected;
412 public DataTable GetSchemaTable ()
414 if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
417 dataTypeNames = new ArrayList ();
419 for (int i = 0; i < statement.ColumnCount; i += 1) {
420 DataRow row = schemaTable.NewRow ();
422 OciParameterDescriptor parameter = statement.GetParameter (i);
424 dataTypeNames.Add (parameter.GetDataTypeName ());
426 row ["ColumnName"] = parameter.GetName ();
427 row ["ColumnOrdinal"] = i + 1;
428 row ["ColumnSize"] = parameter.GetDataSize ();
429 row ["NumericPrecision"] = parameter.GetPrecision ();
430 row ["NumericScale"] = parameter.GetScale ();
431 string sDataTypeName = parameter.GetDataTypeName ();
432 row ["DataType"] = parameter.GetFieldType (sDataTypeName);
433 row ["AllowDBNull"] = parameter.GetIsNull ();
434 row ["BaseColumnName"] = parameter.GetName ();
435 row ["IsReadOnly"] = true;
437 schemaTable.Rows.Add (row);
443 public string GetString (int i)
445 object value = GetValue (i);
446 if (!(value is string))
447 throw new InvalidCastException ();
448 return (string) value;
451 public TimeSpan GetTimeSpan (int i)
453 object value = GetValue (i);
454 if (!(value is TimeSpan))
455 throw new InvalidCastException ();
456 return (TimeSpan) value;
459 public object GetValue (int i)
461 OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
463 if (defineHandle.IsNull)
466 switch (defineHandle.DataType) {
467 case OciDataType.Blob:
468 case OciDataType.Clob:
469 OracleLob lob = GetOracleLob (i);
470 object value = lob.Value;
474 return defineHandle.GetValue ();
478 public int GetValues (object[] values)
480 int len = values.Length;
481 int count = statement.ColumnCount;
489 for (int i = 0; i < retval; i += 1)
490 values [i] = GetValue (i);
495 IEnumerator IEnumerable.GetEnumerator ()
497 return new DbEnumerator (this);
500 public bool IsDBNull (int i)
502 OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
503 return defineHandle.IsNull;
507 public bool NextResult ()
509 // FIXME: get next result
515 bool retval = statement.Fetch ();
520 #endregion // Methods