Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Vatamanescu <victor@mono-cvs.ximian.com>2004-03-03 14:44:45 +0300
committerVictor Vatamanescu <victor@mono-cvs.ximian.com>2004-03-03 14:44:45 +0300
commit58884f3043adb6876f7489a0e9e412602247e1fd (patch)
tree30182cc881dab435df121c86185368ca7673850e /mcs/class/IBM.Data.DB2
parent526a90447189d3f0f1606a512445aead15d86fff (diff)
*** empty log message ***
svn path=/trunk/mcs/; revision=23646
Diffstat (limited to 'mcs/class/IBM.Data.DB2')
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2CLIWrapper.cs344
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ClientUtils.cs39
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Command.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Command.cs)263
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Connection.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Connection.cs)410
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ConnectionPool.cs194
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ConnectionSettings.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ConnectionSettings.cs)32
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Constants.cs179
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2DataReader.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2DataReader.cs)1976
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Environment.cs69
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Error.cs41
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ErrorCollection.cs111
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Exception.cs66
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2InfoMessageEventArgs.cs48
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2OpenConnection.cs196
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Parameter.cs673
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ParameterCollection.cs135
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatedEventArgs.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatedEventArgs.cs)0
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatedEventHandler.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatedEventHandler.cs)0
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatingEventArgs.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatingEventArgs.cs)0
-rwxr-xr-x[-rw-r--r--]mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatingEventHandler.cs (renamed from mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatingEventHandler.cs)0
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Transaction.cs121
-rwxr-xr-xmcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Type.cs35
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2CLIWrapper.cs134
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ClientUtils.cs29
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ConnectionPool.cs288
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Constants.cs184
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2DataAdapter.cs163
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Exception.cs46
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Parameter.cs498
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ParameterCollection.cs103
-rw-r--r--mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Transaction.cs93
31 files changed, 3819 insertions, 2651 deletions
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2CLIWrapper.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2CLIWrapper.cs
new file mode 100755
index 00000000000..ef823991b69
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2CLIWrapper.cs
@@ -0,0 +1,344 @@
+using System;
+using System.Data;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace IBM.Data.DB2
+{
+ /// <summary>
+ /// DB2Prototypes class is a wrapper for the DB2.lib, IBM's Call Level Interface to DB2
+ /// </summary>
+ ///
+
+ internal class DB2CLIWrapper
+ {
+ static bool useLibCli;
+
+ static public short Initialize(ref IntPtr pEnvHandle)
+ {
+ useLibCli = false;
+ try
+ {
+ return DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_ENV, IntPtr.Zero, out pEnvHandle);
+ }
+ catch {}
+ useLibCli = false;
+ return DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_ENV, IntPtr.Zero, out pEnvHandle);
+ }
+
+ static public short SQLAllocHandle(short handleType, IntPtr inputHandle, out IntPtr outputHandle)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLAllocHandle(handleType, inputHandle, out outputHandle);
+ return StaticWrapper36.SQLAllocHandle(handleType, inputHandle, out outputHandle);
+ }
+ static public short SQLFreeHandle(short handleType, IntPtr inputHandle)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLFreeHandle(handleType, inputHandle);
+ return StaticWrapper36.SQLFreeHandle(handleType, inputHandle);
+ }
+ static public short SQLFreeStmt(IntPtr StatementHandle, short option)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLFreeStmt(StatementHandle, option);
+ return StaticWrapper36.SQLFreeStmt(StatementHandle, option);
+ }
+ static public short SQLConnect(IntPtr sqlHdbc, string serverName, short serverNameLength, string userName, short userNameLength, string authentication, short authenticationLength)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLConnect(sqlHdbc, serverName, serverNameLength, userName, userNameLength, authentication, authenticationLength);
+ return StaticWrapper36.SQLConnect(sqlHdbc, serverName, serverNameLength, userName, userNameLength, authentication, authenticationLength);
+ }
+ static public short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, StringBuilder CharacterAttribute, short BufferLength, out short StringLength, out int NumericAttribute)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, out StringLength, out NumericAttribute);
+ return StaticWrapper36.SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, out StringLength, out NumericAttribute);
+ }
+ static public short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, IntPtr ValuePtr, int BufferLength, out int StringLengthPtr)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLGetConnectAttr(ConnectionHandle, Attribute, ValuePtr, BufferLength, out StringLengthPtr);
+ return StaticWrapper36.SQLGetConnectAttr(ConnectionHandle, Attribute, ValuePtr, BufferLength, out StringLengthPtr);
+ }
+ static public short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, out int Value, int BufferLength, IntPtr Zero)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLGetConnectAttr(ConnectionHandle, Attribute, out Value, BufferLength, Zero);
+ return StaticWrapper36.SQLGetConnectAttr(ConnectionHandle, Attribute, out Value, BufferLength, Zero);
+ }
+ static public short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, IntPtr CharacterAttribute, short BufferLength, ref short StringLength, ref int NumericAttribute)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, ref StringLength, ref NumericAttribute);
+ return StaticWrapper36.SQLColAttribute(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, ref StringLength, ref NumericAttribute);
+ }
+ static public short SQLMoreResults(IntPtr StatementHandle)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLMoreResults(StatementHandle);
+ return StaticWrapper36.SQLMoreResults(StatementHandle);
+ }
+ static public short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, StringBuilder sb, int BufferLength, out int StrLen_or_Ind)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLGetData(StatementHandle, ColumnNumber, TargetType, sb, BufferLength, out StrLen_or_Ind);
+ return StaticWrapper36.SQLGetData(StatementHandle, ColumnNumber, TargetType, sb, BufferLength, out StrLen_or_Ind);
+ }
+ static public short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, IntPtr TargetPtr, int BufferLength, out int StrLen_or_Ind)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLGetData(StatementHandle, ColumnNumber, TargetType, TargetPtr, BufferLength, out StrLen_or_Ind);
+ return StaticWrapper36.SQLGetData(StatementHandle, ColumnNumber, TargetType, TargetPtr, BufferLength, out StrLen_or_Ind);
+ }
+ static public short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, byte[] TargetPtr, int BufferLength, out int StrLen_or_Ind)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLGetData(StatementHandle, ColumnNumber, TargetType, TargetPtr, BufferLength, out StrLen_or_Ind);
+ return StaticWrapper36.SQLGetData(StatementHandle, ColumnNumber, TargetType, TargetPtr, BufferLength, out StrLen_or_Ind);
+ }
+ static public short SQLDisconnect(IntPtr sqlHdbc)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLDisconnect(sqlHdbc);
+ return StaticWrapper36.SQLDisconnect(sqlHdbc);
+ }
+ static public short SQLGetDiagRec( short handleType, IntPtr handle, short recNum, StringBuilder sqlState, out int nativeError, StringBuilder errorMessage, int bufferLength, out short textLengthPtr)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLGetDiagRec( handleType, handle, recNum, sqlState, out nativeError, errorMessage, bufferLength, out textLengthPtr);
+ return StaticWrapper36.SQLGetDiagRec( handleType, handle, recNum, sqlState, out nativeError, errorMessage, bufferLength, out textLengthPtr);
+ }
+ static public short SQLSetConnectAttr(IntPtr sqlHdbc, int sqlAttr, IntPtr sqlValuePtr, int sqlValueLength)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLSetConnectAttr(sqlHdbc, sqlAttr, sqlValuePtr, sqlValueLength);
+ return StaticWrapper36.SQLSetConnectAttr(sqlHdbc, sqlAttr, sqlValuePtr, sqlValueLength);
+ }
+ static public short SQLSetStmtAttr(IntPtr sqlHdbc, int sqlAttr, IntPtr sqlValuePtr, int sqlValueLength)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLSetStmtAttr(sqlHdbc, sqlAttr, sqlValuePtr, sqlValueLength);
+ return StaticWrapper36.SQLSetStmtAttr(sqlHdbc, sqlAttr, sqlValuePtr, sqlValueLength);
+ }
+ static public short SQLEndTran (short handleType, IntPtr handle, short fType)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLEndTran (handleType, handle, fType);
+ return StaticWrapper36.SQLEndTran (handleType, handle, fType);
+ }
+ static public short SQLCancel(IntPtr handle)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLCancel(handle);
+ return StaticWrapper36.SQLCancel(handle);
+ }
+ static public short SQLNumResultCols(IntPtr handle, out short numCols)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLNumResultCols(handle, out numCols);
+ return StaticWrapper36.SQLNumResultCols(handle, out numCols);
+ }
+ static public short SQLFetch(IntPtr handle)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLFetch(handle);
+ return StaticWrapper36.SQLFetch(handle);
+ }
+ static public short SQLRowCount(IntPtr stmtHandle, out int numRows)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLRowCount(stmtHandle, out numRows);
+ return StaticWrapper36.SQLRowCount(stmtHandle, out numRows);
+ }
+ static public short SQLExecute(IntPtr handle)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLExecute(handle);
+ return StaticWrapper36.SQLExecute(handle);
+ }
+ static public short SQLExecDirect(IntPtr stmtHandle, string stmt, int length)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLExecDirect(stmtHandle, stmt, length);
+ return StaticWrapper36.SQLExecDirect(stmtHandle, stmt, length);
+ }
+ static public short SQLDriverConnect(IntPtr hdbc, IntPtr windowHandle, string inConnectStr, short inStrLength, StringBuilder outConnectStr, short outStrCapacity, out short outStrLengthReturned, int completion)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLDriverConnect(hdbc, windowHandle, inConnectStr, inStrLength, outConnectStr, outStrCapacity, out outStrLengthReturned, completion);
+ return StaticWrapper36.SQLDriverConnect(hdbc, windowHandle, inConnectStr, inStrLength, outConnectStr, outStrCapacity, out outStrLengthReturned, completion);
+ }
+ static public short SQLPrepare(IntPtr stmtHandle, string stmt, int length)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLPrepare(stmtHandle, stmt, length);
+ return StaticWrapper36.SQLPrepare(stmtHandle, stmt, length);
+ }
+ static public short SQLBindParameter(IntPtr stmtHandle, short paramNumber, short dataType, short valueType, short paramType, int colSize, short decDigits, IntPtr dataBufferPtr, int dataBufferLength, IntPtr StrLen_or_IndPtr)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLBindParameter(stmtHandle, paramNumber, dataType, valueType, paramType, colSize, decDigits, dataBufferPtr, dataBufferLength, StrLen_or_IndPtr);
+ return StaticWrapper36.SQLBindParameter(stmtHandle, paramNumber, dataType, valueType, paramType, colSize, decDigits, dataBufferPtr, dataBufferLength, StrLen_or_IndPtr);
+ }
+ public static short SQLGetInfo(IntPtr sqlHdbc, short fInfoType, [Out] StringBuilder rgbInfoValue, short cbInfoValueMax, out short pcbInfoValue)
+ {
+ if(useLibCli)
+ return StaticWrapperCli.SQLGetInfo(sqlHdbc, fInfoType, rgbInfoValue, cbInfoValueMax, out pcbInfoValue);
+ return StaticWrapper36.SQLGetInfo(sqlHdbc, fInfoType, rgbInfoValue, cbInfoValueMax, out pcbInfoValue);
+ }
+
+ /// <summary>
+ /// db2Prototypes class is a wrapper for the db2.lib, IBM's Call Level Interface to Db2
+ /// </summary>
+ public class StaticWrapperCli
+ {
+ private const string libname = "db2cli";
+
+ [DllImport(libname, EntryPoint = "SQLAllocHandle")]
+ public static extern short SQLAllocHandle(short handleType, IntPtr inputHandle, out IntPtr outputHandle);
+ [DllImport(libname, EntryPoint = "SQLFreeHandle")]
+ public static extern short SQLFreeHandle(short handleType, IntPtr inputHandle);
+
+ [DllImport(libname, EntryPoint = "SQLFreeStmt")]
+ public static extern short SQLFreeStmt(IntPtr StatementHandle, short option);
+
+ [DllImport(libname, EntryPoint = "SQLConnectW", CharSet=CharSet.Unicode)]
+
+ public static extern short SQLConnect(IntPtr sqlHdbc, string serverName, short serverNameLength, string userName, short userNameLength, string authentication, short authenticationLength);
+ [DllImport(libname, EntryPoint = "SQLColAttributeW", CharSet=CharSet.Unicode)]
+ public static extern short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, [Out] StringBuilder CharacterAttribute, short BufferLength, out short StringLength, out int NumericAttribute);
+
+ [DllImport(libname, EntryPoint = "SQLGetConnectAttrW", CharSet=CharSet.Unicode)]
+ public static extern short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, [Out] IntPtr ValuePtr, int BufferLength, out int StringLengthPtr);
+
+ [DllImport(libname, EntryPoint = "SQLGetConnectAttrW", CharSet=CharSet.Unicode)]
+ public static extern short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, out int Value, int BufferLength, IntPtr Zero);
+
+ [DllImport(libname, EntryPoint = "SQLColAttributeW", CharSet=CharSet.Unicode)]
+ public static extern short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, IntPtr CharacterAttribute, short BufferLength, ref short StringLength, ref int NumericAttribute);
+ [DllImport(libname, EntryPoint="SQLMoreResults")]
+ public static extern short SQLMoreResults(IntPtr StatementHandle);
+
+ [DllImport(libname, EntryPoint = "SQLGetData")]
+ public static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, [Out] StringBuilder sb, int BufferLength, out int StrLen_or_Ind);
+
+ [DllImport(libname, EntryPoint = "SQLGetData")]
+ public static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, IntPtr TargetPtr, int BufferLength, out int StrLen_or_Ind);
+
+ [DllImport(libname, EntryPoint = "SQLGetData")]
+ public static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, [Out] byte[] TargetPtr, int BufferLength, out int StrLen_or_Ind);
+
+ [DllImport(libname, EntryPoint = "SQLDisconnect")]
+ public static extern short SQLDisconnect(IntPtr sqlHdbc);
+
+ [DllImport(libname, EntryPoint = "SQLGetDiagRec")]
+ public static extern short SQLGetDiagRec( short handleType, IntPtr handle, short recNum, [Out] StringBuilder sqlState, out int nativeError, [Out] StringBuilder errorMessage, int bufferLength, out short textLengthPtr);
+
+ [DllImport(libname, EntryPoint = "SQLSetConnectAttr")]
+ public static extern short SQLSetConnectAttr(IntPtr sqlHdbc, int sqlAttr, [In] IntPtr sqlValuePtr, int sqlValueLength);
+ [DllImport(libname, EntryPoint = "SQLSetStmtAttr")]
+ public static extern short SQLSetStmtAttr(IntPtr sqlHdbc, int sqlAttr, [In] IntPtr sqlValuePtr, int sqlValueLength);
+ [DllImport(libname, EntryPoint = "SQLEndTran")]
+ public static extern short SQLEndTran (short handleType, IntPtr handle, short fType);
+ [DllImport(libname, EntryPoint = "SQLCancel")]
+ public static extern short SQLCancel(IntPtr handle);
+ [DllImport(libname, EntryPoint = "SQLNumResultCols")]
+ public static extern short SQLNumResultCols(IntPtr handle, out short numCols);
+ [DllImport(libname, EntryPoint = "SQLFetch")]
+ public static extern short SQLFetch(IntPtr handle);
+ [DllImport(libname, EntryPoint = "SQLRowCount")]
+ public static extern short SQLRowCount(IntPtr stmtHandle, out int numRows);
+ [DllImport(libname, EntryPoint = "SQLExecute")]
+ public static extern short SQLExecute(IntPtr handle);
+ [DllImport (libname, EntryPoint = "SQLExecDirectW", CharSet=CharSet.Unicode)]
+ public static extern short SQLExecDirect(IntPtr stmtHandle, string stmt, int length);
+ [DllImport(libname, EntryPoint = "SQLDriverConnectW", CharSet=CharSet.Unicode)]
+ public static extern short SQLDriverConnect(IntPtr hdbc, IntPtr windowHandle, [In] string inConnectStr, [In] short inStrLength, [Out] StringBuilder outConnectStr, [Out] short outStrCapacity, out short outStrLengthReturned, [In] int completion);
+ [DllImport(libname, EntryPoint = "SQLPrepareW", CharSet=CharSet.Unicode)]
+ public static extern short SQLPrepare(IntPtr stmtHandle, string stmt, int length);
+ [DllImport(libname)]
+ public static extern short SQLBindParameter(IntPtr stmtHandle, short paramNumber,
+ short dataType, short valueType, short paramType, int colSize, short decDigits,
+ IntPtr dataBufferPtr, int dataBufferLength, IntPtr StrLen_or_IndPtr);
+ [DllImport(libname, EntryPoint = "SQLGetInfoW", CharSet=CharSet.Unicode)]
+ public static extern short SQLGetInfo(IntPtr sqlHdbc, short fInfoType, [Out] StringBuilder rgbInfoValue, short cbInfoValueMax, out short pcbInfoValue);
+ }
+
+ public class StaticWrapper36
+ {
+ private const string libname = "db2_36";
+
+ [DllImport(libname, EntryPoint = "SQLAllocHandle")]
+ public static extern short SQLAllocHandle(short handleType, IntPtr inputHandle, out IntPtr outputHandle);
+ [DllImport(libname, EntryPoint = "SQLFreeHandle")]
+ public static extern short SQLFreeHandle(short handleType, IntPtr inputHandle);
+
+ [DllImport(libname, EntryPoint = "SQLFreeStmt")]
+ public static extern short SQLFreeStmt(IntPtr StatementHandle, short option);
+
+ [DllImport(libname, EntryPoint = "SQLConnect")]
+
+ public static extern short SQLConnect(IntPtr sqlHdbc, string serverName, short serverNameLength, string userName, short userNameLength, string authentication, short authenticationLength);
+ [DllImport(libname, EntryPoint = "SQLColAttributeW", CharSet=CharSet.Unicode)]
+ public static extern short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, [Out] StringBuilder CharacterAttribute, short BufferLength, out short StringLength, out int NumericAttribute);
+
+ [DllImport(libname, EntryPoint = "SQLGetConnectAttrW", CharSet=CharSet.Unicode)]
+ public static extern short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, [Out] IntPtr ValuePtr, int BufferLength, out int StringLengthPtr);
+
+ [DllImport(libname, EntryPoint = "SQLGetConnectAttrW", CharSet=CharSet.Unicode)]
+ public static extern short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, out int Value, int BufferLength, IntPtr Zero);
+
+ [DllImport(libname, EntryPoint = "SQLColAttributeW", CharSet=CharSet.Unicode)]
+ public static extern short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, IntPtr CharacterAttribute, short BufferLength, ref short StringLength, ref int NumericAttribute);
+ [DllImport(libname, EntryPoint="SQLMoreResults")]
+ public static extern short SQLMoreResults(IntPtr StatementHandle);
+
+ [DllImport(libname, EntryPoint = "SQLGetData")]
+ public static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, [Out] StringBuilder sb, int BufferLength, out int StrLen_or_Ind);
+
+ [DllImport(libname, EntryPoint = "SQLGetData")]
+ public static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, IntPtr TargetPtr, int BufferLength, out int StrLen_or_Ind);
+
+ [DllImport(libname, EntryPoint = "SQLGetData")]
+ public static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, [Out] byte[] TargetPtr, int BufferLength, out int StrLen_or_Ind);
+
+ [DllImport(libname, EntryPoint = "SQLDisconnect")]
+ public static extern short SQLDisconnect(IntPtr sqlHdbc);
+
+ [DllImport(libname, EntryPoint = "SQLGetDiagRec")]
+ public static extern short SQLGetDiagRec( short handleType, IntPtr handle, short recNum, [Out] StringBuilder sqlState, out int nativeError, [Out] StringBuilder errorMessage, int bufferLength, out short textLengthPtr);
+
+ [DllImport(libname, EntryPoint = "SQLSetConnectAttr")]
+ public static extern short SQLSetConnectAttr(IntPtr sqlHdbc, int sqlAttr, [In] IntPtr sqlValuePtr, int sqlValueLength);
+ [DllImport(libname, EntryPoint = "SQLSetStmtAttr")]
+ public static extern short SQLSetStmtAttr(IntPtr sqlHdbc, int sqlAttr, [In] IntPtr sqlValuePtr, int sqlValueLength);
+ [DllImport(libname, EntryPoint = "SQLEndTran")]
+ public static extern short SQLEndTran (short handleType, IntPtr handle, short fType);
+ [DllImport(libname, EntryPoint = "SQLCancel")]
+ public static extern short SQLCancel(IntPtr handle);
+ [DllImport(libname, EntryPoint = "SQLNumResultCols")]
+ public static extern short SQLNumResultCols(IntPtr handle, out short numCols);
+ [DllImport(libname, EntryPoint = "SQLFetch")]
+ public static extern short SQLFetch(IntPtr handle);
+ [DllImport(libname, EntryPoint = "SQLRowCount")]
+ public static extern short SQLRowCount(IntPtr stmtHandle, out int numRows);
+ [DllImport(libname, EntryPoint = "SQLExecute")]
+ public static extern short SQLExecute(IntPtr handle);
+ [DllImport (libname, EntryPoint = "SQLExecDirectW", CharSet=CharSet.Unicode)]
+ public static extern short SQLExecDirect(IntPtr stmtHandle, string stmt, int length);
+ [DllImport(libname, EntryPoint = "SQLDriverConnectW", CharSet=CharSet.Unicode)]
+ public static extern short SQLDriverConnect(IntPtr hdbc, IntPtr windowHandle, [In] string inConnectStr, [In] short inStrLength, [Out] StringBuilder outConnectStr, [Out] short outStrCapacity, out short outStrLengthReturned, [In] int completion);
+ [DllImport(libname, EntryPoint = "SQLPrepareW", CharSet=CharSet.Unicode)]
+ public static extern short SQLPrepare(IntPtr stmtHandle, string stmt, int length);
+ [DllImport(libname)]
+ public static extern short SQLBindParameter(IntPtr stmtHandle, short paramNumber,
+ short dataType, short valueType, short paramType, int colSize, short decDigits,
+ IntPtr dataBufferPtr, int dataBufferLength, IntPtr StrLen_or_IndPtr);
+ [DllImport(libname, EntryPoint = "SQLGetInfo")]
+ public static extern short SQLGetInfo(IntPtr sqlHdbc, short fInfoType, [Out] StringBuilder rgbInfoValue, short cbInfoValueMax, out short pcbInfoValue);
+
+ }
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ClientUtils.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ClientUtils.cs
new file mode 100755
index 00000000000..324f16a8a13
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ClientUtils.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace IBM.Data.DB2
+{
+
+ public class DB2ClientUtils
+ {
+
+ #region DB2CheckReturn
+
+ public static void DB2CheckReturn(short sqlRet, short handleType, IntPtr handle, string message, DB2Connection connection)
+ {
+ switch (sqlRet)
+ {
+ case DB2Constants.SQL_SUCCESS_WITH_INFO:
+ if(connection != null)
+ {
+ connection.OnInfoMessage(handleType, handle);
+ }
+ goto case DB2Constants.SQL_SUCCESS;
+ case DB2Constants.SQL_SUCCESS:
+ case DB2Constants.SQL_NO_DATA:
+ return;
+
+ case DB2Constants.SQL_INVALID_HANDLE:
+ throw new ArgumentException("Invalid handle");
+
+ default:
+ case DB2Constants.SQL_ERROR:
+ throw new DB2Exception(handleType, handle, message);
+ }
+ }
+ public static void DB2CheckReturn(short sqlRet, short handleType, IntPtr handle, string message)
+ {
+ DB2CheckReturn(sqlRet, handleType, handle, message, null);
+ }
+ #endregion
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Command.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Command.cs
index d27138a3bf0..bbcb5fad466 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Command.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Command.cs
@@ -6,22 +6,25 @@ using System.Runtime.InteropServices;
namespace IBM.Data.DB2
{
- public class DB2Command : System.ComponentModel.Component,IDbCommand
+ public class DB2Command : System.ComponentModel.Component, IDbCommand, ICloneable
{
#region Private data members
-
private WeakReference refDataReader;
private string commandText;
private CommandType commandType = CommandType.Text;
private DB2Connection db2Conn;
private DB2Transaction db2Trans;
- private int commandTimeout;
+ private int commandTimeout = 30;
private bool prepared = false;
private IntPtr hwndStmt = IntPtr.Zero; //Our statement handle
private DB2ParameterCollection parameters = new DB2ParameterCollection();
private bool disposed = false;
private bool statementOpen;
+ private CommandBehavior previousBehavior;
+ private UpdateRowSource updatedRowSource = UpdateRowSource.Both;
+ private IntPtr statementParametersMemory;
+ private int statementParametersMemorySize;
#endregion
@@ -29,27 +32,32 @@ namespace IBM.Data.DB2
public DB2Command()
{
- commandTimeout = 30;
hwndStmt = IntPtr.Zero;
}
- public DB2Command(string commandStr):this()
+ public DB2Command(string commandStr)
{
commandText = commandStr;
+ hwndStmt = IntPtr.Zero;
}
- public DB2Command(string commandStr, DB2Connection con) : this(commandStr)
+ public DB2Command(string commandStr, DB2Connection con) :this()
{
db2Conn = con;
- AllocateStatement("Constructor 3");
+ commandText = commandStr;
+ if(con != null)
+ {
+ con.AddCommand(this);
+ }
}
- public DB2Command (string commandStr, DB2Connection con, DB2Transaction trans):this(commandStr, con)
+ public DB2Command (string commandStr, DB2Connection con, DB2Transaction trans)
{
+ commandText = commandStr;
+ db2Conn = con;
db2Trans = trans;
- if(null != con)
+ if(con != null)
{
con.AddCommand(this);
}
- AllocateStatement("Constructor 4");
}
#endregion
@@ -73,6 +81,11 @@ namespace IBM.Data.DB2
db2Conn = null;
}
}
+ if(statementParametersMemory != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(statementParametersMemory);
+ statementParametersMemory = IntPtr.Zero;
+ }
}
base.Dispose(disposing);
disposed = true;
@@ -87,6 +100,8 @@ namespace IBM.Data.DB2
internal void DataReaderClosed()
{
CloseStatementHandle(false);
+ if((previousBehavior & CommandBehavior.CloseConnection) != 0)
+ Connection.Close();
refDataReader = null;
}
@@ -97,7 +112,6 @@ namespace IBM.Data.DB2
if(statementOpen)
{
short sqlRet = DB2CLIWrapper.SQLFreeStmt(hwndStmt, DB2Constants.SQL_CLOSE);
- Db2Environment.Log("Close stm {0,-4} {1}", hwndStmt, sqlRet);
}
if((!prepared && statementOpen) ||
dispose)
@@ -180,6 +194,8 @@ namespace IBM.Data.DB2
set
{
commandTimeout = value;
+ if(hwndStmt != IntPtr.Zero)
+ SetStatementTimeout();
}
}
#endregion
@@ -212,7 +228,6 @@ namespace IBM.Data.DB2
set
{
db2Conn = (DB2Connection)value;
- //AllocateStatement("Connection property set");
}
}
@@ -261,7 +276,7 @@ namespace IBM.Data.DB2
///
/// The transaction this command is associated with
///
- public IDbTransaction Transaction
+ IDbTransaction IDbCommand.Transaction
{
get
{
@@ -272,23 +287,29 @@ namespace IBM.Data.DB2
db2Trans = (DB2Transaction)value;
}
}
- #endregion
- #region UpdatedRowSource property
-
- public UpdateRowSource UpdatedRowSource
+ public DB2Transaction Transaction
{
get
{
- throw new DB2Exception ("TBD");
+ return db2Trans;
}
set
{
- throw new DB2Exception ("TBD");
+ db2Trans = value;
}
}
#endregion
+ #region UpdatedRowSource property
+
+ public UpdateRowSource UpdatedRowSource
+ {
+ get { return updatedRowSource; }
+ set { updatedRowSource = value; }
+ }
+ #endregion
+
#region Statement Handle
///
/// returns the DB2Client statement handle
@@ -308,12 +329,19 @@ namespace IBM.Data.DB2
{
if (db2Conn.DBHandle.ToInt32() == 0) return;
short sqlRet;
- sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_STMT, db2Conn.DBHandle , ref hwndStmt);
- Console.WriteLine("Connection handle : {0}", db2Conn.DBHandle.ToInt32().ToString());
- Db2Environment.Log("Alloc stm {0,-4} {1}", hwndStmt, sqlRet);
+ sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_STMT, db2Conn.DBHandle, out 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.");
+
parameters.HwndStmt = hwndStmt;
+
+ SetStatementTimeout();
+ }
+
+ private void SetStatementTimeout()
+ {
+ short sqlRet = DB2CLIWrapper.SQLSetStmtAttr(hwndStmt, DB2Constants.SQL_ATTR_QUERY_TIMEOUT, new IntPtr(commandTimeout), 0);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Set statement timeout.", db2Conn);
}
#endregion
@@ -337,7 +365,7 @@ namespace IBM.Data.DB2
///
public IDbDataParameter CreateParameter()
{
- throw new DB2Exception("TBD");
+ return new DB2Parameter();
}
#endregion
@@ -345,49 +373,149 @@ namespace IBM.Data.DB2
public int ExecuteNonQuery()
{
- int result = ExecuteNonQueryInternal();
+ ExecuteNonQueryInternal(CommandBehavior.Default);
+
+ int 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
+ short sqlRet = DB2CLIWrapper.SQLRowCount(hwndStmt, out numRows);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecDirect error.", db2Conn);
+
+ do
+ {
+ sqlRet = DB2CLIWrapper.SQLMoreResults(this.hwndStmt);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "DB2ClientDataReader - SQLMoreResults", db2Conn);
+ } while(sqlRet != DB2Constants.SQL_NO_DATA_FOUND);
+
CloseStatementHandle(false);
- return result;
+ return numRows;
}
- public int ExecuteNonQueryInternal()
+ public void ExecuteNonQueryInternal(CommandBehavior behavior)
{
+ short sqlRet;
+
if((db2Conn == null) || (db2Conn.State != ConnectionState.Open))
throw new InvalidOperationException("Prepare needs an open connection");
+ if((refDataReader != null) &&
+ (refDataReader.IsAlive))
+ throw new InvalidOperationException("There is already an open DataReader associated with this Connection which must be closed first.");
+ DB2Transaction connectionTransaction = null;
+ if(db2Conn.WeakRefTransaction != null)
+ connectionTransaction = (DB2Transaction)db2Conn.WeakRefTransaction.Target;
+ if(!Object.ReferenceEquals(connectionTransaction, Transaction))
+ {
+ if(Transaction == null)
+ throw new InvalidOperationException("A transaction was started in the connection, but the command doesn't specify a transaction");
+ throw new InvalidOperationException("The transaction specified at the connection doesn't belong to the connection");
+ }
if (hwndStmt == IntPtr.Zero)
{
AllocateStatement("InternalExecuteNonQuery");
+ previousBehavior = 0;
}
+ if(previousBehavior != behavior)
+ {
+ if(((previousBehavior ^ behavior) & CommandBehavior.SchemaOnly) != 0)
+ {
+ sqlRet = DB2CLIWrapper.SQLSetStmtAttr(hwndStmt, DB2Constants.SQL_ATTR_DEFERRED_PREPARE,
+ new IntPtr((behavior & CommandBehavior.SchemaOnly) != 0 ? 0 : 1), 0);
+ // TODO: don't check. what if it is not supported???
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Defered prepare.", db2Conn);
+
+ previousBehavior = (previousBehavior & ~CommandBehavior.SchemaOnly) | (behavior & CommandBehavior.SchemaOnly);
+ }
+ if(((previousBehavior ^ behavior) & CommandBehavior.SingleRow) != 0)
+ {
+ sqlRet = DB2CLIWrapper.SQLSetStmtAttr(hwndStmt, DB2Constants.SQL_ATTR_MAX_ROWS,
+ new IntPtr((behavior & CommandBehavior.SingleRow) == 0 ? 0 : 1), 0);
+ // TODO: don't check. what if it is not supported???
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Set max rows", db2Conn);
+
+ previousBehavior = (previousBehavior & ~CommandBehavior.SingleRow) | (behavior & CommandBehavior.SingleRow);
+ }
+ previousBehavior = behavior;
+ }
+ if((Transaction == null) &&
+ !db2Conn.openConnection.autoCommit)
+ {
+ sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_AUTOCOMMIT, new IntPtr(DB2Constants.SQL_AUTOCOMMIT_ON), 0);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting AUTOCOMMIT ON in transaction CTOR.", db2Conn);
+ db2Conn.openConnection.autoCommit = true;
+
+ sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_TXN_ISOLATION, new IntPtr(DB2Constants.SQL_TXN_READ_COMMITTED), 0);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting isolation level.", db2Conn);
+ }
+
+
if ((commandText == null) ||(commandText.Length == 0))
throw new InvalidOperationException("Command string is empty");
if(CommandType.StoredProcedure == commandType && !commandText.StartsWith("CALL "))
commandText = "CALL " + commandText;
-
- short sqlRet;
- if (prepared)
+
+ // if(!prepared)
+ // {
+ // Prepare();
+ // }
+ if((behavior & CommandBehavior.SchemaOnly) != 0)
{
- sqlRet = DB2CLIWrapper.SQLExecute(hwndStmt);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecute error.");
+ if(!prepared)
+ {
+ Prepare();
+ }
}
else
{
- sqlRet = DB2CLIWrapper.SQLExecDirect(hwndStmt, commandText, commandText.Length);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecDirect error.");
- }
- statementOpen = true;
-
- 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
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecDirect error.");
-
+ if(statementParametersMemory != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(statementParametersMemory);
+ statementParametersMemory = IntPtr.Zero;
+ }
+ if(parameters.Count > 0)
+ {
+ statementParametersMemorySize = 0;
+ for(int i = 0; i < parameters.Count; i++)
+ {
+ DB2Parameter param = parameters[i];
+ param.CalculateRequiredmemory();
+ statementParametersMemorySize += param.requiredMemory + 8;
+ }
+ statementParametersMemory = Marshal.AllocHGlobal(statementParametersMemorySize);
+ int offset = 0;
+ for(int i = 0; i < parameters.Count; i++)
+ {
+ DB2Parameter param = parameters[i];
+ param.internalBuffer = new IntPtr(statementParametersMemory.ToInt64() + offset);
+ offset += param.requiredMemory;
+ param.internalLengthBuffer = new IntPtr(statementParametersMemory.ToInt64() + offset);
+ offset += 8;
+ sqlRet = param.Bind(this.hwndStmt, (short)(i + 1));
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Error binding parameter in DB2Command: ", db2Conn);
+ }
+ }
+ if (prepared)
+ {
+ sqlRet = DB2CLIWrapper.SQLExecute(hwndStmt);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecute error.", db2Conn);
+ }
+ else
+ {
+ sqlRet = DB2CLIWrapper.SQLExecDirect(hwndStmt, commandText, commandText.Length);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecDirect error.", db2Conn);
+ }
+ statementOpen = true;
- parameters.GetOutValues();
- ///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;
+ parameters.GetOutValues();
+
+ if(statementParametersMemory != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(statementParametersMemory);
+ statementParametersMemory = IntPtr.Zero;
+ }
+ }
}
#endregion
@@ -397,7 +525,7 @@ namespace IBM.Data.DB2
///
IDataReader IDbCommand.ExecuteReader()
{
- return ExecuteReader(0);
+ return ExecuteReader(CommandBehavior.Default);
}
IDataReader IDbCommand.ExecuteReader(CommandBehavior behavior)
@@ -407,7 +535,7 @@ namespace IBM.Data.DB2
public DB2DataReader ExecuteReader()
{
- return ExecuteReader(0);
+ return ExecuteReader(CommandBehavior.Default);
}
public DB2DataReader ExecuteReader(CommandBehavior behavior)
@@ -417,10 +545,8 @@ namespace IBM.Data.DB2
DB2DataReader reader;
- int nrOfRows = ExecuteNonQueryInternal();
-
- reader = new DB2DataReader(db2Conn, this);
- reader.recordsAffected = nrOfRows;
+ ExecuteNonQueryInternal(behavior);
+ reader = new DB2DataReader(db2Conn, this, behavior);
refDataReader = new WeakReference(reader);
@@ -465,25 +591,32 @@ namespace IBM.Data.DB2
IntPtr numParams = IntPtr.Zero;
sqlRet = DB2CLIWrapper.SQLPrepare(hwndStmt, commandText, commandText.Length);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLPrepare error.");
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLPrepare error.", db2Conn);
statementOpen = true;
-
- 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
+
+ #region ICloneable Members
+
+ object ICloneable.Clone()
+ {
+ DB2Command clone = new DB2Command();
+
+ clone.Connection = Connection;
+ clone.commandText = commandText;
+ clone.commandType = commandType;
+ clone.Transaction = db2Trans;
+ clone.commandTimeout = commandTimeout;
+ clone.updatedRowSource = updatedRowSource;
+ clone.parameters = new DB2ParameterCollection();
+ for(int i = 0; i < parameters.Count; i++)
+ clone.Parameters.Add(((ICloneable)parameters[i]).Clone());
+
+ return clone;
+ }
+
+ #endregion
}
}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Connection.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Connection.cs
index 82146169855..a7f1835aa81 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Connection.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Connection.cs
@@ -9,36 +9,33 @@ namespace IBM.Data.DB2
{
- public class DB2Connection : System.ComponentModel.Component, IDbConnection
+ public sealed class DB2Connection : System.ComponentModel.Component, IDbConnection, ICloneable
{
- private ArrayList refCommands;
- private WeakReference refTransaction;
+ #region private data members
- private Db2ConnectionSettings connectionSettings = null;
- //private StringBuilder outConnectStr;
- private int connectionTimeout;
-
- private Db2OpenConnection openConnection;
-
+ private ArrayList refCommands;
+ private WeakReference refTransaction;
+ private DB2ConnectionSettings connectionSettings = null;
+ private int connectionTimeout;
+ internal DB2OpenConnection openConnection;
private bool disposed = false;
+ #endregion
+ #region Constructors
public DB2Connection()
- {
- connectionTimeout = 15;
-
+ {
}
- public DB2Connection(string conString):this()
+ public DB2Connection(string conString)
{
SetConnectionString(conString);
}
-
- public DB2Connection(DB2Connection db2conn):this(db2conn.ConnectionString)
- {
- }
+
+
+ #endregion
#region ConnectionString property
@@ -87,16 +84,40 @@ namespace IBM.Data.DB2
{
get
{
- //if ((long)dbHandle.ToPointer() == DB2Constants.SQL_NULL_HANDLE)
if (openConnection == null)
- {
return ConnectionState.Closed;
- }
-
return ConnectionState.Open;
}
}
#endregion
+
+ #region events
+
+ public event DB2InfoMessageEventHandler InfoMessage;
+ public event StateChangeEventHandler StateChange;
+
+ internal void OnInfoMessage(short handleType, IntPtr handle)
+ {
+ if(InfoMessage != null)
+ {
+ // Don't get error information until we know for sure someone is listening
+ try
+ {
+ InfoMessage(this,
+ new DB2InfoMessageEventArgs(new DB2ErrorCollection(handleType, handle)));
+ }
+ catch(Exception)
+ {}
+ }
+ }
+
+ private void OnStateChange(StateChangeEventArgs args)
+ {
+ if(StateChange != null)
+ StateChange(this, args);
+ }
+
+ #endregion
#region DBHandle
@@ -127,75 +148,87 @@ namespace IBM.Data.DB2
}
public DB2Transaction BeginTransaction(IsolationLevel isolationL)
- {
- if ((refTransaction != null) && (refTransaction.IsAlive))
- {
- throw new InvalidOperationException("Cannot open another transaction");
- }
- if(State != ConnectionState.Open)
- throw new InvalidOperationException("BeginTransaction needs an open connection");
-
- DB2Transaction tran = new DB2Transaction(this, isolationL);
- refTransaction = new WeakReference(tran);
- return tran;
+ {
+ if ((refTransaction != null) && (refTransaction.IsAlive))
+ throw new InvalidOperationException("Cannot open another transaction");
+ if(State != ConnectionState.Open)
+ throw new InvalidOperationException("BeginTransaction needs an open connection");
+
+ if(refTransaction != null)
+ {
+ if(refTransaction.IsAlive)
+ throw new InvalidOperationException("Parallel transactions not supported");
+
+ openConnection.RollbackDeadTransaction();
+ refTransaction = null;
+ }
+ openConnection.transactionOpen = true;
+ DB2Transaction tran = new DB2Transaction(this, isolationL);
+ refTransaction = new WeakReference(tran);
+ return tran;
}
#endregion
#region ChangeDatabase
- unsafe public void ChangeDatabase(string newDBName)
- {
- if(connectionSettings == null)
- {
- throw new InvalidOperationException("No connection string");
- }
- this.Close();
-
- SetConnectionString(connectionSettings.ConnectionString.Replace(connectionSettings.DatabaseAlias, newDBName));
+ unsafe public void ChangeDatabase(string newDBName)
+ {
+ if(connectionSettings == null)
+ {
+ throw new InvalidOperationException("No connection string");
+ }
+ this.Close();
+
+ SetConnectionString(connectionSettings.ConnectionString.Replace(connectionSettings.DatabaseAlias, newDBName));
+
+ this.Open();
+ }
+ #endregion
- this.Open();
+ #region ReleaseObjectPool
+ public static void ReleaseObjectPool()
+ {
+ DB2Environment.Instance.Dispose();
}
#endregion
#region Close
- ///Close, per MSDN documentation
- ///
- public void Close()
- {
- DB2Transaction transaction = null;
- if(refTransaction != null)
- transaction = (DB2Transaction)refTransaction.Target;
- if((transaction != null) && refTransaction.IsAlive)
- {
- transaction.Dispose();
- }
- if(refCommands != null)
- {
- for(int i = 0; i < refCommands.Count; i++)
- {
- DB2Command command = null;
- if(refCommands[i] != null)
- {
- command = (DB2Command)((WeakReference)refCommands[i]).Target;
- }
- if((command != null) && ((WeakReference)refCommands[i]).IsAlive)
- {
- try
- {
- command.ConnectionClosed();
- }
- catch{}
- }
- refCommands[i] = null;
- }
- }
-
- if(openConnection != null)
- {
- openConnection.Close();
- openConnection = null;
- }
- }
+ public void Close()
+ {
+ DB2Transaction transaction = null;
+ if(refTransaction != null)
+ transaction = (DB2Transaction)refTransaction.Target;
+ if((transaction != null) && refTransaction.IsAlive)
+ {
+ transaction.Dispose();
+ }
+ if(refCommands != null)
+ {
+ for(int i = 0; i < refCommands.Count; i++)
+ {
+ DB2Command command = null;
+ if(refCommands[i] != null)
+ {
+ command = (DB2Command)((WeakReference)refCommands[i]).Target;
+ }
+ if((command != null) && ((WeakReference)refCommands[i]).IsAlive)
+ {
+ try
+ {
+ command.ConnectionClosed();
+ }
+ catch{}
+ }
+ //?? refCommands[i] = null;
+ }
+ }
+
+ if(openConnection != null)
+ {
+ openConnection.Close();
+ openConnection = null;
+ }
+ }
#endregion
@@ -213,117 +246,130 @@ namespace IBM.Data.DB2
#endregion
#region Open
- unsafe public void Open()
- {
- if(disposed)
- {
- throw new ObjectDisposedException("connection disposed");
- }
- //short sqlRet=0;
-
- if (this.State == ConnectionState.Open || this.State == ConnectionState.Connecting || this.State == ConnectionState.Executing || this.State == ConnectionState.Fetching)
- {
- throw new InvalidOperationException("Connection already open");
- }
-
- try
- {
- openConnection = connectionSettings.GetRealOpenConnection();
- }
- catch (DB2Exception)
- {
- Close();
- throw;
- }
+ unsafe public void Open()
+ {
+ if(disposed)
+ {
+ throw new ObjectDisposedException("DB2Connection");
+ }
+
+ if (this.State == ConnectionState.Open || this.State == ConnectionState.Connecting || this.State == ConnectionState.Executing || this.State == ConnectionState.Fetching)
+ {
+ throw new InvalidOperationException("Connection already open");
+ }
+
+ try
+ {
+ openConnection = connectionSettings.GetRealOpenConnection(this);
+ }
+ catch (DB2Exception)
+ {
+ Close();
+ throw;
+ }
}
#endregion
#region Dispose
- public new void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected override void Dispose(bool disposing)
- {
- if(!disposed)
- {
- if(disposing)
- {
- // dispose managed resources
- Close();
- }
- }
- base.Dispose(disposing);
- disposed = true;
- }
-
-
- ~DB2Connection()
- {
- Dispose(false);
+ public new void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if(!disposed)
+ {
+ if(disposing)
+ {
+ // dispose managed resources
+ Close();
+ }
+ }
+ base.Dispose(disposing);
+ disposed = true;
+ }
+
+
+ ~DB2Connection()
+ {
+ Dispose(false);
}
#endregion
- private void CheckState()
- {
- if (ConnectionState.Closed == State)
- throw new InvalidOperationException("Connection is currently closed.");
- }
-
- void SetConnectionString (string connectionString)
- {
- if (State != ConnectionState.Closed)
- throw new InvalidOperationException("Connection is not closed.");
-
- this.connectionSettings = Db2ConnectionSettings.GetConnectionSettings(connectionString);
+ private void CheckState()
+ {
+ if (ConnectionState.Closed == State)
+ throw new InvalidOperationException("Connection is currently closed.");
+ }
+
+ void SetConnectionString (string connectionString)
+ {
+ if (State != ConnectionState.Closed)
+ throw new InvalidOperationException("Connection is not closed.");
+
+ this.connectionSettings = DB2ConnectionSettings.GetConnectionSettings(connectionString);
+ }
+
+ internal WeakReference WeakRefTransaction
+ {
+ get
+ {
+ return refTransaction;
+ }
+ set
+ {
+ refTransaction = value;
+ }
+
+ }
+
+ internal void AddCommand(DB2Command command)
+ {
+ if(refCommands == null)
+ {
+ refCommands = new ArrayList();
+ }
+ for(int i = 0; i < refCommands.Count; i++)
+ {
+ WeakReference reference = (WeakReference)refCommands[i];
+ if((reference == null) || !reference.IsAlive)
+ {
+ refCommands[i] = new WeakReference(command);
+ return;
+ }
+ }
+ refCommands.Add(new WeakReference(command));
+
+ }
+
+ internal void RemoveCommand(DB2Command command)
+ {
+ for(int i = 0; i < refCommands.Count; i++)
+ {
+ WeakReference reference = (WeakReference)refCommands[i];
+ if(object.ReferenceEquals(reference, command))
+ {
+ refCommands[i] = null;
+ return;
+ }
+ }
}
- internal WeakReference WeakRefTransaction
- {
- get
- {
- return refTransaction;
- }
- set
- {
- refTransaction = value;
- }
-
- }
-
- internal void AddCommand(DB2Command command)
- {
- if(refCommands == null)
- {
- refCommands = new ArrayList();
- }
- for(int i = 0; i < refCommands.Count; i++)
- {
- WeakReference reference = (WeakReference)refCommands[i];
- if((reference == null) || !reference.IsAlive)
- {
- refCommands[i] = new WeakReference(command);
- return;
- }
- }
- refCommands.Add(new WeakReference(command));
-
- }
-
- internal void RemoveCommand(DB2Command command)
- {
- for(int i = 0; i < refCommands.Count; i++)
- {
- WeakReference reference = (WeakReference)refCommands[i];
- if(object.ReferenceEquals(reference, command))
- {
- refCommands[i] = null;
- return;
- }
- }
- }
+ #region ICloneable Members
+
+ object ICloneable.Clone()
+ {
+ DB2Connection clone = new DB2Connection();
+
+ clone.connectionSettings = connectionSettings;
+ clone.connectionTimeout = connectionTimeout;
+
+ return clone;
+ }
+
+ #endregion
}
}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ConnectionPool.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ConnectionPool.cs
new file mode 100755
index 00000000000..dd1724299bb
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ConnectionPool.cs
@@ -0,0 +1,194 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.Threading;
+
+namespace IBM.Data.DB2
+{
+ /// <summary>
+ ///
+ /// </summary>
+ /// <remarks>One connection pool per connectionstring</remarks>
+ internal sealed class DB2ConnectionPool
+ {
+ private ArrayList openFreeConnections; // list of pooled connections sorted by age. First connection is present at index 'connectionsUsableOffset'
+ private Queue openFreeMinimalAllocated;
+ private int connectionsOpen; // total number of connections open (in pool, an in use by application)
+ private int connectionsInUse; // total connection in use by application
+ private int connectionsUsableOffset; // Offset to the first pooled connection in 'openFreeConnections'
+ private Timer timer;
+ public string databaseProductName;
+ public string databaseVersion;
+ public int majorVersion;
+ public int minorVersion;
+
+ private DB2ConnectionSettings connectionSettings;
+
+ public DB2ConnectionPool(DB2ConnectionSettings connectionSettings)
+ {
+ this.connectionSettings = connectionSettings;
+ openFreeConnections = new ArrayList();
+ }
+
+ public DB2ConnectionSettings ConnectionSettings
+ {
+ get { return connectionSettings; }
+ }
+
+ public DB2OpenConnection GetOpenConnection(DB2Connection db2Conn)
+ {
+ DB2OpenConnection connection = null;
+ lock(openFreeConnections.SyncRoot)
+ {
+ if((connectionSettings.ConnectionPoolSizeMax > 0) &&
+ (connectionsOpen >= connectionSettings.ConnectionPoolSizeMax))
+ {
+ throw new ArgumentException("Maximum connections reached for connectionstring");
+ }
+
+ while(connectionsOpen > connectionsInUse)
+ {
+ connection = (DB2OpenConnection)openFreeConnections[openFreeConnections.Count - 1];
+ openFreeConnections.RemoveAt(openFreeConnections.Count - 1);
+
+ // check if connection is dead
+ int isDead;
+ short sqlRet = DB2CLIWrapper.SQLGetConnectAttr(connection.DBHandle, DB2Constants.SQL_ATTR_CONNECTION_DEAD, out isDead, 0, IntPtr.Zero);
+ if(((sqlRet == DB2Constants.SQL_SUCCESS_WITH_INFO) || (sqlRet == DB2Constants.SQL_SUCCESS)) &&
+ (isDead == DB2Constants.SQL_CD_FALSE))
+ {
+ connectionsInUse++;
+ break;
+ }
+ else
+ {
+ connectionsOpen--;
+ connection.Dispose();
+ connection = null;
+ }
+
+ }
+ if(connectionsOpen == connectionsInUse)
+ {
+ if(timer != null)
+ {
+ timer.Dispose();
+ timer = null;
+ }
+ }
+ }
+ if(connection == null)
+ {
+ openFreeConnections.Clear();
+ connectionsUsableOffset = 0;
+
+ connection = new DB2OpenConnection(connectionSettings, db2Conn);
+
+ connectionsOpen++;
+ connectionsInUse++;
+ }
+
+ return connection;
+ }
+
+ private void DisposeTimedoutConnections(object state)
+ {
+ lock(openFreeConnections.SyncRoot)
+ {
+ if(timer != null)
+ {
+ TimeSpan timeToDispose = TimeSpan.Zero;
+ DB2OpenConnection connection;
+ while(connectionsOpen > connectionsInUse)
+ {
+ connection = (DB2OpenConnection)openFreeConnections[connectionsUsableOffset];
+ timeToDispose = connection.poolDisposalTime.Subtract(DateTime.Now);
+ if((timeToDispose.Ticks < 0) || // time to die
+ (timeToDispose > connectionSettings.ConnectionLifeTime)) // messing with system clock
+ {
+ connection.Dispose();
+ openFreeConnections[connectionsUsableOffset] = null;
+ connectionsOpen--;
+ connectionsUsableOffset++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if(connectionsOpen > connectionsInUse)
+ {
+ connection = (DB2OpenConnection)openFreeConnections[connectionsUsableOffset];
+ timer.Change(timeToDispose, new TimeSpan(-1));
+ }
+ else
+ {
+ timer.Dispose();
+ timer = null;
+ }
+ }
+ if((connectionsUsableOffset > (openFreeConnections.Capacity / 2)) &&
+ (connectionsOpen > connectionsInUse))
+ {
+ openFreeConnections.RemoveRange(0, connectionsUsableOffset); // cleanup once in a while
+ connectionsUsableOffset = 0;
+ }
+ }
+ }
+
+ public void AddToFreeConnections(DB2OpenConnection connection)
+ {
+ lock(openFreeConnections.SyncRoot)
+ {
+ connection.poolDisposalTime = DateTime.Now.Add(connectionSettings.ConnectionLifeTime);
+ if(timer == null)
+ {
+ timer = new Timer(new TimerCallback(DisposeTimedoutConnections), null,
+ connectionSettings.ConnectionLifeTime, new TimeSpan(-1));
+ }
+ connectionsInUse--;
+ openFreeConnections.Add(connection);
+ }
+ }
+
+ public void OpenConnectionFinalized()
+ {
+ lock(openFreeConnections.SyncRoot)
+ {
+ connectionsOpen--;
+ connectionsInUse--;
+ }
+ }
+
+ /// <summary>
+ /// Find a specific connection pool
+ /// </summary>
+ /// <param name="connectionString"></param>
+ /// <returns></returns>
+ static public DB2ConnectionPool FindConnectionPool(string connectionString)
+ {
+ return (DB2ConnectionPool)DB2Environment.Instance.connectionPools[connectionString];
+ }
+
+ /// <summary>
+ /// Get a connection pool. If it doesn't exist yet, create it
+ /// </summary>
+ /// <param name="connectionSettings"></param>
+ /// <returns></returns>
+ static public DB2ConnectionPool GetConnectionPool(DB2ConnectionSettings connectionSettings)
+ {
+ DB2Environment environment = DB2Environment.Instance;
+
+ lock(environment.connectionPools.SyncRoot)
+ {
+ DB2ConnectionPool pool = (DB2ConnectionPool)environment.connectionPools[connectionSettings.ConnectionString];
+ if(pool == null)
+ {
+ pool = new DB2ConnectionPool(connectionSettings);
+ environment.connectionPools.Add(connectionSettings.ConnectionString, pool);
+ }
+ return pool;
+ }
+ }
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ConnectionSettings.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ConnectionSettings.cs
index 877b201c289..303a037fc62 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ConnectionSettings.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ConnectionSettings.cs
@@ -4,7 +4,7 @@ using System.Text;
namespace IBM.Data.DB2
{
- internal sealed class Db2ConnectionSettings
+ internal sealed class DB2ConnectionSettings
{
private string connectionString;
private string userName = "";
@@ -12,49 +12,47 @@ namespace IBM.Data.DB2
private string databaseAlias = "";
private string server = "";
private bool pooling = true;
- private TimeSpan connectTimeout = TimeSpan.Zero;
+ private TimeSpan connectTimeout = new TimeSpan(0, 0, 15);
private TimeSpan connectionLifeTime = new TimeSpan(0, 0, 15); // 15 seconds
private int connectionPoolSizeMin = 0;
private int connectionPoolSizeMax = -1; // no maximum
- private Db2ConnectionPool pool;
+ private DB2ConnectionPool pool;
- private Db2ConnectionSettings(string connectionString)
+ private DB2ConnectionSettings(string connectionString)
{
this.connectionString = connectionString;
this.Parse();
}
- public static Db2ConnectionSettings GetConnectionSettings(string connectionString)
+ public static DB2ConnectionSettings GetConnectionSettings(string connectionString)
{
- Db2ConnectionPool pool = Db2ConnectionPool.FindConnectionPool(connectionString);
+ DB2ConnectionPool pool = DB2ConnectionPool.FindConnectionPool(connectionString);
if(pool != null)
{
return pool.ConnectionSettings;
}
- Db2ConnectionSettings settings = new Db2ConnectionSettings(connectionString);
+ DB2ConnectionSettings settings = new DB2ConnectionSettings(connectionString);
if(settings.Pooling)
{
- settings.pool = Db2ConnectionPool.GetConnectionPool(settings);
+ settings.pool = DB2ConnectionPool.GetConnectionPool(settings);
}
return settings;
}
- public Db2OpenConnection GetRealOpenConnection()
+ public DB2OpenConnection GetRealOpenConnection(DB2Connection connection)
{
if(pool != null)
{
- Console.WriteLine("Getting DB2OpenConnection from connection pool");
- return pool.GetOpenConnection();
+ return pool.GetOpenConnection(connection);
}
else
{
- Console.WriteLine("Creating new DB2OpenConnection");
- return new Db2OpenConnection(this);
+ return new DB2OpenConnection(this, connection);
}
}
- public Db2ConnectionPool Pool
+ public DB2ConnectionPool Pool
{
get { return pool; }
}
@@ -68,7 +66,7 @@ namespace IBM.Data.DB2
{
get { return userName; }
}
-
+
public string PassWord
{
get { return passWord; }
@@ -164,6 +162,10 @@ namespace IBM.Data.DB2
break;
}
}
+ if(connectionLifeTime.Ticks <= 0)
+ {
+ pooling = false;
+ }
}
public override int GetHashCode()
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Constants.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Constants.cs
new file mode 100755
index 00000000000..d1ce469950a
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Constants.cs
@@ -0,0 +1,179 @@
+using System;
+
+namespace IBM.Data.DB2
+{
+ /// <summary>
+ /// Summary description for DB2Constants.
+ /// </summary>
+ internal sealed class DB2Constants
+ {
+ public const short SQL_HANDLE_ENV = 1;
+ public const short SQL_HANDLE_DBC = 2;
+ public const short SQL_HANDLE_STMT = 3;
+ public const short SQL_HANDLE_DESC = 4;
+
+ /* RETCODE values */
+ public const short SQL_SUCCESS = 0;
+ public const short SQL_SUCCESS_WITH_INFO = 1;
+ public const short SQL_NEED_DATA = 99;
+ public const short SQL_NO_DATA = 100;
+ public const short SQL_STILL_EXECUTING = 2;
+ public const short SQL_ERROR = -1;
+ public const short SQL_INVALID_HANDLE = -2;
+
+ public const int SQL_NTS = -3;
+ public const long SQL_NULL_HANDLE = 0L;
+ public const short SQL_COMMIT = 0;
+ public const short SQL_ROLLBACK = 1;
+ public const short SQL_NO_DATA_FOUND = 100;
+
+ /* SQLFreeStmt option values */
+ public const short SQL_CLOSE = 0;
+ public const short SQL_DROP = 1;
+ public const short SQL_UNBIND = 2;
+ public const short SQL_RESET_PARAMS = 3;
+
+ /* Isolation levels */
+ public const long SQL_TXN_READ_UNCOMMITTED = 0x00000001L;
+ public const long SQL_TXN_READ_COMMITTED = 0x00000002L;
+ public const long SQL_TXN_REPEATABLE_READ = 0x00000004L;
+ public const long SQL_TXN_SERIALIZABLE_READ = 0x00000008L;
+ public const long SQL_TXN_NOCOMMIT = 0x00000020L;
+
+ /* Connect options */
+ public const int SQL_ATTR_TXN_ISOLATION= 108;
+ public const int SQL_ATTR_AUTOCOMMIT = 102;
+
+ /* attribute */
+ public const int SQL_ATTR_ANSI_APP = 115;
+ public const int SQL_AA_TRUE = 1; /* the application is an ANSI app */
+ public const int SQL_AA_FALSE = 0; /* the application is a Unicode app */
+
+ public const int SQL_ATTR_CONNECTION_DEAD = 1209; /* GetConnectAttr only */
+ public const int SQL_CD_TRUE = 1; /* the connection is dead */
+ public const int SQL_CD_FALSE = 0; /* the connection is not dead */
+
+ public const int SQL_ATTR_QUERY_TIMEOUT = 0;
+ public const int SQL_ATTR_MAX_ROWS = 1;
+ public const int SQL_ATTR_DEFERRED_PREPARE = 1277;
+
+ public const int SQL_IS_POINTER = -4;
+ public const int SQL_IS_UINTEGER = -5;
+ public const int SQL_IS_INTEGER = -6;
+ public const int SQL_IS_USMALLINT = -7;
+ public const int SQL_IS_SMALLINT = -8;
+
+
+
+ public const long SQL_AUTOCOMMIT_OFF = 0L;
+ public const long SQL_AUTOCOMMIT_ON = 1L;
+
+ /* Data Types */
+ public const int SQL_UNKNOWN_TYPE = 0;
+ public const int SQL_CHAR = 1;
+ public const int SQL_NUMERIC = 2;
+ public const int SQL_DECIMAL = 3;
+ public const int SQL_INTEGER = 4;
+ public const int SQL_SMALLINT = 5;
+ public const int SQL_FLOAT = 6;
+ public const int SQL_REAL = 7;
+ public const int SQL_DOUBLE = 8;
+ public const int SQL_DATETIME = 9;
+ public const int SQL_VARCHAR = 12;
+ public const int SQL_VARBINARY = (-3);
+ public const int SQL_LONGVARBINARY = (-4);
+ public const int SQL_BIGINT = (-5);
+ public const int SQL_BIT = (-7);
+ public const int SQL_WCHAR = (-8);
+ public const int SQL_WVARCHAR = (-9);
+ public const int SQL_WLONGVARCHAR = (-10);
+ public const int SQL_GUID = (-11);
+ public const int SQL_UTINYINT = (-28);
+
+ public const int SQL_TYPE_DATE = 91;
+ public const int SQL_TYPE_TIME = 92;
+ public const int SQL_TYPE_TIMESTAMP = 93;
+ public const int SQL_TYPE_BINARY = -2;
+ public const int SQL_GRAPHIC = -95;
+ public const int SQL_VARGRAPHIC = -96;
+ public const int SQL_LONGVARGRAPHIC = -97;
+ public const int SQL_TYPE_BLOB = -98;
+ public const int SQL_TYPE_CLOB = -99;
+ public const int SQL_DBCLOB = 350;
+
+ public const int SQL_C_CHAR = SQL_CHAR;
+ public const int SQL_C_WCHAR = SQL_WCHAR;
+ public const int SQL_C_SBIGINT = -25;
+ public const int SQL_C_SLONG = -16;
+ public const int SQL_C_SSHORT = -15;
+ public const int SQL_C_TYPE_BINARY = -2;
+ public const int SQL_C_DOUBLE = 8;
+ public const int SQL_C_DECIMAL_IBM = 3;
+ public const int SQL_C_DECIMAL_OLEDB = 2514;
+ public const int SQL_C_DEFAULT = 99;
+ public const int SQL_C_TYPE_DATE = 91;
+ public const int SQL_C_TYPE_TIME = 92;
+ public const int SQL_C_TYPE_TIMESTAMP = 93;
+ public const int SQL_C_TYPE_NUMERIC = 2;
+ public const int SQL_C_TYPE_REAL = 7;
+
+ public const int SQL_BLOB_LOCATOR = 31;
+ public const int SQL_CLOB_LOCATOR = 41;
+ public const int SQL_DBCLOB_LOCATOR = -351;
+
+ public const int SQL_C_BLOB_LOCATOR = SQL_BLOB_LOCATOR;
+ public const int SQL_C_CLOB_LOCATOR = SQL_CLOB_LOCATOR;
+ public const int SQL_C_DBCLOB_LOCATOR = SQL_DBCLOB_LOCATOR;
+
+ public const int SQL_USER_DEFINED_TYPE = (-450);
+
+ /* Special length values */
+ public const int SQL_NULL_DATA = -1;
+
+ /* SQLDriverConnect Options */
+ public const int SQL_DRIVER_NOPROMPT = 0;
+ public const int SQL_DRIVER_COMPLETE = 1;
+ public const int SQL_DRIVER_PROMPT = 2;
+ public const int SQL_DRIVER_COMPLETE_REQUIRED = 3;
+
+ /* Null settings */
+ public const int SQL_NO_NULLS = 0;
+ public const int SQL_NULLABLE = 1;
+ public const int SQL_NULLABLE_UNKNOWN = 2;
+
+ /* Defines for SQLBindParameter and SQLProcedureColumns */
+ public const int SQL_PARAM_TYPE_UNKNOWN = 0;
+ public const int SQL_PARAM_INPUT = 1;
+ public const int SQL_PARAM_INPUT_OUTPUT = 2;
+ public const int SQL_RESULT_COL = 3;
+ public const int SQL_PARAM_OUTPUT = 4;
+ public const int SQL_RETURN_VALUE = 5;
+
+ /*Defines for SQLColAttributeW*/
+ public const int SQL_DESC_ALLOC_TYPE = 1099;
+ public const int SQL_DESC_AUTO_UNIQUE_VALUE = 11;
+ public const int SQL_DESC_BASE_COLUMN_NAME = 22;
+ public const int SQL_DESC_BASE_TABLE_NAME = 23;
+ public const int SQL_DESC_COLUMN_CATALOG_NAME = 17;
+ public const int SQL_DESC_COLUMN_NAME = 1;
+ public const int SQL_DESC_SCHEMA_NAME = 16;
+ public const int SQL_DESC_COLUMN_TABLE_NAME = 15;
+ public const int SQL_DESC_CONCISE_TYPE = 2;
+ public const int SQL_DESC_COUNT = 1001;
+ public const int SQL_DESC_DATA_PTR = 1010;
+ public const int SQL_DESC_DATETIME_INTERVAL_CODE = 1007;
+ public const int SQL_DESC_INDICATOR_PTR = 1009;
+ public const int SQL_DESC_LENGTH = 1003;
+ public const int SQL_DESC_NAME = 1011;
+ public const int SQL_DESC_NULLABLE = 1008;
+ public const int SQL_DESC_OCTET_LENGTH = 1013;
+ public const int SQL_DESC_OCTET_LENGTH_PTR = 1004;
+ public const int SQL_DESC_PRECISION = 1005;
+ public const int SQL_DESC_SCALE = 1006;
+ public const int SQL_DESC_TYPE = 1002;
+ public const int SQL_DESC_TYPE_NAME = 14;
+ public const int SQL_DESC_UNNAMED = 1012;
+ public const int SQL_DESC_UNSIGNED = 8;
+ public const int SQL_DESC_UPDATABLE = 10;
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2DataReader.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2DataReader.cs
index 0670a49b260..7014c5233b7 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2DataReader.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2DataReader.cs
@@ -11,67 +11,69 @@ namespace IBM.Data.DB2
/// Summary description for DB2ClientDataReader.
/// DB2ClientDataReader.
/// </summary>
- public class DB2DataReader : MarshalByRefObject, IDataReader
+ public sealed class DB2DataReader : MarshalByRefObject, IDataReader
{
- private struct ColumnInfo
- {
- public string Colname;
- public int Sqltype;
+ private struct ColumnInfo
+ {
+ public string Colname;
+ public int Sqltype;
}
- private object[] _resultSet;
- private ColumnInfo[] columnInfo;
- private Hashtable columnsNames;
- private const int internalBufferSize = 100;
- private IntPtr internalBuffer;
- internal DB2Connection db2Conn;
- internal DB2Command db2Comm;
- internal IntPtr hwndStmt;
- internal int recordsAffected;
- private bool hasData = false;
- private int fieldCount = -1;
- private int row=-1;
-
- internal IntPtr Ptr = IntPtr.Zero;
- BLOBWrapperCollection _blobs = new BLOBWrapperCollection();
-
- //private DataTable _schemaTable ;
- //private DataTable _resultInfo;
-
- IntPtr intPtr = IntPtr.Zero;
- //IntPtr[] ipTarget;
+ private object[] _resultSet;
+ private ColumnInfo[] columnInfo;
+ private Hashtable columnsNames;
+ private const int internalBufferSize = 100;
+ private IntPtr internalBuffer;
+ internal DB2Connection db2Conn;
+ internal DB2Command db2Comm;
+ internal IntPtr hwndStmt;
+ private int recordsAffected;
+ private bool hasData;
+ private int fieldCount = -1;
+ private CommandBehavior behavior;
+ private bool hasRows;
+ private bool skipReadOnce;
+
#region Constructors and destructors
/// <summary>
///
/// </summary>
- /// <param name="con"></Connection object to DB2>
+ /// <param name="con"></Connection object to Db2>
/// <param name="com"></Command object>
- internal DB2DataReader(DB2Connection con, DB2Command com)
+ internal DB2DataReader(DB2Connection con, DB2Command com, CommandBehavior behavior)
{
db2Conn = con;
db2Comm = com;
+ this.behavior = behavior;
hwndStmt = com.statementHandle; //We have access to the results through the statement handle
-
- short sqlRet;
_resultSet = null;
-
- int colCount = 0;
- sqlRet = DB2CLIWrapper.SQLNumResultCols(hwndStmt, ref colCount);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "DB2ClientDataReader - SQLNumResultCols");
-
- fieldCount = colCount;
-
- //internalBuffer = Marshal.AllocHGlobal(internalBufferSize);
- InitMem(internalBufferSize, ref internalBuffer);
+ GetFieldCountAndAffectedRows();
+ internalBuffer = Marshal.AllocHGlobal(internalBufferSize);
isClosed = false;
}
#endregion
+ private void GetFieldCountAndAffectedRows()
+ {
+ short sqlRet;
+ recordsAffected = -1;
+ if((behavior & CommandBehavior.SchemaOnly) == 0)
+ {
+ //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
+ sqlRet = DB2CLIWrapper.SQLRowCount(hwndStmt, out recordsAffected);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "SQLExecDirect error.", db2Conn);
+ }
+ short colCount;
+ sqlRet = DB2CLIWrapper.SQLNumResultCols(hwndStmt, out colCount);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "DB2ClientDataReader - SQLNumResultCols", db2Conn);
+ fieldCount = colCount;
+ }
+
#region Properties
#region Depth property
@@ -84,6 +86,10 @@ namespace IBM.Data.DB2
{
get
{
+ if(isClosed)
+ {
+ throw new InvalidOperationException("Reader is closed");
+ }
return depth;
}
}
@@ -98,9 +104,6 @@ namespace IBM.Data.DB2
{
get
{
- if (db2Conn.DBHandle == IntPtr.Zero){
- isClosed = true;
- }
return isClosed;
}
}
@@ -125,156 +128,238 @@ namespace IBM.Data.DB2
#region Methods
- #region Dispose
+
+
+ #region Close method
+
+ public void Close()
+ {
+ Dispose();
+ }
public void Dispose()
{
- Dispose(true);
+ Dispose(true);
GC.SuppressFinalize(this);
}
- void Dispose(bool disposing)
- {
- if(!isClosed)
- {
- if(disposing)
- {
- _resultSet = null;
- hasData = false;
- isClosed=true;
-
- if(db2Comm != null)
- {
- db2Comm.DataReaderClosed();
- db2Comm = null;
- }
- }
- Marshal.FreeHGlobal(internalBuffer);
- }
- isClosed = true;
- }
-
- ~DB2DataReader()
- {
- Dispose(false);
+
+ void Dispose(bool disposing)
+ {
+ if(!isClosed)
+ {
+ if(disposing)
+ {
+ short sqlRet;
+ do
+ {
+ sqlRet = DB2CLIWrapper.SQLMoreResults(this.hwndStmt);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Db2ClientDataReader - SQLMoreResults", db2Conn);
+ } while(sqlRet != DB2Constants.SQL_NO_DATA_FOUND);
+
+ _resultSet = null;
+ hasData = false;
+ isClosed=true;
+
+ if(db2Comm != null)
+ {
+ db2Comm.DataReaderClosed();
+ db2Comm = null;
+ }
+ }
+ Marshal.FreeHGlobal(internalBuffer);
+ }
+ isClosed = true;
}
- #endregion
- #region Close method
- ///
- ///
- public void Close()
+
+ ~DB2DataReader()
{
- Dispose();
+ Dispose(false);
}
+
#endregion
#region GetSchemaTable
- public DataTable GetSchemaTable()
- {
- if(isClosed)
- {
- throw new InvalidOperationException("No data exists for the row/column.");
- }
-
- DataTable _schemaTable = BuildNewSchemaTable();
-
- short sqlRet;
- IntPtr ptrCharacterAttribute = IntPtr.Zero;
- InitMem(256, ref ptrCharacterAttribute);
- short buflen = 256;
- short strlen = 256;
- int numericattr = 0;
- int colsize;
- string colname;
- int sqltype;
- int precision;
- int scale;
- int nullable;
- int updatable;
- int isautoincrement;
- //string baseschemaname;
- //string basecatalogname;
- string basetablename;
- string basecolumnname;
-
-
- for (short i=1; i<=fieldCount; i++)
- {
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_BASE_COLUMN_NAME, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- colname = Marshal.PtrToStringAnsi(ptrCharacterAttribute);
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_CONCISE_TYPE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- sqltype = numericattr;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_LENGTH, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- colsize = numericattr;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_PRECISION, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- precision = numericattr;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_SCALE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- scale = numericattr;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_NULLABLE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- nullable = numericattr;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_UPDATABLE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- updatable = numericattr;
-
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_AUTO_UNIQUE_VALUE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- isautoincrement = numericattr;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_BASE_COLUMN_NAME, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- basecolumnname = Marshal.PtrToStringAnsi(ptrCharacterAttribute);
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_BASE_TABLE_NAME, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- basetablename = Marshal.PtrToStringAnsi(ptrCharacterAttribute);
-
-
- DataRow r = _schemaTable.NewRow();
-
- switch((int)sqltype)
- {
- case DB2Constants.SQL_TYPE_BLOB:
- case DB2Constants.SQL_TYPE_BINARY:
- _blobs.Add(i);
-
- break;
- }
-
- r["ColumnName"] = colname;
- r["ColumnOrdinal"] = i;
- r["ColumnSize"] = colsize;
- r["NumericPrecision"] = precision;
- r["NumericScale"] = scale;
- r["DataType"] = GetManagedType((short)sqltype);
- r["ProviderType"] = sqltype;
- r["IsLong"] = IsLong((short)sqltype);
- r["AllowDBNull"] = (nullable==0)?true:false;
- r["IsReadOnly"] = false;
- r["IsRowVersion"] = false;
- r["IsKey"] = false;
- r["IsAutoIncrement"] = (isautoincrement==0)?true:false;
- r["BaseColumnName"] = basecolumnname;
- r["BaseTableName"] = basetablename;
- r["BaseCatalogName"] = "";
- r["BaseSchemaName"] = "";
-
- _schemaTable.Rows.Add(r);
- }
- return _schemaTable;
+ public DataTable GetSchemaTable()
+ {
+ if(isClosed)
+ {
+ throw new InvalidOperationException("No data exists for the row/column.");
+ }
+
+ DataTable _schemaTable = BuildNewSchemaTable();
+
+ short sqlRet;
+ IntPtr ptrCharacterAttribute = IntPtr.Zero;
+ InitMem(256, ref ptrCharacterAttribute);
+ short buflen = 256;
+ short strlen = 256;
+ int numericattr = 0;
+ int colsize;
+ string colname;
+ int sqltype;
+ int precision;
+ int scale;
+ int nullable;
+ int updatable;
+ int isautoincrement;
+ string baseschemaname;
+ //string basecatalogname;
+ string basetablename;
+ string basecolumnname;
+
+ string previousTableName = null;
+ string previousSchemaName = null;
+ bool differentTablesUsed = false;
+
+ for (short i=1; i<=fieldCount; i++)
+ {
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_COLUMN_NAME, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ colname = Marshal.PtrToStringUni(ptrCharacterAttribute);
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_CONCISE_TYPE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ sqltype = numericattr;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_OCTET_LENGTH, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ colsize = numericattr;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_PRECISION, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ precision = numericattr;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_SCALE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ scale = numericattr;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_NULLABLE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ nullable = numericattr;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_UPDATABLE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ updatable = numericattr;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_AUTO_UNIQUE_VALUE, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ isautoincrement = numericattr;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_BASE_COLUMN_NAME, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ basecolumnname = Marshal.PtrToStringUni(ptrCharacterAttribute);
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_BASE_TABLE_NAME, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ basetablename = Marshal.PtrToStringUni(ptrCharacterAttribute);
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)i, (short)DB2Constants.SQL_DESC_SCHEMA_NAME, ptrCharacterAttribute, buflen, ref strlen, ref numericattr);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable", db2Conn);
+ baseschemaname = Marshal.PtrToStringUni(ptrCharacterAttribute);
+ DataRow r = _schemaTable.NewRow();
+
+
+ r["ColumnName"] = colname;
+ r["ColumnOrdinal"] = i - 1;
+ r["ColumnSize"] = colsize;
+ r["NumericPrecision"] = precision;
+ r["NumericScale"] = scale;
+ r["DataType"] = GetManagedType((short)sqltype);
+ r["ProviderType"] = sqltype;
+ r["IsLong"] = IsLong((short)sqltype);
+ r["AllowDBNull"] = (nullable==0) ? false : true;
+ r["IsReadOnly"] = (basecolumnname == null) || (basecolumnname == "");
+ r["IsRowVersion"] = false;
+ r["IsUnique"] = false;
+ r["IsKeyColumn"] = false;
+ r["IsAutoIncrement"] = (isautoincrement==0) ? false : true;
+ r["BaseSchemaName"] = baseschemaname;
+ r["BaseCatalogName"] = "";
+ r["BaseTableName"] = basetablename;
+ r["BaseColumnName"] = basecolumnname;
+
+
+ _schemaTable.Rows.Add(r);
+
+
+ if(!differentTablesUsed)
+ {
+ if(((previousSchemaName == baseschemaname) && (previousTableName == basetablename)) ||
+ (previousTableName == null))
+ {
+ previousTableName = basetablename;
+ previousSchemaName = baseschemaname;
+ }
+ else
+ {
+ differentTablesUsed = true;
+ }
+ }
+ }
+ if(!differentTablesUsed &&
+ ((behavior & CommandBehavior.KeyInfo) != 0) &&
+ (db2Comm.Transaction == null) &&
+ (previousTableName != null) &&
+ (previousTableName != ""))
+ {
+ DB2Command schemaInfoCommand = db2Conn.CreateCommand();
+ schemaInfoCommand.CommandText =
+ "select concat(concat(INDSCHEMA,'.'),INDNAME), COLNAMES, UNIQUERULE from syscat.INDEXES " +
+ "where TABSCHEMA=? and TABNAME=? and uniquerule in ('P','U') order by UNIQUERULE";
+ schemaInfoCommand.Parameters.Add("TABSCHEMA", previousSchemaName);
+ schemaInfoCommand.Parameters.Add("TABNAME", previousTableName);
+ using(DB2DataReader reader = schemaInfoCommand.ExecuteReader())
+ {
+ bool keyColumnSet = false;
+ while(reader.Read())
+ {
+ string indexName = reader.GetString(0);
+ string[] indexColumns = reader.GetString(1).TrimStart('-', '+').Split('-', '+');
+ bool primary = reader.GetString(2) == "P";
+
+ bool allColumnsFound = true;
+ for(int i= 0; i < indexColumns.Length; i++)
+ {
+ int ordinal = FieldNameLookup(_schemaTable, indexColumns[i]);
+ if(ordinal < 0)
+ {
+ allColumnsFound = false;
+ break;
+ }
+ if(indexColumns.Length == 1)
+ _schemaTable.Rows[ordinal]["IsUnique"] = true;
+ }
+ if(allColumnsFound && !keyColumnSet)
+ {
+ for(int i= 0; i < indexColumns.Length; i++)
+ _schemaTable.Rows[FieldNameLookup(_schemaTable, indexColumns[i])]["IsKeyColumn"] = true;
+ keyColumnSet = true;
+ }
+ }
+ }
+ if(db2Conn.openConnection.MajorVersion >= 8)
+ {
+ try
+ {
+ schemaInfoCommand.CommandText =
+ "select COLNAME from SYSCAT.COLIDENTATTRIBUTES where TABSCHEMA=? and TABNAME=?";
+ using(DB2DataReader reader = schemaInfoCommand.ExecuteReader())
+ {
+ while(reader.Read())
+ {
+ string columnName = reader.GetString(0);
+
+ int ordinal = FieldNameLookup(_schemaTable, columnName);
+ if(ordinal >= 0)
+ _schemaTable.Rows[ordinal]["IsAutoIncrement"] = true;
+ }
+ }
+ }
+ catch{}
+ }
+ }
+ return _schemaTable;
}
#endregion
@@ -282,82 +367,98 @@ namespace IBM.Data.DB2
public bool NextResult()
{
+ hasRows = false;
+ skipReadOnce = false;
+ hasData = false;
+ columnInfo = null;
+ _resultSet = null;
- hasData = false;
-
- //throw new Db2Exception("To be done");
- short result = DB2CLIWrapper.SQLMoreResults(this.hwndStmt);
- DB2ClientUtils.DB2CheckReturn(result, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Db2ClientDataReader - SQLMoreResults");
-
-
- if (DB2Constants.SQL_SUCCESS == result)
- {
- int colCount = 0;
- result = DB2CLIWrapper.SQLNumResultCols(hwndStmt, ref colCount);
- fieldCount = colCount;
- DB2ClientUtils.DB2CheckReturn(result, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Db2ClientDataReader - SQLNumResultCols");
-
- columnInfo = null;
- _resultSet = null;
- _blobs = new BLOBWrapperCollection();
- return true;
- }
- return false;
-
-
- //Deferring the meat of this until the batch stuff is implemented
+ if((behavior & (CommandBehavior.SchemaOnly | CommandBehavior.SingleResult)) != 0)
+ return false;
+
+ short sqlRet = DB2CLIWrapper.SQLMoreResults(this.hwndStmt);
+ if(sqlRet == DB2Constants.SQL_NO_DATA_FOUND)
+ return false;
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Db2ClientDataReader - SQLMoreResults", db2Conn);
+ return true;
}
#endregion
#region Read
- ///
- /// Apparently, this function does nothing other than tell you if you can move to the
- /// next row in the resultset. I have to move the fetching stuff elswhere...
- ///
- public bool Read()
- {
- _resultSet = null;
-
- if (isClosed)
- throw new InvalidOperationException("Reader is closed");
- row++;
- if (FetchResults(null))
- return true;
- else return false;
-
+
+#if !NET_1_0
+ public bool HasRows
+ {
+ get
+ {
+ if(hasData)
+ return true;
+
+ hasRows = Read();
+ hasData = false;
+ skipReadOnce = true;
+ return hasRows;
+ }
+ }
+#endif
+
+ public bool Read()
+ {
+ if (isClosed)
+ throw new InvalidOperationException("Reader is closed");
+ if((behavior & CommandBehavior.SchemaOnly) != 0)
+ return false;
+
+ if(skipReadOnce)
+ {
+ skipReadOnce = false;
+ hasData = hasRows;
+ return hasRows;
+ }
+
+ _resultSet = null;
+ hasData = false;
+
+ short sqlRet = DB2CLIWrapper.SQLFetch(hwndStmt);
+ if(sqlRet == DB2Constants.SQL_NO_DATA_FOUND)
+ return false;
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "DB2ClientDataReader - SQLFetch 1", db2Conn);
+
+ hasData = true;
+ return true;
}
#endregion
#region GetColumnInfo
- private void GetColumnInfo()
- {
- if(isClosed)
- throw new InvalidOperationException("Reader is closed");
- if(fieldCount <= 0)
- throw new InvalidOperationException("No Fields found"); // TODO: check error
- if(columnInfo != null)
- return;
-
- columnInfo = new ColumnInfo[fieldCount];
- columnsNames = new Hashtable(fieldCount);
-
- StringBuilder sb = new StringBuilder(400);
- for(int i = 0; i < columnInfo.Length; i++)
- {
- short sqlRet;
- short strlen;
- int numericAttribute;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)(i + 1), (short)DB2Constants.SQL_DESC_BASE_COLUMN_NAME, sb, (short)sb.Capacity, out strlen, out numericAttribute);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
- columnInfo[i].Colname = sb.ToString();
- columnsNames[columnInfo[i].Colname.ToUpper()] = i;
-
- sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)(i + 1), (short)DB2Constants.SQL_DESC_CONCISE_TYPE, sb, (short)sb.Capacity, out strlen, out columnInfo[i].Sqltype);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
-
-
- }
+ private void GetColumnInfo()
+ {
+ if(isClosed)
+ throw new InvalidOperationException("Reader is closed");
+ if(fieldCount <= 0)
+ throw new InvalidOperationException("No Fields found"); // TODO: check error
+ if(columnInfo != null)
+ return;
+
+ columnInfo = new ColumnInfo[fieldCount];
+ columnsNames = new Hashtable(fieldCount);
+
+ StringBuilder sb = new StringBuilder(400);
+ for(int i = 0; i < columnInfo.Length; i++)
+ {
+ short sqlRet;
+ short strlen;
+ int numericAttribute;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)(i + 1), (short)DB2Constants.SQL_DESC_BASE_COLUMN_NAME, sb, (short)sb.Capacity, out strlen, out numericAttribute);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
+ columnInfo[i].Colname = sb.ToString();
+ columnsNames[columnInfo[i].Colname.ToUpper()] = i;
+
+ sqlRet = DB2CLIWrapper.SQLColAttribute(hwndStmt, (short)(i + 1), (short)DB2Constants.SQL_DESC_CONCISE_TYPE, sb, (short)sb.Capacity, out strlen, out columnInfo[i].Sqltype);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "GetSchemaTable");
+
+
+ }
}
#endregion
@@ -374,153 +475,286 @@ namespace IBM.Data.DB2
/// <param name="dbVals"></param>
/// <param name="sqlLen_or_IndPtr"></param>
/// <param name="_resultSet"></param>
- private bool FetchResults(/*IntPtr[] sqlLen_or_IndPtr, */DataTable _resultSet)
- {
- short sqlRet = 0;
- string str = String.Empty;
-
- hasData = false;
-
- sqlRet = DB2CLIWrapper.SQLFetch(hwndStmt);
- if(DB2Constants.SQL_NO_DATA_FOUND == sqlRet)
- return false;
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_STMT, hwndStmt, "Db2ClientDataReader - SQLFetch 1");
-
- hasData = true;
- return true;
+ private int FieldNameLookup(DataTable _schemaTable, string name)
+ {
+ for(int i = 0; i < _schemaTable.Rows.Count; i++)
+ {
+ if(CultureInfo.CurrentCulture.CompareInfo.Compare(name, (string)_schemaTable.Rows[i]["BaseColumnName"],
+ CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase) == 0)
+ {
+ return i;
+ }
+ }
+ return -1;
}
#endregion
+
#region IDataRecord Interface
///Code for the IDataRecord interface
///
#region FieldCount
///
///
- public int FieldCount
- {
- get
- {
- if (isClosed)
- throw new InvalidOperationException("Reader is closed");
-
- return fieldCount;
- }
+ public int FieldCount
+ {
+ get
+ {
+ if (isClosed)
+ throw new InvalidOperationException("Reader is closed");
+
+ return fieldCount;
+ }
}
#endregion
#region Item accessors
- public object this[string name]
- {
- get
- {
- int ordinal = GetOrdinal(name);
- return this[ordinal];
- }
- }
- public object this[int col]
- {
- get
- {
- if(columnInfo == null)
- {
- GetColumnInfo();
- }
- switch(columnInfo[col].Sqltype)
- {
- case DB2Constants.SQL_INTEGER:
- return GetInt32Internal(col);
- case DB2Constants.SQL_SMALLINT:
- return GetInt16Internal(col);
- case DB2Constants.SQL_BIGINT:
- return GetInt64Internal(col);
- case DB2Constants.SQL_DOUBLE:
- return GetDoubleInternal(col);
- case DB2Constants.SQL_REAL:
- return GetFloatInternal(col);
- case DB2Constants.SQL_DECIMAL:
- return GetDecimalInternal(col);
- case DB2Constants.SQL_DATETIME:
- case DB2Constants.SQL_TYPE_TIMESTAMP:
- return GetDateTimeInternal(col);
- case DB2Constants.SQL_TYPE_DATE:
- return GetDateInternal(col);
- case DB2Constants.SQL_TYPE_TIME:
- return GetTimeInternal(col);
- case DB2Constants.SQL_TYPE_CLOB:
- case DB2Constants.SQL_CHAR:
- case DB2Constants.SQL_VARCHAR:
- return GetStringInternal(col);
- case DB2Constants.SQL_TYPE_BLOB:
- case DB2Constants.SQL_TYPE_BINARY:
- case DB2Constants.SQL_LONGVARBINARY:
- case DB2Constants.SQL_VARBINARY:
- return GetBlobDataInternal(col);
- }
- throw new NotImplementedException("Unknown SQL type " + columnInfo[col].Sqltype);
- }
+ public object this[string name]
+ {
+ get
+ {
+ int ordinal = GetOrdinal(name);
+ return this[ordinal];
+ }
+ }
+ public object this[int col]
+ {
+ get
+ {
+ if(columnInfo == null)
+ {
+ GetColumnInfo();
+ }
+ switch(columnInfo[col].Sqltype)
+ {
+ case DB2Constants.SQL_INTEGER:
+ return GetInt32Internal(col);
+ case DB2Constants.SQL_SMALLINT:
+ return GetInt16Internal(col);
+ case DB2Constants.SQL_BIGINT:
+ return GetInt64Internal(col);
+ case DB2Constants.SQL_DOUBLE:
+ return GetDoubleInternal(col);
+ case DB2Constants.SQL_REAL:
+ return GetFloatInternal(col);
+ case DB2Constants.SQL_DECIMAL:
+ return GetDecimalInternal(col);
+ case DB2Constants.SQL_DATETIME:
+ case DB2Constants.SQL_TYPE_TIMESTAMP:
+ return GetDateTimeInternal(col);
+ case DB2Constants.SQL_TYPE_DATE:
+ return GetDateInternal(col);
+ case DB2Constants.SQL_TYPE_TIME:
+ return GetTimeInternal(col);
+ case DB2Constants.SQL_TYPE_CLOB:
+ case DB2Constants.SQL_CHAR:
+ case DB2Constants.SQL_VARCHAR:
+ return GetStringInternal(col);
+ case DB2Constants.SQL_TYPE_BLOB:
+ case DB2Constants.SQL_TYPE_BINARY:
+ case DB2Constants.SQL_LONGVARBINARY:
+ case DB2Constants.SQL_VARBINARY:
+ return GetBlobDataInternal(col);
+ }
+ throw new NotImplementedException("Unknown SQL type " + columnInfo[col].Sqltype);
+ }
}
#endregion
- #region GetBoolean method
+ #region GetBytes
///
- ///Use the Convert class for all of these returns
+ /// GetBytes, return a stream of bytes
///
- public bool GetBoolean(int col)
- {
- return Convert.ToBoolean(this[col]);
+ public long GetBytes(int col, long fieldOffset, byte[] buffer, int bufferOffset, int length)
+ {
+ // TODO: need better implementation for big BLOBs
+
+ byte[] sourceArray = (byte[])this[col];
+#if NET_1_0
+ if(buffer == null)
+ {
+ Array.Copy(sourceArray, (int)fieldOffset, buffer, bufferOffset, length);
+ }
+ return sourceArray.Length;
+#else
+ if(buffer == null)
+ {
+ Array.Copy(sourceArray, fieldOffset, buffer, bufferOffset, length);
+ }
+ return sourceArray.LongLength;
+#endif
}
#endregion
- #region GetByte
+ #region GetChars
///
- ///GetByte
+ ///GetChars, returns char array
///
- public byte GetByte(int col)
- {
- return Convert.ToByte(this[col]);
+ public long GetChars(int col, long fieldOffset, char[] buffer, int bufferOffset, int length)
+ {
+ // TODO: need better implementation for big CLOBs
+
+ string sourceString = GetString(col);
+ if(buffer == null)
+ {
+ sourceString.CopyTo((int)fieldOffset, buffer, bufferOffset, length);
+ }
+ return (long)sourceString.Length;
}
#endregion
- #region GetBytes
- ///
- /// GetBytes, return a stream of bytes
+ #region GetBoolean method
+
+ public Boolean GetBoolean(int col)
+ {
+ return (Boolean)GetBooleanInternal(col);
+ }
+ internal object GetBooleanInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_BIT, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.ReadByte(internalBuffer) != 0;
+ }
+ }
+ return _resultSet[col];
+ }
+ #endregion
+
+ #region GetGuid
///
- public long GetBytes(int col, long fieldOffset, byte[] buffer, int bufferOffset, int length)
+ /// GetDateTime method
+ ///
+ public Guid GetGuid(int col)
{
- if (isClosed) throw new InvalidOperationException("Invalid attempt to read when no data is present");
- byte[] sourceArray = (byte[])this[col];
- if(buffer == null)
+ return (Guid)GetGuidInternal(col);
+ }
+ internal object GetGuidInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
{
- Array.Copy(sourceArray, (int)fieldOffset, buffer, bufferOffset, length);
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
}
- return sourceArray.Length; // should use LongLength property in v1.1 framework;
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_GUID, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(Guid));
+ }
+ }
+ return _resultSet[col];
}
+
#endregion
- #region GetChar
+ #region GetByte
///
- ///GetChar, return column as a char
+ ///GetByte
///
- public char GetChar(int col)
- {
- return Convert.ToChar(this[col]);
+ public Byte GetByte(int col)
+ {
+ return (Byte)GetByteInternal(col);
+ }
+ internal object GetByteInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_UTINYINT, internalBuffer, 10, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.ReadByte(internalBuffer);
+ }
+ }
+ return _resultSet[col];
}
#endregion
- #region GetChars
+ #region GetChar
///
- ///GetChars, returns char array
+ ///GetChar, return column as a char
///
- public long GetChars(int col, long fieldOffset, char[] buffer, int bufferOffset, int length)
+ public Char GetChar(int col)
{
- if (isClosed) throw new InvalidOperationException("Invalid attempt to read when no data is present");
- char[] sourceArray = (char[])this[col];
- if(buffer == null)
+ return (Char)GetCharInternal(col);
+ }
+ internal object GetCharInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
{
- Array.Copy(sourceArray, (int)fieldOffset, buffer, bufferOffset, length);
+ throw new IndexOutOfRangeException("col");
}
- return sourceArray.Length;
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_WCHAR, internalBuffer, 10, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(char));
+ }
+ }
+ return _resultSet[col];
}
#endregion
@@ -532,7 +766,7 @@ namespace IBM.Data.DB2
{
//Have to research this one, not quite sure what the docs mean
//DB2 does have some structured data types, is that what this is for?
- throw new DB2Exception("Not yet supported.");
+ throw new NotSupportedException();
}
#endregion
@@ -542,10 +776,48 @@ namespace IBM.Data.DB2
///
public string GetDataTypeName(int col)
{
- //I could check the meta data as a starting point for this one, but until I implement
- //returning the result sets, I'm not exactly sure what info I'll have, so this function
- //waits until then...
- throw new DB2Exception("Not yet implemented");
+ if(columnInfo == null)
+ {
+ GetColumnInfo();
+ }
+ switch(columnInfo[col].Sqltype)
+ {
+ case DB2Constants.SQL_INTEGER:
+ return "INTEGER";
+ case DB2Constants.SQL_SMALLINT:
+ return "SMALLINT";
+ case DB2Constants.SQL_BIGINT:
+ return "BIGINT";
+ case DB2Constants.SQL_DOUBLE:
+ return "DOUBLE";
+ case DB2Constants.SQL_REAL:
+ return "REAL";
+ case DB2Constants.SQL_DECIMAL:
+ return "DECIMAL";
+ case DB2Constants.SQL_DATETIME:
+ return "DATETIME";
+ case DB2Constants.SQL_TYPE_TIMESTAMP:
+ return "TIMESTAMP";
+ case DB2Constants.SQL_TYPE_DATE:
+ return "DATE";
+ case DB2Constants.SQL_TYPE_TIME:
+ return "TIME";
+ case DB2Constants.SQL_TYPE_CLOB:
+ return "CLOB";
+ case DB2Constants.SQL_CHAR:
+ return "CHAR";
+ case DB2Constants.SQL_VARCHAR:
+ return "VARCHAR";
+ case DB2Constants.SQL_TYPE_BLOB:
+ return "BLOB";
+ case DB2Constants.SQL_TYPE_BINARY:
+ return "BINARY";
+ case DB2Constants.SQL_LONGVARBINARY:
+ return "LONGVARBINARY";
+ case DB2Constants.SQL_VARBINARY:
+ return "VARBINARY";
+ }
+ throw new NotImplementedException("Unknown SQL type " + columnInfo[col].Sqltype);
}
#endregion
@@ -554,137 +826,136 @@ namespace IBM.Data.DB2
/// GetDateTime method
///
-
- public DateTime GetDateTime(int col)
- {
- return (DateTime)GetDateTimeInternal(col);
- }
- internal object GetDateTimeInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_TIMESTAMP, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- DateTime ret = new DateTime(
- Marshal.ReadInt16(internalBuffer, 0), // year
- Marshal.ReadInt16(internalBuffer, 2), // month
- Marshal.ReadInt16(internalBuffer, 4), // day
- Marshal.ReadInt16(internalBuffer, 6), // hour
- Marshal.ReadInt16(internalBuffer, 8), // minute
- Marshal.ReadInt16(internalBuffer, 10));// second
- _resultSet[col] = ret.AddTicks(Marshal.ReadInt32(internalBuffer, 12) / 100); // nanoseconds
- }
- }
- return _resultSet[col];
+ public DateTime GetDateTime(int col)
+ {
+ return (DateTime)GetDateTimeInternal(col);
+ }
+ internal object GetDateTimeInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_TIMESTAMP, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ DateTime ret = new DateTime(
+ Marshal.ReadInt16(internalBuffer, 0), // year
+ Marshal.ReadInt16(internalBuffer, 2), // month
+ Marshal.ReadInt16(internalBuffer, 4), // day
+ Marshal.ReadInt16(internalBuffer, 6), // hour
+ Marshal.ReadInt16(internalBuffer, 8), // minute
+ Marshal.ReadInt16(internalBuffer, 10));// second
+ _resultSet[col] = ret.AddTicks(Marshal.ReadInt32(internalBuffer, 12) / 100); // nanoseconds
+ }
+ }
+ return _resultSet[col];
}
#endregion
- #region GetDate
- ///
- /// GetDate method
- ///
- public DateTime GetDate(int col)
- {
- return (DateTime)GetDateInternal(col);
- }
- internal object GetDateInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_DATE, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = new DateTime(
- Marshal.ReadInt16(internalBuffer, 0), // year
- Marshal.ReadInt16(internalBuffer, 2), // month
- Marshal.ReadInt16(internalBuffer, 4)); // day
- }
- }
- return _resultSet[col];
- }
-
+ #region GetDate
+ ///
+ /// GetDate method
+ ///
+ public DateTime GetDate(int col)
+ {
+ return (DateTime)GetDateInternal(col);
+ }
+ internal object GetDateInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_DATE, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = new DateTime(
+ Marshal.ReadInt16(internalBuffer, 0), // year
+ Marshal.ReadInt16(internalBuffer, 2), // month
+ Marshal.ReadInt16(internalBuffer, 4)); // day
+ }
+ }
+ return _resultSet[col];
+ }
+
#endregion
- #region GetTime
- ///
- /// GetTime method
- ///
- public TimeSpan GetTimeSpan(int col)
- {
- return (TimeSpan)GetTimeInternal(col);
- }
- public TimeSpan GetTime(int col)
- {
- return (TimeSpan)GetTimeInternal(col);
- }
- internal object GetTimeInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_TIME, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = new TimeSpan(
- Marshal.ReadInt16(internalBuffer, 0), // Hour
- Marshal.ReadInt16(internalBuffer, 2), // Minute
- Marshal.ReadInt16(internalBuffer, 4)); // Second
- }
- }
- return _resultSet[col];
- }
-
+ #region GetTime
+ ///
+ /// GetTime method
+ ///
+ public TimeSpan GetTimeSpan(int col)
+ {
+ return (TimeSpan)GetTimeInternal(col);
+ }
+ public TimeSpan GetTime(int col)
+ {
+ return (TimeSpan)GetTimeInternal(col);
+ }
+ internal object GetTimeInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_TIME, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = new TimeSpan(
+ Marshal.ReadInt16(internalBuffer, 0), // Hour
+ Marshal.ReadInt16(internalBuffer, 2), // Minute
+ Marshal.ReadInt16(internalBuffer, 4)); // Second
+ }
+ }
+ return _resultSet[col];
+ }
+
#endregion
@@ -692,83 +963,84 @@ namespace IBM.Data.DB2
///
///GetDecimal method
///
-
- #region GetDecimal
- ///
- ///GetDecimal method
- ///
- public Decimal GetDecimal(int col)
- {
- return (Decimal)GetDecimalInternal(col);
- }
- internal object GetDecimalInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_DECIMAL_OLEDB, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(decimal));
- }
- }
- return _resultSet[col];
- }
- #endregion
+
+ public Decimal GetDecimal(int col)
+ {
+ return (Decimal)GetDecimalInternal(col);
+ }
+ internal object GetDecimalInternal(int col)
+ {
+ object tmp = GetStringInternal(col);
+ if(tmp is string)
+ {
+ _resultSet[col] = decimal.Parse(((string)_resultSet[col]).Replace(',','.'), // sometimes we get a '.' and sometimes we get a ','
+ System.Globalization.CultureInfo.InvariantCulture);
+ }
+ // if((col < 0) || (col >= fieldCount)) // only works on windows UDB DB2 V8?
+ // {
+ // throw new IndexOutOfRangeException("col");
+ // }
+ // if(!hasData)
+ // {
+ // throw new InvalidOperationException("No data");
+ // }
+ // if(_resultSet == null)
+ // {
+ // _resultSet = new object[fieldCount];
+ // }
+ // if(_resultSet[col] == null)
+ // {
+ // int len;
+ // short sqlRet = Db2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)Db2Constants.SQL_C_DECIMAL_OLEDB, internalBuffer, internalBufferSize, out len);
+ // if(len == Db2Constants.SQL_NULL_DATA)
+ // {
+ // _resultSet[col] = DBNull.Value;
+ // }
+ // else
+ // {
+ // _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(decimal));
+ // }
+ // }
+ return _resultSet[col];
+ }
#endregion
#region GetDouble
///
/// GetDouble
///
- public Double GetDouble(int col)
- {
- return (Double)GetDoubleInternal(col);
- }
- internal object GetDoubleInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_DOUBLE, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = Marshal.PtrToStructure(Ptr, typeof(double));
- }
- }
- return _resultSet[col];
+ public Double GetDouble(int col)
+ {
+ return (Double)GetDoubleInternal(col);
+ }
+ internal object GetDoubleInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_DOUBLE, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(double));
+ }
+ }
+ return _resultSet[col];
}
#endregion
@@ -778,7 +1050,11 @@ namespace IBM.Data.DB2
///
public Type GetFieldType(int col)
{
- return this[col].GetType();
+ if(columnInfo == null)
+ {
+ GetColumnInfo();
+ }
+ return GetManagedType(columnInfo[col].Sqltype);
}
#endregion
@@ -786,48 +1062,38 @@ namespace IBM.Data.DB2
///
/// GetFloat
///
- public float GetFloat(int col)
- {
- return (float)GetFloatInternal(col);
- }
- internal object GetFloatInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_REAL, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = Marshal.PtrToStructure(Ptr, typeof(float));
- }
- }
- return _resultSet[col];
+ public float GetFloat(int col)
+ {
+ return (float)GetFloatInternal(col);
}
- #endregion
-
- #region GetGuid
- ///
- /// GetGuid
- ///
- public Guid GetGuid(int col)
+ internal object GetFloatInternal(int col)
{
- throw new DB2Exception("TBD");
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_REAL, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(float));
+ }
+ }
+ return _resultSet[col];
}
#endregion
@@ -835,127 +1101,129 @@ namespace IBM.Data.DB2
///
///GetInt16
///
- public short GetInt16(int col)
- {
- return (short)GetInt16Internal(col);
- }
-
- internal object GetInt16Internal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_SSHORT, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(short));
- }
- }
- return _resultSet[col];
+ public short GetInt16(int col)
+ {
+ return (short)GetInt16Internal(col);
+ }
+
+ internal object GetInt16Internal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_SSHORT, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(short));
+ }
+ }
+ return _resultSet[col];
}
///
///GetInt32
///
- public int GetInt32(int col)
- {
- return (int)GetInt32Internal(col);
- }
-
- internal object GetInt32Internal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_SLONG, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(int));
- }
- }
- return _resultSet[col];
+ public int GetInt32(int col)
+ {
+ return (int)GetInt32Internal(col);
+ }
+
+ internal object GetInt32Internal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_SLONG, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(int));
+ }
+ }
+ return _resultSet[col];
}
+
///
///GetInt64
///
- public long GetInt64(int col)
- {
- return (int)GetInt64Internal(col);
- }
-
- internal object GetInt64Internal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int len;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_SBIGINT, internalBuffer, internalBufferSize, out len);
- if(len == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(long));
- }
- }
- return _resultSet[col];
+ public long GetInt64(int col)
+ {
+ return (long)GetInt64Internal(col);
+ }
+
+ internal object GetInt64Internal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int len;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_SBIGINT, internalBuffer, internalBufferSize, out len);
+ if(len == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ _resultSet[col] = Marshal.PtrToStructure(internalBuffer, typeof(long));
+ }
+ }
+ return _resultSet[col];
}
+
#endregion
#region GetName
///
///GetName, returns the name of the field
///
- public string GetName(int col)
- {
- if(columnInfo == null)
- {
- GetColumnInfo();
- }
- return columnInfo[col].Colname;
+ public string GetName(int col)
+ {
+ if(columnInfo == null)
+ {
+ GetColumnInfo();
+ }
+ return columnInfo[col].Colname;
}
#endregion
@@ -963,18 +1231,18 @@ namespace IBM.Data.DB2
///
/// GetOrdinal, return the index of the named column
///
- public int GetOrdinal(string name)
- {
- if(columnInfo == null)
- {
- GetColumnInfo();
- }
- object ordinal = columnsNames[name.ToUpper()];
- if(ordinal == null)
- {
- throw new IndexOutOfRangeException("name");
- }
- return (int)ordinal;
+ public int GetOrdinal(string name)
+ {
+ if(columnInfo == null)
+ {
+ GetColumnInfo();
+ }
+ object ordinal = columnsNames[name.ToUpper()];
+ if(ordinal == null)
+ {
+ throw new IndexOutOfRangeException("name");
+ }
+ return (int)ordinal;
}
#endregion
@@ -982,42 +1250,42 @@ namespace IBM.Data.DB2
///
/// GetString returns a string
///
- public string GetString(int col)
- {
- return (string)GetStringInternal(col);
- }
-
- public object GetStringInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int length;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_WCHAR, (StringBuilder)null, 0, out length);
- if(length == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- IntPtr mem = Marshal.AllocHGlobal(length + 2);
- sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_WCHAR, mem, length + 2, out length);
- _resultSet[col] = Marshal.PtrToStringUni(mem);
- Marshal.FreeHGlobal(mem);
- }
- }
- return _resultSet[col];
+ public string GetString(int col)
+ {
+ return (string)GetStringInternal(col);
+ }
+
+ public object GetStringInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int length;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_WCHAR, (StringBuilder)null, 0, out length);
+ if(length == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ IntPtr mem = Marshal.AllocHGlobal(length + 2);
+ sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_WCHAR, mem, length + 2, out length);
+ _resultSet[col] = Marshal.PtrToStringUni(mem);
+ Marshal.FreeHGlobal(mem);
+ }
+ }
+ return _resultSet[col];
}
#endregion
@@ -1035,17 +1303,17 @@ namespace IBM.Data.DB2
///
/// GetValues returns all columns in the row through the argument, and the number of columns in the return value
///
- public int GetValues(object[] values)
- {
- int count = Math.Min(fieldCount, values.Length);
-
- for (int i = 0; i < count; i++)
- {
- values[i] = this[i];
-
- }
-
- return count;
+ public int GetValues(object[] values)
+ {
+ int count = Math.Min(fieldCount, values.Length);
+
+ for (int i = 0; i < count; i++)
+ {
+ values[i] = this[i];
+
+ }
+
+ return count;
}
#endregion
@@ -1053,10 +1321,10 @@ namespace IBM.Data.DB2
///
/// IsDBNull Is the column null
///
- public bool IsDBNull(int col)
- {
- //Proper implementation once I get the SQLDescribe/SQLBind/SQLFetch stuff in place
- return Convert.IsDBNull(this[col]);
+ public bool IsDBNull(int col)
+ {
+ //Proper implementation once I get the SQLDescribe/SQLBind/SQLFetch stuff in place
+ return Convert.IsDBNull(this[col]);
}
#endregion
@@ -1064,30 +1332,31 @@ namespace IBM.Data.DB2
#region private methods
- private DataTable BuildNewSchemaTable()
- {
- DataTable schemaTable = new DataTable("SchemaTable");
-
- schemaTable.Columns.Add(new DataColumn("ColumnName", typeof(string)));
- schemaTable.Columns.Add(new DataColumn("ColumnOrdinal", typeof(int)));
- schemaTable.Columns.Add(new DataColumn("ColumnSize", typeof(int)));
- schemaTable.Columns.Add(new DataColumn("NumericPrecision", typeof(short)));
- schemaTable.Columns.Add(new DataColumn("NumericScale", typeof(short)));
- schemaTable.Columns.Add(new DataColumn("DataType", typeof(System.Type)));
- schemaTable.Columns.Add(new DataColumn("ProviderType", typeof(int)));
- schemaTable.Columns.Add(new DataColumn("IsLong", typeof(bool)));
- schemaTable.Columns.Add(new DataColumn("AllowDBNull", typeof(bool)));
- schemaTable.Columns.Add(new DataColumn("IsReadOnly", typeof(bool)));
- schemaTable.Columns.Add(new DataColumn("IsRowVersion", typeof(bool)));
- schemaTable.Columns.Add(new DataColumn("IsUnique", typeof(bool)));
- schemaTable.Columns.Add(new DataColumn("IsKey", typeof(bool)));
- schemaTable.Columns.Add(new DataColumn("IsAutoIncrement", typeof(bool)));
- schemaTable.Columns.Add(new DataColumn("BaseSchemaName", typeof(string)));
- schemaTable.Columns.Add(new DataColumn("BaseCatalogName", typeof(string)));
- schemaTable.Columns.Add(new DataColumn("BaseTableName", typeof(string)));
- schemaTable.Columns.Add(new DataColumn("BaseColumnName", typeof(string)));
-
- return schemaTable;
+ private DataTable BuildNewSchemaTable()
+ {
+ DataTable schemaTable = new DataTable("SchemaTable");
+
+ schemaTable.Columns.Add(new DataColumn("ColumnName", typeof(string)));
+ schemaTable.Columns.Add(new DataColumn("ColumnOrdinal", typeof(int)));
+ schemaTable.Columns.Add(new DataColumn("ColumnSize", typeof(int)));
+ schemaTable.Columns.Add(new DataColumn("NumericPrecision", typeof(short)));
+ schemaTable.Columns.Add(new DataColumn("NumericScale", typeof(short)));
+ schemaTable.Columns.Add(new DataColumn("DataType", typeof(System.Type)));
+ schemaTable.Columns.Add(new DataColumn("ProviderType", typeof(int)));
+ schemaTable.Columns.Add(new DataColumn("IsLong", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("AllowDBNull", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("IsReadOnly", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("IsRowVersion", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("IsUnique", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("IsKey", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("IsKeyColumn", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("IsAutoIncrement", typeof(bool)));
+ schemaTable.Columns.Add(new DataColumn("BaseSchemaName", typeof(string)));
+ schemaTable.Columns.Add(new DataColumn("BaseCatalogName", typeof(string)));
+ schemaTable.Columns.Add(new DataColumn("BaseTableName", typeof(string)));
+ schemaTable.Columns.Add(new DataColumn("BaseColumnName", typeof(string)));
+
+ return schemaTable;
}
#endregion
@@ -1101,74 +1370,79 @@ namespace IBM.Data.DB2
}
}
- private Type GetManagedType(short sql_type)
- {
- switch(sql_type)
- {
- case DB2Constants.SQL_INTEGER:
- return typeof(int);
- case DB2Constants.SQL_SMALLINT:
- return typeof(short);
- case DB2Constants.SQL_BIGINT:
- return typeof(long);
- case DB2Constants.SQL_DOUBLE:
- return typeof(double);
- case DB2Constants.SQL_DECIMAL:
- return typeof(decimal);
- case DB2Constants.SQL_DATETIME:
- case DB2Constants.SQL_TYPE_DATE:
- case DB2Constants.SQL_TYPE_TIMESTAMP:
- return typeof(DateTime);
- case DB2Constants.SQL_TYPE_TIME:
- return typeof(TimeSpan);
- case DB2Constants.SQL_CHAR:
- case DB2Constants.SQL_VARCHAR:
- return typeof(string);
- case DB2Constants.SQL_TYPE_BLOB:
- case DB2Constants.SQL_TYPE_BINARY:
- case DB2Constants.SQL_LONGVARBINARY:
- case DB2Constants.SQL_VARBINARY:
- return typeof(byte[]);
- }
- throw new NotImplementedException("Unknown SQL type " + sql_type);
+ private Type GetManagedType(int sql_type)
+ {
+ switch(sql_type)
+ {
+ case DB2Constants.SQL_INTEGER:
+ return typeof(int);
+ case DB2Constants.SQL_SMALLINT:
+ return typeof(short);
+ case DB2Constants.SQL_BIGINT:
+ return typeof(long);
+ case DB2Constants.SQL_DOUBLE:
+ return typeof(double);
+ case DB2Constants.SQL_DECIMAL:
+ return typeof(decimal);
+ case DB2Constants.SQL_DATETIME:
+ case DB2Constants.SQL_TYPE_DATE:
+ case DB2Constants.SQL_TYPE_TIMESTAMP:
+ return typeof(DateTime);
+ case DB2Constants.SQL_TYPE_TIME:
+ return typeof(TimeSpan);
+ case DB2Constants.SQL_CHAR:
+ case DB2Constants.SQL_VARCHAR:
+ case DB2Constants.SQL_TYPE_CLOB:
+ return typeof(string);
+ case DB2Constants.SQL_TYPE_BLOB:
+ case DB2Constants.SQL_TYPE_BINARY:
+ case DB2Constants.SQL_LONGVARBINARY:
+ case DB2Constants.SQL_VARBINARY:
+ return typeof(byte[]);
+ }
+ throw new NotImplementedException("Unknown SQL type " + sql_type);
}
- private bool IsLong(short sql_type){
- switch(sql_type){
- default:
- return false;
+ private bool IsLong(short sql_type)
+ {
+ switch(sql_type)
+ {
+ case DB2Constants.SQL_TYPE_CLOB:
+ case DB2Constants.SQL_TYPE_BLOB:
+ return true;
}
+ return false;
}
- private object GetBlobDataInternal(int col)
- {
- if((col < 0) || (col >= fieldCount))
- {
- throw new IndexOutOfRangeException("col");
- }
- if(!hasData)
- {
- throw new InvalidOperationException("No data");
- }
- if(_resultSet == null)
- {
- _resultSet = new object[fieldCount];
- }
- if(_resultSet[col] == null)
- {
- int length;
- short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_BINARY, (StringBuilder)null, 0, out length);
- if(length == DB2Constants.SQL_NULL_DATA)
- {
- _resultSet[col] = DBNull.Value;
- }
- else
- {
- byte[] result = new byte[length];
- sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_BINARY, result, length, out length);
- _resultSet[col] = result;
- }
- }
- return _resultSet[col];
+ private object GetBlobDataInternal(int col)
+ {
+ if((col < 0) || (col >= fieldCount))
+ {
+ throw new IndexOutOfRangeException("col");
+ }
+ if(!hasData)
+ {
+ throw new InvalidOperationException("No data");
+ }
+ if(_resultSet == null)
+ {
+ _resultSet = new object[fieldCount];
+ }
+ if(_resultSet[col] == null)
+ {
+ int length;
+ short sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_BINARY, (StringBuilder)null, 0, out length);
+ if(length == DB2Constants.SQL_NULL_DATA)
+ {
+ _resultSet[col] = DBNull.Value;
+ }
+ else
+ {
+ byte[] result = new byte[length];
+ sqlRet = DB2CLIWrapper.SQLGetData(this.hwndStmt, (short)(col + 1), (short)DB2Constants.SQL_C_TYPE_BINARY, result, length, out length);
+ _resultSet[col] = result;
+ }
+ }
+ return _resultSet[col];
}
}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Environment.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Environment.cs
new file mode 100755
index 00000000000..1a5cee3792f
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Environment.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections;
+
+namespace IBM.Data.DB2
+{
+
+ internal sealed class DB2Environment : IDisposable
+ {
+ private static DB2Environment environment;
+ internal Hashtable connectionPools;
+ internal IntPtr penvHandle = IntPtr.Zero;
+
+ private DB2Environment()
+ {
+ connectionPools = Hashtable.Synchronized(new Hashtable());
+
+ // short sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_ENV, IntPtr.Zero, ref penvHandle);
+ short sqlRet = DB2CLIWrapper.Initialize(ref penvHandle);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, 0, IntPtr.Zero, "Unable to allocate Environment handle.", null);
+
+ // SQLSetEnvAttr( hEnv=0:1, fAttribute=SQL_ATTR_APP_TYPE 2473, vParam=4, cbParam=0 ) // 4=ADO.NET apptype????
+ // SQLSetEnvAttr( hEnv=0:1, fAttribute=SQL_ATTR_OUTPUT_NTS 10001, vParam=0, cbParam=0 ) // strings not 0-terminated
+ }
+
+ public static DB2Environment Instance
+ {
+ get
+ {
+ if(environment == null)
+ {
+ lock(typeof(DB2Environment))
+ {
+ if(environment == null)
+ {
+ environment = new DB2Environment();
+ }
+ }
+ }
+ return environment;
+ }
+ }
+ #region IDisposable Members
+
+ bool disposed;
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ public void Dispose(bool disposing)
+ {
+ if(disposed)
+ {
+ DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_ENV, penvHandle);
+ environment = null;
+ }
+ disposed = true;
+ }
+
+ ~DB2Environment()
+ {
+ Dispose(false);
+ }
+
+ #endregion
+ }
+
+} \ No newline at end of file
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Error.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Error.cs
new file mode 100755
index 00000000000..06084ff8963
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Error.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace IBM.Data.DB2
+{
+ public sealed class DB2Error
+ {
+ string message;
+ string state;
+ int nativeerror;
+
+ internal DB2Error(string message, string state, int nativeerror)
+ {
+ this.message = message;
+ this.state = state;
+ this.nativeerror = nativeerror;
+ }
+
+ public override string ToString()
+ {
+ return Message;
+ }
+ public string Message
+ {
+ get { return message; }
+ }
+ public int NativeError
+ {
+ get { return nativeerror; }
+ }
+ public string Source
+ {
+ get { return "IBM.Data.DB2"; }
+ }
+ public string SQLState
+ {
+ get { return state; }
+ }
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ErrorCollection.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ErrorCollection.cs
new file mode 100755
index 00000000000..bdebaf47d64
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ErrorCollection.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections;
+using System.Text;
+
+namespace IBM.Data.DB2
+{
+ [Serializable()]
+ public class DB2ErrorCollection : CollectionBase
+ {
+
+ public DB2ErrorCollection(short sqlHandleType, IntPtr sqlHandle)
+ {
+ StringBuilder sqlState = new StringBuilder(10);
+ StringBuilder errorMessage = new StringBuilder(1025);
+
+ int sqlReturn;
+ short recNum=1;
+
+ do
+ {
+ int nativeError;
+ short errorMessageLength;
+ sqlReturn = DB2CLIWrapper.SQLGetDiagRec(sqlHandleType, sqlHandle, recNum++, sqlState, out nativeError, errorMessage, errorMessage.Capacity - 1, out errorMessageLength);
+ if(sqlReturn == 0)
+ {
+ Add(new DB2Error(errorMessage.ToString(), sqlState.ToString(), nativeError));
+ }
+ }
+ while (sqlReturn == 0);
+ }
+
+ public DB2Error this[int index]
+ {
+ get
+ {
+ return ((DB2Error)(List[index]));
+ }
+ }
+ internal int Add(DB2Error value)
+ {
+ return List.Add(value);
+ }
+
+ public void CopyTo(DB2Error[] array, int index)
+ {
+ List.CopyTo(array, index);
+ }
+
+ /// <summary>
+ /// <para>Returns an enumerator that can iterate through
+ /// the <see cref='d.DB2ErrorCollection'/> .</para>
+ /// </summary>
+ /// <returns><para>None.</para></returns>
+ /// <seealso cref='System.Collections.IEnumerator'/>
+ public new DB2ErrorEnumerator GetEnumerator()
+ {
+ return new DB2ErrorEnumerator(this);
+ }
+
+ public class DB2ErrorEnumerator : object, IEnumerator
+ {
+
+ private IEnumerator baseEnumerator;
+
+ private IEnumerable temp;
+
+ public DB2ErrorEnumerator(DB2ErrorCollection mappings)
+ {
+ this.temp = ((IEnumerable)(mappings));
+ this.baseEnumerator = temp.GetEnumerator();
+ }
+
+ public DB2Error Current
+ {
+ get
+ {
+ return ((DB2Error)(baseEnumerator.Current));
+ }
+ }
+
+ object IEnumerator.Current
+ {
+ get
+ {
+ return baseEnumerator.Current;
+ }
+ }
+
+ public bool MoveNext()
+ {
+ return baseEnumerator.MoveNext();
+ }
+
+ bool IEnumerator.MoveNext()
+ {
+ return baseEnumerator.MoveNext();
+ }
+
+ public void Reset()
+ {
+ baseEnumerator.Reset();
+ }
+
+ void IEnumerator.Reset()
+ {
+ baseEnumerator.Reset();
+ }
+ }
+
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Exception.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Exception.cs
new file mode 100755
index 00000000000..5ac077377ec
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Exception.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Runtime.Serialization;
+
+namespace IBM.Data.DB2
+{
+
+
+ [Serializable]
+ public sealed class DB2Exception : Exception
+ {
+ private DB2ErrorCollection errors;
+ private string message;
+
+
+ public DB2ErrorCollection Errors
+ {
+ get
+ {
+ return errors;
+ }
+ }
+ public override string Message
+ {
+ get
+ {
+ if(errors.Count > 0)
+ {
+ string result = "";
+ for(int i = 0; i < errors.Count; i++)
+ {
+ if(i > 0)
+ {
+ result += " ";
+ }
+ result += "ERROR [" + errors[i].SQLState + "] " + errors[i].Message;
+ }
+ if(message != null)
+ {
+ result += " " + message;
+ }
+ return result;
+ }
+ return "No error information";
+ }
+ }
+
+ private DB2Exception(SerializationInfo si, StreamingContext sc)
+ {
+ throw new NotImplementedException();
+ }
+ public override void GetObjectData(SerializationInfo si, StreamingContext context)
+ {
+ throw new NotImplementedException();
+ }
+
+ internal DB2Exception(short sqlHandleType, IntPtr sqlHandle, string message)
+ {
+ this.message = message;
+ errors = new DB2ErrorCollection(sqlHandleType, sqlHandle);
+
+
+ }
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2InfoMessageEventArgs.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2InfoMessageEventArgs.cs
new file mode 100755
index 00000000000..d0eea684e40
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2InfoMessageEventArgs.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Data;
+using System.Runtime.InteropServices;
+
+namespace IBM.Data.DB2
+{
+ public delegate void DB2InfoMessageEventHandler(object sender, DB2InfoMessageEventArgs e);
+
+ public sealed class DB2InfoMessageEventArgs : EventArgs
+ {
+ private DB2ErrorCollection errors;
+
+ public DB2InfoMessageEventArgs(DB2ErrorCollection errors)
+ {
+ this.errors = errors;
+ }
+
+ public DB2ErrorCollection Errors
+ {
+ get
+ {
+ return errors;
+ }
+ }
+ public string Message
+ {
+ get
+ {
+ if(errors.Count > 0)
+ {
+ string result = "";
+ for(int i = 0; i < errors.Count; i++)
+ {
+ if(i > 0)
+ {
+ result += " ";
+ }
+ result += "INFO [" + errors[i].SQLState + "] " + errors[i].Message;
+ }
+ return result;
+ }
+ return "No information";
+ }
+ }
+
+ }
+}
+
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2OpenConnection.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2OpenConnection.cs
new file mode 100755
index 00000000000..668df8b7f0b
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2OpenConnection.cs
@@ -0,0 +1,196 @@
+using System;
+using System.Collections;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+namespace IBM.Data.DB2
+{
+
+ internal sealed class DB2OpenConnection : IDisposable
+ {
+ private IntPtr dbHandle = IntPtr.Zero;
+
+ private DB2ConnectionSettings settings;
+ private bool disposed = false;
+ internal DateTime poolDisposalTime; // time to live used for disposal of connections in the connection pool
+ public bool transactionOpen;
+ public bool autoCommit = true;
+ private string databaseProductName;
+ private string databaseVersion;
+ private int majorVersion;
+ private int minorVersion;
+
+ public IntPtr DBHandle
+ {
+ get { return dbHandle; }
+ }
+ public string DatabaseProductName
+ {
+ get { return databaseProductName; }
+ }
+ public string DatabaseVersion
+ {
+ get { return databaseVersion; }
+ }
+ public int MajorVersion
+ {
+ get { return majorVersion; }
+ }
+ public int MinorVersion
+ {
+ get { return minorVersion; }
+ }
+
+ public DB2OpenConnection(DB2ConnectionSettings settings, DB2Connection connection)
+ {
+ this.settings = settings;
+ try
+ {
+ short sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_DBC, DB2Environment.Instance.penvHandle, out dbHandle);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, DB2Environment.Instance.penvHandle, "Unable to allocate database handle in DB2Connection.", connection);
+
+ if(settings.Server.Length > 0)
+ {
+ StringBuilder outConnectStr = new StringBuilder(60); // TODO: ????
+ short numOutCharsReturned;
+
+ sqlRet = DB2CLIWrapper.SQLDriverConnect(dbHandle, IntPtr.Zero,
+ settings.ConnectionString, (short)settings.ConnectionString.Length,
+ outConnectStr, (short)outConnectStr.Length, out numOutCharsReturned,
+ DB2Constants.SQL_DRIVER_NOPROMPT /*SQL_DRIVER_COMPLETE*/);
+
+ }
+ else
+ {
+ sqlRet = DB2CLIWrapper.SQLConnect(dbHandle,
+ settings.DatabaseAlias, (short)settings.DatabaseAlias.Length,
+ settings.UserName, (short)settings.UserName.Length,
+ settings.PassWord, (short)settings.PassWord.Length);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, dbHandle, "Unable to connect to the database.", connection);
+ }
+
+
+
+ if((settings.Pool == null) || (settings.Pool.databaseProductName == null))
+ {
+ StringBuilder sb = new StringBuilder(256);
+ short stringLength;
+ sqlRet = DB2CLIWrapper.SQLGetInfo(dbHandle, /*SQL_DBMS_NAME*/17, sb, (short)(sb.Capacity / 2), out stringLength);
+ new DB2ErrorCollection(DB2Constants.SQL_HANDLE_DBC, dbHandle).ToString();
+
+
+
+ if(sqlRet == 0)
+ databaseProductName = sb.ToString(); //(0, Math.Min(sb.Capacity, stringLength / 2));
+ sqlRet = DB2CLIWrapper.SQLGetInfo(dbHandle, /*SQL_DBMS_VER*/18, sb, (short)(sb.Capacity / 2), out stringLength);
+ if(sqlRet == 0)
+ {
+ databaseVersion = sb.ToString(0, Math.Min(sb.Capacity, stringLength / 2));
+ try
+ {
+ string[] splitVersion = databaseVersion.Split('.');
+ majorVersion = int.Parse(splitVersion[0]);
+ minorVersion = int.Parse(splitVersion[1]);
+ }
+ catch{}
+ }
+ if(settings.Pool != null)
+ {
+ settings.Pool.databaseProductName = databaseProductName;
+ settings.Pool.databaseVersion = databaseVersion;
+ settings.Pool.majorVersion = majorVersion;
+ settings.Pool.minorVersion = minorVersion;
+ }
+ }
+ else if(settings.Pool != null)
+ {
+ if(settings.Pool != null)
+ {
+ databaseProductName = settings.Pool.databaseProductName;
+ databaseVersion = settings.Pool.databaseVersion;
+ majorVersion = settings.Pool.majorVersion;
+ minorVersion = settings.Pool.minorVersion;
+ }
+ }
+ }
+ catch
+ {
+ if(dbHandle != IntPtr.Zero)
+ {
+ DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);
+ dbHandle = IntPtr.Zero;
+ }
+ throw;
+ }
+ }
+
+ public void RollbackDeadTransaction()
+ {
+ DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, DBHandle, DB2Constants.SQL_ROLLBACK);
+ transactionOpen = false;
+ }
+
+ public void Close()
+ {
+ if(transactionOpen)
+ RollbackDeadTransaction();
+
+ if(settings.Pool != null)
+ {
+ settings.Pool.AddToFreeConnections(this);
+ }
+ else
+ {
+ Dispose();
+ }
+ }
+
+ private void FreeHandles()
+ {
+ if(dbHandle != IntPtr.Zero)
+ {
+ short sqlRet = DB2CLIWrapper.SQLDisconnect(dbHandle);
+ // Note that SQLDisconnect() automatically drops any statements and
+ // descriptors open on the connection.
+ sqlRet = DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);
+
+ dbHandle = IntPtr.Zero;
+ }
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if(!disposed)
+ {
+ if(disposing)
+ {
+ // dispose managed resources
+ }
+ FreeHandles();
+ }
+ disposed = true;
+ }
+
+
+ ~DB2OpenConnection()
+ {
+ if(settings.Pool != null)
+ {
+ settings.Pool.OpenConnectionFinalized();
+ }
+ Dispose(false);
+ }
+ #endregion
+ }
+
+
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Parameter.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Parameter.cs
new file mode 100755
index 00000000000..8fc044fc202
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Parameter.cs
@@ -0,0 +1,673 @@
+using System;
+using System.Data;
+using System.Runtime.InteropServices;
+
+namespace IBM.Data.DB2
+{
+
+ public sealed class DB2Parameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
+ {
+ private DbType dbType = DbType.Object;
+ private DB2Type db2Type = DB2Type.Invalid;
+ private short db2DataType = DB2Constants.SQL_UNKNOWN_TYPE;
+ private short db2LastUsedDataType = DB2Constants.SQL_UNKNOWN_TYPE;
+
+ private ParameterDirection direction;
+ private short db2Direction = DB2Constants.SQL_PARAM_INPUT;
+ private bool nullable = true;
+ private string parameterName;
+ private string sourceColumn;
+ private DataRowVersion sourceVersion;
+ private object dataVal;
+ private byte scale, precision;
+ private int size;
+ internal IntPtr internalBuffer;
+ internal IntPtr internalLengthBuffer;
+ internal int requiredMemory;
+
+ #region Contructors and destructors
+ public DB2Parameter()
+ {
+ direction = ParameterDirection.Input;
+ sourceVersion = DataRowVersion.Current;
+ }
+
+ public DB2Parameter(string name, DB2Type type)
+ {
+ direction = ParameterDirection.Input;
+ sourceVersion = DataRowVersion.Current;
+ this.ParameterName = name;
+ this.DB2Type = type;
+ }
+
+ public DB2Parameter(string name, DB2Type type, int size)
+ {
+ direction = ParameterDirection.Input;
+ sourceVersion = DataRowVersion.Current;
+ this.ParameterName = name;
+ this.DB2Type = type;
+ this.Size = size;
+ }
+
+ public DB2Parameter(string name, DB2Type type, int size, string sourceColumn)
+ {
+ direction = ParameterDirection.Input;
+ sourceVersion = DataRowVersion.Current;
+ this.ParameterName = name;
+ this.DB2Type = type;
+ this.Size = size;
+ this.SourceColumn = sourceColumn;
+ }
+
+ public DB2Parameter(string parameterName, object value)
+ {
+ direction = ParameterDirection.Input;
+ sourceVersion = DataRowVersion.Current;
+ this.ParameterName = parameterName;
+ this.Value = value;
+ }
+
+ public DB2Parameter(string parameterName, DB2Type db2Type, int size, ParameterDirection parameterDirection, bool isNullable, byte precision, byte scale, string srcColumn, DataRowVersion srcVersion, object value)
+ {
+ this.ParameterName = parameterName;
+ this.DB2Type = db2Type;
+ this.Size = size;
+ this.Direction = parameterDirection;
+ this.IsNullable = isNullable;
+ this.Precision = precision;
+ this.Scale = scale;
+ this.SourceColumn = srcColumn;
+ this.SourceVersion = srcVersion;
+ this.Value = value;
+ }
+
+ #endregion
+ #region Properties
+ #region DbType Property
+ public DB2Type DB2Type
+ {
+ get
+ {
+ return db2Type;
+ }
+ set
+ {
+ db2Type = value;
+ switch(db2Type)
+ {
+ case DB2Type.Invalid: dbType = DbType.Object; db2DataType = DB2Constants.SQL_UNKNOWN_TYPE; break;
+ case DB2Type.SmallInt: dbType = DbType.Int16; db2DataType = DB2Constants.SQL_SMALLINT; break;
+ case DB2Type.Integer: dbType = DbType.Int32; db2DataType = DB2Constants.SQL_INTEGER; break;
+ case DB2Type.BigInt: dbType = DbType.Int64; db2DataType = DB2Constants.SQL_BIGINT; break;
+ case DB2Type.Real: dbType = DbType.Single; db2DataType = DB2Constants.SQL_REAL; break;
+ case DB2Type.Double: dbType = DbType.Double; db2DataType = DB2Constants.SQL_DOUBLE; break;
+ case DB2Type.Float: dbType = DbType.Single; db2DataType = DB2Constants.SQL_REAL; break;
+ case DB2Type.Decimal: dbType = DbType.Decimal; db2DataType = DB2Constants.SQL_DECIMAL; break;
+ case DB2Type.Numeric: dbType = DbType.VarNumeric; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.Date: dbType = DbType.Date; db2DataType = DB2Constants.SQL_TYPE_DATE; break;
+ case DB2Type.Time: dbType = DbType.Time; db2DataType = DB2Constants.SQL_TYPE_TIME; break;
+ case DB2Type.Timestamp: dbType = DbType.DateTime; db2DataType = DB2Constants.SQL_TYPE_TIMESTAMP; break;
+ case DB2Type.Char: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.VarChar: dbType = DbType.StringFixedLength; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.LongVarChar: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.Binary: dbType = DbType.Binary; db2DataType = DB2Constants.SQL_VARBINARY; break;
+ case DB2Type.VarBinary: dbType = DbType.Binary; db2DataType = DB2Constants.SQL_VARBINARY; break;
+ case DB2Type.LongVarBinary: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.Graphic: dbType = DbType.StringFixedLength; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.VarGraphic: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.LongVarGraphic: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.Clob: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.Blob: dbType = DbType.Binary; db2DataType = DB2Constants.SQL_VARBINARY; break;
+ case DB2Type.DbClob: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DB2Type.Datalink: dbType = DbType.Byte; db2DataType = DB2Constants.SQL_VARBINARY; break;
+ case DB2Type.RowId: dbType = DbType.Decimal; db2DataType = DB2Constants.SQL_DECIMAL; break;
+ case DB2Type.XmlReader: dbType = DbType.String; db2DataType = DB2Constants.SQL_WCHAR; break;
+ default:
+ throw new NotSupportedException("Value is of unknown data type");
+ }
+ }
+ }
+ ///
+ /// Parameter data type
+ ///
+ public DbType DbType
+ {
+ get
+ {
+ return dbType;
+ }
+ set
+ {
+ dbType = value;
+ switch(dbType)
+ {
+ case DbType.AnsiString: db2Type = DB2Type.VarChar; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DbType.AnsiStringFixedLength: db2Type = DB2Type.Char; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DbType.Binary: db2Type = DB2Type.Binary; db2DataType = DB2Constants.SQL_VARBINARY; break;
+ case DbType.Boolean: db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_BIT; break;
+ case DbType.Byte: db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_UTINYINT; break;
+ case DbType.Currency: db2Type = DB2Type.Decimal; db2DataType = DB2Constants.SQL_DECIMAL; break;
+ case DbType.Date: db2Type = DB2Type.Date; db2DataType = DB2Constants.SQL_TYPE_DATE; break;
+ case DbType.DateTime: db2Type = DB2Type.Timestamp; db2DataType = DB2Constants.SQL_TYPE_TIMESTAMP; break;
+ case DbType.Decimal: db2Type = DB2Type.Decimal; db2DataType = DB2Constants.SQL_DECIMAL; break;
+ case DbType.Double: db2Type = DB2Type.Double; db2DataType = DB2Constants.SQL_DOUBLE; break;
+ case DbType.Guid: db2Type = DB2Type.Binary; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DbType.Int16: db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_SMALLINT; break;
+ case DbType.Int32: db2Type = DB2Type.Integer; db2DataType = DB2Constants.SQL_INTEGER; break;
+ case DbType.Int64: db2Type = DB2Type.BigInt; db2DataType = DB2Constants.SQL_BIGINT; break;
+ case DbType.Object: db2Type = DB2Type.Invalid; db2DataType = DB2Constants.SQL_UNKNOWN_TYPE; break;
+ case DbType.SByte: db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_UTINYINT; break;
+ case DbType.Single: db2Type = DB2Type.Float; db2DataType = DB2Constants.SQL_REAL; break;
+ case DbType.String: db2Type = DB2Type.VarChar; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DbType.StringFixedLength: db2Type = DB2Type.Char; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case DbType.Time: db2Type = DB2Type.Time; db2DataType = DB2Constants.SQL_TYPE_TIME; break;
+ case DbType.UInt16: db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_SMALLINT; break;
+ case DbType.UInt32: db2Type = DB2Type.Integer; db2DataType = DB2Constants.SQL_INTEGER; break;
+ case DbType.UInt64: db2Type = DB2Type.BigInt; db2DataType = DB2Constants.SQL_BIGINT; break;
+ case DbType.VarNumeric: db2Type = DB2Type.Numeric; db2DataType = DB2Constants.SQL_WCHAR; break;
+ default:
+ throw new NotSupportedException("Value is of unknown data type");
+ }
+ }
+ }
+
+ #endregion
+ #region Direction
+ ///
+ /// In or out parameter, or both
+ ///
+ public ParameterDirection Direction
+ {
+ get
+ {
+ return direction;
+ }
+ set
+ {
+ direction = value;
+ switch(direction)
+ {
+ default:
+ case ParameterDirection.Input: db2Direction = DB2Constants.SQL_PARAM_INPUT; break;
+ case ParameterDirection.Output: db2Direction = DB2Constants.SQL_PARAM_OUTPUT; break;
+ case ParameterDirection.InputOutput: db2Direction = DB2Constants.SQL_PARAM_INPUT_OUTPUT; break;
+ case ParameterDirection.ReturnValue: db2Direction = DB2Constants.SQL_RETURN_VALUE; break;
+ }
+ }
+ }
+ #endregion
+ #region IsNullable
+ ///
+ /// Does this parameter support a null value
+ ///
+ public bool IsNullable
+ {
+ get
+ {
+ return nullable;
+ }
+ set
+ {
+ nullable = value;
+ }
+ }
+ #endregion
+ #region ParameterName
+ public string ParameterName
+ {
+ get
+ {
+ return parameterName;
+ }
+ set
+ {
+ parameterName = value;
+ }
+ }
+ #endregion
+ #region SourceColumn
+ ///
+ /// Gets or sets the name of the source column that is mapped to the DataSet
+ ///
+ public string SourceColumn
+ {
+ get
+ {
+ return sourceColumn;
+ }
+ set
+ {
+ sourceColumn = value;
+ }
+ }
+ #endregion
+ #region SourceVersion
+ ///
+ /// DataRowVersion property
+ ///
+ public DataRowVersion SourceVersion
+ {
+ get
+ {
+ return sourceVersion;
+ }
+ set
+ {
+ sourceVersion = value;
+ }
+ }
+ #endregion
+ #region IDbDataParameter properties
+ public byte Precision
+ {
+ get
+ {
+ return precision;
+ }
+ set
+ {
+ precision = value;
+ }
+ }
+
+ public byte Scale
+ {
+ get
+ {
+ return scale;
+ }
+ set
+ {
+ scale = value;
+ }
+ }
+
+ public int Size
+ {
+ get
+ {
+ return size;
+ }
+ set
+ {
+ size = value;
+ }
+ }
+ #endregion
+ #region Value
+ ///
+ /// The actual parameter data
+ ///
+ public object Value
+ {
+ get
+ {
+ return dataVal;
+ }
+ set
+ {
+ this.dataVal = value;
+ }
+ }
+ #endregion
+ #endregion
+ #region inferType Method
+ /// <summary>
+ /// Determine the data type based on the value
+ /// </summary>
+ private void InferType()
+ {
+ if(Value == null)
+ throw new ArgumentException("No DB2Parameter.Value found");
+
+ if(Value is IConvertible)
+ {
+ switch(((IConvertible)Value).GetTypeCode())
+ {
+ case TypeCode.Char: dbType = DbType.Byte; db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_WCHAR; break;
+ case TypeCode.Boolean: dbType = DbType.Byte; db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_BIT; break;
+ case TypeCode.SByte:
+ case TypeCode.Byte: dbType = DbType.Byte; db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_UTINYINT; break;
+ case TypeCode.UInt16:
+ case TypeCode.Int16: dbType = DbType.Int16; db2Type = DB2Type.SmallInt; db2DataType = DB2Constants.SQL_SMALLINT; break;
+ case TypeCode.UInt32:
+ case TypeCode.Int32: dbType = DbType.Int32; db2Type = DB2Type.Integer; db2DataType = DB2Constants.SQL_INTEGER; break;
+ case TypeCode.UInt64:
+ case TypeCode.Int64: dbType = DbType.Int64; db2Type = DB2Type.BigInt; db2DataType = DB2Constants.SQL_BIGINT; break;
+ case TypeCode.Single: dbType = DbType.Single; db2Type = DB2Type.Float; db2DataType = DB2Constants.SQL_REAL; break;
+ case TypeCode.Double: dbType = DbType.Double; db2Type = DB2Type.Double; db2DataType = DB2Constants.SQL_DOUBLE; break;
+ case TypeCode.Decimal: dbType = DbType.Decimal; db2Type = DB2Type.Decimal; db2DataType = DB2Constants.SQL_DECIMAL; break;
+ case TypeCode.DateTime: dbType = DbType.DateTime; db2Type = DB2Type.Timestamp; db2DataType = DB2Constants.SQL_TYPE_TIMESTAMP; break;
+ case TypeCode.String: dbType = DbType.String; db2Type = DB2Type.VarChar; db2DataType = DB2Constants.SQL_WCHAR; break;
+
+ case TypeCode.Object:
+ case TypeCode.DBNull:
+ case TypeCode.Empty:
+ throw new SystemException("Unknown data type");
+ default:
+ throw new SystemException("Value is of unknown data type");
+ }
+ }
+ else if(Value is byte[])
+ {
+ dbType = DbType.Binary;
+ db2Type = DB2Type.VarBinary;
+ db2DataType = DB2Constants.SQL_VARBINARY;
+ }
+ else if(Value is TimeSpan)
+ {
+ dbType = DbType.Time;
+ db2Type = DB2Type.Time;
+ db2DataType = DB2Constants.SQL_TYPE_TIME;
+ }
+ else
+ {
+ throw new NotSupportedException("Value is of unsupported data type");
+ }
+ }
+ #endregion
+
+ internal void CalculateRequiredmemory()
+ {
+ if((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))
+ {
+ if(Value == null)
+ throw new ArgumentException("Value missing");
+ }
+ if(dbType == DbType.Object)
+ {
+ if((direction == ParameterDirection.Output) || (direction == ParameterDirection.ReturnValue))
+ throw new ArgumentException("Unknown type");
+
+ if((direction != ParameterDirection.Input) || !Convert.IsDBNull(Value))
+ {
+ InferType();
+ }
+ }
+
+ if((db2DataType == DB2Constants.SQL_VARBINARY) ||
+ (db2DataType == DB2Constants.SQL_WCHAR))
+ {
+ if(Size <= 0)
+ {
+ if(direction != ParameterDirection.Input)
+ throw new ArgumentException("Size not specified");
+ if(Value == DBNull.Value)
+ requiredMemory = 0;
+ else if(Value is string)
+ requiredMemory = ((string)Value).Length;
+ else if(Value is byte[])
+ requiredMemory = ((byte[])Value).Length;
+ else
+ throw new ArgumentException("wrong type!?");
+ }
+ else
+ {
+ requiredMemory = Size;
+ }
+ if(db2DataType == DB2Constants.SQL_WCHAR)
+ requiredMemory = (requiredMemory * 2) + 2;
+ requiredMemory = (requiredMemory | 0xf) + 1;
+ }
+ requiredMemory = Math.Max(128, requiredMemory);
+ }
+
+ #region Bind
+ ///
+ /// Bind this parameter
+ ///
+ internal short Bind(IntPtr hwndStmt, short paramNum)
+ {
+ int inLength = requiredMemory;
+ db2LastUsedDataType = db2DataType;
+ short db2CType = DB2Constants.SQL_C_DEFAULT;
+ if((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))
+ {
+ if(Convert.IsDBNull(Value))
+ {
+ inLength = DB2Constants.SQL_NULL_DATA;
+ if((db2DataType == DB2Constants.SQL_UNKNOWN_TYPE) ||
+ (db2DataType == DB2Constants.SQL_DECIMAL))
+ {
+ db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;
+ db2CType = DB2Constants.SQL_C_WCHAR;
+ }
+ }
+ }
+ if((direction == ParameterDirection.Input) || (direction == ParameterDirection.InputOutput))
+ {
+ switch (db2DataType)
+ {
+ case DB2Constants.SQL_WCHAR:
+ string tmpString = Convert.ToString(Value);
+ inLength = tmpString.Length;
+ if((Size > 0) && (inLength > Size))
+ inLength = Size;
+ Marshal.Copy(tmpString.ToCharArray(), 0, internalBuffer, inLength);
+ inLength *= 2;
+ db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;
+ db2CType = DB2Constants.SQL_C_WCHAR;
+ break;
+ case DB2Constants.SQL_VARBINARY:
+ byte[] tmpBytes = (byte[])Value;
+ inLength = tmpBytes.Length;
+ if((Size > 0) && (inLength > Size))
+ inLength = Size;
+ Marshal.Copy(tmpBytes, 0, internalBuffer, inLength);
+ db2CType = DB2Constants.SQL_TYPE_BINARY;
+ break;
+ case DB2Constants.SQL_BIT:
+ case DB2Constants.SQL_UTINYINT:
+ case DB2Constants.SQL_SMALLINT:
+ Marshal.WriteInt16(internalBuffer, Convert.ToInt16(Value));
+ db2CType = DB2Constants.SQL_C_SSHORT;
+ break;
+ case DB2Constants.SQL_INTEGER:
+ Marshal.WriteInt32(internalBuffer, Convert.ToInt32(Value));
+ db2CType = DB2Constants.SQL_C_SLONG;
+ break;
+ case DB2Constants.SQL_BIGINT:
+ Marshal.WriteInt64(internalBuffer, Convert.ToInt64(Value));
+ db2CType = DB2Constants.SQL_C_SBIGINT;
+ break;
+ case DB2Constants.SQL_REAL:
+ Marshal.StructureToPtr((float)Convert.ToDouble(Value), internalBuffer, false);
+ db2CType = DB2Constants.SQL_C_TYPE_REAL;
+ break;
+ case DB2Constants.SQL_DOUBLE:
+ Marshal.StructureToPtr(Convert.ToDouble(Value), internalBuffer, false);
+ db2CType = DB2Constants.SQL_C_DOUBLE;
+ break;
+ case DB2Constants.SQL_DECIMAL:
+ byte[] tmpDecimalData = System.Text.Encoding.UTF8.GetBytes(
+ Convert.ToDecimal(Value).ToString(System.Globalization.CultureInfo.InvariantCulture));
+ inLength = Math.Min(tmpDecimalData.Length, requiredMemory);
+ Marshal.Copy(tmpDecimalData, 0, internalBuffer, inLength);
+ db2LastUsedDataType = DB2Constants.SQL_VARCHAR;
+ db2CType = DB2Constants.SQL_C_CHAR;
+ break;
+ case DB2Constants.SQL_TYPE_DATE:
+ DateTime tmpDate = Convert.ToDateTime(Value);
+ Marshal.WriteInt16(internalBuffer, 0, (short)tmpDate.Year);
+ Marshal.WriteInt16(internalBuffer, 2, (short)tmpDate.Month);
+ Marshal.WriteInt16(internalBuffer, 4, (short)tmpDate.Day);
+ db2CType = DB2Constants.SQL_C_TYPE_DATE;
+ break;
+ case DB2Constants.SQL_TYPE_TIMESTAMP:
+ DateTime tmpDateTime = Convert.ToDateTime(Value);
+ Marshal.WriteInt16(internalBuffer, 0, (short)tmpDateTime.Year);
+ Marshal.WriteInt16(internalBuffer, 2, (short)tmpDateTime.Month);
+ Marshal.WriteInt16(internalBuffer, 4, (short)tmpDateTime.Day);
+ Marshal.WriteInt16(internalBuffer, 6, (short)tmpDateTime.Hour);
+ Marshal.WriteInt16(internalBuffer, 8, (short)tmpDateTime.Minute);
+ Marshal.WriteInt16(internalBuffer, 10, (short)tmpDateTime.Second);
+ Marshal.WriteInt32(internalBuffer, 12, (int)((tmpDateTime.Ticks % 10000000) * 100));
+ db2CType = DB2Constants.SQL_C_TYPE_TIMESTAMP;
+ break;
+ case DB2Constants.SQL_TYPE_TIME:
+ TimeSpan tmpTime = (TimeSpan)Value;
+ Marshal.WriteInt16(internalBuffer, 0, (short)tmpTime.Hours);
+ Marshal.WriteInt16(internalBuffer, 2, (short)tmpTime.Minutes);
+ Marshal.WriteInt16(internalBuffer, 4, (short)tmpTime.Seconds);
+ db2CType = DB2Constants.SQL_C_TYPE_TIME;
+ break;
+ }
+ }
+ else
+ {
+ switch (db2DataType)
+ {
+ case DB2Constants.SQL_WCHAR:
+ db2LastUsedDataType = DB2Constants.SQL_VARGRAPHIC;
+ db2CType = DB2Constants.SQL_C_WCHAR;
+ break;
+ case DB2Constants.SQL_VARBINARY:
+ db2CType = DB2Constants.SQL_TYPE_BINARY;
+ break;
+ case DB2Constants.SQL_BIT:
+ case DB2Constants.SQL_UTINYINT:
+ case DB2Constants.SQL_SMALLINT:
+ db2CType = DB2Constants.SQL_C_SSHORT;
+ break;
+ case DB2Constants.SQL_INTEGER:
+ db2CType = DB2Constants.SQL_C_SLONG;
+ break;
+ case DB2Constants.SQL_BIGINT:
+ db2CType = DB2Constants.SQL_C_SBIGINT;
+ break;
+ case DB2Constants.SQL_REAL:
+ db2CType = DB2Constants.SQL_C_TYPE_REAL;
+ break;
+ case DB2Constants.SQL_DOUBLE:
+ db2CType = DB2Constants.SQL_C_DOUBLE;
+ break;
+ case DB2Constants.SQL_DECIMAL:
+ db2LastUsedDataType = DB2Constants.SQL_VARCHAR;
+ db2CType = DB2Constants.SQL_C_CHAR;
+ break;
+ case DB2Constants.SQL_TYPE_DATE:
+ db2CType = DB2Constants.SQL_C_TYPE_DATE;
+ break;
+ case DB2Constants.SQL_TYPE_TIMESTAMP:
+ db2CType = DB2Constants.SQL_C_TYPE_TIMESTAMP;
+ break;
+ case DB2Constants.SQL_TYPE_TIME:
+ db2CType = DB2Constants.SQL_C_TYPE_TIME;
+ break;
+ }
+ }
+ Marshal.WriteInt32(internalLengthBuffer, inLength);
+ short sqlRet = DB2CLIWrapper.SQLBindParameter(hwndStmt, paramNum, db2Direction,
+ db2CType, db2LastUsedDataType, Size, Scale,
+ internalBuffer, requiredMemory, internalLengthBuffer);
+
+ return sqlRet;
+ }
+ #endregion
+ object ICloneable.Clone ()
+ {
+ DB2Parameter clone = new DB2Parameter();
+ clone.dbType = dbType;
+ clone.db2Type = db2Type;
+ clone.db2DataType = db2DataType;
+ clone.db2LastUsedDataType = db2LastUsedDataType;
+ clone.direction = direction;
+ clone.db2Direction = db2Direction;
+ clone.nullable = nullable;
+ clone.parameterName = parameterName;
+ clone.sourceColumn = sourceColumn;
+ clone.sourceVersion = sourceVersion;
+ clone.dataVal = dataVal;
+ clone.scale = scale;
+ clone.precision = precision;
+ clone.size = size;
+ if(dataVal is ICloneable)
+ {
+ clone.dataVal = ((ICloneable)dataVal).Clone();
+ }
+ return clone;
+ }
+
+ internal void GetOutValue()
+ {
+ int length = Marshal.ReadInt32(internalLengthBuffer);
+ if(length == DB2Constants.SQL_NULL_DATA)
+ {
+ dataVal = DBNull.Value;
+ return;
+ }
+ switch(DB2Type)
+ {
+ case DB2Type.SmallInt:
+ dataVal = Marshal.ReadInt16(internalBuffer);
+ break;
+ case DB2Type.Integer:
+ dataVal = Marshal.ReadInt32(internalBuffer);
+ break;
+ case DB2Type.BigInt:
+ dataVal = Marshal.ReadInt64(internalBuffer);
+ break;
+ case DB2Type.Double:
+ dataVal = Marshal.PtrToStructure(internalBuffer, typeof(Double));
+ break;
+ case DB2Type.Float:
+ dataVal = Marshal.PtrToStructure(internalBuffer, typeof(Single));
+ break;
+ case DB2Type.Char:
+ case DB2Type.VarChar:
+ case DB2Type.LongVarChar:
+ case DB2Type.Graphic:
+ case DB2Type.VarGraphic:
+ case DB2Type.LongVarGraphic:
+ case DB2Type.Clob:
+ case DB2Type.DbClob:
+ dataVal = Marshal.PtrToStringUni(internalBuffer, Math.Min(Size, length / 2));
+ break;
+ case DB2Type.Binary:
+ case DB2Type.VarBinary:
+ case DB2Type.LongVarBinary:
+ case DB2Type.Blob:
+ case DB2Type.Datalink:
+ length = Math.Min(Size, length);
+ dataVal = new byte[length];
+ Marshal.Copy(internalBuffer, (byte[])dataVal, 0, length);
+ break;
+ case DB2Type.Decimal:
+ dataVal = decimal.Parse(Marshal.PtrToStringAnsi(internalBuffer, length),
+ System.Globalization.CultureInfo.InvariantCulture);
+ break;
+ case DB2Type.Timestamp:
+ DateTime dtTmp = new DateTime(
+ Marshal.ReadInt16(internalBuffer, 0), // year
+ Marshal.ReadInt16(internalBuffer, 2), // month
+ Marshal.ReadInt16(internalBuffer, 4), // day
+ Marshal.ReadInt16(internalBuffer, 6), // hour
+ Marshal.ReadInt16(internalBuffer, 8), // minute
+ Marshal.ReadInt16(internalBuffer, 10));// second
+ dataVal = dtTmp.AddTicks(Marshal.ReadInt32(internalBuffer, 12) / 100); // nanoseconds
+ break;
+ case DB2Type.Date:
+ dataVal = new DateTime(
+ Marshal.ReadInt16(internalBuffer, 0),
+ Marshal.ReadInt16(internalBuffer, 2),
+ Marshal.ReadInt16(internalBuffer, 4));
+ break;
+ case DB2Type.Time:
+ dataVal = new TimeSpan(
+ Marshal.ReadInt16(internalBuffer, 0), // Hour
+ Marshal.ReadInt16(internalBuffer, 2), // Minute
+ Marshal.ReadInt16(internalBuffer, 4)); // Second
+ break;
+
+ case DB2Type.Invalid:
+ case DB2Type.Real:
+ case DB2Type.Numeric:
+ case DB2Type.RowId:
+ case DB2Type.XmlReader:
+ throw new NotImplementedException();
+ default:
+ throw new NotSupportedException("unknown data type");
+ }
+ }
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ParameterCollection.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ParameterCollection.cs
new file mode 100755
index 00000000000..0ec08424831
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2ParameterCollection.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Data;
+using System.Collections;
+using System.Globalization;
+
+
+namespace IBM.Data.DB2
+{
+
+ public class DB2ParameterCollection : ArrayList, IDataParameterCollection
+ {
+ IntPtr hwndStmt = IntPtr.Zero;
+
+ internal IntPtr HwndStmt
+ {
+ set
+ {
+ hwndStmt = value;
+ }
+ }
+ public new DB2Parameter this[int index]
+ {
+ get
+ {
+ return (DB2Parameter)base[index];
+ }
+ set
+ {
+ base[index] = value;
+ }
+ }
+ public DB2Parameter this[string index]
+ {
+ get
+ {
+ return (DB2Parameter)base[IndexOf(index)];
+ }
+ set
+ {
+ base[IndexOf(index)] = value;
+ }
+ }
+ object IDataParameterCollection.this[string index]
+ {
+ get
+ {
+ return this[IndexOf(index)];
+ }
+ set
+ {
+ this[IndexOf(index)] = (DB2Parameter)value;
+ }
+ }
+ public bool Contains(string paramName)
+ {
+ return(-1 != IndexOf(paramName));
+ }
+
+ public int IndexOf(string paramName)
+ {
+ int index = 0;
+ for(index = 0; index < Count; index++)
+ {
+ if (0 == _cultureAwareCompare(((DB2Parameter)this[index]).ParameterName, paramName))
+ {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ public void RemoveAt(string paramName)
+ {
+ RemoveAt(IndexOf(paramName));
+ }
+
+ public override int Add(object obj)
+ {
+ DB2Parameter value = (DB2Parameter)obj;
+ if(value.ParameterName == null)
+ throw new ArgumentException("parameter must be named");
+ if(IndexOf(value.ParameterName) >= 0)
+ throw new ArgumentException("parameter name is already in collection");
+ return base.Add(value);
+ }
+
+ public DB2Parameter Add(DB2Parameter value)
+ {
+ if(value.ParameterName == null)
+ throw new ArgumentException("parameter must be named");
+ if(IndexOf(value.ParameterName) >= 0)
+ throw new ArgumentException("parameter name is already in collection");
+ base.Add(value);
+ return value;
+ }
+
+ public DB2Parameter Add(string paramName, DB2Type type)
+ {
+ return Add(new DB2Parameter(paramName, type));
+ }
+
+ public DB2Parameter Add(string paramName, object value)
+ {
+ return Add(new DB2Parameter(paramName, value));
+ }
+
+ public DB2Parameter Add(string paramName, DB2Type dbType, int size)
+ {
+ return Add(new DB2Parameter(paramName, dbType, size));
+ }
+
+ public DB2Parameter Add(string paramName, DB2Type dbType, int size, string sourceColumn)
+ {
+ return Add(new DB2Parameter(paramName, dbType, size, sourceColumn));
+ }
+
+ private int _cultureAwareCompare(string strA, string strB)
+ {
+ return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase);
+ }
+
+ internal void GetOutValues()
+ {
+ foreach(DB2Parameter param in this)
+ {
+ if(ParameterDirection.Output == param.Direction || ParameterDirection.InputOutput == param.Direction)
+ {
+ param.GetOutValue();
+ //Console.WriteLine(param.ParameterName);
+ }
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatedEventArgs.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatedEventArgs.cs
index ab896f2fa94..ab896f2fa94 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatedEventArgs.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatedEventArgs.cs
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatedEventHandler.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatedEventHandler.cs
index 4bdf4b01d24..4bdf4b01d24 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatedEventHandler.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatedEventHandler.cs
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatingEventArgs.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatingEventArgs.cs
index bd35a06fec6..bd35a06fec6 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatingEventArgs.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatingEventArgs.cs
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatingEventHandler.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatingEventHandler.cs
index fd50e5d67d9..fd50e5d67d9 100644..100755
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2RowUpdatingEventHandler.cs
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2RowUpdatingEventHandler.cs
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Transaction.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Transaction.cs
new file mode 100755
index 00000000000..0e9e20c000e
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Transaction.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Data;
+using System.Runtime.InteropServices;
+
+namespace IBM.Data.DB2
+{
+ public sealed class DB2Transaction : MarshalByRefObject, IDbTransaction
+ {
+ private enum TransactionState
+ {
+ Open,
+ Committed,
+ Rolledback,
+ }
+ IsolationLevel isolationLevel;
+ DB2Connection db2Conn;
+ TransactionState state;
+
+
+
+ internal DB2Transaction(DB2Connection con, IsolationLevel isoL)
+ {
+ long db2IsoL;
+ db2Conn = con;
+ short sqlRet;
+
+ isolationLevel = isoL;
+
+ switch (isoL)
+ {
+ default:
+ case System.Data.IsolationLevel.Chaos: //No DB2equivalent, default to SQL_TXN_READ_COMMITTED
+ case System.Data.IsolationLevel.ReadCommitted: //SQL_TXN_READ_COMMITTED
+ db2IsoL = DB2Constants.SQL_TXN_READ_COMMITTED;
+ break;
+ case System.Data.IsolationLevel.ReadUncommitted: //SQL_TXN_READ_UNCOMMITTED
+ db2IsoL = DB2Constants.SQL_TXN_READ_UNCOMMITTED;
+ break;
+ case System.Data.IsolationLevel.RepeatableRead: //SQL_TXN_REPEATABLE_READ
+ db2IsoL = DB2Constants.SQL_TXN_REPEATABLE_READ;
+ break;
+ case System.Data.IsolationLevel.Serializable: //SQL_TXN_SERIALIZABLE_READ
+ db2IsoL = DB2Constants.SQL_TXN_SERIALIZABLE_READ;
+ break;
+ }
+
+ if(db2Conn.openConnection.autoCommit)
+ {
+ sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_AUTOCOMMIT, new IntPtr(DB2Constants.SQL_AUTOCOMMIT_OFF), 0);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting AUTOCOMMIT OFF in transaction CTOR.", db2Conn);
+ db2Conn.openConnection.autoCommit = false;
+ }
+ sqlRet = DB2CLIWrapper.SQLSetConnectAttr(db2Conn.DBHandle, DB2Constants.SQL_ATTR_TXN_ISOLATION, new IntPtr(db2IsoL), 0);
+ DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, "Error setting isolation level.", db2Conn);
+
+ state = TransactionState.Open;
+ }
+
+ /// <summary>
+ /// DB2Connection associated with this transaction
+ /// </summary>
+ public IDbConnection Connection
+ {
+ get
+ {
+ return db2Conn;
+ }
+ }
+ /// <summary>
+ /// IsolationLevel property
+ /// </summary>
+ ///
+ public IsolationLevel IsolationLevel
+ {
+ get
+ {
+ CheckStateOpen();
+ return isolationLevel;
+ }
+ }
+
+ internal void CheckStateOpen()
+ {
+ if(state == TransactionState.Committed)
+ throw new InvalidOperationException("Transaction was already committed. It is no longer usable.");
+ if(state == TransactionState.Rolledback)
+ throw new InvalidOperationException("Transaction was already rolled back. It is no longer usable.");
+ }
+
+ public void Commit()
+ {
+ CheckStateOpen();
+ DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, DB2Constants.SQL_COMMIT);
+ this.state = TransactionState.Committed;
+ this.db2Conn.openConnection.transactionOpen = false;
+ this.db2Conn.WeakRefTransaction = null;
+ this.db2Conn = null;
+ }
+
+ public void Rollback()
+ {
+ CheckStateOpen();
+ DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, db2Conn.DBHandle, DB2Constants.SQL_ROLLBACK);
+ this.db2Conn.openConnection.transactionOpen = false;
+ this.state = TransactionState.Rolledback;
+ this.db2Conn.WeakRefTransaction = null;
+ this.db2Conn = null;
+ }
+
+ /// <summary>
+ /// Dispose method.
+ /// </summary>
+ public void Dispose()
+ {
+ if (state != TransactionState.Open)
+ return;
+
+ Rollback();
+ }
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Type.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Type.cs
new file mode 100755
index 00000000000..fc2516301c1
--- /dev/null
+++ b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/DB2Type.cs
@@ -0,0 +1,35 @@
+using System;
+
+namespace IBM.Data.DB2
+{
+ public enum DB2Type
+ {
+ Invalid = 0,
+ SmallInt = 1,
+ Integer = 2,
+ BigInt = 3,
+ Real = 4,
+ Double = 5,
+ Float = 6,
+ Decimal = 7,
+ Numeric = 8,
+ Date = 9,
+ Time = 10,
+ Timestamp = 11,
+ Char = 12,
+ VarChar = 13,
+ LongVarChar = 14,
+ Binary = 15,
+ VarBinary = 16,
+ LongVarBinary = 17,
+ Graphic = 18,
+ VarGraphic = 19,
+ LongVarGraphic = 20,
+ Clob = 21,
+ Blob = 22,
+ DbClob = 23,
+ Datalink = 24,
+ RowId = 25,
+ XmlReader = 26,
+ }
+}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2CLIWrapper.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2CLIWrapper.cs
deleted file mode 100644
index 17b401da9c1..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2CLIWrapper.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-using System;
-using System.Data;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace IBM.Data.DB2
-{
- /// <summary>
- /// DB2Prototypes class is a wrapper for the DB2.lib, IBM's Call Level Interface to DB2
- /// </summary>
- internal class DB2CLIWrapper
- {
- #if (OS_LINUX)
- private const string libname = "db2_36";
- #endif
-
- #if (OS_WINDOWS)
- private const string libname = libname;
- #endif
-
- [DllImport(libname, EntryPoint = "SQLAllocHandle")]
- internal static extern short SQLAllocHandle(short handleType, IntPtr inputHandle, ref IntPtr outputHandle);
-
- [DllImport(libname, EntryPoint = "SQLFreeHandle")]
- internal static extern short SQLFreeHandle(short handleType, IntPtr inputHandle);
-
- [DllImport(libname, EntryPoint = "SQLGetConnectAttrW")]
- internal static extern short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, [Out] IntPtr ValuePtr, int BufferLength, out int StringLengthPtr);
-
- [DllImport(libname, EntryPoint = "SQLGetConnectAttrW")]
- internal static extern short SQLGetConnectAttr(IntPtr ConnectionHandle, int Attribute, out int Value, int BufferLength, IntPtr Zero);
-
- [DllImport(libname, EntryPoint = "SQLFreeStmt")]
- internal static extern short SQLFreeStmt(IntPtr StatementHandle, short option);
-
- [DllImport(libname, EntryPoint = "SQLConnect")]
- internal static extern short SQLConnect(IntPtr sqlHdbc, string serverName, short serverNameLength, string userName, short userNameLength, string authentication, short authenticationLength);
- [DllImport(libname, EntryPoint = "SQLColAttribute")]
- internal static extern short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, IntPtr CharacterAttribute, short BufferLength, ref short StringLength, ref int NumericAttribute);
- //[DllImport(libname, EntryPoint = "SQLGetData")]
- // internal static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, IntPtr TargetPtr, IntPtr BufferLength, ref IntPtr StrLen_or_Ind);
- [DllImport(libname, EntryPoint="SQLMoreResults")]
- internal static extern short SQLMoreResults(IntPtr StatementHandle);
-
- //[DllImport(libname, EntryPoint = "SQLGetData")]
- //internal static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, IntPtr TargetPtr, IntPtr BufferLength, out int StrLen_or_Ind);
- [DllImport(libname, EntryPoint = "SQLGetData")]
- internal static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, IntPtr TargetPtr, int BufferLength, out int StrLen_or_Ind);
-
-
- //[DllImport(libname, EntryPoint = "SQLGetData")]
- //internal static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, byte[] TargetPtr, IntPtr BufferLength, ref IntPtr StrLen_or_Ind);
-
- [DllImport(libname, EntryPoint = "SQLGetData")]
- internal static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, byte[] TargetPtr, int BufferLength, out int StrLen_or_Ind);
-
- [DllImport(libname, EntryPoint = "SQLGetData")]
- internal static extern short SQLGetData(IntPtr StatementHandle, short ColumnNumber, short TargetType, [Out] StringBuilder sb, int BufferLength, out int StrLen_or_Ind);
-
- [DllImport(libname, EntryPoint = "SQLColAttributeW")]
- internal static extern short SQLColAttribute(IntPtr StatementHandle, short ColumnNumber, short FieldIdentifier, [Out] StringBuilder CharacterAttribute, short BufferLength, out short StringLength, out int NumericAttribute);
-
- [DllImport(libname, CharSet = CharSet.Auto, EntryPoint = "SQLDisconnect")]
- internal static extern short SQLDisconnect(IntPtr sqlHdbc);
- [DllImport(libname, EntryPoint = "SQLGetDiagRec")]
- internal static extern short SQLGetDiagRec( short handleType, IntPtr handle, short recNum, [Out] StringBuilder sqlState, ref IntPtr nativeErrorPtr, [Out] StringBuilder errorMessage, short bufferLength, ref IntPtr shortTextLengthPtr);
- [DllImport(libname, EntryPoint = "SQLSetConnectAttr")]
- internal static extern short SQLSetConnectAttr(IntPtr sqlHdbc, long sqlAttr, [In] IntPtr sqlValuePtr, long sqlValueLength);
- [DllImport(libname, EntryPoint = "SQLSetStmtAttr")]
- internal static extern short SQLSetStmtAttr(IntPtr sqlHstmt, long sqlAttr, [In] IntPtr sqlValuePtr, long sqlValueLength);
- [DllImport(libname, EntryPoint = "SQLEndTran")]
- internal static extern short SQLEndTran (short handleType, IntPtr handle, short fType);
- [DllImport(libname, EntryPoint = "SQLCancel")]
- internal static extern short SQLCancel(IntPtr handle);
- [DllImport(libname, EntryPoint = "SQLNumResultCols")]
- internal static extern short SQLNumResultCols(IntPtr handle, ref int numCols);
- [DllImport(libname, EntryPoint = "SQLFetch")]
- internal static extern short SQLFetch(IntPtr handle);
- [DllImport(libname, EntryPoint = "SQLRowCount")]
- internal static extern short SQLRowCount(IntPtr stmtHandle, ref int numRows);
- [DllImport(libname, EntryPoint = "SQLExecute")]
- internal static extern short SQLExecute(IntPtr handle);
- [DllImport (libname, EntryPoint = "SQLExecDirect")]
- internal static extern short SQLExecDirect(IntPtr stmtHandle, string stmt, int length);
- [DllImport(libname, EntryPoint = "SQLDescribeCol")]
- internal static extern short SQLDescribeCol(IntPtr stmtHandle, ushort colNum, StringBuilder colName, short colNameMaxLength, IntPtr colNameLength, ref IntPtr dataType, ref IntPtr colSizePtr, ref IntPtr scalePtr, ref IntPtr nullablePtr );
- [DllImport(libname, EntryPoint = "SQLBindCol")]
- internal static extern short SQLBindCol(IntPtr StatementHandle, short ColumnNumber, short TargetType, IntPtr TargetValue, IntPtr BufferLength, ref IntPtr StrLen_or_Ind);
- [DllImport(libname, EntryPoint = "SQLDriverConnect")]
- internal static extern short SQLDriverConnect(IntPtr hdbc, int centered, [In] string inConnectStr, [In] int inStrLength, [Out] StringBuilder outConnectStr, [Out] int outStrCapacity, [Out] IntPtr outStrLengthReturned, [In] int completion);
- [DllImport(libname, EntryPoint = "SQLPrepare")]
- internal static extern short SQLPrepare(IntPtr stmtHandle, string stmt, int length);
- [DllImport(libname, EntryPoint = "SQLDescribeParam")]
- internal static extern short SQLDescribeParam(IntPtr stmtHandle, short paramNumber,ref IntPtr dataType, ref IntPtr paramSize, ref IntPtr decimalDigits, ref IntPtr nullable);
- [DllImport(libname, EntryPoint = "SQLNumParams")]
- internal static extern short SQLNumParams(IntPtr stmtHandle, ref IntPtr numParams);
-
- [DllImport(libname)]
- internal static extern short SQLBindParameter(IntPtr stmtHandle, ushort paramNumber,
- short dataType, short valueType, short paramType, uint colSize, short decDigits,
- IntPtr dataBufferPtr, int dataBufferLength, IntPtr StrLen_or_IndPtr);
-
- [DllImport(libname)]
- internal static extern short SQLBindParameter(IntPtr stmtHandle, ushort paramNumber,
- short dataType, short valueType, short paramType, uint colSize, short decDigits,
- byte[] dataBufferPtr, int dataBufferLength, IntPtr StrLen_or_IndPtr);
-
- [DllImport(libname, EntryPoint = "SQLBindParameter")]
- internal static extern short SQLBindParameter(IntPtr stmtHandle, ushort paramNumber,
- short dataType, short valueType, short paramType, uint colSize, short decDigits,
- ref int dataBufferPtr, int dataBufferLength, IntPtr StrLen_or_IndPtr);
-
- [DllImport(libname, EntryPoint = "SQLBindParameter")]
- internal static extern short SQLBindParameter(IntPtr stmtHandle, ushort paramNumber,
- short dataType, short valueType, short paramType, uint colSize, short decDigits,
- ref double dataBufferPtr, int dataBufferLength, IntPtr StrLen_or_IndPtr);
-
- [DllImport(libname, EntryPoint = "SQLDescribeParam")]
- internal static extern short SQLDescribeParam(IntPtr stmtHandle, short ParameterNumber, IntPtr DataTypePtr, IntPtr ParameterSizePtr, IntPtr DecimalDigitsPtr, IntPtr NullablePtr);
-
- [DllImport(libname, EntryPoint = "SQLGetLength")]
- internal static extern short SQLGetLength( IntPtr stmtHandle, short locatorCType, int Locator,
- IntPtr stringLength, IntPtr indicatorValue);
- [DllImport(libname, EntryPoint = "SQLGetPosition")]
- internal static extern short SQLGetPosition(IntPtr stmtHandle, short locatorCType, int sourceLocator, int searchLocator,
- string searchLiteral, int searchLiteralLength, uint fromPosition, IntPtr locatedAt, IntPtr indicatorValue);
- [DllImport(libname, EntryPoint = "SQLGetPosition")]
- internal static extern short SQLBindFileToCol (IntPtr stmtHandle, ushort colNum, string fileName, IntPtr fileNameLength,
- IntPtr fileOptions, short maxFileNameLength, IntPtr stringLength, IntPtr indicatorValue);
- [DllImport(libname, EntryPoint = "SQLGetPosition")]
- internal static extern short SQLBindFileToParam (IntPtr stmtHandle, ushort targetType, short dataType, string fileName,
- IntPtr fileNameLength, short maxFileNameLength, IntPtr indicatorValue);
- }
-}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ClientUtils.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ClientUtils.cs
deleted file mode 100644
index 9c747a3d558..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ClientUtils.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-
-namespace IBM.Data.DB2
-{
-
- public class DB2ClientUtils
- {
- public DB2ClientUtils()
- {
-
- }
- #region DB2CheckReturn
-
- public static int DB2CheckReturn(short sqlRet, short handleType, IntPtr handle, string message)
- {
- switch ((long)sqlRet)
- {
- case DB2Constants.SQL_ERROR:
- if (handleType != 0)
- throw new DB2Exception(handleType, handle, message);
- else
- throw new DB2Exception(message);
- default:
- return 0;
- }
- }
- #endregion
- }
-}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ConnectionPool.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ConnectionPool.cs
deleted file mode 100644
index 5306e7e39e5..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ConnectionPool.cs
+++ /dev/null
@@ -1,288 +0,0 @@
-using System;
-using System.Collections;
-using System.Text;
-
-namespace IBM.Data.DB2
-{
- internal sealed class Db2Environment
- {
- private static Db2Environment environment;
- internal Hashtable connectionPools;
- internal IntPtr penvHandle = IntPtr.Zero;
-
- private static System.IO.StreamWriter log;
- public static void Log(string format, params object[] args)
- {
- if(log == null)
- {
- log = new System.IO.StreamWriter(DB2Constants.LOG_PATH, false, System.Text.Encoding.UTF8);
- }
- if(args[0] is IntPtr)
- {
- args[0] = ((IntPtr)args[0]).ToInt32() / 0x1000 + ":" + ((IntPtr)args[0]).ToInt32() % 0x1000;
- }
- log.WriteLine(format, args);
- log.Flush();
- return;
- }
-
- private Db2Environment()
- {
- connectionPools = Hashtable.Synchronized(new Hashtable());
-
- short sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_ENV, IntPtr.Zero, ref penvHandle);
- Db2Environment.Log("Alloc env {0,-4} {1}", penvHandle, sqlRet);
- DB2ClientUtils.DB2CheckReturn(sqlRet, 0, IntPtr.Zero, "Unable to allocate Environment handle.");
-
- // SQLSetEnvAttr( hEnv=0:1, fAttribute=SQL_ATTR_APP_TYPE 2473, vParam=4, cbParam=0 ) // 4=ADO.NET apptype????
- // SQLSetEnvAttr( hEnv=0:1, fAttribute=SQL_ATTR_OUTPUT_NTS 10001, vParam=0, cbParam=0 ) // strings not 0-terminated
- }
-
- public static Db2Environment Instance
- {
- get
- {
- if(environment == null)
- {
- lock(typeof(Db2Environment))
- {
- if(environment == null)
- {
- environment = new Db2Environment();
- }
- }
- }
- return environment;
- }
- }
-
- }
-
- internal sealed class Db2OpenConnection : IDisposable
- {
- private IntPtr dbHandle = IntPtr.Zero;
-
- private Db2ConnectionSettings settings;
- private bool disposed = false;
-
-
- public IntPtr DBHandle
- {
- get { return dbHandle; }
- }
-
- public Db2OpenConnection(Db2ConnectionSettings settings)
- {
- if(dbHandle == IntPtr.Zero)
- {
- this.settings = settings;
- try
- {
- short sqlRet = DB2CLIWrapper.SQLAllocHandle(DB2Constants.SQL_HANDLE_DBC, Db2Environment.Instance.penvHandle, ref dbHandle);
- Db2Environment.Log("Alloc dbc {0,-4} {1}", dbHandle, sqlRet);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, Db2Environment.Instance.penvHandle, "Unable to allocate database handle in Db2Connection.");
-
- Console.WriteLine("DB2OpenConnection SQLConnect... User: {0}, Password: {1}", settings.UserName, settings.PassWord);
-
- /*if(settings.Server.Length > 0)
- {
- StringBuilder outConnectStr = new StringBuilder(60); // TODO: ????
- IntPtr numOutCharsReturned = IntPtr.Zero;
-
- sqlRet = DB2CLIWrapper.SQLDriverConnect(dbHandle, 0, settings.ConnectionString,
- settings.ConnectionString.Length, outConnectStr, 100, numOutCharsReturned,
- DB2Constants.SQL_DRIVER_COMPLETE);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, dbHandle, "Unable to connect to the database.");
- }
- else
- {*/
- sqlRet = DB2CLIWrapper.SQLConnect(dbHandle,
- settings.DatabaseAlias, (short)settings.DatabaseAlias.Length,
- settings.UserName, (short)settings.UserName.Length,
- settings.PassWord, (short)settings.PassWord.Length);
-
- Db2Environment.Log("Connect {0,-4} {1}", dbHandle, sqlRet);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, dbHandle, "Unable to connect to the database.");
- //}
- }
- catch
- {
- if(dbHandle != IntPtr.Zero)
- {
- DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);
- dbHandle = IntPtr.Zero;
- }
- throw;
- }
- }
- }
-
- public void Close()
- {
- if(settings.Pool != null)
- {
- settings.Pool.AddToFreeConnections(this);
- }
- else
- {
- Dispose();
- }
- }
-
- private void FreeHandles()
- {
- if(dbHandle != IntPtr.Zero)
- {
- short sqlRet = DB2CLIWrapper.SQLDisconnect(dbHandle);
- Db2Environment.Log("Disconnec {0,-4} {1}", dbHandle, sqlRet);
- // Note that SQLDisconnect() automatically drops any statements and
- // descriptors open on the connection.
- sqlRet = DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);
- Db2Environment.Log("Free dbc {0,-4} {1}", dbHandle, sqlRet);
-
- dbHandle = IntPtr.Zero;
- }
- }
-
- #region IDisposable Members
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- internal void Dispose(bool disposing)
- {
- if(!disposed)
- {
- if(disposing)
- {
- // dispose managed resources
- }
- FreeHandles();
- }
- disposed = true;
- }
-
-
- ~Db2OpenConnection()
- {
- if(settings.Pool != null)
- {
- settings.Pool.OpenConnectionFinalized();
- }
- Dispose(false);
- }
- #endregion
- }
-
- internal sealed class Db2ConnectionPool
- {
- private ArrayList openFreeConnections;
- private int connectionsOpen;
- private int connectionsInUse;
- //private int connectionsUsableOffset;
-
- private Db2ConnectionSettings connectionSettings;
-
- public Db2ConnectionPool(Db2ConnectionSettings connectionSettings)
- {
- this.connectionSettings = connectionSettings;
- openFreeConnections = new ArrayList();
- }
-
- public Db2ConnectionSettings ConnectionSettings
- {
- get { return connectionSettings; }
- }
-
-
- public Db2OpenConnection GetOpenConnection()
- {
- Db2OpenConnection connection = null;
- lock(openFreeConnections.SyncRoot)
- {
- while(connectionsOpen > connectionsInUse)
- {
- connection = (Db2OpenConnection)openFreeConnections[openFreeConnections.Count - 1];
- openFreeConnections.RemoveAt(openFreeConnections.Count - 1);
-
- // check if connection is s
- int isDead;
- short sqlRet = DB2CLIWrapper.SQLGetConnectAttr(connection.DBHandle, DB2Constants.SQL_ATTR_CONNECTION_DEAD, out isDead, 0, IntPtr.Zero);
- if(((sqlRet == DB2Constants.SQL_SUCCESS_WITH_INFO) || (sqlRet == DB2Constants.SQL_SUCCESS)) &&
- (isDead == DB2Constants.SQL_CD_FALSE))
- {
- connectionsInUse++;
- break;
- }
- else
- {
- connectionsOpen--;
- connection.Dispose();
- connection = null;
- }
-
- }
- }
- if(connection == null)
- {
- connection = new Db2OpenConnection(connectionSettings);
- connectionsOpen++;
- connectionsInUse++;
- }
-
- return connection;
- }
-
- public void AddToFreeConnections(Db2OpenConnection connection)
- {
- lock(openFreeConnections.SyncRoot)
- {
- connectionsInUse--;
- openFreeConnections.Add(connection);
- }
- }
-
- public void OpenConnectionFinalized()
- {
- lock(openFreeConnections.SyncRoot)
- {
- connectionsOpen--;
- connectionsInUse--;
- }
- }
-
- /// <summary>
- /// Find a specific connection pool
- /// </summary>
- /// <param name="connectionString"></param>
- /// <returns></returns>
- static public Db2ConnectionPool FindConnectionPool(string connectionString)
- {
- return (Db2ConnectionPool)Db2Environment.Instance.connectionPools[connectionString];
- }
-
- /// <summary>
- /// Get a connection pool. If it doesn't exist yet, create it
- /// </summary>
- /// <param name="connectionSettings"></param>
- /// <returns></returns>
- static public Db2ConnectionPool GetConnectionPool(Db2ConnectionSettings connectionSettings)
- {
- Db2Environment environment = Db2Environment.Instance;
-
- lock(environment.connectionPools.SyncRoot)
- {
- Db2ConnectionPool pool = (Db2ConnectionPool)environment.connectionPools[connectionSettings.ConnectionString];
- if(pool == null)
- {
- pool = new Db2ConnectionPool(connectionSettings);
- environment.connectionPools.Add(connectionSettings.ConnectionString, pool);
- }
- return pool;
- }
- }
- }
-}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Constants.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Constants.cs
deleted file mode 100644
index f70e191c34d..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Constants.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-using System;
-
-namespace IBM.Data.DB2
-{
- /// <summary>
- /// Summary description for DB2Constants.
- /// </summary>
- public class DB2Constants
- {
- public DB2Constants()
- {
-
-
- }
- public const short SQL_HANDLE_ENV = 1;
- public const short SQL_HANDLE_DBC = 2;
- public const short SQL_HANDLE_STMT = 3;
- public const short SQL_HANDLE_DESC = 4;
-
- /* RETCODE values */
- public const short SQL_SUCCESS = 0;
- public const short SQL_SUCCESS_WITH_INFO = 1;
- public const short SQL_NEED_DATA = 99;
- public const short SQL_NO_DATA = 100;
- public const short SQL_STILL_EXECUTING = 2;
- public const short SQL_ERROR = -1;
- public const short SQL_INVALID_HANDLE = -2;
-
- /* SQLFreeStmt option values */
- public const short SQL_CLOSE = 0;
- public const short SQL_DROP = 1;
- public const short SQL_UNBIND = 2;
- public const short SQL_RESET_PARAMS = 3;
-
- public const int SQL_NTS = -3;
- public const long SQL_NULL_HANDLE = 0L;
- public const short SQL_COMMIT = 0;
- public const short SQL_ROLLBACK = 1;
- public const short SQL_NO_DATA_FOUND = 100;
-
- /* Isolation levels */
- public const long SQL_TXN_READ_UNCOMMITTED = 0x00000001L;
- public const long SQL_TXN_READ_COMMITTED = 0x00000002L;
- public const long SQL_TXN_REPEATABLE_READ = 0x00000004L;
- public const long SQL_TXN_SERIALIZABLE_READ = 0x00000008L;
- public const long SQL_TXN_NOCOMMIT = 0x00000020L;
-
- /* Connect options */
- public const long SQL_TXN_ISOLATION = 108;
- public const long SQL_AUTOCOMMIT = 102;
-
- public const long SQL_AUTOCOMMIT_OFF = 0L;
- public const long SQL_AUTOCOMMIT_ON = 1L;
-
-
- /* attribute */
- public const int SQL_ATTR_ANSI_APP = 115;
- public const int SQL_AA_TRUE = 1; /* the application is an ANSI app */
- public const int SQL_AA_FALSE = 0; /* the application is a Unicode app */
-
- public const int SQL_ATTR_CONNECTION_DEAD = 1209; /* GetConnectAttr only */
- public const int SQL_CD_TRUE = 1; /* the connection is dead */
- public const int SQL_CD_FALSE = 0; /* the connection is not dead */
-
- public const int SQL_IS_POINTER = -4;
- public const int SQL_IS_UINTEGER = -5;
- public const int SQL_IS_INTEGER = -6;
- public const int SQL_IS_USMALLINT = -7;
- public const int SQL_IS_SMALLINT = -8;
-
-
-
-
- /* Data Types */
- public const int SQL_UNKNOWN_TYPE = 0;
- public const int SQL_CHAR = 1;
- public const int SQL_NUMERIC = 2;
- public const int SQL_DECIMAL = 3;
- public const int SQL_INTEGER = 4;
- public const int SQL_SMALLINT = 5;
- public const int SQL_FLOAT = 6;
- public const int SQL_REAL = 7;
- public const int SQL_DOUBLE = 8;
- public const int SQL_DATETIME = 9;
- public const int SQL_VARCHAR = 12;
- public const int SQL_BIGINT = (-5);
- public const int SQL_WCHAR = (-8);
- public const int SQL_WVARCHAR = (-9);
- public const int SQL_WLONGVARCHAR = (-10);
- public const int SQL_LONGVARCHAR = (-4);
- public const int SQL_TYPE_DATE = 91;
- public const int SQL_TYPE_TIME = 92;
- public const int SQL_TYPE_TIMESTAMP = 93;
- public const int SQL_TYPE_BINARY = -2;
- public const int SQL_TYPE_BLOB = -98;
- public const int SQL_TYPE_CLOB = -99;
- public const int SQL_VARBINARY = (-3);
- public const int SQL_LONGVARBINARY = (-4);
-
-
- public const int SQL_C_CHAR = SQL_CHAR;
- public const int SQL_C_WCHAR = SQL_WCHAR;
- public const int SQL_C_SBIGINT = -25;
- public const int SQL_C_SLONG = -16;
- public const int SQL_C_SSHORT = -15;
- public const int SQL_C_TYPE_BINARY = -2;
- public const int SQL_C_DOUBLE = 8;
- public const int SQL_C_DECIMAL_IBM = 3;
- public const int SQL_C_DECIMAL_OLEDB = 2514;
- public const int SQL_C_DEFAULT = 99;
- public const int SQL_C_TYPE_DATE = 91;
- public const int SQL_C_TYPE_TIME = 92;
- public const int SQL_C_TYPE_TIMESTAMP = 93;
- public const int SQL_C_TYPE_NUMERIC = 2;
- public const int SQL_C_TYPE_REAL = 7;
-
- //BLOBs
- public const int SQL_BLOB_LOCATOR = 31;
- public const int SQL_CLOB_LOCATOR = 41;
- public const int SQL_DBCLOB_LOCATOR = -351;
-
- public const int SQL_C_BLOB_LOCATOR = SQL_BLOB_LOCATOR;
- public const int SQL_C_CLOB_LOCATOR = SQL_CLOB_LOCATOR;
- public const int SQL_C_DBCLOB_LOCATOR = SQL_DBCLOB_LOCATOR;
-
- //UDFs
- public const int SQL_USER_DEFINED_TYPE = (-450);
-
- public const int SQL_NULL_DATA = -1;
-
- /* SQLDriverConnect Options */
- public const int SQL_DRIVER_NOPROMPT = 0;
- public const int SQL_DRIVER_COMPLETE = 1;
- public const int SQL_DRIVER_PROMPT = 2;
- public const int SQL_DRIVER_COMPLETE_REQUIRED = 3;
-
- /* Null settings */
- public const int SQL_NO_NULLS = 0;
- public const int SQL_NULLABLE = 1;
- public const int SQL_NULLABLE_UNKNOWN = 2;
-
- /* Defines for SQLBindParameter and SQLProcedureColumns */
- public const int SQL_PARAM_TYPE_UNKNOWN = 0;
- public const int SQL_PARAM_INPUT = 1;
- public const int SQL_PARAM_INPUT_OUTPUT = 2;
- public const int SQL_RESULT_COL = 3;
- public const int SQL_PARAM_OUTPUT = 4;
- public const int SQL_RETURN_VALUE = 5;
-
- /*Defines for SQLColAttributeW*/
- public const int SQL_DESC_ALLOC_TYPE = 1099;
- public const int SQL_DESC_AUTO_UNIQUE_VALUE = 11;
- public const int SQL_DESC_BASE_COLUMN_NAME = 22;
- public const int SQL_DESC_BASE_TABLE_NAME = 23;
- public const int SQL_DESC_COLUMN_CATALOG_NAME = 17;
- public const int SQL_DESC_COLUMN_NAME = 1;
- public const int SQL_DESC_COLUMN_OWNER_NAME = 16;
- public const int SQL_DESC_COLUMN_TABLE_NAME = 15;
- public const int SQL_DESC_CONCISE_TYPE = 2;
- public const int SQL_DESC_COUNT = 1001;
- public const int SQL_DESC_DATA_PTR = 1010;
- public const int SQL_DESC_DATETIME_INTERVAL_CODE = 1007;
- public const int SQL_DESC_INDICATOR_PTR = 1009;
- public const int SQL_DESC_LENGTH = 1003;
- public const int SQL_DESC_NAME = 1011;
- public const int SQL_DESC_NULLABLE = 1008;
- public const int SQL_DESC_OCTET_NULLABLE = 1013;
- public const int SQL_DESC_OCTET_LENGTH_PTR = 1004;
- public const int SQL_DESC_PRECISION = 1005;
- public const int SQL_DESC_SCALE = 1006;
- public const int SQL_DESC_TYPE = 1002;
- public const int SQL_DESC_TYPE_NAME = 14;
- public const int SQL_DESC_UNNAMED = 1012;
- public const int SQL_DESC_UNSIGNED = 8;
- public const int SQL_DESC_UPDATABLE = 10;
-
- /*Defines for SQLSetStmtAttr*/
- public const int SQL_ATTR_QUERY_TIMEOUT = 0;
-
- public const string LOG_PATH = "db2mp.log";
-
-
- }
-}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2DataAdapter.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2DataAdapter.cs
deleted file mode 100644
index ea3c36655a1..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2DataAdapter.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Data;
-using System.Data.Common;
-
-namespace IBM.Data.DB2 {
-
- public sealed class DB2DataAdapter : DbDataAdapter, IDbDataAdapter
- {
- #region Fields
-
- bool disposed = false;
- DB2Command deleteCommand;
- DB2Command insertCommand;
- DB2Command selectCommand;
- DB2Command updateCommand;
-
- #endregion
-
- #region Constructors
-
- public DB2DataAdapter ()
- : this (new DB2Command ())
- {
- }
-
- public DB2DataAdapter (DB2Command selectCommand)
- {
- DeleteCommand = null;
- InsertCommand = null;
- SelectCommand = selectCommand;
- UpdateCommand = null;
- }
-
- public DB2DataAdapter (string selectCommandText, DB2Connection selectConnection)
- : this (new DB2Command (selectCommandText, selectConnection))
- {
- }
-
- public DB2DataAdapter (string selectCommandText, string selectConnectionString)
- : this (selectCommandText, new DB2Connection (selectConnectionString))
- {
- }
-
- #endregion
-
- #region Properties
-
-
- public DB2Command DeleteCommand {
- get { return deleteCommand; }
- set { deleteCommand = value; }
- }
-
-
- public DB2Command InsertCommand {
- get { return insertCommand; }
- set { insertCommand = value; }
- }
-
-
- public DB2Command SelectCommand {
- get { return selectCommand; }
- set { selectCommand = value; }
- }
-
-
- public DB2Command UpdateCommand {
- get { return updateCommand; }
- set { updateCommand = value; }
- }
-
- IDbCommand IDbDataAdapter.DeleteCommand {
- get { return DeleteCommand; }
- set {
- if (!(value is DB2Command))
- throw new ArgumentException ();
- DeleteCommand = (DB2Command)value;
- }
- }
-
- IDbCommand IDbDataAdapter.InsertCommand {
- get { return InsertCommand; }
- set {
- if (!(value is DB2Command))
- throw new ArgumentException ();
- InsertCommand = (DB2Command)value;
- }
- }
-
- IDbCommand IDbDataAdapter.SelectCommand {
- get { return SelectCommand; }
- set {
- if (!(value is DB2Command))
- throw new ArgumentException ();
- SelectCommand = (DB2Command)value;
- }
- }
-
- IDbCommand IDbDataAdapter.UpdateCommand {
- get { return UpdateCommand; }
- set {
- if (!(value is DB2Command))
- throw new ArgumentException ();
- UpdateCommand = (DB2Command)value;
- }
- }
-
-
- ITableMappingCollection IDataAdapter.TableMappings {
- get { return TableMappings; }
- }
-
- #endregion
-
- #region Methods
-
- protected override RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
- {
- return new DB2RowUpdatedEventArgs (dataRow, command, statementType, tableMapping);
- }
-
-
- protected override RowUpdatingEventArgs CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
- {
- return new DB2RowUpdatingEventArgs (dataRow, command, statementType, tableMapping);
- }
-
- protected override void Dispose (bool disposing)
- {
- if (!disposed) {
- if (disposing) {
-
- }
-
- disposed = true;
- }
- }
-
- protected override void OnRowUpdated (RowUpdatedEventArgs value)
- {
- if (RowUpdated != null)
- RowUpdated (this, (DB2RowUpdatedEventArgs) value);
- }
-
- protected override void OnRowUpdating (RowUpdatingEventArgs value)
- {
- if (RowUpdating != null)
- RowUpdating (this, (DB2RowUpdatingEventArgs) value);
- }
-
- #endregion
-
- #region Events and Delegates
-
- public event DB2RowUpdatedEventHandler RowUpdated;
-
- public event DB2RowUpdatingEventHandler RowUpdating;
-
- #endregion
-
- }
-}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Exception.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Exception.cs
deleted file mode 100644
index 6ddb7b102dc..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Exception.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace IBM.Data.DB2
-{
-
- public class DB2Exception : Exception
- {
- internal string message;
- public DB2Exception(string Message)
- {
- this.message = Message;
- }
- public DB2Exception(short sqlHandleType, IntPtr sqlHandle, string Message)
- {
- StringBuilder sqlState = new StringBuilder(50);
- StringBuilder errorMessage = new StringBuilder(1025);
-
- int sqlReturn;
- short recNum=1;
- short bufLength = 1025;
-
- IntPtr textLengthPtr = IntPtr.Zero;
- IntPtr nativeErrorPtr = IntPtr.Zero;
-
- sqlReturn = DB2CLIWrapper.SQLGetDiagRec(sqlHandleType, sqlHandle, recNum, sqlState, ref nativeErrorPtr, errorMessage, bufLength, ref textLengthPtr);
- this.message = Message + "\n" + sqlState.ToString() + " " + errorMessage.ToString()+"\n";
- //See if there are more errors to retrieve and get them.
- while (sqlReturn != DB2Constants.SQL_NO_DATA && sqlReturn > 0)
- {
- recNum++;
- sqlReturn = DB2CLIWrapper.SQLGetDiagRec(sqlHandleType, sqlHandle, recNum, sqlState, ref nativeErrorPtr, errorMessage, bufLength, ref textLengthPtr);
- this.message += "\n" + sqlState.ToString() + " " + errorMessage.ToString()+"\n";
- }
-
- }
- public override string Message
- {
- get
- {
- return this.message;
- }
- }
- }
-}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Parameter.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Parameter.cs
deleted file mode 100644
index 5e1d8359604..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Parameter.cs
+++ /dev/null
@@ -1,498 +0,0 @@
-using System;
-using System.Data;
-using System.Runtime.InteropServices;
-
-namespace IBM.Data.DB2
-{
-
- public sealed class DB2Parameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
- {
- private DbType dbType;
- private IntPtr DB2DataType;
- private ParameterDirection direction;
- private bool nullable;
- private string parameterName;
- private string sourceColumn;
- private IntPtr paramSize;
- private IntPtr decimalDigits;
- private DataRowVersion sourceVersion;
- object dataVal;
- IntPtr DataValPtr = IntPtr.Zero;
- byte[] bDataVal;
- private int iDataVal;
- private double dblDataVal;
- private byte scale, precision;
- private int size;
- //bool selfDescribe = false;
-
- IntPtr StrLen_or_IndPtr = IntPtr.Zero;
-
- #region Contructors and destructors
- public DB2Parameter()
- {
- }
- public DB2Parameter (string name)
- {
- parameterName = name;
- }
-
- public DB2Parameter(string name, DbType type)
- {
- parameterName = name;
- dbType = type;
- int DB2Type = inferDB2TypeFromType(type);
- DB2DataType = new IntPtr(DB2Type);
- }
- public DB2Parameter(string name, object data)
- {
- parameterName = name;
- dbType = inferType(data);
- int DB2Type = inferDB2TypeFromType(dbType);
- DB2DataType = new IntPtr(DB2Type);
- this.Value = data;
- }
- public DB2Parameter(string name, DbType type, string columnName)
- {
- parameterName = name;
- dbType = type;
- sourceColumn = columnName;
- }
- public DB2Parameter(string name, int DB2Type)
- {
- parameterName = name;
- dbType = inferTypeFromDB2Type(DB2Type);
- DB2DataType = new IntPtr(DB2Type);
- }
- #endregion
- #region Properties
- #region DbType Property
- ///
- /// Parameter data type
- ///
- public DbType DbType
- {
- get
- {
- return dbType;
- }
- set
- {
- dbType = value;
- }
- }
- #endregion
- #region Direction
- ///
- /// In or out parameter, or both
- ///
- public ParameterDirection Direction
- {
- get
- {
- return direction;
- }
- set
- {
- direction = value;
- }
- }
- #endregion
- #region IsNullable
- ///
- /// Does this parameter support a null value
- ///
- public bool IsNullable
- {
- get
- {
- return nullable;
- }
- set
- {
- nullable = value;
- }
- }
- #endregion
- #region ParameterName
- public string ParameterName
- {
- get
- {
- return parameterName;
- }
- set
- {
- parameterName = value;
- }
- }
- #endregion
- #region SourceColumn
- ///
- /// Gets or sets the name of the source column that is mapped to the DataSet
- ///
- public string SourceColumn
- {
- get
- {
- return sourceColumn;
- }
- set
- {
- sourceColumn = value;
- }
- }
- #endregion
- #region SourceVersion
- ///
- /// DataRowVersion property
- ///
- public DataRowVersion SourceVersion
- {
- get
- {
- return sourceVersion;
- }
- set
- {
- sourceVersion = value;
- }
- }
- #endregion
- #region IDbDataParameter properties
- public byte Precision
- {
- get
- {
- return precision;
- }
- set
- {
- precision = value;
- }
- }
-
- public byte Scale
- {
- get
- {
- return scale;
- }
- set
- {
- scale = value;
- }
- }
-
- public int Size
- {
- get
- {
- return size;
- }
- set
- {
- size = value;
- }
- }
- #endregion
- #region Value
- ///
- /// The actual parameter data
- ///
- public object Value
- {
- get
- {
- return dataVal;
- }
- set
- {
- this.dataVal = value;
- DbType = inferType(dataVal);
- if (dbType==DbType.Int32){
- iDataVal=(int) value;
- //DataValPtr = new IntPtr((int)value);
- }
- else
- {
- if (bDataVal==null || bDataVal.Length< (((int)paramSize>20)?(int)paramSize:20) )
- bDataVal=new byte[((int)paramSize>20)?(int)paramSize:20];
- else
- bDataVal.Initialize();
- byte[] strValueBuffer=System.Text.Encoding.ASCII.GetBytes(dataVal.ToString());
-
- strValueBuffer.CopyTo(bDataVal,0);
- }
- }
- }
- #endregion
- #endregion
- #region inferType Method
- /// <summary>
- /// Determine the data type based on the value
- /// </summary>
- private DbType inferType (object Data)
- {
- switch (Type.GetTypeCode(Data.GetType()))
- {
- case TypeCode.Empty:
- throw new SystemException("Invalid data type");
-
- case TypeCode.Object:
- return DbType.Object;
-
- case TypeCode.DBNull:
- case TypeCode.Char:
- case TypeCode.SByte:
- case TypeCode.UInt16:
- case TypeCode.UInt32:
- case TypeCode.UInt64:
- // Throw a SystemException for unsupported data types.
- throw new SystemException("Invalid data type");
-
- case TypeCode.Boolean:
- return DbType.Boolean;
-
- case TypeCode.Byte:
- return DbType.Byte;
-
- case TypeCode.Int16:
- return DbType.Int16;
-
- case TypeCode.Int32:
- return DbType.Int32;
-
- case TypeCode.Int64:
- return DbType.Int64;
-
- case TypeCode.Single:
- return DbType.Single;
-
- case TypeCode.Double:
- return DbType.Double;
-
- case TypeCode.Decimal:
- return DbType.Decimal;
-
- case TypeCode.DateTime:
- return DbType.DateTime;
-
- case TypeCode.String:
- return DbType.String;
-
- default:
- throw new SystemException("Value is of unknown data type");
- }
- }
- #endregion
- #region inferTypeFromDB2Type
- ///
- /// Determine the DbType from the SQL type returned by SQLDescribeParam
- ///
- private DbType inferTypeFromDB2Type(int DB2Type)
- {
- switch (DB2Type)
- {
- case DB2Constants.SQL_CHAR:
- return DbType.AnsiString;
- case DB2Constants.SQL_NUMERIC:
- case DB2Constants.SQL_DECIMAL:
- return DbType.Decimal;
- case DB2Constants.SQL_DATETIME:
- return DbType.DateTime;
- case DB2Constants.SQL_FLOAT:
- case DB2Constants.SQL_DOUBLE:
- return DbType.Double;
- case DB2Constants.SQL_INTEGER:
- return DbType.Int32;
- case DB2Constants.SQL_SMALLINT:
- return DbType.Int16;
- case DB2Constants.SQL_VARCHAR:
- return DbType.String;
- case DB2Constants.SQL_USER_DEFINED_TYPE:
- return DbType.Object;
- default:
- throw new SystemException("DB2 Data type is unknown.");
- }
- }
- #endregion
-
- private int inferDB2TypeFromType(DbType _dbType)
- {
- switch (_dbType)
- {
- case DbType.AnsiString:
- return DB2Constants.SQL_CHAR;
- case DbType.Decimal:
- return DB2Constants.SQL_DECIMAL;
- case DbType.DateTime:
- return DB2Constants.SQL_DATETIME;
- case DbType.Double:
- return DB2Constants.SQL_DOUBLE;
- case DbType.Int32:
- return DB2Constants.SQL_INTEGER;
- case DbType.Int16:
- return DB2Constants.SQL_SMALLINT;
- case DbType.String:
- return DB2Constants.SQL_VARCHAR;
- case DbType.Object:
- return DB2Constants.SQL_USER_DEFINED_TYPE;
- default:
- throw new SystemException("DB2 Data type is unknown.");
- }
- }
-
- #region Describe
- ///
- /// Describe the parameter. Use at the caller's discretion
- ///
- public short Describe(IntPtr hwndStmt, short paramNum)
- {
- IntPtr nullable = IntPtr.Zero;
- paramSize = IntPtr.Zero;
- decimalDigits = IntPtr.Zero;
- short sqlRet = 0;
-
- sqlRet = DB2CLIWrapper.SQLDescribeParam(hwndStmt, paramNum, ref DB2DataType, ref paramSize, ref decimalDigits, ref nullable);
- return sqlRet;
- }
- #endregion
- #region Bind
- ///
- /// Bind this parameter
- ///
- public short Bind(IntPtr hwndStmt, short paramNum)
- {
- short sqlRet = 0;
-
- if(IntPtr.Zero == DataValPtr){
- InitMem(20, ref DataValPtr);
- }
-
- IntPtr DataTypePtr = IntPtr.Zero;
- InitMem(4, ref DataTypePtr);
-
- IntPtr ParameterSizePtr = IntPtr.Zero;
- InitMem(4, ref ParameterSizePtr);
-
- IntPtr DecimalDigitsPtr = IntPtr.Zero;
- InitMem(4, ref DecimalDigitsPtr);
-
-
- IntPtr NullablePtr = IntPtr.Zero;
- InitMem(4, ref NullablePtr);
-
- IntPtr StrLen_or_IndPtr = IntPtr.Zero;
- InitMem(4, ref StrLen_or_IndPtr);
-
- sqlRet = DB2CLIWrapper.SQLDescribeParam(hwndStmt, paramNum, DataTypePtr, ParameterSizePtr, DecimalDigitsPtr, NullablePtr);
-
- int _dataType = (int)Marshal.PtrToStructure(DataTypePtr, typeof(int));
- int _parameterSize = (int)Marshal.PtrToStructure(ParameterSizePtr, typeof(int));
- int _decimalDigits = (int)Marshal.PtrToStructure(DecimalDigitsPtr, typeof(int));
- int _nullable = (int)Marshal.PtrToStructure(NullablePtr, typeof(int));
- paramSize = new IntPtr(_parameterSize);
- switch ((int)DB2DataType)
- {
- //These types are treated as SQL_C_CHAR for binding purposes
- case DB2Constants.SQL_DATETIME:
- case DB2Constants.SQL_TYPE_DATE:
- case DB2Constants.SQL_TYPE_TIME:
- case DB2Constants.SQL_TYPE_TIMESTAMP:
- case DB2Constants.SQL_VARCHAR:
- case DB2Constants.SQL_CHAR:
- case DB2Constants.SQL_DECIMAL:
-
- if(ParameterDirection.Output == direction || ParameterDirection.InputOutput == direction){
- sqlRet = DB2CLIWrapper.SQLBindParameter(hwndStmt, (ushort)paramNum,
- ConvertParameterDirection(direction), DB2Constants.SQL_C_DEFAULT,
- (short)DB2DataType, Convert.ToUInt32((int)paramSize + _decimalDigits) ,
- (short) _decimalDigits, DataValPtr, _parameterSize, StrLen_or_IndPtr);
- }
- else{
- sqlRet = DB2CLIWrapper.SQLBindParameter(hwndStmt, (ushort)paramNum,
- ConvertParameterDirection(direction), DB2Constants.SQL_C_DEFAULT,
- (short)DB2DataType, Convert.ToUInt32((int)paramSize + _decimalDigits) ,
- (short) _decimalDigits, bDataVal, _parameterSize, StrLen_or_IndPtr);
- }
- break;
-
- case DB2Constants.SQL_INTEGER:
- sqlRet = DB2CLIWrapper.SQLBindParameter(hwndStmt, (ushort)paramNum,
- ConvertParameterDirection(direction), DB2Constants.SQL_C_DEFAULT,
- (short)DB2DataType, Convert.ToUInt32((int)paramSize),
- (short)_decimalDigits, ref iDataVal, _parameterSize, StrLen_or_IndPtr);
- break;
- case DB2Constants.SQL_DOUBLE:
- sqlRet = DB2CLIWrapper.SQLBindParameter(hwndStmt, (ushort)paramNum,
- ConvertParameterDirection(direction), DB2Constants.SQL_C_DEFAULT,
- (short)DB2DataType, Convert.ToUInt32((int)paramSize),
- (short)_decimalDigits, ref dblDataVal, _parameterSize, StrLen_or_IndPtr);
- break;
-
- default:
- throw new DB2Exception ("Unknown data type");
- }
- return sqlRet;
- }
- #endregion
- object ICloneable.Clone ()
- {
- throw new NotImplementedException ();
- }
-
- public short ConvertParameterDirection(ParameterDirection direction){
- switch(direction){
- case(ParameterDirection.Input):
- return DB2Constants.SQL_PARAM_INPUT;
- case(ParameterDirection.Output):
- return DB2Constants.SQL_PARAM_OUTPUT;
- case(ParameterDirection.InputOutput):
- return DB2Constants.SQL_PARAM_INPUT_OUTPUT;
- default:
- return DB2Constants.SQL_PARAM_INPUT;
- }
- }
-
- private void InitMem(int memSize, ref IntPtr ptr){
- if (ptr.ToInt32() == 0){
- unsafe{
- fixed(byte* arr = new byte[memSize]){
- ptr = new IntPtr(arr);
- }
- }
- }
- }
- internal void GetOutValue(){
-
- switch ((int)DB2DataType)
- {
- case DB2Constants.SQL_INTEGER:
- dataVal = iDataVal;
- break;
- case DB2Constants.SQL_DOUBLE:
- dataVal = dblDataVal;
- break;
- case DB2Constants.SQL_VARCHAR:
- case DB2Constants.SQL_CHAR:
- case DB2Constants.SQL_DECIMAL:
- dataVal = Marshal.PtrToStringAnsi(DataValPtr);
- break;
-
- case DB2Constants.SQL_DATETIME:
- case DB2Constants.SQL_TYPE_DATE:
- case DB2Constants.SQL_TYPE_TIME:
- case DB2Constants.SQL_TYPE_TIMESTAMP:
- //dataVal = Marshal.PtrToStringAnsi(DataValPtr);
- short year = Marshal.ReadInt16(DataValPtr, 0);
- short month = Marshal.ReadInt16(DataValPtr, 2);
- short day = Marshal.ReadInt16(DataValPtr, 4);
- dataVal = new DateTime(year, month, day);
- break;
-
- default:
- throw new DB2Exception("Unknown data type");
- }
- }
- }
-}
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ParameterCollection.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ParameterCollection.cs
deleted file mode 100644
index 03b3c4d2a03..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2ParameterCollection.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using System;
-using System.Data;
-using System.Collections;
-using System.Globalization;
-
-
-namespace IBM.Data.DB2
-{
-
- public class DB2ParameterCollection : ArrayList, IDataParameterCollection
- {
- IntPtr hwndStmt = IntPtr.Zero;
-
- internal IntPtr HwndStmt{
- set{
- hwndStmt = value;
- }
- }
- public object this[string index]
- {
- get
- {
- return this[IndexOf(index)];
- }
- set
- {
- this[IndexOf(index)] = value;
- }
- }
- public bool Contains(string paramName)
- {
- return(-1 != IndexOf(paramName));
- }
-
- public int IndexOf(string paramName)
- {
- int index = 0;
- foreach(DB2Parameter item in this)
- {
- if (0 == _cultureAwareCompare(item.ParameterName, paramName))
- {
- return index;
- }
- index++;
- }
- return -1;
- }
-
- public void RemoveAt(string paramName)
- {
- RemoveAt(IndexOf(paramName));
- }
-
- public override int Add(object value)
- {
- return Add((DB2Parameter)value);
- }
-
- public int Add(DB2Parameter value)
- {
- if (((DB2Parameter)value).ParameterName != null)
- {
-
- int result = base.Add(value);
- //value.Bind(hwndStmt, (short)this.Count);
- //Console.WriteLine("{0}", this.Count.ToString());
- return result;
- }
- else
- throw new ArgumentException("parameter must be named");
- }
-
- public int Add(string paramName, DbType type)
- {
- return Add(new DB2Parameter(paramName, type));
- }
-
- public int Add(string paramName, object value)
- {
- return Add(new DB2Parameter(paramName, value));
- }
-
- public int Add(string paramName, DbType dbType, string sourceColumn)
- {
- return Add(new DB2Parameter(paramName, dbType, sourceColumn));
- }
-
- private int _cultureAwareCompare(string strA, string strB)
- {
- return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase);
- }
-
- internal void GetOutValues(){
- foreach(DB2Parameter param in this){
- if(ParameterDirection.Output == param.Direction || ParameterDirection.InputOutput == param.Direction){
- param.GetOutValue();
- //Console.WriteLine(param.ParameterName);
- }
- }
- }
- }
-}
-
diff --git a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Transaction.cs b/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Transaction.cs
deleted file mode 100644
index 1499a151510..00000000000
--- a/mcs/class/IBM.Data.DB2/IBM.Data.DB2/Db2Transaction.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using System;
-using System.Data;
-using System.Runtime.InteropServices;
-
-namespace IBM.Data.DB2
-{
- public class DB2Transaction : IDbTransaction
- {
- IsolationLevel IL = IsolationLevel.Unspecified;
- DB2Connection DB2Conn;
- public DB2Transaction(DB2Connection con, IsolationLevel isoL)
- {
- long DB2IsoL = DB2Constants.SQL_TXN_READ_COMMITTED;
- DB2Conn = con;
- short sqlRet;
-
- switch (isoL)
- {
- case System.Data.IsolationLevel.Chaos: //No DB2equivalent, default to SQL_TXN_READ_COMMITTED
- break;
- case System.Data.IsolationLevel.ReadCommitted: //SQL_TXN_READ_COMMITTED
- DB2IsoL = DB2Constants.SQL_TXN_READ_COMMITTED;
- break;
- case System.Data.IsolationLevel.ReadUncommitted: //SQL_TXN_READ_UNCOMMITTED
- DB2IsoL = DB2Constants.SQL_TXN_READ_UNCOMMITTED;
- break;
- case System.Data.IsolationLevel.RepeatableRead: //SQL_TXN_REPEATABLE_READ
- DB2IsoL = DB2Constants.SQL_TXN_REPEATABLE_READ;
- break;
- case System.Data.IsolationLevel.Serializable: //SQL_TXN_SERIALIZABLE_READ
- DB2IsoL = DB2Constants.SQL_TXN_SERIALIZABLE_READ;
- break;
- }
-
- IL = isoL;
- IntPtr iso = new IntPtr(DB2IsoL);
- IntPtr attr = new IntPtr(DB2Constants.SQL_AUTOCOMMIT_OFF);
- sqlRet = DB2CLIWrapper.SQLSetConnectAttr(DB2Conn.DBHandle, DB2Constants.SQL_AUTOCOMMIT, attr, 0);
- DB2ClientUtils.DB2CheckReturn(sqlRet, DB2Constants.SQL_HANDLE_DBC, DB2Conn.DBHandle, "Error setting AUTOCOMMIT OFF in transaction CTOR.");
-//
-
- }
-
- /// <summary>
- /// DB2Connection associated with this transaction
- /// </summary>
- public IDbConnection Connection
- {
- get
- {
- return DB2Conn;
- }
- }
- /// <summary>
- /// IsolationLevel property
- /// </summary>
- ///
- public IsolationLevel IsolationLevel
- {
- get
- {
- return IL;
- }
- }
-
- public void Commit() {
- DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, DB2Conn.DBHandle, DB2Constants.SQL_COMMIT);
- //this.DB2Conn.WeakRefTransaction = null;
- //this.DB2Conn = null;
- }
-
- public void Rollback()
- {
- DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, DB2Conn.DBHandle, DB2Constants.SQL_ROLLBACK);
- //this.DB2Conn.WeakRefTransaction = null;
- //this.DB2Conn = null;
- }
-
- /// <summary>
- /// Dispose method.
- /// </summary>
- private bool Done = false;
- public void Dispose()
- {
- if (Done)
- return;
- Rollback();
- IL = IsolationLevel.Unspecified;
- DB2Conn = null;
- Done = true;
- }
- }
-}