Example #1
0
        /// <summary>
        /// Opens a database connection with the property settings specified by the
        /// <see cref="Npgsql.NpgsqlConnection.ConnectionString">ConnectionString</see>.
        /// </summary>
        public override void Open()
        {
            CheckConnectionClosed();

            // Check if there is any missing argument.
            if (!settings.ContainsKey(Keywords.Host))
            {
                throw new ArgumentException("Connection string argument missing!",
                                            NpgsqlConnectionStringBuilder.GetKeyName(Keywords.Host));
            }
            if (!settings.ContainsKey(Keywords.UserName) && !settings.ContainsKey(Keywords.IntegratedSecurity))
            {
                throw new ArgumentException("Connection string argument missing!",
                                            NpgsqlConnectionStringBuilder.GetKeyName(Keywords.UserName));
            }

            // Get a Connector, either from the pool or creating one ourselves.
            if (Pooling)
            {
                connector = NpgsqlConnectorPool.ConnectorPoolMgr.RequestConnector(this);
            }
            else
            {
                connector = new NpgsqlConnector(this);

                connector.ProvideClientCertificatesCallback += ProvideClientCertificatesCallbackDelegate;
                connector.CertificateSelectionCallback      += CertificateSelectionCallbackDelegate;
                connector.CertificateValidationCallback     += CertificateValidationCallbackDelegate;
                connector.PrivateKeySelectionCallback       += PrivateKeySelectionCallbackDelegate;

                connector.Open();
            }

            connector.Notice       += NoticeDelegate;
            connector.Notification += NotificationDelegate;
            connector.StateChanged += connector_StateChanged;

            if (SyncNotification)
            {
                connector.AddNotificationThread();
            }

            if (Enlist)
            {
                Promotable.Enlist(Transaction.Current);
            }
            this.OnStateChange(new StateChangeEventArgs(ConnectionState.Closed, ConnectionState.Open));
        }
Example #2
0
        /// <summary>
        /// Find an available pooled connector in the non-shared pool, or create
        /// a new one if none found.
        /// </summary>
        private NpgsqlConnector GetPooledConnector(NpgsqlConnection Connection)
        {
            ConnectorQueue  Queue;
            NpgsqlConnector Connector = null;

            // We only need to lock all pools when trying to get one pool or create one.
            lock (locker)
            {
                // Try to find a queue.
                if (!PooledConnectors.TryGetValue(Connection.ConnectionString, out Queue))
                {
                    Queue = new ConnectorQueue();
                    Queue.ConnectionLifeTime = Connection.ConnectionLifeTime;
                    Queue.MinPoolSize        = Connection.MinPoolSize;
                    PooledConnectors[Connection.ConnectionString] = Queue;
                }
            }

            // Now we can simply lock on the pool itself.
            lock (Queue)
            {
                if (Queue.Available.Count > 0)
                {
                    // Found a queue with connectors.  Grab the top one.
                    // Check if the connector is still valid.
                    Connector = Queue.Available.Dequeue();
                    Queue.Busy.Add(Connector, null);
                }
            }

            if (Connector != null)
            {
                if (!Connector.IsValid())
                {
                    lock (Queue)
                    {
                        Queue.Busy.Remove(Connector);
                    }

                    Connector.Close();
                    return(GetPooledConnector(Connection));                    //Try again
                }

                return(Connector);
            }

            lock (Queue)
            {
                if (Queue.Available.Count + Queue.Busy.Count < Connection.MaxPoolSize)
                {
                    Connector = new NpgsqlConnector(Connection);
                    Queue.Busy.Add(Connector, null);
                }
            }

            if (Connector != null)
            {
                Connector.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
                Connector.CertificateSelectionCallback      += Connection.CertificateSelectionCallbackDelegate;
                Connector.CertificateValidationCallback     += Connection.CertificateValidationCallbackDelegate;
                Connector.PrivateKeySelectionCallback       += Connection.PrivateKeySelectionCallbackDelegate;

                try
                {
                    Connector.Open();
                }
                catch
                {
                    lock (Queue)
                    {
                        Queue.Busy.Remove(Connector);
                    }

                    Connector.Close();

                    throw;
                }

                // Meet the MinPoolSize requirement if needed.
                if (Connection.MinPoolSize > 1)
                {
                    lock (Queue)
                    {
                        while (Queue.Available.Count + Queue.Busy.Count < Connection.MinPoolSize)
                        {
                            NpgsqlConnector Spare = new NpgsqlConnector(Connection);

                            Spare.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
                            Spare.CertificateSelectionCallback      += Connection.CertificateSelectionCallbackDelegate;
                            Spare.CertificateValidationCallback     += Connection.CertificateValidationCallbackDelegate;
                            Spare.PrivateKeySelectionCallback       += Connection.PrivateKeySelectionCallbackDelegate;

                            Spare.Open();

                            Spare.ProvideClientCertificatesCallback -= Connection.ProvideClientCertificatesCallbackDelegate;
                            Spare.CertificateSelectionCallback      -= Connection.CertificateSelectionCallbackDelegate;
                            Spare.CertificateValidationCallback     -= Connection.CertificateValidationCallbackDelegate;
                            Spare.PrivateKeySelectionCallback       -= Connection.PrivateKeySelectionCallbackDelegate;

                            Queue.Available.Enqueue(Spare);
                        }
                    }
                }
            }

            return(Connector);
        }
Example #3
0
		/// <summary>
		/// Opens a database connection with the property settings specified by the
		/// <see cref="Npgsql.NpgsqlConnection.ConnectionString">ConnectionString</see>.
		/// </summary>
		public override void Open()
		{
			CheckConnectionClosed();

			// Check if there is any missing argument.
			if (!settings.ContainsKey(Keywords.Host))
			{
				throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"),
											NpgsqlConnectionStringBuilder.GetKeyName(Keywords.Host));
			}
			if (!settings.ContainsKey(Keywords.UserName) && !settings.ContainsKey(Keywords.IntegratedSecurity))
			{
				throw new ArgumentException(resman.GetString("Exception_MissingConnStrArg"),
											NpgsqlConnectionStringBuilder.GetKeyName(Keywords.UserName));
			}

			// Get a Connector, either from the pool or creating one ourselves.
			if (Pooling)
			{
				connector = NpgsqlConnectorPool.ConnectorPoolMgr.RequestConnector(this);
			}
			else
			{
				connector = new NpgsqlConnector(this);

				connector.ProvideClientCertificatesCallback += ProvideClientCertificatesCallbackDelegate;
				connector.CertificateSelectionCallback += CertificateSelectionCallbackDelegate;
				connector.CertificateValidationCallback += CertificateValidationCallbackDelegate;
				connector.PrivateKeySelectionCallback += PrivateKeySelectionCallbackDelegate;

				connector.Open();
			}

			connector.Notice += NoticeDelegate;
			connector.Notification += NotificationDelegate;
			connector.StateChanged += connector_StateChanged;

			if (SyncNotification)
			{
				connector.AddNotificationThread();
			}

			if (Enlist)
			{
				Promotable.Enlist(Transaction.Current);
			}
			this.OnStateChange(new StateChangeEventArgs(ConnectionState.Closed, ConnectionState.Open));
		}
Example #4
0
		/// <summary>
		/// Find an available pooled connector in the non-shared pool, or create
		/// a new one if none found.
		/// </summary>
		private NpgsqlConnector GetPooledConnector(NpgsqlConnection Connection)
		{
			ConnectorQueue Queue;
			NpgsqlConnector Connector = null;

			// We only need to lock all pools when trying to get one pool or create one.
			lock (locker)
			{
				// Try to find a queue.
				if (!PooledConnectors.TryGetValue(Connection.ConnectionString, out Queue))
				{
					Queue = new ConnectorQueue();
					Queue.ConnectionLifeTime = Connection.ConnectionLifeTime;
					Queue.MinPoolSize = Connection.MinPoolSize;
					PooledConnectors[Connection.ConnectionString] = Queue;
				}
			}

			// Now we can simply lock on the pool itself.
			lock (Queue)
			{
				if (Queue.Available.Count > 0)
				{
					// Found a queue with connectors.  Grab the top one.
					// Check if the connector is still valid.
					Connector = Queue.Available.Dequeue();
					Queue.Busy.Add(Connector, null);
				}
			}

			if (Connector != null)
			{
				if (!Connector.IsValid())
				{
					lock (Queue)
					{
						Queue.Busy.Remove(Connector);
					}

					Connector.Close();
					return GetPooledConnector(Connection); //Try again
				}

				return Connector;
			}

			lock (Queue)
			{
				if (Queue.Available.Count + Queue.Busy.Count < Connection.MaxPoolSize)
				{
					Connector = new NpgsqlConnector(Connection);
					Queue.Busy.Add(Connector, null);
				}
			}

			if (Connector != null)
			{
				Connector.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
				Connector.CertificateSelectionCallback += Connection.CertificateSelectionCallbackDelegate;
				Connector.CertificateValidationCallback += Connection.CertificateValidationCallbackDelegate;
				Connector.PrivateKeySelectionCallback += Connection.PrivateKeySelectionCallbackDelegate;

				try
				{
					Connector.Open();
				}
				catch
				{
					lock (Queue)
					{
						Queue.Busy.Remove(Connector);
					}

					Connector.Close();

					throw;
				}

				// Meet the MinPoolSize requirement if needed.
				if (Connection.MinPoolSize > 1)
				{
					lock (Queue)
					{
						while (Queue.Available.Count + Queue.Busy.Count < Connection.MinPoolSize)
						{
							NpgsqlConnector Spare = new NpgsqlConnector(Connection);

							Spare.ProvideClientCertificatesCallback += Connection.ProvideClientCertificatesCallbackDelegate;
							Spare.CertificateSelectionCallback += Connection.CertificateSelectionCallbackDelegate;
							Spare.CertificateValidationCallback += Connection.CertificateValidationCallbackDelegate;
							Spare.PrivateKeySelectionCallback += Connection.PrivateKeySelectionCallbackDelegate;

							Spare.Open();

							Spare.ProvideClientCertificatesCallback -= Connection.ProvideClientCertificatesCallbackDelegate;
							Spare.CertificateSelectionCallback -= Connection.CertificateSelectionCallbackDelegate;
							Spare.CertificateValidationCallback -= Connection.CertificateValidationCallbackDelegate;
							Spare.PrivateKeySelectionCallback -= Connection.PrivateKeySelectionCallbackDelegate;

							Queue.Available.Enqueue(Spare);
						}
					}
				}
			}

			return Connector;
		}