3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 using System
.Collections
;
24 using System
.Runtime
.InteropServices
;
26 using System
.Threading
;
28 namespace IBM
.Data
.DB2
31 internal sealed class DB2OpenConnection
: IDisposable
33 private IntPtr dbHandle
= IntPtr
.Zero
;
35 private DB2ConnectionSettings settings
;
36 private bool disposed
= false;
37 internal DateTime poolDisposalTime
; // time to live used for disposal of connections in the connection pool
38 public bool transactionOpen
;
39 public bool autoCommit
= true;
40 private string databaseProductName
;
41 private string databaseVersion
;
42 private int majorVersion
;
43 private int minorVersion
;
45 public IntPtr DBHandle
47 get { return dbHandle; }
49 public string DatabaseProductName
51 get { return databaseProductName; }
53 public string DatabaseVersion
55 get { return databaseVersion; }
57 public int MajorVersion
59 get { return majorVersion; }
61 public int MinorVersion
63 get { return minorVersion; }
66 public DB2OpenConnection(DB2ConnectionSettings settings
, DB2Connection connection
)
68 this.settings
= settings
;
71 short sqlRet
= DB2CLIWrapper
.SQLAllocHandle(DB2Constants
.SQL_HANDLE_DBC
, DB2Environment
.Instance
.penvHandle
, out dbHandle
);
72 DB2ClientUtils
.DB2CheckReturn(sqlRet
, DB2Constants
.SQL_HANDLE_DBC
, DB2Environment
.Instance
.penvHandle
, "Unable to allocate database handle in DB2Connection.", connection
);
74 if(settings
.Server
.Length
> 0)
76 StringBuilder outConnectStr
= new StringBuilder(60); // TODO: ????
77 short numOutCharsReturned
;
79 sqlRet
= DB2CLIWrapper
.SQLDriverConnect(dbHandle
, IntPtr
.Zero
,
80 settings
.ConnectionString
, (short)settings
.ConnectionString
.Length
,
81 outConnectStr
, (short)outConnectStr
.Length
, out numOutCharsReturned
,
82 DB2Constants
.SQL_DRIVER_NOPROMPT
/*SQL_DRIVER_COMPLETE*/);
86 sqlRet
= DB2CLIWrapper
.SQLConnect(dbHandle
,
87 settings
.DatabaseAlias
, (short)settings
.DatabaseAlias
.Length
,
88 settings
.UserName
, (short)settings
.UserName
.Length
,
89 settings
.PassWord
, (short)settings
.PassWord
.Length
);
90 DB2ClientUtils
.DB2CheckReturn(sqlRet
, DB2Constants
.SQL_HANDLE_DBC
, dbHandle
, "Unable to connect to the database.", connection
);
93 if((settings
.Pool
== null) || (settings
.Pool
.databaseProductName
== null))
95 StringBuilder sb
= new StringBuilder(256);
97 sqlRet
= DB2CLIWrapper
.SQLGetInfo(dbHandle
, /*SQL_DBMS_NAME*/17, sb
, (short)(sb
.Capacity
/ 2), out stringLength
);
98 new DB2ErrorCollection(DB2Constants
.SQL_HANDLE_DBC
, dbHandle
).ToString();
100 databaseProductName
= sb
.ToString(0, Math
.Min(sb
.Capacity
, stringLength
/ 2));
101 sqlRet
= DB2CLIWrapper
.SQLGetInfo(dbHandle
, /*SQL_DBMS_VER*/18, sb
, (short)(sb
.Capacity
/ 2), out stringLength
);
104 databaseVersion
= sb
.ToString(0, Math
.Min(sb
.Capacity
, stringLength
/ 2));
107 string[] splitVersion
= databaseVersion
.Split('.');
108 majorVersion
= int.Parse(splitVersion
[0]);
109 minorVersion
= int.Parse(splitVersion
[1]);
113 if(settings
.Pool
!= null)
115 settings
.Pool
.databaseProductName
= databaseProductName
;
116 settings
.Pool
.databaseVersion
= databaseVersion
;
117 settings
.Pool
.majorVersion
= majorVersion
;
118 settings
.Pool
.minorVersion
= minorVersion
;
121 else if(settings
.Pool
!= null)
123 if(settings
.Pool
!= null)
125 databaseProductName
= settings
.Pool
.databaseProductName
;
126 databaseVersion
= settings
.Pool
.databaseVersion
;
127 majorVersion
= settings
.Pool
.majorVersion
;
128 minorVersion
= settings
.Pool
.minorVersion
;
134 if(dbHandle
!= IntPtr
.Zero
)
136 DB2CLIWrapper
.SQLFreeHandle(DB2Constants
.SQL_HANDLE_DBC
, dbHandle
);
137 dbHandle
= IntPtr
.Zero
;
143 public void RollbackDeadTransaction()
145 DB2CLIWrapper
.SQLEndTran(DB2Constants
.SQL_HANDLE_DBC
, DBHandle
, DB2Constants
.SQL_ROLLBACK
);
146 transactionOpen
= false;
152 RollbackDeadTransaction();
154 if(settings
.Pool
!= null)
156 settings
.Pool
.AddToFreeConnections(this);
164 private void FreeHandles()
166 if(dbHandle
!= IntPtr
.Zero
)
168 short sqlRet
= DB2CLIWrapper
.SQLDisconnect(dbHandle
);
169 // Note that SQLDisconnect() automatically drops any statements and
170 // descriptors open on the connection.
171 sqlRet
= DB2CLIWrapper
.SQLFreeHandle(DB2Constants
.SQL_HANDLE_DBC
, dbHandle
);
173 dbHandle
= IntPtr
.Zero
;
177 #region IDisposable Members
179 public void Dispose()
182 GC
.SuppressFinalize(this);
185 private void Dispose(bool disposing
)
191 // dispose managed resources
201 if(settings
.Pool
!= null)
203 settings
.Pool
.OpenConnectionFinalized();