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.Collections.Specialized;
26 using System.Runtime.InteropServices;
29 namespace IBM.Data.DB2
33 public class DB2Connection : System.ComponentModel.Component, IDbConnection, ICloneable
35 #region private data members
37 private ArrayList refCommands;
\r
38 private WeakReference refTransaction;
\r
39 private DB2ConnectionSettings connectionSettings = null;
\r
40 private int connectionTimeout;
\r
41 internal DB2OpenConnection openConnection;
\r
42 private bool disposed = false;
48 public DB2Connection()
50 connectionTimeout = 15;
54 public DB2Connection(string conString)
57 SetConnectionString(conString);
63 #region ConnectionString property
65 public string ConnectionString
69 return connectionSettings.ConnectionString;
73 SetConnectionString(value);
79 #region ConnectionTimeout property
80 public int ConnectionTimeout
84 return connectionTimeout;
88 connectionTimeout = value;
93 #region Database property
94 public string Database
98 return connectionSettings.DatabaseAlias;
103 #region State property
106 unsafe public ConnectionState State
110 //if ((long)dbHandle.ToPointer() == DB2Constants.SQL_NULL_HANDLE)
111 if (openConnection == null)
112 return ConnectionState.Closed;
113 return ConnectionState.Open;
120 public event DB2InfoMessageEventHandler InfoMessage;
\r
121 public event StateChangeEventHandler StateChange;
\r
123 internal void OnInfoMessage(short handleType, IntPtr handle)
\r
125 if(InfoMessage != null)
\r
127 // Don't get error information until we know for sure someone is listening
\r
131 new DB2InfoMessageEventArgs(new DB2ErrorCollection(handleType, handle)));
\r
138 private void OnStateChange(StateChangeEventArgs args)
\r
140 if(StateChange != null)
\r
141 StateChange(this, args);
\r
148 internal IntPtr DBHandle
152 return (openConnection == null) ? IntPtr.Zero : openConnection.DBHandle;
157 #region BeginTransaction Method
159 IDbTransaction IDbConnection.BeginTransaction()
161 return BeginTransaction();
164 IDbTransaction IDbConnection.BeginTransaction(IsolationLevel isolationL)
166 return BeginTransaction(isolationL);
169 public DB2Transaction BeginTransaction()
171 return BeginTransaction(IsolationLevel.ReadCommitted);
174 public DB2Transaction BeginTransaction(IsolationLevel isolationL)
176 if ((refTransaction != null) && (refTransaction.IsAlive))
\r
177 throw new InvalidOperationException("Cannot open another transaction");
\r
178 if(State != ConnectionState.Open)
\r
179 throw new InvalidOperationException("BeginTransaction needs an open connection");
\r
181 if(refTransaction != null)
\r
183 if(refTransaction.IsAlive)
\r
184 throw new InvalidOperationException("Parallel transactions not supported");
\r
186 openConnection.RollbackDeadTransaction();
\r
187 refTransaction = null;
\r
189 openConnection.transactionOpen = true;
\r
190 DB2Transaction tran = new DB2Transaction(this, isolationL);
\r
191 refTransaction = new WeakReference(tran);
\r
197 #region ChangeDatabase
198 unsafe public void ChangeDatabase(string newDBName)
\r
200 if(connectionSettings == null)
\r
202 throw new InvalidOperationException("No connection string");
\r
206 SetConnectionString(connectionSettings.ConnectionString.Replace(connectionSettings.DatabaseAlias, newDBName));
\r
212 #region ReleaseObjectPool
213 public static void ReleaseObjectPool()
\r
215 DB2Environment.Instance.Dispose();
\r
220 public void Close()
\r
222 DB2Transaction transaction = null;
\r
223 if(refTransaction != null)
\r
224 transaction = (DB2Transaction)refTransaction.Target;
\r
225 if((transaction != null) && refTransaction.IsAlive)
\r
227 transaction.Dispose();
\r
229 if(refCommands != null)
\r
231 for(int i = 0; i < refCommands.Count; i++)
\r
233 DB2Command command = null;
\r
234 if(refCommands[i] != null)
\r
236 command = (DB2Command)((WeakReference)refCommands[i]).Target;
\r
238 if((command != null) && ((WeakReference)refCommands[i]).IsAlive)
\r
242 command.ConnectionClosed();
\r
246 //?? refCommands[i] = null;
\r
250 if(openConnection != null)
\r
252 openConnection.Close();
\r
253 openConnection = null;
\r
259 #region CreateCommand
260 IDbCommand IDbConnection.CreateCommand()
262 return CreateCommand();
265 public DB2Command CreateCommand()
268 return new DB2Command(null, this);
274 unsafe public void Open()
\r
278 throw new ObjectDisposedException("DB2Connection");
\r
281 if (this.State == ConnectionState.Open || this.State == ConnectionState.Connecting || this.State == ConnectionState.Executing || this.State == ConnectionState.Fetching)
\r
283 throw new InvalidOperationException("Connection already open");
\r
288 openConnection = connectionSettings.GetRealOpenConnection(this);
\r
290 catch (DB2Exception)
\r
299 public new void Dispose()
\r
302 GC.SuppressFinalize(this);
\r
305 protected override void Dispose(bool disposing)
\r
311 // dispose managed resources
\r
315 base.Dispose(disposing);
\r
326 private void CheckState()
\r
328 if (ConnectionState.Closed == State)
\r
329 throw new InvalidOperationException("Connection is currently closed.");
\r
332 void SetConnectionString (string connectionString)
\r
334 if (State != ConnectionState.Closed)
\r
335 throw new InvalidOperationException("Connection is not closed.");
\r
337 this.connectionSettings = DB2ConnectionSettings.GetConnectionSettings(connectionString);
\r
340 internal WeakReference WeakRefTransaction
\r
344 return refTransaction;
\r
348 refTransaction = value;
\r
353 internal void AddCommand(DB2Command command)
\r
355 if(refCommands == null)
\r
357 refCommands = new ArrayList();
\r
359 for(int i = 0; i < refCommands.Count; i++)
\r
361 WeakReference reference = (WeakReference)refCommands[i];
\r
362 if((reference == null) || !reference.IsAlive)
\r
364 refCommands[i] = new WeakReference(command);
\r
368 refCommands.Add(new WeakReference(command));
\r
372 internal void RemoveCommand(DB2Command command)
\r
374 for(int i = 0; i < refCommands.Count; i++)
\r
376 WeakReference reference = (WeakReference)refCommands[i];
\r
377 if(object.ReferenceEquals(reference, command))
\r
379 refCommands[i] = null;
\r
385 #region ICloneable Members
\r
387 object ICloneable.Clone()
\r
389 DB2Connection clone = new DB2Connection();
\r
391 clone.connectionSettings = connectionSettings;
\r
392 clone.connectionTimeout = connectionTimeout;
\r