Npgsql.NpgsqlConnector.Open C# (CSharp) Method

Open() private method

Opens the physical connection to the server.
Usually called by the RequestConnector Method of the connection pool manager.
private Open ( ) : void
return void
        internal void Open()
        {
            ServerVersion = null;
            // If Connection.ConnectionString specifies a protocol version, we will
            // not try to fall back to version 2 on failure.

            _backendProtocolVersion = (settings.Protocol == ProtocolVersion.Unknown)
                                          ? ProtocolVersion.Version3
                                          : settings.Protocol;

            // Reset state to initialize new connector in pool.
            CurrentState = NpgsqlClosedState.Instance;

            // Keep track of time remaining; Even though there may be multiple timeout-able calls,
            // this allows us to still respect the caller's timeout expectation.
            int connectTimeRemaining = this.ConnectionTimeout * 1000;
            DateTime attemptStart = DateTime.Now;

            // Get a raw connection, possibly SSL...
            CurrentState.Open(this, connectTimeRemaining);
            try
            {
                // Establish protocol communication and handle authentication...
                CurrentState.Startup(this,settings);
            }
            catch (NpgsqlException ne)
            {
                if (_stream != null)
                {
                    try
                    {
                        _stream.Dispose();
                    }
                    catch
                    {
                    }
                }

                connectTimeRemaining -= Convert.ToInt32((DateTime.Now - attemptStart).TotalMilliseconds);

                // Check for protocol not supported.  If we have been told what protocol to use,
                // we will not try this step.
                if (settings.Protocol != ProtocolVersion.Unknown)
                {
                    throw;
                }
                // If we attempted protocol version 3, it may be possible to drop back to version 2.
                if (BackendProtocolVersion != ProtocolVersion.Version3)
                {
                    throw;
                }
                NpgsqlError Error0 = (NpgsqlError) ne.Errors[0];

                // If NpgsqlError..ctor() encounters a version 2 error,
                // it will set its own protocol version to version 2.  That way, we can tell
                // easily if the error was a FATAL: protocol error.
                if (Error0.BackendProtocolVersion != ProtocolVersion.Version2)
                {
                    throw;
                }
                // Try using the 2.0 protocol.
                BackendProtocolVersion = ProtocolVersion.Version2;
                CurrentState = NpgsqlClosedState.Instance;

                // Get a raw connection, possibly SSL...
                CurrentState.Open(this, connectTimeRemaining);
                // Establish protocol communication and handle authentication...
                CurrentState.Startup(this,this.settings);
            }

            // Change the state of connection to open and ready.
            _connection_state = ConnectionState.Open;
            CurrentState = NpgsqlReadyState.Instance;

            // After attachment, the stream will close the connector (this) when the stream gets disposed.
            _baseStream.AttachConnector(this);

            // Fall back to the old way, SELECT VERSION().
            // This should not happen for protocol version 3+.
            if (ServerVersion == null)
            {
                //NpgsqlCommand command = new NpgsqlCommand("set DATESTYLE TO ISO;select version();", this);
                //ServerVersion = new Version(PGUtil.ExtractServerVersion((string) command.ExecuteScalar()));
                using (NpgsqlCommand command = new NpgsqlCommand("set DATESTYLE TO ISO;select version();", this))
                {
                    ServerVersion = new Version(PGUtil.ExtractServerVersion((string)command.ExecuteScalar()));
                }
            }

            ProcessServerVersion();

            StringWriter sbInitQueries = new StringWriter();

            if (BackendProtocolVersion == ProtocolVersion.Version2)
            {
                sbInitQueries.WriteLine("SET DATESTYLE TO ISO;");

                // Adjust client encoding.

                NpgsqlParameterStatus clientEncodingParam = null;
                if (
                    !ServerParameters.TryGetValue("client_encoding", out clientEncodingParam) ||
                    (!string.Equals(clientEncodingParam.ParameterValue, "UTF8", StringComparison.OrdinalIgnoreCase) && !string.Equals(clientEncodingParam.ParameterValue, "UNICODE", StringComparison.OrdinalIgnoreCase))
                  )
                {
                    sbInitQueries.WriteLine("SET CLIENT_ENCODING TO UTF8;");
                }

                if (!string.IsNullOrEmpty(settings.SearchPath))
                {
                    // TODO: Add proper message when finding a semicolon in search_path.
                    // This semicolon could lead to a sql injection security hole as someone could write in connection string:
                    // searchpath=public;delete from table; and it would be executed.

                    if (settings.SearchPath.Contains(";"))
                    {
                        throw new InvalidOperationException();
                    }

                    // This is using string concatenation because set search_path doesn't allow type casting. ::text
                    sbInitQueries.WriteLine("SET SEARCH_PATH = {0};", settings.SearchPath);
                }

                if (!string.IsNullOrEmpty(settings.ApplicationName))
                {
                    if (!SupportsApplicationName)
                    {
                        //TODO
                        //throw new InvalidOperationException(resman.GetString("Exception_ApplicationNameNotSupported"));
                        throw new InvalidOperationException("ApplicationName not supported.");
                    }

                    if (settings.ApplicationName.Contains(";"))
                    {
                        throw new InvalidOperationException();
                    }

                    sbInitQueries.WriteLine("SET APPLICATION_NAME='{0}';", settings.ApplicationName);
                }

                /*
                 * Try to set SSL negotiation to 0. As of 2010-03-29, recent problems in SSL library implementations made
                 * postgresql to add a parameter to set a value when to do this renegotiation or 0 to disable it.
                 * Currently, Npgsql has a problem with renegotiation so, we are trying to disable it here.
                 * This only works on postgresql servers where the ssl renegotiation settings is supported of course.
                 * See http://lists.pgfoundry.org/pipermail/npgsql-devel/2010-February/001065.html for more information.
                 */

                if (SupportsSslRenegotiationLimit)
                {
                    sbInitQueries.WriteLine("SET ssl_renegotiation_limit=0;");
                }

                /*
                 * Set precision digits to maximum value possible. For postgresql before 9 it was 2, after that, it is 3.
                 * Check bug report #1010992 for more information.
                 */

                if (SupportsExtraFloatDigits3)
                {
                    sbInitQueries.WriteLine("SET extra_float_digits=3;");
                }
                else if (SupportsExtraFloatDigits)
                {
                    sbInitQueries.WriteLine("SET extra_float_digits=2;");
                }

                /*
                 * Set lc_monetary format to 'C' in order to get a culture agnostic representation of money.
                 * I noticed that on Windows, even when the lc_monetary is English_United States.UTF-8, negative
                 * money is formatted as ($value) with parentheses to indicate negative value.
                 * By going with a culture agnostic format, we get a consistent behavior.
                 */

                sbInitQueries.WriteLine("SET lc_monetary='C';");
            }
            else
            {
                // Some connection parameters for protocol 3 had been sent in the startup packet.
                // The rest will be setted here.
                if (SupportsExtraFloatDigits3)
                {
                    sbInitQueries.WriteLine("SET extra_float_digits=3;");
                }

                if (SupportsSslRenegotiationLimit)
                {
                    sbInitQueries.WriteLine("SET ssl_renegotiation_limit=0;");
                }

            }

            initQueries = sbInitQueries.ToString();

            NpgsqlCommand.ExecuteBlind(this, initQueries, 60);

            // Make a shallow copy of the type mapping that the connector will own.
            // It is possible that the connector may add types to its private
            // mapping that will not be valid to another connector, even
            // if connected to the same backend version.
            NativeToBackendTypeConverterOptions.OidToNameMapping = NpgsqlTypesHelper.CreateAndLoadInitialTypesMapping(this).Clone();

            // The connector is now fully initialized. Beyond this point, it is
            // safe to release it back to the pool rather than closing it.
            IsInitialized = true;
        }

Usage 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()
        {
            // If we're postponing a close (see doc on this variable), the connection is already
            // open and can be silently reused
            if (_postponingClose)
            {
                return;
            }

            CheckConnectionClosed();

            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "Open");

            // 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.RemoteCertificateValidationCallback += RemoteCertificateValidationCallback;
//                connector.ProvideClientCertificatesCallback += ProvideClientCertificatesCallbackDelegate;
//                connector.CertificateSelectionCallback += CertificateSelectionCallbackDelegate;
//                connector.CertificateValidationCallback += CertificateValidationCallbackDelegate;
//                connector.PrivateKeySelectionCallback += PrivateKeySelectionCallbackDelegate;
//                connector.ValidateRemoteCertificateCallback += ValidateRemoteCertificateCallbackDelegate;

                connector.Open();
            }

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

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

            if (Enlist)
            {
                Promotable.Enlist(Transaction.Current);
            }

            this.OnStateChange(new StateChangeEventArgs(ConnectionState.Closed, ConnectionState.Open));
        }
All Usage Examples Of Npgsql.NpgsqlConnector::Open