Thread: [pgsqlclient-checkins] pgsqlclient_10/PostgreSql.Data.PgSqlClient/source PgConnectionInternal.cs,NON
Status: Inactive
Brought to you by:
carlosga_fb
From: Carlos G. Á. <car...@us...> - 2004-09-29 12:09:30
|
Update of /cvsroot/pgsqlclient/pgsqlclient_10/PostgreSql.Data.PgSqlClient/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15552 Added Files: PgConnectionInternal.cs Log Message: Mayor update of the PgSqlClient sources --- NEW FILE: PgConnectionInternal.cs --- /* PgSqlClient - ADO.NET Data Provider for PostgreSQL 7.4+ * Copyright (c) 2003-2004 Carlos Guzman Alvarez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ using System; using System.Collections; using System.Data; using System.Text; using System.Text.RegularExpressions; using Mono.Security.Protocol.Tls; using PostgreSql.Data.NPgClient; using PostgreSql.Data.PgSqlClient.DbSchema; namespace PostgreSql.Data.PgSqlClient { internal sealed class PgConnectionInternal : MarshalByRefObject { #region Fields private string connectionString; private PgConnection owningConnection; private PgDbClient database; private PgConnectionParams options; private PgTransaction activeTransaction; private ArrayList preparedCommands; private int lifetime; private long created; private bool pooled; #endregion #region Properties public PgDbClient Database { get { return this.database; } } public PgTransaction ActiveTransaction { get { return this.activeTransaction; } set { this.activeTransaction = value; } } public string ConnectionString { get { return this.connectionString; } } public int Lifetime { get { return this.lifetime; } set { this.lifetime = value; } } public long Created { get { return this.created; } set { this.created = value; } } public bool Pooled { get { return this.pooled; } set { this.pooled = value; } } public PgConnectionParams Options { get { return this.options; } } public ArrayList PreparedCommands { get { if (this.preparedCommands == null) { this.preparedCommands = new ArrayList(); } return this.preparedCommands; } } public bool HasActiveTransaction { get { return (this.activeTransaction != null && !this.activeTransaction.IsUpdated); } } public PgConnection OwningConnection { set { this.owningConnection = value; } } #endregion #region Constructors public PgConnectionInternal(string connectionString) { this.options = new PgConnectionParams(); this.connectionString = connectionString; this.lifetime = 0; this.created = 0; this.pooled = true; this.database = new PgDbClient(); this.owningConnection = owningConnection; if (connectionString != null) { this.ParseConnectionString(connectionString); } } #endregion #region Methods public void Connect() { try { this.database.SslConnection = new SslConnectionCallback(OnSslConnection); this.database.Settings = this.Options; this.database.Connect(); } catch (PgClientException ex) { throw new PgException(ex.Message, ex); } } public void Disconnect() { try { this.database.Disconnect(); } catch (PgClientException ex) { throw new PgException(ex.Message, ex); } } public PgTransaction BeginTransaction(IsolationLevel level) { if (this.activeTransaction != null && !this.activeTransaction.IsUpdated) { throw new InvalidOperationException("A transaction is currently active. Parallel transactions are not supported."); } try { this.activeTransaction = new PgTransaction(this.owningConnection, level); this.activeTransaction.InternalBeginTransaction(); } catch (PgClientException ex) { throw new PgException(ex.Message, ex); } return this.activeTransaction; } public DataTable GetSchema(string collectionName, string[] restrictions) { PgDbSchema dbSchema = PgDbSchemaFactory.GetSchema(collectionName); if (dbSchema == null) { throw new NotSupportedException("Specified schema type is not supported."); } if (restrictions != null) { if (restrictions.Length > dbSchema.RestrictionColumns.Count) { throw new InvalidOperationException("The number of specified restrictions is not valid."); } } return dbSchema.GetSchema(this.owningConnection, restrictions); } public void DisposeActiveTransaction() { // Rollback active transation if (this.HasActiveTransaction) { this.activeTransaction.Dispose(); this.activeTransaction = null; } } public void DisposePreparedCommands() { if (this.PreparedCommands.Count > 0) { PgCommand[] commands = new PgCommand[this.PreparedCommands.Count]; this.PreparedCommands.CopyTo(0, commands, 0, commands.Length); foreach (PgCommand command in commands) { command.Dispose(); } this.preparedCommands.Clear(); this.preparedCommands = null; } } public void AddPreparedCommand(PgCommand command) { if (!this.PreparedCommands.Contains(command)) { this.PreparedCommands.Add(command); } } public void RemovePreparedCommand(PgCommand command) { if (this.PreparedCommands.Contains(command)) { this.PreparedCommands.Remove(command); } } #endregion #region Internal Methods internal bool Verify() { bool isValid = true; try { // Try to send a Sync message to the PostgreSQL Server this.database.Sync(); } catch (Exception) { isValid = false; } return isValid; } #endregion #region Private Methods private void ParseConnectionString(string connectionStirng) { Regex search = new Regex(@"([\w\s\d]*)\s*=\s*([^;]*)"); MatchCollection elements = search.Matches(connectionString); foreach (Match element in elements) { if (element.Groups[2].Value.Trim().Length > 0) { switch (element.Groups[1].Value.Trim().ToLower()) { case "datasource": case "server": case "host": this.options.ServerName = element.Groups[2].Value.Trim(); break; case "database": this.options.Database = element.Groups[2].Value.Trim(); break; case "user name": case "user": this.options.UserName = element.Groups[2].Value.Trim(); break; case "user password": case "password": this.options.UserPassword = element.Groups[2].Value.Trim(); break; case "port": this.options.ServerPort = Int32.Parse(element.Groups[2].Value.Trim()); break; case "connection lifetime": this.lifetime = Int32.Parse(element.Groups[2].Value.Trim()); break; case "timeout": case "connection timeout": this.options.Timeout = Int32.Parse(element.Groups[2].Value.Trim()); break; case "packet size": this.options.PacketSize = Int32.Parse(element.Groups[2].Value.Trim()); break; case "pooling": this.options.Pooling = Boolean.Parse(element.Groups[2].Value.Trim()); break; case "ssl": this.options.SSL = Boolean.Parse(element.Groups[2].Value.Trim()); break; } } } if (options.UserName == String.Empty || options.ServerName == String.Empty || options.ServerPort == 0) { throw new ArgumentException("An invalid connection string argument has been supplied or a required connection string argument has not been supplied."); } else { if (options.PacketSize < 512 || options.PacketSize > 32767) { StringBuilder msg = new StringBuilder(); msg.AppendFormat("'Packet Size' value of {0} is not valid.\r\nThe value should be an integer >= 512 and <= 32767.", options.PacketSize); throw new ArgumentException(msg.ToString()); } } } #endregion #region SSL Callbacks private void OnSslConnection() { // Server certificate validation this.database.SslClientStream.ServerCertValidationDelegate = new CertificateValidationCallback(owningConnection.OnServerCertificateValidation); // Client certificate selection this.database.SslClientStream.ClientCertSelectionDelegate = new CertificateSelectionCallback(owningConnection.OnClientCertificateSelection); } #endregion } } |