Click here to Skip to main content
15,895,011 members
Articles / Mobile Apps

Building applications with Mono

Rate me:
Please Sign up or sign in to vote.
4.56/5 (20 votes)
6 Nov 20032 min read 94.4K   325   32  
Developing .NET cross platform applications using mono and IBM DB2
using System;
using System.Data;
using System.Runtime.InteropServices;


namespace System.Data.DB2Client
{

	public class DB2Command : IDbCommand
	{
		#region Private data members
		
		
		private string commandText;
		private CommandType commandType = CommandType.Text;
		private DB2Connection db2Conn;
		private DB2Transaction db2Trans;
		private int commandTimeout;
		private bool prepared = false;
		private IntPtr hwndStmt = IntPtr.Zero;  //Our statement handle
		private DB2ParameterCollection parameters = new DB2ParameterCollection();

		#endregion

		#region Constructors

		public DB2Command()
		{
			hwndStmt = IntPtr.Zero;
		}
		public DB2Command(string commandStr)
		{
			commandText = commandStr;
			hwndStmt = IntPtr.Zero;
			
		}
		public DB2Command(string commandStr, DB2Connection con) : this()
		{
			commandText = commandStr;
			db2Conn = con;
			AllocateStatement("Constructor 3");
		}
		public DB2Command (string commandStr, DB2Connection con, DB2Transaction trans)
		{
			commandText = commandStr;
			db2Conn = con;
			db2Trans = trans;
			AllocateStatement("Constructor 4");
		}
		///DB2 Specific constructors
		///
		public DB2Command (IntPtr hwndSt)
		{
			hwndStmt = hwndSt;
		}
		public void Dispose()
		{
		}
		#endregion
		#region SelfDescribe property
		///
		/// Property dictates whether or not any paramter markers will get their describe info
		/// from the database, or if the user will supply the information
		/// 
		bool selfDescribe = false;
		public bool SelfDescribe
		{
			get 
			{
				return selfDescribe;
			}
			set 
			{
				selfDescribe = value;
			}
		}
		#endregion
		#region CommandText property
		///
		///The query;  If it gets set, reset the prepared property
		///
		public string CommandText
		{
			get
			{
				return commandText;
			}
			set
			{
				prepared = false;
				commandText = value;
			}
		}
		#endregion
		#region CommandTimeout property
		///
		/// The Timeout property states how long we wait for results to return
		/// 
		public int CommandTimeout
		{
			get
			{
				return commandTimeout;
			}
			set 
			{
				commandTimeout = value;
			}
		}
		#endregion

		#region CommandType property
		///
		/// I believe this one is left as text all of the time for DB2, but I have to check that...
		/// 
		public CommandType CommandType
		{
			get
			{
				return commandType;
			}
			set
			{
				commandType = value;
			}
		}
		#endregion

		#region Connection property
		///
		///  The connection we'll be executing on.
		///  
		IDbConnection IDbCommand.Connection
		{
			get
			{
				return db2Conn;
			}
			set
			{
				db2Conn = (DB2Connection)value;
				AllocateStatement("Connection property set");
			}
		}

		public DB2Connection Connection
		{
			get
			{
				return db2Conn;
			}
			set
			{
				db2Conn = value;
				AllocateStatement("Connection property set");
			}
		}
		#endregion
		#region Parameters property
		///
		/// Parameter list, Not yet implemented
		/// 
		public DB2ParameterCollection Parameters
		{
			get
			{
				return parameters;
			}
		}
		IDataParameterCollection IDbCommand.Parameters
		{
			get
			{
				return parameters;
			}
		}
		#endregion

		#region Transaction property
			///
			/// The transaction this command is associated with
			/// 
			public IDbTransaction Transaction
		{
			get
			{
				return db2Trans;
			}
			set
			{
				db2Trans = (DB2Transaction)value;
			}
		}
		#endregion

		#region UpdatedRowSource property
		///
		/// Need to see how this works with DB2...
		/// 
		public UpdateRowSource UpdatedRowSource
		{
			get
			{
				throw new DB2Exception ("TBD");
			}
			set
			{
				throw new DB2Exception ("TBD");
			}
		}
		#endregion

		#region Statement Handle
		///
		/// returns the DB2Client statement handle
		/// 
		public IntPtr statementHandle
		{
			get
			{
				return hwndStmt;
			}
		}
		#endregion

		#region AllocateStatement function
		///
		/// Allocate a statement handle, internal.  Pass in the name of the caller for exception info.
		/// I think I'll make the handle a property and add a constructor with the handle argument so that 
		/// statements can be executed on the same handle if need be, though you could accomplish the same by 
		/// just keeping the command object open. 
		/// 
		internal void AllocateStatement(string location)
		{
			short sqlRet;
			sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_STMT, db2Conn.DBHandle , ref hwndStmt);
			if ((sqlRet != DB2Constants.SQL_SUCCESS) && (sqlRet != DB2Constants.SQL_SUCCESS_WITH_INFO))
				throw new DB2Exception(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, location +": Unable to allocate statement handle.");
		}
		#endregion

		#region Cancel
		/// <summary>
		/// Attempt to cancel an executing command
		/// </summary>
		public void Cancel()
		{
			DB2CLIWrapper.SQLCancel(hwndStmt);
		}
		#endregion

		#region CreateParameter
		///
		///Returns a parameter
		///
		public IDbDataParameter CreateParameter()
		{
			throw new DB2Exception("TBD");
		}
		#endregion

		#region ExecuteNonQuery
		///
		/// ExecuteNonQuery  Executes an SQL statement without returning a DataSet
		/// 
		public int ExecuteNonQuery()
		{
			if ((commandText == null) ||(commandText.Length == 0))
				throw new DB2Exception("Command string is empty");
			short sqlRet;
			if (prepared)
				sqlRet = DB2CLIWrapper.SQLExecute(hwndStmt);
			else
				sqlRet = DB2CLIWrapper.SQLExecDirect(hwndStmt, commandText, commandText.Length);
			
			int numRows = 0;
			sqlRet = DB2CLIWrapper.SQLRowCount(hwndStmt, ref numRows);   //How many rows affected.  numRows will be -1 if we aren't dealing with an Insert, Delete or Update, or if the statement did not execute successfully
			///At this point, I think we need to save any results, but not return them
			///For now, we will go execute and return the number of rows affected
			return numRows;
		}
		#endregion

		#region ExecuteReader calls
		///
		///ExecuteReader
		///
		IDataReader IDbCommand.ExecuteReader()
		{
			return ExecuteReader();
		}

		public DB2DataReader ExecuteReader()
		{
			DB2DataReader reader;

			
			if (!prepared) 
			{
				ExecuteNonQuery();
				reader = new DB2DataReader(db2Conn, this);
			}
			else
				reader = new DB2DataReader(db2Conn, this, true);
			
			return reader;
		}

		public IDataReader ExecuteReader(CommandBehavior behavior)
		{
			throw new DB2Exception("TBD");
		}
		#endregion

		#region ExecuteScalar
		///
		/// ExecuteScalar
		/// 
		public object ExecuteScalar()
		{
			throw new DB2Exception("TBD");
		}
		#endregion

		#region Prepare ()
		///
		/// Prepare a statement against the database
		/// 
		public void Prepare ()
		{
		
			short sqlRet = 0;

			IntPtr numParams = IntPtr.Zero;
			sqlRet = DB2CLIWrapper.SQLPrepare(hwndStmt, commandText, commandText.Length);
			DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLPrepare error.");
			short i=1;
			foreach ( DB2Parameter param in parameters) 
			{
				if (selfDescribe) 
				{
					sqlRet = param.Describe(this.hwndStmt, i);
					DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Error binding parameter in DB2Command: ");
				}
				sqlRet = param.Bind(this.hwndStmt, i);
				DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Error binding parameter in DB2Command: ");
				i++;
			}
			prepared=true;
		}
		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions