2 * Firebird ADO.NET Data provider for .NET and Mono
4 * The contents of this file are subject to the Initial
5 * Developer's Public License Version 1.0 (the "License");
6 * you may not use this file except in compliance with the
7 * License. You may obtain a copy of the License at
8 * http://www.firebirdsql.org/index.php?op=doc&id=idpl
10 * Software distributed under the License is distributed on
11 * an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
12 * express or implied. See the License for the specific
13 * language governing rights and limitations under the License.
15 * Copyright (c) 2002, 2005 Carlos Guzman Alvarez
16 * All Rights Reserved.
20 using System.Collections;
24 using FirebirdSql.Data.Common;
25 using FirebirdSql.Data.Firebird.DbSchema;
27 namespace FirebirdSql.Data.Firebird
29 internal class FbConnectionInternal : MarshalByRefObject
34 private FbTransaction activeTransaction;
35 private ArrayList preparedCommands;
36 private FbConnectionString options;
37 private FbConnection owningConnection;
39 private long lifetime;
46 public IDatabase Database
48 get { return this.db; }
53 get { return this.lifetime; }
54 set { this.lifetime = value; }
59 get { return this.created; }
60 set { this.created = value; }
65 get { return this.pooled; }
66 set { this.pooled = value; }
69 public bool HasActiveTransaction
73 return this.activeTransaction != null && !this.activeTransaction.IsUpdated;
77 public ArrayList PreparedCommands
81 if (this.preparedCommands == null)
83 this.preparedCommands = new ArrayList();
86 return this.preparedCommands;
90 public FbTransaction ActiveTransaction
92 get { return this.activeTransaction; }
95 public FbConnectionString ConnectionOptions
97 get { return this.options; }
100 public FbConnection OwningConnection
102 get { return this.owningConnection; }
103 set { this.owningConnection = value; }
110 public FbConnectionInternal(FbConnectionString options) : this(options, null)
114 public FbConnectionInternal(FbConnectionString options, FbConnection owningConnection)
116 this.options = options;
117 this.owningConnection = owningConnection;
122 #region Create and Drop database methods
124 public void CreateDatabase(DatabaseParameterBuffer dpb)
126 IDatabase db = ClientFactory.CreateDatabase(this.options.ServerType);
127 db.CreateDatabase(dpb, this.options.DataSource, this.options.Port, this.options.Database);
130 public void DropDatabase()
132 IDatabase db = ClientFactory.CreateDatabase(this.options.ServerType);
133 db.Attach(this.BuildDpb(db, this.options), this.options.DataSource, this.options.Port, this.options.Database);
139 #region Connect and Disconenct methods
141 public void Connect()
145 this.db = ClientFactory.CreateDatabase(this.options.ServerType);
146 this.db.Charset = Charset.SupportedCharsets[this.options.Charset];
147 this.db.Dialect = this.options.Dialect;
148 this.db.PacketSize = this.options.PacketSize;
150 DatabaseParameterBuffer dpb = this.BuildDpb(this.db, options);
152 this.db.Attach(dpb, this.options.DataSource, this.options.Port, this.options.Database);
154 catch (IscException ex)
156 throw new FbException(ex.Message, ex);
160 public void Disconnect()
166 this.owningConnection = null;
172 this.DisposePreparedCommands();
174 catch (IscException ex)
176 throw new FbException(ex.Message, ex);
182 #region Transaction Methods
184 public FbTransaction BeginTransaction(IsolationLevel level, string transactionName)
188 if (this.HasActiveTransaction)
190 throw new InvalidOperationException("A transaction is currently active. Parallel transactions are not supported.");
195 this.activeTransaction = new FbTransaction(this.owningConnection, level);
196 this.activeTransaction.BeginTransaction();
198 if (transactionName != null)
200 this.activeTransaction.Save(transactionName);
203 catch (IscException ex)
205 throw new FbException(ex.Message, ex);
209 return this.activeTransaction;
212 public FbTransaction BeginTransaction(FbTransactionOptions options, string transactionName)
216 if (this.HasActiveTransaction)
218 throw new InvalidOperationException("A transaction is currently active. Parallel transactions are not supported.");
223 this.activeTransaction = new FbTransaction(
224 this.owningConnection, IsolationLevel.Unspecified);
226 this.activeTransaction.BeginTransaction(options);
228 if (transactionName != null)
230 this.activeTransaction.Save(transactionName);
233 catch (IscException ex)
235 throw new FbException(ex.Message, ex);
239 return this.activeTransaction;
242 public void DisposeTransaction()
244 if (this.activeTransaction != null)
246 this.activeTransaction.Dispose();
247 this.activeTransaction = null;
251 public void TransactionUpdated()
253 for (int i = 0; i < this.PreparedCommands.Count; i++)
255 FbCommand command = (FbCommand)this.PreparedCommands[i];
257 if (command.Transaction != null)
259 command.CloseReader();
260 command.Transaction = null;
267 #region Schema Methods
269 public DataTable GetSchema(string collectionName, string[] restrictions)
271 return FbDbSchemaFactory.GetSchema(this.owningConnection, collectionName, restrictions);
275 public DataTable GetSchema(string collectionName, object[] restrictions)
277 return FbDbSchemaFactory.GetSchema(this.owningConnection, collectionName, restrictions);
282 #region Prepared Commands Methods
284 public void AddPreparedCommand(FbCommand command)
286 if (!this.PreparedCommands.Contains(command))
288 this.PreparedCommands.Add(command);
292 public void RemovePreparedCommand(FbCommand command)
294 this.PreparedCommands.Remove(command);
297 public void DisposePreparedCommands()
299 if (this.preparedCommands != null)
301 if (this.PreparedCommands.Count > 0)
303 FbCommand[] commands = (FbCommand[])this.PreparedCommands.ToArray(typeof(FbCommand));
305 for (int i = 0; i < commands.Length; i++)
307 // Release statement handle
308 commands[i].Release();
312 this.PreparedCommands.Clear();
313 this.preparedCommands = null;
319 #region Firebird Events Methods
321 public void CloseEventManager()
323 if (this.db.HasRemoteEventSupport)
327 this.db.CloseEventManager();
334 #region Connection Verification
338 // Do not actually ask for any information
339 byte[] items = new byte[]
341 IscCodes.isc_info_end
346 this.db.GetDatabaseInfo(items, 16);
358 #region Private Methods
360 private DatabaseParameterBuffer BuildDpb(IDatabase db, FbConnectionString options)
362 DatabaseParameterBuffer dpb = db.CreateDatabaseParameterBuffer();
364 dpb.Append(IscCodes.isc_dpb_version1);
365 dpb.Append(IscCodes.isc_dpb_dummy_packet_interval,
366 new byte[] { 120, 10, 0, 0 });
367 dpb.Append(IscCodes.isc_dpb_sql_dialect,
368 new byte[] { Convert.ToByte(options.Dialect), 0, 0, 0 });
369 dpb.Append(IscCodes.isc_dpb_lc_ctype, options.Charset);
370 if (options.Role != null && options.Role.Length > 0)
372 dpb.Append(IscCodes.isc_dpb_sql_role_name, options.Role);
374 dpb.Append(IscCodes.isc_dpb_connect_timeout, options.ConnectionTimeout);
375 dpb.Append(IscCodes.isc_dpb_user_name, options.UserID);
376 dpb.Append(IscCodes.isc_dpb_password, options.Password);