X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Data.OracleClient%2FSystem.Data.OracleClient%2FOracleCommand.cs;h=db39d3d551fe0ba6d4a1031cce61ca67fd66604e;hb=7e234e0af7c05b9adadf9cba632c528aac1333d5;hp=1bbc3bcd97c5621bc151459ef3716a62033ff94d;hpb=4cb4c3d17516dca42d4bf9f9c7c6f932f065a8aa;p=mono.git diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs index 1bbc3bcd97c..db39d3d551f 100644 --- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs +++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs @@ -1,4 +1,4 @@ -// +// // OracleCommand.cs // // Part of the Mono class libraries at @@ -7,9 +7,10 @@ // Assembly: System.Data.OracleClient.dll // Namespace: System.Data.OracleClient // -// Authors: +// Authors: // Daniel Morgan // Tim Coleman +// Marek Safar // // Copyright (C) Daniel Morgan, 2002, 2004-2005 // Copyright (C) Tim Coleman , 2003 @@ -20,14 +21,26 @@ using System; using System.ComponentModel; using System.Data; +#if NET_2_0 +using System.Data.Common; +#endif using System.Data.OracleClient.Oci; using System.Drawing.Design; using System.Text; -namespace System.Data.OracleClient { +namespace System.Data.OracleClient +{ +#if NET_2_0 + [DefaultEvent ("RecordsAffected")] +#endif [Designer ("Microsoft.VSDesigner.Data.VS.OracleCommandDesigner, " + Consts.AssemblyMicrosoft_VSDesigner)] [ToolboxItem (true)] - public sealed class OracleCommand : Component, ICloneable, IDbCommand + public sealed class OracleCommand : +#if NET_2_0 + DbCommand, ICloneable +#else + Component, ICloneable, IDbCommand +#endif { #region Fields @@ -39,9 +52,9 @@ namespace System.Data.OracleClient { OracleParameterCollection parameters; OracleTransaction transaction; UpdateRowSource updatedRowSource; - - private OciStatementHandle preparedStatement; - OciStatementType statementType; + OciStatementHandle preparedStatement; + + int moreResults; #endregion // Fields @@ -64,15 +77,15 @@ namespace System.Data.OracleClient { public OracleCommand (string commandText, OracleConnection connection, OracleTransaction tx) { + moreResults = -1; preparedStatement = null; CommandText = commandText; Connection = connection; Transaction = tx; CommandType = CommandType.Text; UpdatedRowSource = UpdateRowSource.Both; - DesignTimeVisible = false; - - parameters = new OracleParameterCollection (this); + DesignTimeVisible = true; + parameters = new OracleParameterCollection (); } #endregion // Constructors @@ -82,33 +95,84 @@ namespace System.Data.OracleClient { [DefaultValue ("")] [RefreshProperties (RefreshProperties.All)] [Editor ("Microsoft.VSDesigner.Data.Oracle.Design.OracleCommandTextEditor, " + Consts.AssemblyMicrosoft_VSDesigner, typeof(UITypeEditor))] - public string CommandText { - get { return commandText; } + public +#if NET_2_0 + override +#endif + string CommandText { + get { + if (commandText == null) + return string.Empty; + + return commandText; + } set { commandText = value; } } [RefreshProperties (RefreshProperties.All)] [DefaultValue (CommandType.Text)] - public CommandType CommandType { + public +#if NET_2_0 + override +#endif + CommandType CommandType { get { return commandType; } - set { + set { if (value == CommandType.TableDirect) throw new ArgumentException ("OracleClient provider does not support TableDirect CommandType."); - commandType = value; + commandType = value; } } [DefaultValue (null)] [Editor ("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, " + Consts.AssemblyMicrosoft_VSDesigner, typeof(UITypeEditor))] - public OracleConnection Connection { + public +#if NET_2_0 + new +#endif + OracleConnection Connection { get { return connection; } set { connection = value; } } +#if NET_2_0 + [Browsable (false)] + [EditorBrowsable (EditorBrowsableState.Never)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] + public override int CommandTimeout { + get { return 0; } + set { } + } + + [MonoTODO] + protected override DbConnection DbConnection { + get { return Connection; } + set { Connection = (OracleConnection) value; } + } + + [MonoTODO] + protected override DbParameterCollection DbParameterCollection { + get { return Parameters; } + } + + [MonoTODO] + protected override DbTransaction DbTransaction { + get { return Transaction; } + set { Transaction = (OracleTransaction) value; } + } +#endif + [DefaultValue (true)] [Browsable (false)] [DesignOnly (true)] - public bool DesignTimeVisible { +#if NET_2_0 + [EditorBrowsable (EditorBrowsableState.Never)] +#endif + public +#if NET_2_0 + override +#endif + bool DesignTimeVisible { get { return designTimeVisible; } set { designTimeVisible = value; } } @@ -121,6 +185,7 @@ namespace System.Data.OracleClient { get { return Connection.ErrorHandle; } } +#if !NET_2_0 int IDbCommand.CommandTimeout { get { return 0; } set { } @@ -130,9 +195,8 @@ namespace System.Data.OracleClient { [DefaultValue (null)] IDbConnection IDbCommand.Connection { get { return Connection; } - set { - if (!(value is OracleConnection)) - throw new InvalidCastException ("The value was not a valid OracleConnection."); + set { + // InvalidCastException is expected when types do not match Connection = (OracleConnection) value; } } @@ -143,27 +207,39 @@ namespace System.Data.OracleClient { IDbTransaction IDbCommand.Transaction { get { return Transaction; } - set { - if (!(value is OracleTransaction)) - throw new ArgumentException (); - Transaction = (OracleTransaction) value; + set { + // InvalidCastException is expected when types do not match + Transaction = (OracleTransaction) value; } } +#endif [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] - public OracleParameterCollection Parameters { + public +#if NET_2_0 + new +#endif + OracleParameterCollection Parameters { get { return parameters; } } [Browsable (false)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] - public OracleTransaction Transaction { + public +#if NET_2_0 + new +#endif + OracleTransaction Transaction { get { return transaction; } set { transaction = value; } } [DefaultValue (UpdateRowSource.Both)] - public UpdateRowSource UpdatedRowSource { + public +#if NET_2_0 + override +#endif + UpdateRowSource UpdatedRowSource { get { return updatedRowSource; } set { updatedRowSource = value; } } @@ -174,7 +250,7 @@ namespace System.Data.OracleClient { private void AssertCommandTextIsSet () { - if (CommandText == String.Empty || CommandText == null) + if (CommandText.Length == 0) throw new InvalidOperationException ("The command text for this Command has not been set."); } @@ -184,12 +260,6 @@ namespace System.Data.OracleClient { throw new InvalidOperationException ("An open Connection object is required to continue."); } - private void AssertNoDataReader () - { - if (Connection.DataReader != null) - throw new InvalidOperationException ("There is already an open DataReader associated with this Connection which must be closed first."); - } - private void AssertTransactionMatch () { if (Connection.Transaction != null && Transaction != Connection.Transaction) @@ -203,7 +273,11 @@ namespace System.Data.OracleClient { } [MonoTODO] - public void Cancel () + public +#if NET_2_0 + override +#endif + void Cancel () { throw new NotImplementedException (); } @@ -212,9 +286,9 @@ namespace System.Data.OracleClient { public object Clone () { // create a new OracleCommand object with the same properties - + OracleCommand cmd = new OracleCommand (); - + cmd.CommandText = this.CommandText; cmd.CommandType = this.CommandType; @@ -222,7 +296,7 @@ namespace System.Data.OracleClient { // or get a clone of these too cmd.Connection = this.Connection; cmd.Transaction = this.Transaction; - + foreach (OracleParameter parm in this.Parameters) { OracleParameter newParm = cmd.CreateParameter (); @@ -233,8 +307,8 @@ namespace System.Data.OracleClient { newParm.Offset = parm.Offset; newParm.OracleType = parm.OracleType; newParm.ParameterName = parm.ParameterName; - newParm.Precision = parm.Precision; - newParm.Scale = parm.Scale; + //newParm.Precision = parm.Precision; + //newParm.Scale = parm.Scale; newParm.SourceColumn = parm.SourceColumn; newParm.SourceVersion = parm.SourceVersion; newParm.Value = parm.Value; @@ -251,29 +325,62 @@ namespace System.Data.OracleClient { return cmd; } - internal void UpdateParameterValues () +#if NET_2_0 + protected override DbParameter CreateDbParameter () + { + return CreateParameter (); + } + + protected override DbDataReader ExecuteDbDataReader (CommandBehavior behavior) { + return ExecuteReader (behavior); + } +#endif + + internal void UpdateParameterValues () + { + moreResults = -1; if (Parameters.Count > 0) { - foreach (OracleParameter parm in Parameters) - parm.Update (this); + bool foundCursor = false; + for (int p = 0; p < Parameters.Count; p++) { + OracleParameter parm = Parameters [p]; + if (parm.OracleType.Equals (OracleType.Cursor)) { + if (!foundCursor && parm.Direction != ParameterDirection.Input) { + // if there are multiple REF CURSORs, + // you only can get the first cursor for now + // because user of OracleDataReader + // will do a NextResult to get the next + // REF CURSOR (if it exists) + foundCursor = true; + parm.Update (this); + if (p + 1 == Parameters.Count) + moreResults = -1; + else + moreResults = p; + } + } else + parm.Update (this); + } } } internal void CloseDataReader () { - UpdateParameterValues (); - Connection.DataReader = null; if ((behavior & CommandBehavior.CloseConnection) != 0) Connection.Close (); } - public OracleParameter CreateParameter () + public +#if NET_2_0 + new +#endif + OracleParameter CreateParameter () { return new OracleParameter (); } - internal void DeriveParameters () + internal void DeriveParameters () { if (commandType != CommandType.StoredProcedure) throw new InvalidOperationException (String.Format ("OracleCommandBuilder DeriveParameters only supports CommandType.StoredProcedure, not CommandType.{0}", commandType)); @@ -285,6 +392,8 @@ namespace System.Data.OracleClient { private int ExecuteNonQueryInternal (OciStatementHandle statement, bool useAutoCommit) { + moreResults = -1; + if (preparedStatement == null) PrepareStatement (statement); @@ -299,16 +408,22 @@ namespace System.Data.OracleClient { UpdateParameterValues (); int rowsAffected = statement.GetAttributeInt32 (OciAttributeType.RowCount, ErrorHandle); - + return rowsAffected; } - public int ExecuteNonQuery () + public +#if NET_2_0 + override +#endif + int ExecuteNonQuery () { + moreResults = -1; + AssertConnectionIsOpen (); AssertTransactionMatch (); AssertCommandTextIsSet (); - bool useAutoCommit = false; + bool useAutoCommit = false; if (Transaction != null) Transaction.AttachToServiceContext (); @@ -318,18 +433,19 @@ namespace System.Data.OracleClient { OciStatementHandle statement = GetStatementHandle (); try { return ExecuteNonQueryInternal (statement, useAutoCommit); - } - finally { + } finally { SafeDisposeHandle (statement); } } public int ExecuteOracleNonQuery (out OracleString rowid) { + moreResults = -1; + AssertConnectionIsOpen (); AssertTransactionMatch (); AssertCommandTextIsSet (); - bool useAutoCommit = false; + bool useAutoCommit = false; if (Transaction != null) Transaction.AttachToServiceContext (); @@ -340,22 +456,20 @@ namespace System.Data.OracleClient { try { int retval = ExecuteNonQueryInternal (statement, useAutoCommit); - - OciRowIdDescriptor descriptor = (OciRowIdDescriptor) Environment.Allocate (OciHandleType.RowId); - descriptor.SetHandle (statement.GetAttributeIntPtr (OciAttributeType.RowId, ErrorHandle)); - - rowid = new OracleString (descriptor.GetRowId (ErrorHandle)); - + OciRowIdDescriptor rowIdDescriptor = statement.GetAttributeRowIdDescriptor (ErrorHandle, Environment); + string srowid = rowIdDescriptor.GetRowIdToString (ErrorHandle); + rowid = new OracleString (srowid); + rowIdDescriptor = null; return retval; - } - finally { + } finally { SafeDisposeHandle (statement); } } - [MonoTODO] public object ExecuteOracleScalar () { + moreResults = -1; + object output = DBNull.Value; AssertConnectionIsOpen (); @@ -382,7 +496,7 @@ namespace System.Data.OracleClient { if (statement.Fetch ()) { OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [0]; if (!defineHandle.IsNull) - output = defineHandle.GetOracleValue (); + output = defineHandle.GetOracleValue (Connection.SessionFormatProvider, Connection); switch (defineHandle.DataType) { case OciDataType.Blob: case OciDataType.Clob: @@ -394,13 +508,12 @@ namespace System.Data.OracleClient { } return output; - } - finally { + } finally { SafeDisposeHandle (statement); } } - private bool IsNonQuery (OciStatementHandle statementHandle) + private bool IsNonQuery (OciStatementHandle statementHandle) { // assumes Prepare() has been called prior to calling this function @@ -411,28 +524,38 @@ namespace System.Data.OracleClient { return true; } - public OracleDataReader ExecuteReader () + public +#if NET_2_0 + new +#endif + OracleDataReader ExecuteReader () { return ExecuteReader (CommandBehavior.Default); } - public OracleDataReader ExecuteReader (CommandBehavior behavior) + public +#if NET_2_0 + new +#endif + OracleDataReader ExecuteReader (CommandBehavior behavior) { AssertConnectionIsOpen (); AssertTransactionMatch (); AssertCommandTextIsSet (); - AssertNoDataReader (); + + moreResults = -1; + bool hasRows = false; - this.behavior = behavior; - - if (Transaction != null) + this.behavior = behavior; + + if (Transaction != null) Transaction.AttachToServiceContext (); - + OciStatementHandle statement = GetStatementHandle (); OracleDataReader rd = null; - try { + try { if (preparedStatement == null) PrepareStatement (statement); else @@ -442,18 +565,33 @@ namespace System.Data.OracleClient { BindParameters (statement); - if (isNonQuery) + if (isNonQuery) ExecuteNonQueryInternal (statement, false); - else { + else { if ((behavior & CommandBehavior.SchemaOnly) != 0) statement.ExecuteQuery (true); else hasRows = statement.ExecuteQuery (false); + + UpdateParameterValues (); } - rd = new OracleDataReader (this, statement, hasRows, behavior); - } - finally { + if (Parameters.Count > 0) { + for (int p = 0; p < Parameters.Count; p++) { + OracleParameter parm = Parameters [p]; + if (parm.OracleType.Equals (OracleType.Cursor)) { + if (parm.Direction != ParameterDirection.Input) { + rd = (OracleDataReader) parm.Value; + break; + } + } + } + } + + if (rd == null) + rd = new OracleDataReader (this, statement, hasRows, behavior); + + } finally { if (statement != null && rd == null) statement.Dispose(); } @@ -461,9 +599,14 @@ namespace System.Data.OracleClient { return rd; } - public object ExecuteScalar () + public +#if NET_2_0 + override +#endif + object ExecuteScalar () { - object output = DBNull.Value; + moreResults = -1; + object output = null;//if we find nothing we return this AssertConnectionIsOpen (); AssertTransactionMatch (); @@ -488,41 +631,71 @@ namespace System.Data.OracleClient { if (statement.Fetch ()) { OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [0]; - if (defineHandle.IsNull) - output = DBNull.Value; - else { + if (!defineHandle.IsNull) + { switch (defineHandle.DataType) { case OciDataType.Blob: case OciDataType.Clob: - OracleLob lob = (OracleLob) defineHandle.GetValue (); + OracleLob lob = (OracleLob) defineHandle.GetValue ( + Connection.SessionFormatProvider, Connection); lob.connection = Connection; output = lob.Value; lob.Close (); break; default: - output = defineHandle.GetValue (); + output = defineHandle.GetValue ( + Connection.SessionFormatProvider, Connection); break; } } } - else - output = DBNull.Value; UpdateParameterValues (); } - } - finally { + } finally { SafeDisposeHandle (statement); } return output; } + internal OciStatementHandle GetNextResult () + { + if (moreResults == -1) + return null; + + if (Parameters.Count > 0) { + int p = moreResults + 1; + + if (p >= Parameters.Count) { + moreResults = -1; + return null; + } + + for (; p < Parameters.Count; p++) { + OracleParameter parm = Parameters [p]; + if (parm.OracleType.Equals (OracleType.Cursor)) { + if (parm.Direction != ParameterDirection.Input) { + if (p + 1 == Parameters.Count) + moreResults = -1; + else + moreResults = p; + return parm.GetOutRefCursor (this); + + } + } + } + } + + moreResults = -1; + return null; + } + private OciStatementHandle GetStatementHandle () { AssertConnectionIsOpen (); - if (preparedStatement != null) + if (preparedStatement != null) return preparedStatement; - + OciStatementHandle h = (OciStatementHandle) Connection.Environment.Allocate (OciHandleType.Statement); h.ErrorHandle = Connection.ErrorHandle; h.Service = Connection.ServiceContext; @@ -532,10 +705,11 @@ namespace System.Data.OracleClient { private void SafeDisposeHandle (OciStatementHandle h) { - if (h != null && h != preparedStatement) + if (h != null && h != preparedStatement) h.Dispose(); } +#if !NET_2_0 IDbDataParameter IDbCommand.CreateParameter () { return CreateParameter (); @@ -550,8 +724,9 @@ namespace System.Data.OracleClient { { return ExecuteReader (behavior); } +#endif - void PrepareStatement (OciStatementHandle statement) + void PrepareStatement (OciStatementHandle statement) { if (commandType == CommandType.StoredProcedure) { StringBuilder sb = new StringBuilder (); @@ -559,17 +734,20 @@ namespace System.Data.OracleClient { foreach (OracleParameter parm in Parameters) { if (sb.Length > 0) sb.Append (","); - sb.Append (":" + parm.ParameterName); + sb.Append (parm.ParameterName + "=>:" + parm.ParameterName); } - string sql = "call " + commandText + "(" + sb.ToString() + ")"; + string sql = "begin " + commandText + "(" + sb.ToString() + "); end;"; statement.Prepare (sql); - } - else // Text + } else // Text statement.Prepare (commandText); } - public void Prepare () + public +#if NET_2_0 + override +#endif + void Prepare () { AssertConnectionIsOpen (); OciStatementHandle statement = GetStatementHandle (); @@ -577,6 +755,15 @@ namespace System.Data.OracleClient { preparedStatement = statement; } + protected override void Dispose (bool disposing) + { + if (disposing) + if (Parameters.Count > 0) + foreach (OracleParameter parm in Parameters) + parm.FreeHandle (); + base.Dispose (disposing); + } + #endregion // Methods } }