**** Merged from MCS ****
[mono-project.git] / mcs / class / IBM.Data.DB2 / IBM.Data.DB2 / DB2OpenConnection.cs
blob59a7f7aab4e7e2169f91fc9dcab6d5a0a4bc2d6e
2 //
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:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
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.
22 using System;
23 using System.Collections;
24 using System.Runtime.InteropServices;
25 using System.Text;
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;
69 try
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*/);
84 else
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);
96 short stringLength;
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();
99 if(sqlRet == 0)
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);
102 if(sqlRet == 0)
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]);
111 catch{}
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;
132 catch
134 if(dbHandle != IntPtr.Zero)
136 DB2CLIWrapper.SQLFreeHandle(DB2Constants.SQL_HANDLE_DBC, dbHandle);
137 dbHandle = IntPtr.Zero;
139 throw;
143 public void RollbackDeadTransaction()
145 DB2CLIWrapper.SQLEndTran(DB2Constants.SQL_HANDLE_DBC, DBHandle, DB2Constants.SQL_ROLLBACK);
146 transactionOpen = false;
149 public void Close()
151 if(transactionOpen)
152 RollbackDeadTransaction();
154 if(settings.Pool != null)
156 settings.Pool.AddToFreeConnections(this);
158 else
160 Dispose();
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()
181 Dispose(true);
182 GC.SuppressFinalize(this);
185 private void Dispose(bool disposing)
187 if(!disposed)
189 if(disposing)
191 // dispose managed resources
193 FreeHandles();
195 disposed = true;
199 ~DB2OpenConnection()
201 if(settings.Pool != null)
203 settings.Pool.OpenConnectionFinalized();
205 Dispose(false);
207 #endregion