|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.