813 lines
18 KiB
C#
813 lines
18 KiB
C#
//
|
|
// OracleDataReader.cs
|
|
//
|
|
// Part of the Mono class libraries at
|
|
// mcs/class/System.Data.OracleClient/System.Data.OracleClient
|
|
//
|
|
// Assembly: System.Data.OracleClient.dll
|
|
// Namespace: System.Data.OracleClient
|
|
//
|
|
// Authors: Tim Coleman <tim@timcoleman.com>
|
|
// Daniel Morgan <danmorg@sc.rr.com>
|
|
//
|
|
// Copyright (C) Tim Coleman, 2003
|
|
// Copyright (C) Daniel Morgan, 2003, 2005
|
|
//
|
|
// Licensed under the MIT/X11 License.
|
|
//
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Specialized;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Data.Common;
|
|
using System.Data.OracleClient.Oci;
|
|
using System.Globalization;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
namespace System.Data.OracleClient
|
|
{
|
|
public sealed class OracleDataReader :
|
|
DbDataReader
|
|
{
|
|
#region Fields
|
|
|
|
OracleCommand command;
|
|
ArrayList dataTypeNames;
|
|
bool isClosed;
|
|
bool hasRows;
|
|
DataTable schemaTable;
|
|
CommandBehavior behavior;
|
|
|
|
int recordsAffected = -1;
|
|
OciStatementType statementType;
|
|
OciStatementHandle statement;
|
|
|
|
#endregion // Fields
|
|
|
|
#region Constructors
|
|
|
|
internal OracleDataReader (OracleCommand command, OciStatementHandle statement, bool extHasRows, CommandBehavior behavior)
|
|
{
|
|
this.command = command;
|
|
this.hasRows = extHasRows;
|
|
this.schemaTable = ConstructSchemaTable ();
|
|
this.statement = statement;
|
|
this.statementType = statement.GetStatementType ();
|
|
this.behavior = behavior;
|
|
}
|
|
|
|
~OracleDataReader ()
|
|
{
|
|
Dispose (false);
|
|
}
|
|
|
|
#endregion // Constructors
|
|
|
|
#region Properties
|
|
|
|
public
|
|
override
|
|
int Depth {
|
|
get { return 0; }
|
|
}
|
|
|
|
public
|
|
override
|
|
int FieldCount {
|
|
get { return statement.ColumnCount; }
|
|
}
|
|
|
|
public
|
|
override
|
|
bool HasRows {
|
|
get { return hasRows; }
|
|
}
|
|
|
|
public
|
|
override
|
|
bool IsClosed {
|
|
get { return isClosed; }
|
|
}
|
|
|
|
public
|
|
override
|
|
object this [string name] {
|
|
get { return GetValue (GetOrdinal (name)); }
|
|
}
|
|
|
|
public
|
|
override
|
|
object this [int i] {
|
|
get { return GetValue (i); }
|
|
}
|
|
|
|
public
|
|
override
|
|
int RecordsAffected {
|
|
get {
|
|
return GetRecordsAffected ();
|
|
}
|
|
}
|
|
|
|
#endregion // Properties
|
|
|
|
#region Methods
|
|
|
|
public
|
|
override
|
|
void Close ()
|
|
{
|
|
if (!isClosed) {
|
|
GetRecordsAffected ();
|
|
if (command != null)
|
|
command.CloseDataReader ();
|
|
}
|
|
if (statement != null) {
|
|
statement.Dispose();
|
|
statement = null;
|
|
}
|
|
if (schemaTable != null) {
|
|
schemaTable.Dispose ();
|
|
schemaTable = null;
|
|
}
|
|
isClosed = true;
|
|
}
|
|
|
|
private static DataTable ConstructSchemaTable ()
|
|
{
|
|
Type booleanType = typeof (bool);
|
|
Type stringType = typeof (string);
|
|
Type intType = typeof (int);
|
|
Type typeType = typeof (Type);
|
|
Type shortType = typeof (short);
|
|
|
|
DataTable schemaTable = new DataTable ("SchemaTable");
|
|
schemaTable.Columns.Add ("ColumnName", stringType);
|
|
schemaTable.Columns.Add ("ColumnOrdinal", intType);
|
|
schemaTable.Columns.Add ("ColumnSize", intType);
|
|
schemaTable.Columns.Add ("NumericPrecision", shortType);
|
|
schemaTable.Columns.Add ("NumericScale", shortType);
|
|
schemaTable.Columns.Add ("DataType", typeType);
|
|
schemaTable.Columns.Add ("ProviderType", intType);
|
|
schemaTable.Columns.Add ("IsLong", booleanType);
|
|
schemaTable.Columns.Add ("AllowDBNull", booleanType);
|
|
schemaTable.Columns.Add ("IsAliased", booleanType);
|
|
schemaTable.Columns.Add ("IsExpression", booleanType);
|
|
schemaTable.Columns.Add ("IsKey", booleanType);
|
|
schemaTable.Columns.Add ("IsUnique", booleanType);
|
|
schemaTable.Columns.Add ("BaseSchemaName", stringType);
|
|
schemaTable.Columns.Add ("BaseTableName", stringType);
|
|
schemaTable.Columns.Add ("BaseColumnName", stringType);
|
|
|
|
return schemaTable;
|
|
}
|
|
|
|
|
|
public
|
|
override
|
|
bool GetBoolean (int i)
|
|
{
|
|
throw new NotSupportedException ();
|
|
}
|
|
|
|
public
|
|
override
|
|
byte GetByte (int i)
|
|
{
|
|
throw new NotSupportedException ();
|
|
}
|
|
|
|
public
|
|
override
|
|
long GetBytes (int i, long fieldOffset, byte[] buffer2, int bufferoffset, int length)
|
|
{
|
|
byte[] value = (byte[]) GetValue (i);
|
|
|
|
if (buffer2 == null)
|
|
return value.Length; // Return length of data
|
|
|
|
// Copy data into buffer
|
|
long lobLength = value.Length;
|
|
if ((lobLength - fieldOffset) < length)
|
|
length = (int) (lobLength - fieldOffset);
|
|
Array.Copy (value, (int) fieldOffset, buffer2,
|
|
bufferoffset, length);
|
|
return length; // return actual read count
|
|
}
|
|
|
|
public
|
|
override
|
|
char GetChar (int i)
|
|
{
|
|
throw new NotSupportedException ();
|
|
}
|
|
|
|
public
|
|
override
|
|
long GetChars (int i, long fieldOffset, char[] buffer2, int bufferoffset, int length)
|
|
{
|
|
char [] value = (char[]) GetValue (i);
|
|
Array.Copy (value, (int) fieldOffset, buffer2,
|
|
bufferoffset, length);
|
|
return (value.Length - fieldOffset);
|
|
}
|
|
|
|
|
|
public
|
|
override
|
|
string GetDataTypeName (int i)
|
|
{
|
|
return dataTypeNames [i].ToString ().ToUpper ();
|
|
}
|
|
|
|
public
|
|
override
|
|
DateTime GetDateTime (int i)
|
|
{
|
|
IConvertible c = (IConvertible) GetValue (i);
|
|
return c.ToDateTime (CultureInfo.CurrentCulture);
|
|
}
|
|
|
|
public
|
|
override
|
|
decimal GetDecimal (int i)
|
|
{
|
|
IConvertible c = (IConvertible) GetValue (i);
|
|
return c.ToDecimal (CultureInfo.CurrentCulture);
|
|
}
|
|
|
|
public
|
|
override
|
|
double GetDouble (int i)
|
|
{
|
|
IConvertible c = (IConvertible) GetValue (i);
|
|
return c.ToDouble (CultureInfo.CurrentCulture);
|
|
}
|
|
|
|
public
|
|
override
|
|
Type GetFieldType (int i)
|
|
{
|
|
OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
|
|
return defineHandle.FieldType;
|
|
}
|
|
|
|
public
|
|
override
|
|
float GetFloat (int i)
|
|
{
|
|
IConvertible c = (IConvertible) GetValue (i);
|
|
return c.ToSingle (CultureInfo.CurrentCulture);
|
|
}
|
|
|
|
public
|
|
override
|
|
Guid GetGuid (int i)
|
|
{
|
|
throw new NotSupportedException ();
|
|
}
|
|
|
|
public
|
|
override
|
|
short GetInt16 (int i)
|
|
{
|
|
throw new NotSupportedException ();
|
|
}
|
|
|
|
public
|
|
override
|
|
int GetInt32 (int i)
|
|
{
|
|
IConvertible c = (IConvertible) GetValue (i);
|
|
return c.ToInt32 (CultureInfo.CurrentCulture);
|
|
}
|
|
|
|
public
|
|
override
|
|
long GetInt64 (int i)
|
|
{
|
|
IConvertible c = (IConvertible) GetValue (i);
|
|
return c.ToInt64 (CultureInfo.CurrentCulture);
|
|
}
|
|
|
|
public
|
|
override
|
|
string GetName (int i)
|
|
{
|
|
return statement.GetParameter (i).GetName ();
|
|
}
|
|
|
|
[MonoTODO]
|
|
public OracleBFile GetOracleBFile (int i)
|
|
{
|
|
throw new NotImplementedException ();
|
|
}
|
|
|
|
[MonoTODO]
|
|
public OracleBinary GetOracleBinary (int i)
|
|
{
|
|
if (IsDBNull (i))
|
|
throw new InvalidOperationException("The value is null");
|
|
|
|
return new OracleBinary ((byte[]) GetValue (i));
|
|
}
|
|
|
|
public OracleLob GetOracleLob (int i)
|
|
{
|
|
if (IsDBNull (i))
|
|
throw new InvalidOperationException("The value is null");
|
|
|
|
OracleLob output = (OracleLob) ((OciDefineHandle) statement.Values [i]).GetValue (
|
|
command.Connection.SessionFormatProvider, command.Connection);
|
|
output.connection = command.Connection;
|
|
return output;
|
|
}
|
|
|
|
public OracleNumber GetOracleNumber (int i)
|
|
{
|
|
if (IsDBNull (i))
|
|
throw new InvalidOperationException("The value is null");
|
|
|
|
return new OracleNumber (GetDecimal (i));
|
|
}
|
|
|
|
public OracleDateTime GetOracleDateTime (int i)
|
|
{
|
|
if (IsDBNull (i))
|
|
throw new InvalidOperationException("The value is null");
|
|
|
|
return new OracleDateTime (GetDateTime (i));
|
|
}
|
|
|
|
public OracleMonthSpan GetOracleMonthSpan (int i)
|
|
{
|
|
if (IsDBNull (i))
|
|
throw new InvalidOperationException("The value is null");
|
|
|
|
OracleMonthSpan output = (OracleMonthSpan) ((OciDefineHandle) statement.Values [i]).GetValue (
|
|
command.Connection.SessionFormatProvider, command.Connection);
|
|
return output;
|
|
}
|
|
|
|
public OracleString GetOracleString (int i)
|
|
{
|
|
if (IsDBNull (i))
|
|
throw new InvalidOperationException("The value is null");
|
|
|
|
return new OracleString (GetString (i));
|
|
}
|
|
|
|
public object GetOracleValue (int i)
|
|
{
|
|
OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
|
|
|
|
switch (defineHandle.DataType) {
|
|
case OciDataType.Raw:
|
|
return GetOracleBinary (i);
|
|
case OciDataType.Date:
|
|
return GetOracleDateTime (i);
|
|
case OciDataType.Clob:
|
|
case OciDataType.Blob:
|
|
return GetOracleLob (i);
|
|
case OciDataType.Integer:
|
|
case OciDataType.Number:
|
|
case OciDataType.Float:
|
|
return GetOracleNumber (i);
|
|
case OciDataType.VarChar2:
|
|
case OciDataType.String:
|
|
case OciDataType.VarChar:
|
|
case OciDataType.Char:
|
|
case OciDataType.CharZ:
|
|
case OciDataType.OciString:
|
|
case OciDataType.LongVarChar:
|
|
case OciDataType.Long:
|
|
case OciDataType.RowIdDescriptor:
|
|
return GetOracleString (i);
|
|
case OciDataType.IntervalDayToSecond:
|
|
return GetOracleTimeSpan (i);
|
|
case OciDataType.IntervalYearToMonth:
|
|
return GetOracleMonthSpan (i);
|
|
default:
|
|
throw new NotImplementedException ();
|
|
}
|
|
}
|
|
|
|
public int GetOracleValues (object[] values)
|
|
{
|
|
int len = values.Length;
|
|
int count = statement.ColumnCount;
|
|
int retval = 0;
|
|
|
|
if (len > count)
|
|
retval = count;
|
|
else
|
|
retval = len;
|
|
|
|
for (int i = 0; i < retval; i += 1)
|
|
values [i] = GetOracleValue (i);
|
|
|
|
return retval;
|
|
}
|
|
|
|
public OracleTimeSpan GetOracleTimeSpan (int i)
|
|
{
|
|
return new OracleTimeSpan (GetTimeSpan (i));
|
|
}
|
|
|
|
public
|
|
override
|
|
int GetOrdinal (string name)
|
|
{
|
|
int i = GetOrdinalInternal (name);
|
|
if (i == -1)
|
|
throw new IndexOutOfRangeException ();
|
|
return i;
|
|
}
|
|
|
|
private int GetOrdinalInternal (string name)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < statement.ColumnCount; i += 1) {
|
|
if (String.Compare (statement.GetParameter(i).GetName(), name, false) == 0)
|
|
return i;
|
|
}
|
|
|
|
for (i = 0; i < statement.ColumnCount; i += 1) {
|
|
if (String.Compare (statement.GetParameter(i).GetName(), name, true) == 0)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
private int GetRecordsAffected ()
|
|
{
|
|
if (statementType == OciStatementType.Select)
|
|
return -1;
|
|
else {
|
|
if (!isClosed) {
|
|
if (recordsAffected == -1)
|
|
if (statement != null)
|
|
recordsAffected = statement.GetAttributeInt32 (OciAttributeType.RowCount, command.ErrorHandle);
|
|
}
|
|
}
|
|
|
|
return recordsAffected;
|
|
}
|
|
|
|
// get the KeyInfo about table columns (primary key)
|
|
private StringCollection GetKeyInfo (out string ownerName, out string tableName)
|
|
{
|
|
ArrayList tables = new ArrayList ();
|
|
ParseSql (command.CommandText, ref tables);
|
|
// TODO: handle multiple tables
|
|
GetOwnerAndName ((string)tables[0], out ownerName, out tableName);
|
|
return GetKeyColumns (ownerName, tableName);
|
|
}
|
|
|
|
// get the columns in a table that have a primary key
|
|
private StringCollection GetKeyColumns(string owner, string table)
|
|
{
|
|
OracleCommand cmd = command.Connection.CreateCommand ();
|
|
|
|
StringCollection columns = new StringCollection ();
|
|
|
|
if (command.Transaction != null)
|
|
cmd.Transaction = command.Transaction;
|
|
|
|
cmd.CommandText = "select col.column_name " +
|
|
"from all_constraints pk, all_cons_columns col " +
|
|
"where pk.owner = '" + owner + "' " +
|
|
"and pk.table_name = '" + table + "' " +
|
|
"and pk.constraint_type = 'P' " +
|
|
"and pk.owner = col.owner " +
|
|
"and pk.table_name = col.table_name " +
|
|
"and pk.constraint_name = col.constraint_name";
|
|
|
|
OracleDataReader rdr = cmd.ExecuteReader ();
|
|
while (rdr.Read ())
|
|
columns.Add (rdr.GetString (0));
|
|
|
|
rdr.Close();
|
|
rdr = null;
|
|
cmd.Dispose();
|
|
cmd = null;
|
|
|
|
return columns;
|
|
}
|
|
|
|
// parse the list of table names in the SQL
|
|
// TODO: parse the column aliases and table aliases too
|
|
// and determine if a column is a true table column
|
|
// or an expression
|
|
private void ParseSql (string sql, ref ArrayList tables) {
|
|
if (sql == String.Empty)
|
|
return;
|
|
|
|
char[] chars = sql.ToCharArray ();
|
|
StringBuilder wb = new StringBuilder ();
|
|
|
|
bool bFromFound = false;
|
|
bool bEnd = false;
|
|
int i = 0;
|
|
bool bTableFound = false;
|
|
|
|
for (; !bEnd && i < chars.Length; i++) {
|
|
char ch = chars[i];
|
|
|
|
if (Char.IsLetter (ch)) {
|
|
wb.Append (ch);
|
|
} else if (Char.IsWhiteSpace (ch)) {
|
|
if (wb.Length > 0) {
|
|
if (!bFromFound) {
|
|
string word = wb.ToString ().ToUpper ();
|
|
if (word.Equals ("FROM")) {
|
|
bFromFound = true;
|
|
}
|
|
wb = null;
|
|
wb = new StringBuilder ();
|
|
bTableFound = false;
|
|
} else {
|
|
switch (wb.ToString ().ToUpper ()) {
|
|
case "WHERE":
|
|
case "ORDER":
|
|
case "GROUP":
|
|
bEnd = true;
|
|
bTableFound = false;
|
|
break;
|
|
default:
|
|
if (bTableFound)
|
|
bTableFound = false; // this is done in case of a table alias
|
|
else {
|
|
bTableFound = true;
|
|
tables.Add (wb.ToString ().ToUpper ());
|
|
}
|
|
wb = null;
|
|
wb = new StringBuilder ();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else if (bFromFound) {
|
|
switch (ch) {
|
|
case ',':
|
|
if (bTableFound)
|
|
bTableFound = false;
|
|
else
|
|
tables.Add (wb.ToString ().ToUpper ());
|
|
wb = null;
|
|
wb = new StringBuilder ();
|
|
break;
|
|
case '$':
|
|
case '_':
|
|
case '.':
|
|
wb.Append (ch);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!bEnd) {
|
|
if (wb.Length > 0) {
|
|
if (!bFromFound && wb.ToString ().ToUpper ().Equals ("FROM"))
|
|
bFromFound = true;
|
|
if (bFromFound) {
|
|
switch(wb.ToString ().ToUpper ()) {
|
|
case "WHERE":
|
|
case "ORDER":
|
|
case "GROUP":
|
|
bEnd = true;
|
|
break;
|
|
default:
|
|
if (!bTableFound)
|
|
tables.Add (wb.ToString ().ToUpper ());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// takes a object name like "owner.name" and parses it into "owner" and "name" strings
|
|
// if object name is only "name", then it gets the username as the owner and returns
|
|
// the name
|
|
private void GetOwnerAndName (string objectName, out string owner, out string name)
|
|
{
|
|
int idx = objectName.IndexOf (".");
|
|
if (idx == -1) {
|
|
OracleCommand cmd = command.Connection.CreateCommand ();
|
|
if (command.Transaction != null)
|
|
cmd.Transaction = command.Transaction;
|
|
|
|
cmd.CommandText = "SELECT USER FROM DUAL";
|
|
owner = (string) cmd.ExecuteScalar();
|
|
name = objectName;
|
|
cmd.Dispose();
|
|
cmd = null;
|
|
} else {
|
|
owner = objectName.Substring (0, idx);
|
|
name = objectName.Substring (idx + 1);
|
|
}
|
|
}
|
|
|
|
[MonoTODO("Implement this properly, with all needed information.")]
|
|
public
|
|
override
|
|
DataTable GetSchemaTable ()
|
|
{
|
|
StringCollection keyinfo = null;
|
|
|
|
if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
|
|
return schemaTable;
|
|
|
|
string owner = String.Empty;
|
|
string table = String.Empty;
|
|
if ((behavior & CommandBehavior.KeyInfo) != 0)
|
|
keyinfo = GetKeyInfo (out owner, out table);
|
|
|
|
dataTypeNames = new ArrayList ();
|
|
|
|
for (int i = 0; i < statement.ColumnCount; i += 1) {
|
|
DataRow row = schemaTable.NewRow ();
|
|
|
|
OciParameterDescriptor parameter = statement.GetParameter (i);
|
|
|
|
dataTypeNames.Add (parameter.GetDataTypeName ());
|
|
|
|
row ["ColumnName"] = parameter.GetName ();
|
|
row ["ColumnOrdinal"] = i + 1;
|
|
row ["ColumnSize"] = parameter.GetDataSize ();
|
|
row ["NumericPrecision"] = parameter.GetPrecision ();
|
|
row ["NumericScale"] = parameter.GetScale ();
|
|
|
|
string sDataTypeName = parameter.GetDataTypeName ();
|
|
row ["DataType"] = parameter.GetFieldType (sDataTypeName);
|
|
|
|
OciDataType ociType = parameter.GetDataType();
|
|
OracleType oraType = OciParameterDescriptor.OciDataTypeToOracleType (ociType);
|
|
row ["ProviderType"] = (int) oraType;
|
|
|
|
if (ociType == OciDataType.Blob || ociType == OciDataType.Clob)
|
|
row ["IsLong"] = true;
|
|
else
|
|
row ["IsLong"] = false;
|
|
|
|
row ["AllowDBNull"] = parameter.GetIsNull ();
|
|
|
|
row ["IsAliased"] = DBNull.Value; // TODO:
|
|
row ["IsExpression"] = DBNull.Value; // TODO:
|
|
|
|
if ((behavior & CommandBehavior.KeyInfo) != 0) {
|
|
if (keyinfo.IndexOf ((string)row ["ColumnName"]) >= 0)
|
|
row ["IsKey"] = true;
|
|
else
|
|
row ["IsKey"] = false;
|
|
|
|
row ["IsUnique"] = DBNull.Value; // TODO: only set this if CommandBehavior.KeyInfo, otherwise, null
|
|
row ["BaseSchemaName"] = owner;
|
|
row ["BaseTableName"] = table;
|
|
row ["BaseColumnName"] = row ["ColumnName"];
|
|
} else {
|
|
row ["IsKey"] = DBNull.Value;
|
|
row ["IsUnique"] = DBNull.Value;
|
|
row ["BaseSchemaName"] = DBNull.Value;
|
|
row ["BaseTableName"] = DBNull.Value;
|
|
row ["BaseColumnName"] = DBNull.Value;
|
|
}
|
|
|
|
schemaTable.Rows.Add (row);
|
|
}
|
|
|
|
return schemaTable;
|
|
}
|
|
|
|
public
|
|
override
|
|
string GetString (int i)
|
|
{
|
|
return (string) GetValue (i);
|
|
}
|
|
|
|
public TimeSpan GetTimeSpan (int i)
|
|
{
|
|
return (TimeSpan) GetValue (i);
|
|
}
|
|
|
|
public
|
|
override
|
|
object GetValue (int i)
|
|
{
|
|
OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
|
|
|
|
if (defineHandle.IsNull)
|
|
return DBNull.Value;
|
|
|
|
switch (defineHandle.DataType) {
|
|
case OciDataType.Blob:
|
|
case OciDataType.Clob:
|
|
OracleLob lob = GetOracleLob (i);
|
|
object value = lob.Value;
|
|
lob.Close ();
|
|
return value;
|
|
default:
|
|
return defineHandle.GetValue (command.Connection.SessionFormatProvider, command.Connection);
|
|
}
|
|
}
|
|
|
|
public
|
|
override
|
|
int GetValues (object [] values)
|
|
{
|
|
int len = values.Length;
|
|
int count = statement.ColumnCount;
|
|
int retval = 0;
|
|
|
|
if (len > count)
|
|
retval = count;
|
|
else
|
|
retval = len;
|
|
|
|
for (int i = 0; i < retval; i += 1)
|
|
values [i] = GetValue (i);
|
|
|
|
return retval;
|
|
}
|
|
|
|
public override IEnumerator GetEnumerator ()
|
|
{
|
|
return new DbEnumerator (this);
|
|
}
|
|
|
|
public
|
|
override
|
|
bool IsDBNull (int i)
|
|
{
|
|
OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [i];
|
|
return defineHandle.IsNull;
|
|
}
|
|
|
|
void ValidateState ()
|
|
{
|
|
if (IsClosed)
|
|
throw new InvalidOperationException ("Invalid attempt to read data when reader is closed");
|
|
}
|
|
|
|
public
|
|
override
|
|
bool NextResult ()
|
|
{
|
|
ValidateState ();
|
|
|
|
if (statement == null)
|
|
return false;
|
|
|
|
statement.Dispose ();
|
|
statement = null;
|
|
|
|
statement = command.GetNextResult ();
|
|
|
|
if (statement == null)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public
|
|
override
|
|
bool Read ()
|
|
{
|
|
ValidateState ();
|
|
|
|
if (hasRows) {
|
|
bool retval = statement.Fetch ();
|
|
hasRows = retval;
|
|
return retval;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
[MonoTODO]
|
|
public override Type GetProviderSpecificFieldType (int i)
|
|
{
|
|
return GetOracleValue (i).GetType ();
|
|
}
|
|
|
|
[MonoTODO]
|
|
public override object GetProviderSpecificValue (int i)
|
|
{
|
|
return GetOracleValue (i);
|
|
}
|
|
|
|
[MonoTODO]
|
|
public override int GetProviderSpecificValues (object [] values)
|
|
{
|
|
return GetOracleValues (values);
|
|
}
|
|
|
|
#endregion // Methods
|
|
}
|
|
}
|