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
;
38 private WeakReference refTransaction
;
39 private DB2ConnectionSettings connectionSettings
= null;
40 private int connectionTimeout
;
41 internal DB2OpenConnection openConnection
;
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
;
121 public event StateChangeEventHandler StateChange
;
123 internal void OnInfoMessage(short handleType
, IntPtr handle
)
125 if(InfoMessage
!= null)
127 // Don't get error information until we know for sure someone is listening
131 new DB2InfoMessageEventArgs(new DB2ErrorCollection(handleType
, handle
)));
138 private void OnStateChange(StateChangeEventArgs args
)
140 if(StateChange
!= null)
141 StateChange(this, args
);
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
))
177 throw new InvalidOperationException("Cannot open another transaction");
178 if(State
!= ConnectionState
.Open
)
179 throw new InvalidOperationException("BeginTransaction needs an open connection");
181 if(refTransaction
!= null)
183 if(refTransaction
.IsAlive
)
184 throw new InvalidOperationException("Parallel transactions not supported");
186 openConnection
.RollbackDeadTransaction();
187 refTransaction
= null;
189 openConnection
.transactionOpen
= true;
190 DB2Transaction tran
= new DB2Transaction(this, isolationL
);
191 refTransaction
= new WeakReference(tran
);
197 #region ChangeDatabase
198 unsafe public void ChangeDatabase(string newDBName
)
200 if(connectionSettings
== null)
202 throw new InvalidOperationException("No connection string");
206 SetConnectionString(connectionSettings
.ConnectionString
.Replace(connectionSettings
.DatabaseAlias
, newDBName
));
212 #region ReleaseObjectPool
213 public static void ReleaseObjectPool()
215 DB2Environment
.Instance
.Dispose();
222 DB2Transaction transaction
= null;
223 if(refTransaction
!= null)
224 transaction
= (DB2Transaction
)refTransaction
.Target
;
225 if((transaction
!= null) && refTransaction
.IsAlive
)
227 transaction
.Dispose();
229 if(refCommands
!= null)
231 for(int i
= 0; i
< refCommands
.Count
; i
++)
233 DB2Command command
= null;
234 if(refCommands
[i
] != null)
236 command
= (DB2Command
)((WeakReference
)refCommands
[i
]).Target
;
238 if((command
!= null) && ((WeakReference
)refCommands
[i
]).IsAlive
)
242 command
.ConnectionClosed();
246 //?? refCommands[i] = null;
250 if(openConnection
!= null)
252 openConnection
.Close();
253 openConnection
= null;
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()
278 throw new ObjectDisposedException("DB2Connection");
281 if (this.State
== ConnectionState
.Open
|| this.State
== ConnectionState
.Connecting
|| this.State
== ConnectionState
.Executing
|| this.State
== ConnectionState
.Fetching
)
283 throw new InvalidOperationException("Connection already open");
288 openConnection
= connectionSettings
.GetRealOpenConnection(this);
299 public new void Dispose()
302 GC
.SuppressFinalize(this);
305 protected override void Dispose(bool disposing
)
311 // dispose managed resources
315 base.Dispose(disposing
);
326 private void CheckState()
328 if (ConnectionState
.Closed
== State
)
329 throw new InvalidOperationException("Connection is currently closed.");
332 void SetConnectionString (string connectionString
)
334 if (State
!= ConnectionState
.Closed
)
335 throw new InvalidOperationException("Connection is not closed.");
337 this.connectionSettings
= DB2ConnectionSettings
.GetConnectionSettings(connectionString
);
340 internal WeakReference WeakRefTransaction
344 return refTransaction
;
348 refTransaction
= value;
353 internal void AddCommand(DB2Command command
)
355 if(refCommands
== null)
357 refCommands
= new ArrayList();
359 for(int i
= 0; i
< refCommands
.Count
; i
++)
361 WeakReference reference
= (WeakReference
)refCommands
[i
];
362 if((reference
== null) || !reference
.IsAlive
)
364 refCommands
[i
] = new WeakReference(command
);
368 refCommands
.Add(new WeakReference(command
));
372 internal void RemoveCommand(DB2Command command
)
374 for(int i
= 0; i
< refCommands
.Count
; i
++)
376 WeakReference reference
= (WeakReference
)refCommands
[i
];
377 if(object.ReferenceEquals(reference
, command
))
379 refCommands
[i
] = null;
385 #region ICloneable Members
387 object ICloneable
.Clone()
389 DB2Connection clone
= new DB2Connection();
391 clone
.connectionSettings
= connectionSettings
;
392 clone
.connectionTimeout
= connectionTimeout
;