| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- //
- // OracleCommand.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:
- // Daniel Morgan <[email protected]>
- // Tim Coleman <[email protected]>
- //
- // Copyright (C) Daniel Morgan, 2002, 2004-2005
- // Copyright (C) Tim Coleman , 2003
- //
- // Licensed under the MIT/X11 License.
- //
- using System;
- using System.ComponentModel;
- using System.Data;
- using System.Data.OracleClient.Oci;
- using System.Drawing.Design;
- using System.Text;
- namespace System.Data.OracleClient {
- [Designer ("Microsoft.VSDesigner.Data.VS.OracleCommandDesigner, " + Consts.AssemblyMicrosoft_VSDesigner)]
- [ToolboxItem (true)]
- public sealed class OracleCommand : Component, ICloneable, IDbCommand
- {
- #region Fields
- CommandBehavior behavior;
- string commandText;
- CommandType commandType;
- OracleConnection connection;
- bool designTimeVisible;
- OracleParameterCollection parameters;
- OracleTransaction transaction;
- UpdateRowSource updatedRowSource;
- private OciStatementHandle preparedStatement;
- OciStatementType statementType;
- #endregion // Fields
- #region Constructors
- public OracleCommand ()
- : this (String.Empty, null, null)
- {
- }
- public OracleCommand (string commandText)
- : this (commandText, null, null)
- {
- }
- public OracleCommand (string commandText, OracleConnection connection)
- : this (commandText, connection, null)
- {
- }
- public OracleCommand (string commandText, OracleConnection connection, OracleTransaction tx)
- {
- preparedStatement = null;
- CommandText = commandText;
- Connection = connection;
- Transaction = tx;
- CommandType = CommandType.Text;
- UpdatedRowSource = UpdateRowSource.Both;
- DesignTimeVisible = false;
- parameters = new OracleParameterCollection (this);
- }
- #endregion // Constructors
- #region Properties
- [DefaultValue ("")]
- [RefreshProperties (RefreshProperties.All)]
- [Editor ("Microsoft.VSDesigner.Data.Oracle.Design.OracleCommandTextEditor, " + Consts.AssemblyMicrosoft_VSDesigner, typeof(UITypeEditor))]
- public string CommandText {
- get { return commandText; }
- set { commandText = value; }
- }
- [RefreshProperties (RefreshProperties.All)]
- [DefaultValue (CommandType.Text)]
- public CommandType CommandType {
- get { return commandType; }
- set {
- if (value == CommandType.TableDirect)
- throw new ArgumentException ("OracleClient provider does not support TableDirect CommandType.");
- commandType = value;
- }
- }
- [DefaultValue (null)]
- [Editor ("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, " + Consts.AssemblyMicrosoft_VSDesigner, typeof(UITypeEditor))]
- public OracleConnection Connection {
- get { return connection; }
- set { connection = value; }
- }
- [DefaultValue (true)]
- [Browsable (false)]
- [DesignOnly (true)]
- public bool DesignTimeVisible {
- get { return designTimeVisible; }
- set { designTimeVisible = value; }
- }
- internal OciEnvironmentHandle Environment {
- get { return Connection.Environment; }
- }
- internal OciErrorHandle ErrorHandle {
- get { return Connection.ErrorHandle; }
- }
- int IDbCommand.CommandTimeout {
- get { return 0; }
- set { }
- }
- [Editor ("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, " + Consts.AssemblyMicrosoft_VSDesigner, typeof(UITypeEditor))]
- [DefaultValue (null)]
- IDbConnection IDbCommand.Connection {
- get { return Connection; }
- set {
- if (!(value is OracleConnection))
- throw new InvalidCastException ("The value was not a valid OracleConnection.");
- Connection = (OracleConnection) value;
- }
- }
- IDataParameterCollection IDbCommand.Parameters {
- get { return Parameters; }
- }
- IDbTransaction IDbCommand.Transaction {
- get { return Transaction; }
- set {
- if (!(value is OracleTransaction))
- throw new ArgumentException ();
- Transaction = (OracleTransaction) value;
- }
- }
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
- public OracleParameterCollection Parameters {
- get { return parameters; }
- }
- [Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public OracleTransaction Transaction {
- get { return transaction; }
- set { transaction = value; }
- }
- [DefaultValue (UpdateRowSource.Both)]
- public UpdateRowSource UpdatedRowSource {
- get { return updatedRowSource; }
- set { updatedRowSource = value; }
- }
- #endregion
- #region Methods
- private void AssertCommandTextIsSet ()
- {
- if (CommandText == String.Empty || CommandText == null)
- throw new InvalidOperationException ("The command text for this Command has not been set.");
- }
- private void AssertConnectionIsOpen ()
- {
- if (Connection == null || Connection.State == ConnectionState.Closed)
- 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)
- throw new InvalidOperationException ("Execute requires the Command object to have a Transaction object when the Connection object assigned to the command is in a pending local transaction. The Transaction property of the Command has not been initialized.");
- }
- private void BindParameters (OciStatementHandle statement)
- {
- foreach (OracleParameter p in Parameters)
- p.Bind (statement, Connection);
- }
- [MonoTODO]
- public void Cancel ()
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- public object Clone ()
- {
- // create a new OracleCommand object with the same properties
-
- OracleCommand cmd = new OracleCommand ();
-
- cmd.CommandText = this.CommandText;
- cmd.CommandType = this.CommandType;
- // FIXME: not sure if I should set the same object here
- // 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 ();
- newParm.DbType = parm.DbType;
- newParm.Direction = parm.Direction;
- newParm.IsNullable = parm.IsNullable;
- newParm.Offset = parm.Offset;
- newParm.OracleType = parm.OracleType;
- newParm.ParameterName = parm.ParameterName;
- newParm.Precision = parm.Precision;
- newParm.Scale = parm.Scale;
- newParm.SourceColumn = parm.SourceColumn;
- newParm.SourceVersion = parm.SourceVersion;
- newParm.Value = parm.Value;
- cmd.Parameters.Add (newParm);
- }
- //cmd.Container = this.Container;
- cmd.DesignTimeVisible = this.DesignTimeVisible;
- //cmd.DesignMode = this.DesignMode;
- cmd.Site = this.Site;
- //cmd.UpdateRowSource = this.UpdateRowSource;
- return cmd;
- }
- internal void CloseDataReader ()
- {
- Connection.DataReader = null;
- if ((behavior & CommandBehavior.CloseConnection) != 0)
- Connection.Close ();
- }
- public OracleParameter CreateParameter ()
- {
- return new OracleParameter ();
- }
- private int ExecuteNonQueryInternal (OciStatementHandle statement, bool useAutoCommit)
- {
- if (preparedStatement == null)
- PrepareStatement (statement);
- bool isNonQuery = IsNonQuery (statement);
- BindParameters (statement);
- if (isNonQuery == true)
- statement.ExecuteNonQuery (useAutoCommit);
- else
- statement.ExecuteQuery ();
- int rowsAffected = statement.GetAttributeInt32 (OciAttributeType.RowCount, ErrorHandle);
-
- return rowsAffected;
- }
- public int ExecuteNonQuery ()
- {
- AssertConnectionIsOpen ();
- AssertTransactionMatch ();
- AssertCommandTextIsSet ();
- bool useAutoCommit = false;
- if (Transaction != null)
- Transaction.AttachToServiceContext ();
- else
- useAutoCommit = true;
- OciStatementHandle statement = GetStatementHandle ();
- try {
- return ExecuteNonQueryInternal (statement, useAutoCommit);
- }
- finally {
- SafeDisposeHandle (statement);
- }
- }
- public int ExecuteOracleNonQuery (out OracleString rowid)
- {
- AssertConnectionIsOpen ();
- AssertTransactionMatch ();
- AssertCommandTextIsSet ();
- bool useAutoCommit = false;
- if (Transaction != null)
- Transaction.AttachToServiceContext ();
- else
- useAutoCommit = true;
- OciStatementHandle statement = GetStatementHandle ();
- 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));
- return retval;
- }
- finally {
- SafeDisposeHandle (statement);
- }
- }
- [MonoTODO]
- public object ExecuteOracleScalar ()
- {
- object output = DBNull.Value;
- AssertConnectionIsOpen ();
- AssertTransactionMatch ();
- AssertCommandTextIsSet ();
- if (Transaction != null)
- Transaction.AttachToServiceContext ();
- OciStatementHandle statement = GetStatementHandle ();
- try {
- if (preparedStatement == null)
- PrepareStatement (statement);
- bool isNonQuery = IsNonQuery (statement);
- BindParameters (statement);
- if (isNonQuery == true)
- ExecuteNonQueryInternal (statement, false);
- else {
- statement.ExecuteQuery ();
- if (statement.Fetch ()) {
- OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [0];
- if (!defineHandle.IsNull)
- output = defineHandle.GetOracleValue ();
- switch (defineHandle.DataType) {
- case OciDataType.Blob:
- case OciDataType.Clob:
- ((OracleLob) output).connection = Connection;
- break;
- }
- }
- }
- return output;
- }
- finally {
- SafeDisposeHandle (statement);
- }
- }
- private bool IsNonQuery (OciStatementHandle statementHandle)
- {
- // assumes Prepare() has been called prior to calling this function
- OciStatementType statementType = statementHandle.GetStatementType ();
- if (statementType.Equals (OciStatementType.Select))
- return false;
- return true;
- }
- public OracleDataReader ExecuteReader ()
- {
- return ExecuteReader (CommandBehavior.Default);
- }
- public OracleDataReader ExecuteReader (CommandBehavior behavior)
- {
- AssertConnectionIsOpen ();
- AssertTransactionMatch ();
- AssertCommandTextIsSet ();
- AssertNoDataReader ();
- bool hasRows = false;
- this.behavior = behavior;
-
- if (Transaction != null)
- Transaction.AttachToServiceContext ();
-
- OciStatementHandle statement = GetStatementHandle ();
- OracleDataReader rd = null;
- try {
- if (preparedStatement == null)
- PrepareStatement (statement);
- else
- preparedStatement = null; // OracleDataReader releases the statement handle
- bool isNonQuery = IsNonQuery (statement);
- BindParameters (statement);
- if (isNonQuery)
- ExecuteNonQueryInternal (statement, false);
- else
- hasRows = statement.ExecuteQuery ();
- rd = new OracleDataReader (this, statement, hasRows);
- }
- finally {
- if (statement != null && rd == null)
- statement.Dispose();
- }
- return rd;
- }
- public object ExecuteScalar ()
- {
- object output = DBNull.Value;
- AssertConnectionIsOpen ();
- AssertTransactionMatch ();
- AssertCommandTextIsSet ();
- if (Transaction != null)
- Transaction.AttachToServiceContext ();
- OciStatementHandle statement = GetStatementHandle ();
- try {
- if (preparedStatement == null)
- PrepareStatement (statement);
- bool isNonQuery = IsNonQuery (statement);
- BindParameters (statement);
- if (isNonQuery == true)
- ExecuteNonQueryInternal (statement, false);
- else {
- statement.ExecuteQuery ();
- if (statement.Fetch ()) {
- OciDefineHandle defineHandle = (OciDefineHandle) statement.Values [0];
- if (defineHandle.IsNull)
- output = DBNull.Value;
- else {
- switch (defineHandle.DataType) {
- case OciDataType.Blob:
- case OciDataType.Clob:
- OracleLob lob = (OracleLob) defineHandle.GetValue ();
- lob.connection = Connection;
- output = lob.Value;
- lob.Close ();
- break;
- default:
- output = defineHandle.GetValue ();
- break;
- }
- }
- }
- else
- output = DBNull.Value;
- }
- }
- finally {
- SafeDisposeHandle (statement);
- }
- return output;
- }
- private OciStatementHandle GetStatementHandle ()
- {
- AssertConnectionIsOpen ();
- if (preparedStatement != null)
- return preparedStatement;
-
- OciStatementHandle h = (OciStatementHandle) Connection.Environment.Allocate (OciHandleType.Statement);
- h.ErrorHandle = Connection.ErrorHandle;
- h.Service = Connection.ServiceContext;
- h.Command = this;
- return h;
- }
- private void SafeDisposeHandle (OciStatementHandle h)
- {
- if (h != null && h != preparedStatement)
- h.Dispose();
- }
- IDbDataParameter IDbCommand.CreateParameter ()
- {
- return CreateParameter ();
- }
- IDataReader IDbCommand.ExecuteReader ()
- {
- return ExecuteReader ();
- }
- IDataReader IDbCommand.ExecuteReader (CommandBehavior behavior)
- {
- return ExecuteReader (behavior);
- }
- void PrepareStatement (OciStatementHandle statement)
- {
- if (commandType == CommandType.StoredProcedure) {
- StringBuilder sb = new StringBuilder ();
- if (Parameters.Count > 0)
- foreach (OracleParameter parm in Parameters) {
- if (sb.Length > 0)
- sb.Append (",");
- sb.Append (":" + parm.ParameterName);
- }
- string sql = "call " + commandText + "(" + sb.ToString() + ")";
- statement.Prepare (sql);
- }
- else // Text
- statement.Prepare (commandText);
- }
- public void Prepare ()
- {
- AssertConnectionIsOpen ();
- OciStatementHandle statement = GetStatementHandle ();
- PrepareStatement (statement);
- preparedStatement = statement;
- }
- #endregion // Methods
- }
- }
|