public FieldDataV2(Stream stream, NpgsqlBackendTypeMapping typeMapping)
 {
     Name         = PGUtil.ReadString(stream);
     TypeInfo     = typeMapping[TypeOID = PGUtil.ReadInt32(stream)];
     TypeSize     = PGUtil.ReadInt16(stream);
     TypeModifier = PGUtil.ReadInt32(stream);
 }
        protected NpgsqlRowDescription(Stream stream, NpgsqlBackendTypeMapping type_mapping, Version compatVersion)
        {
            int num = ReadNumFields(stream);

            fields_data = new FieldData[num];
            if ((_compatVersion = compatVersion) < KANA_FIX_VERSION)
            {
                field_name_index_table        = new Dictionary <string, int>(num, StringComparer.InvariantCulture);
                caseInsensitiveNameIndexTable = new Dictionary <string, int>(num, StringComparer.InvariantCultureIgnoreCase);
            }
            else
            {
                field_name_index_table        = new Dictionary <string, int>(num, KanaWidthInsensitiveComparer.INSTANCE);
                caseInsensitiveNameIndexTable = new Dictionary <string, int>(num, KanaWidthCaseInsensitiveComparator.INSTANCE);
            }
            for (int i = 0; i != num; ++i)
            {
                FieldData fd = BuildFieldData(stream, type_mapping);
                fields_data[i] = fd;
                if (!field_name_index_table.ContainsKey(fd.Name))
                {
                    field_name_index_table.Add(fd.Name, i);
                    if (!caseInsensitiveNameIndexTable.ContainsKey(fd.Name))
                    {
                        caseInsensitiveNameIndexTable.Add(fd.Name, i);
                    }
                }
            }
        }
예제 #3
0
            private NpgsqlBackendTypeInfo _typeInfo; // everything we know about this field type

            public FieldData(Stream stream, NpgsqlBackendTypeMapping typeMapping)
            {
                Name     = stream.ReadString();
                TableOID = stream.ReadInt32();
                ColumnAttributeNumber = stream.ReadInt16();
                TypeInfo     = typeMapping[TypeOID = stream.ReadInt32()];
                TypeSize     = stream.ReadInt16();
                TypeModifier = stream.ReadInt32();
                FormatCode   = (FormatCode)stream.ReadInt16();
            }
 public FieldDataV3(Stream stream, NpgsqlBackendTypeMapping typeMapping)
 {
     Name     = PGUtil.ReadString(stream);
     TableOID = PGUtil.ReadInt32(stream);
     ColumnAttributeNumber = PGUtil.ReadInt16(stream);
     TypeInfo     = typeMapping[TypeOID = PGUtil.ReadInt32(stream)];
     TypeSize     = PGUtil.ReadInt16(stream);
     TypeModifier = PGUtil.ReadInt32(stream);
     FormatCode   = (FormatCode)PGUtil.ReadInt16(stream);
 }
 public FieldData(Stream stream, NpgsqlBackendTypeMapping typeMapping, byte[] buffer, ByteBuffer queue)
 {
     Name     = PGUtil.ReadString(stream, queue);
     TableOID = PGUtil.ReadInt32(stream, buffer);
     ColumnAttributeNumber = PGUtil.ReadInt16(stream, buffer);
     TypeOID      = PGUtil.ReadInt32(stream, buffer);
     TypeInfo     = typeMapping[TypeOID];
     TypeSize     = PGUtil.ReadInt16(stream, buffer);
     TypeModifier = PGUtil.ReadInt32(stream, buffer);
     FormatCode   = (FormatCode)PGUtil.ReadInt16(stream, buffer);
 }
예제 #6
0
        public NpgsqlRowDescription(Stream stream, NpgsqlBackendTypeMapping type_mapping, Version compatVersion, byte[] buffer, ByteBuffer queue)
        {
            _compatVersion = compatVersion;
            PGUtil.EatStreamBytes(stream, 4);
            var num = PGUtil.ReadInt16(stream, buffer);

            fields_data = new FieldData[num];
            for (int i = 0; i < fields_data.Length; i++)
            {
                fields_data[i] = new FieldData(stream, type_mapping, buffer, queue);
            }
        }
예제 #7
0
        public void ReadFromStream(Stream input_stream, Encoding encoding, NpgsqlBackendTypeMapping type_mapping)
        {
            switch (protocol_version)
            {
            case ProtocolVersion.Version2:
                ReadFromStream_Ver_2(input_stream, encoding, type_mapping);
                break;

            case ProtocolVersion.Version3:
                ReadFromStream_Ver_3(input_stream, encoding, type_mapping);
                break;
            }
        }
예제 #8
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="ConnectionString">Connection string.</param>
 /// <param name="Pooled">Pooled</param>
 /// <param name="Shared">Controls whether the connector can be shared.</param>
 public NpgsqlConnector(NpgsqlConnectionStringBuilder ConnectionString, bool Pooled, bool Shared)
 {
     this.settings                = ConnectionString;
     _connection_state            = ConnectionState.Closed;
     _pooled                      = Pooled;
     _shared                      = Shared;
     _isInitialized               = false;
     _state                       = NpgsqlClosedState.Instance;
     _mediator                    = new NpgsqlMediator();
     _oidToNameMapping            = new NpgsqlBackendTypeMapping();
     _planIndex                   = 0;
     _portalIndex                 = 0;
     _notificationThreadStopCount = 1;
     _notificationAutoResetEvent  = new AutoResetEvent(true);
 }
예제 #9
0
        private void ReadFromStream_Ver_2(Stream input_stream, Encoding encoding, NpgsqlBackendTypeMapping type_mapping)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_2");

            Byte[] input_buffer = new Byte[10]; // Max read will be 4 + 2 + 4

            // Read the number of fields.
            input_stream.Read(input_buffer, 0, 2);
            Int16 num_fields = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 0));


            // Temporary FieldData object to get data from stream and put in array.
            NpgsqlRowDescriptionFieldData fd;

            fields_data  = new NpgsqlRowDescriptionFieldData[num_fields];
            fields_index = new string[num_fields];

            field_name_index_table = new Hashtable(num_fields);


            // Now, iterate through each field getting its data.
            for (Int16 i = 0; i < num_fields; i++)
            {
                fd = new NpgsqlRowDescriptionFieldData();

                // Set field name.
                fd.name = PGUtil.ReadString(input_stream, encoding);

                // Read type_oid(Int32), type_size(Int16), type_modifier(Int32)
                input_stream.Read(input_buffer, 0, 4 + 2 + 4);

                fd.type_oid      = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 0));
                fd.type_info     = type_mapping[fd.type_oid];
                fd.type_size     = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(input_buffer, 4));
                fd.type_modifier = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(input_buffer, 6));

                // Add field data to array.
                fields_data[i] = fd;

                fields_index[i] = fd.name;

                if (!field_name_index_table.ContainsKey(fd.name))
                {
                    field_name_index_table.Add(fd.name, i);
                }
            }
        }
예제 #10
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Shared">Controls whether the connector can be shared.</param>
 public NpgsqlConnector(NpgsqlConnectionStringBuilder ConnectionString, bool Pooled, bool Shared)
 {
     this.settings                = ConnectionString;
     State                        = ConnectionState.Closed;
     _pooled                      = Pooled;
     _shared                      = Shared;
     _isInitialized               = false;
     _state                       = NpgsqlClosedState.Instance;
     _mediator                    = new NpgsqlMediator();
     _oidToNameMapping            = new NpgsqlBackendTypeMapping();
     _planIndex                   = 0;
     _portalIndex                 = 0;
     _notificationThreadStopCount = 1;
     _notificationAutoResetEvent  = new AutoResetEvent(true);
     rowDescription               = new NpgsqlRowDescription(CompatVersion);
     rowReader                    = new StringRowReader(rowDescription, Stream, TmpBuffer, ArrayBuffer);
     forwardReader                = new ForwardsOnlyRow(rowReader);
 }
        public NpgsqlRowDescription Process(Stream stream, NpgsqlBackendTypeMapping type_mapping, byte[] buffer, ByteBuffer queue)
        {
            PGUtil.EatStreamBytes(stream, 4);
            var num = PGUtil.ReadInt16(stream, buffer);

            fields_data_len = num;
            if (num > fields_data.Length)
            {
                fields_data = new FieldData[num];
            }
            for (int i = 0; i < fields_data_len; i++)
            {
                fields_data[i] = new FieldData(stream, type_mapping, buffer, queue);
            }
            _field_name_index_table        = null;
            _caseInsensitiveNameIndexTable = null;
            return(this);
        }
예제 #12
0
        public NpgsqlRowDescription(Stream stream, NpgsqlBackendTypeMapping type_mapping)
        {
            int num = ReadNumFields(stream);

            fields_data                   = new FieldData[num];
            field_name_index_table        = new Dictionary <string, int>(num, KanaWidthInsensitiveComparer.INSTANCE);
            caseInsensitiveNameIndexTable = new Dictionary <string, int>(num, KanaWidthCaseInsensitiveComparator.INSTANCE);
            for (int i = 0; i != num; ++i)
            {
                FieldData fd = BuildFieldData(stream, type_mapping);
                fields_data[i] = fd;
                if (!field_name_index_table.ContainsKey(fd.Name))
                {
                    field_name_index_table.Add(fd.Name, i);
                    if (!caseInsensitiveNameIndexTable.ContainsKey(fd.Name))
                    {
                        caseInsensitiveNameIndexTable.Add(fd.Name, i);
                    }
                }
            }
        }
예제 #13
0
        private void ReadFromStream_Ver_3(Stream input_stream, Encoding encoding, NpgsqlBackendTypeMapping type_mapping)
        {
            NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "ReadFromStream_Ver_3");

            Byte[] input_buffer = new Byte[4]; // Max read will be 4 + 2 + 4 + 2 + 4 + 2

            // Read the length of message.
            // [TODO] Any use for now?
            PGUtil.ReadInt32(input_stream, input_buffer);
            Int16 num_fields = PGUtil.ReadInt16(input_stream, input_buffer);

            // Temporary FieldData object to get data from stream and put in array.
            NpgsqlRowDescriptionFieldData fd;

            fields_data            = new NpgsqlRowDescriptionFieldData[num_fields];
            fields_index           = new string[num_fields];
            field_name_index_table = new Hashtable(num_fields);

            for (Int16 i = 0; i < num_fields; i++)
            {
                fd = new NpgsqlRowDescriptionFieldData();

                fd.name      = PGUtil.ReadString(input_stream, encoding);
                fd.table_oid = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.column_attribute_number = PGUtil.ReadInt16(input_stream, input_buffer);
                fd.type_oid      = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.type_info     = type_mapping[fd.type_oid];
                fd.type_size     = PGUtil.ReadInt16(input_stream, input_buffer);
                fd.type_modifier = PGUtil.ReadInt32(input_stream, input_buffer);
                fd.format_code   = (FormatCode)PGUtil.ReadInt16(input_stream, input_buffer);

                fields_data[i]  = fd;
                fields_index[i] = fd.name;

                if (!field_name_index_table.ContainsKey(fd.name))
                {
                    field_name_index_table.Add(fd.name, i);
                }
            }
        }
 protected abstract FieldData BuildFieldData(Stream stream, NpgsqlBackendTypeMapping typeMapping);
 public NpgsqlRowDescriptionV3(Stream stream, NpgsqlBackendTypeMapping typeMapping, Version compatVersion)
     : base(stream, typeMapping, compatVersion)
 {
 }
예제 #16
0
        /*/// <value>Counts the numbers of Connections that share
         * /// this Connector. Used in Release() to decide wether this
         * /// connector is to be moved to the PooledConnectors list.</value>
         * // internal int mShareCount;*/

        /// <summary>
        /// Opens the physical connection to the server.
        /// </summary>
        /// <remarks>Usually called by the RequestConnector
        /// Method of the connection pool manager.</remarks>
        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);
            }
            catch (NpgsqlException ne)
            {
                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.
                _mediator.ResetResponses();
                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);
            }

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

            // 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()));
                }
            }

            // 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))
                )
            {
                new NpgsqlCommand("SET CLIENT_ENCODING TO UTF8", this).ExecuteBlind();
            }

            if (!string.IsNullOrEmpty(settings.SearchPath))
            {
                /*NpgsqlParameter p = new NpgsqlParameter("p", DbType.String);
                 * p.Value = settings.SearchPath;
                 * NpgsqlCommand commandSearchPath = new NpgsqlCommand("SET SEARCH_PATH TO :p,public", this);
                 * commandSearchPath.Parameters.Add(p);
                 * commandSearchPath.ExecuteNonQuery();*/

                /*NpgsqlParameter p = new NpgsqlParameter("p", DbType.String);
                 * p.Value = settings.SearchPath;
                 * NpgsqlCommand commandSearchPath = new NpgsqlCommand("SET SEARCH_PATH TO :p,public", this);
                 * commandSearchPath.Parameters.Add(p);
                 * commandSearchPath.ExecuteNonQuery();*/

                // 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
                NpgsqlCommand commandSearchPath = new NpgsqlCommand("SET SEARCH_PATH=" + settings.SearchPath, this);
                commandSearchPath.ExecuteBlind();
            }

            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();
                }

                NpgsqlCommand commandApplicationName = new NpgsqlCommand("SET APPLICATION_NAME='" + settings.ApplicationName + "'", this);
                commandApplicationName.ExecuteBlind();
            }

            /*
             * 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.
             */

            try
            {
                NpgsqlCommand commandSslrenegotiation = new NpgsqlCommand("SET ssl_renegotiation_limit=0", this);
                commandSslrenegotiation.ExecuteBlind();
            }
            catch {}



            /*
             * Set precision digits to maximum value possible. For postgresql before 9 it was 2, after that, it is 3.
             * This way, we set first to 2 and then to 3. If there is an error because of 3, it will have been set to 2 at least.
             * Check bug report #1010992 for more information.
             */


            try
            {
                NpgsqlCommand commandSingleDoublePrecision = new NpgsqlCommand("SET extra_float_digits=2;SET extra_float_digits=3;", this);
                commandSingleDoublePrecision.ExecuteBlind();
            }
            catch {}


            /*
             * Set lc_monetary format to 'C' ir 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.
             */

            try
            {
                NpgsqlCommand commandMonetaryFormatC = new NpgsqlCommand("SET lc_monetary='C';", this);
                commandMonetaryFormatC.ExecuteBlind();
            }
            catch
            {
            }


            // 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.
            _oidToNameMapping = NpgsqlTypesHelper.CreateAndLoadInitialTypesMapping(this).Clone();

            ProcessServerVersion();

            // 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;
        }
예제 #17
0
        /// <value>Counts the numbers of Connections that share
        /// this Connector. Used in Release() to decide wether this
        /// connector is to be moved to the PooledConnectors list.</value>
        // internal int mShareCount;

        /// <summary>
        /// Opens the physical connection to the server.
        /// </summary>
        /// <remarks>Usually called by the RequestConnector
        /// Method of the connection pool manager.</remarks>
        internal void Open()
        {
            ProtocolVersion PV;

            // If Connection.ConnectionString specifies a protocol version, we will
            // not try to fall back to version 2 on failure.
            if (ConnectionString.Contains(ConnectionStringKeys.Protocol))
            {
                PV = ConnectionString.ToProtocolVersion(ConnectionStringKeys.Protocol);
            }
            else
            {
                PV = ProtocolVersion.Unknown;
            }

            _backendProtocolVersion = (PV == ProtocolVersion.Unknown) ? ProtocolVersion.Version3 : PV;

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

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

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

                    // If NpgsqlError.ReadFromStream_Ver_3() 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)
                    {
                        // Try using the 2.0 protocol.
                        _mediator.ResetResponses();
                        BackendProtocolVersion = ProtocolVersion.Version2;
                        CurrentState           = NpgsqlClosedState.Instance;

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

            // Check for errors and do the Right Thing.
            // FIXME - CheckErrors needs to be moved to Connector
            CheckErrors();

            _backend_keydata = _mediator.BackendKeyData;

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

            String ServerVersionString = String.Empty;

            // First try to determine backend server version using the newest method.
            if (((NpgsqlParameterStatus)_mediator.Parameters["__npgsql_server_version"]) != null)
            {
                ServerVersionString = ((NpgsqlParameterStatus)_mediator.Parameters["__npgsql_server_version"]).ParameterValue;
            }


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

            // Cook version string so we can use it for enabling/disabling things based on
            // backend version.
            ServerVersion = PGUtil.ParseServerVersion(ServerVersionString);

            // Adjust client encoding.

            //NpgsqlCommand commandEncoding1 = new NpgsqlCommand("show client_encoding", _connector);
            //String clientEncoding1 = (String)commandEncoding1.ExecuteScalar();

            if (ConnectionString.ToString(ConnectionStringKeys.Encoding, ConnectionStringDefaults.Encoding).ToUpper() == "UNICODE")
            {
                Encoding = Encoding.UTF8;
                NpgsqlCommand commandEncoding = new NpgsqlCommand("SET CLIENT_ENCODING TO UNICODE", this);
                commandEncoding.ExecuteNonQuery();
            }

            // 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.
            _oidToNameMapping = NpgsqlTypesHelper.CreateAndLoadInitialTypesMapping(this).Clone();

            ProcessServerVersion();

            // 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;
        }
 protected override FieldData BuildFieldData(Stream stream, NpgsqlBackendTypeMapping typeMapping)
 {
     return(new FieldDataV3(stream, typeMapping));
 }
예제 #19
0
        /// <summary>
        /// Opens the physical connection to the server.
        /// </summary>
        /// <remarks>Usually called by the RequestConnector
        /// Method of the connection pool manager.</remarks>
        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;

            // Get a raw connection, possibly SSL...
            CurrentState.Open(this);
            try
            {
                // Establish protocol communication and handle authentication...
                CurrentState.Startup(this);
            }
            catch (NpgsqlException ne)
            {
                // 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.
                _mediator.ResetResponses();
                BackendProtocolVersion = ProtocolVersion.Version2;
                CurrentState           = NpgsqlClosedState.Instance;

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

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

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

            StringBuilder sbInit = new StringBuilder();

            // 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))
            {
                sbInit.AppendLine("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();
                }

                sbInit.AppendLine("SET SEARCH_PATH=" + 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();
                }

                sbInit.AppendLine("SET APPLICATION_NAME='" + settings.ApplicationName.Replace('\'', '-') + "';");
            }

            /*
             * 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.
             */
            sbInit.AppendLine("SET ssl_renegotiation_limit=0;");

            /*
             * Set precision digits to maximum value possible. For postgresql before 9 it was 2, after that, it is 3.
             * This way, we set first to 2 and then to 3. If there is an error because of 3, it will have been set to 2 at least.
             * Check bug report #1010992 for more information.
             */
            sbInit.AppendLine("SET extra_float_digits=3;");
            try
            {
                new NpgsqlCommand(sbInit.ToString(), this).ExecuteBlind();
            }
            catch
            {
                foreach (var line in sbInit.ToString().Split(Environment.NewLine.ToCharArray()))
                {
                    try
                    {
                        if (line.Length > 0)
                        {
                            new NpgsqlCommand(line, this).ExecuteBlind();
                        }
                    }
                    catch { }
                }
            }

            // 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.
            _oidToNameMapping = NpgsqlTypesHelper.CreateAndLoadInitialTypesMapping(this).Clone();

            ProcessServerVersion();

            // 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;
        }
예제 #20
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Shared">Controls whether the connector can be shared.</param>
 public NpgsqlConnector(NpgsqlConnectionStringBuilder ConnectionString, bool Pooled, bool Shared)
 {
     this.settings = ConnectionString;
     State = ConnectionState.Closed;
     _pooled = Pooled;
     _shared = Shared;
     _isInitialized = false;
     _state = NpgsqlClosedState.Instance;
     _mediator = new NpgsqlMediator();
     _oidToNameMapping = new NpgsqlBackendTypeMapping();
     _planIndex = 0;
     _portalIndex = 0;
     _notificationThreadStopCount = 1;
     _notificationAutoResetEvent = new AutoResetEvent(true);
 }
예제 #21
0
 private FieldData BuildFieldData(Stream stream, NpgsqlBackendTypeMapping typeMapping)
 {
     return(new FieldData(stream, typeMapping));
 }
예제 #22
0
        /// <summary>
        /// Opens the physical connection to the server.
        /// </summary>
        /// <remarks>Usually called by the RequestConnector
        /// Method of the connection pool manager.</remarks>
        internal void Open()
        {
            ServerVersion = null;
            // If Connection.ConnectionString specifies a protocol version, we will
            // not try to fall back to version 2 on failure.

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

            // Get a raw connection, possibly SSL...
            CurrentState.Open(this);
            try
            {
                // Establish protocol communication and handle authentication...
                CurrentState.Startup(this);
            }
            catch (NpgsqlException)
            {
                throw;
            }

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

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

            StringBuilder sbInit = new StringBuilder();

            // 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))
                sbInit.AppendLine("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();
                }

                sbInit.AppendLine("SET SEARCH_PATH=" + 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();
                }

                sbInit.AppendLine("SET APPLICATION_NAME='" + settings.ApplicationName.Replace('\'', '-') + "';");
            }

            /*
             * 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.
             */
            sbInit.AppendLine("SET ssl_renegotiation_limit=0;");

            /*
             * Set precision digits to maximum value possible. For postgresql before 9 it was 2, after that, it is 3.
             * This way, we set first to 2 and then to 3. If there is an error because of 3, it will have been set to 2 at least.
             * Check bug report #1010992 for more information.
             */
            sbInit.AppendLine("SET extra_float_digits=3;");
            try
            {
                new NpgsqlCommand(sbInit.ToString(), this).ExecuteBlind();
            }
            catch
            {
                foreach (var line in sbInit.ToString().Split(Environment.NewLine.ToCharArray()))
                {
                    try
                    {
                        if (line.Length > 0)
                        {
                            new NpgsqlCommand(line, this).ExecuteBlind();
                        }
                    }
                    catch { }
                }
            }

            // 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.
            _oidToNameMapping = NpgsqlTypesHelper.CreateAndLoadInitialTypesMapping(this).Clone();

            ProcessServerVersion();

            // 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;
        }
예제 #23
0
        /*/// <value>Counts the numbers of Connections that share
         * /// this Connector. Used in Release() to decide wether this
         * /// connector is to be moved to the PooledConnectors list.</value>
         * // internal int mShareCount;*/

        /// <summary>
        /// Opens the physical connection to the server.
        /// </summary>
        /// <remarks>Usually called by the RequestConnector
        /// Method of the connection pool manager.</remarks>
        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;

            // Get a raw connection, possibly SSL...
            CurrentState.Open(this);
            try
            {
                // Establish protocol communication and handle authentication...
                CurrentState.Startup(this);
            }
            catch (NpgsqlException ne)
            {
                // 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.
                _mediator.ResetResponses();
                BackendProtocolVersion = ProtocolVersion.Version2;
                CurrentState           = NpgsqlClosedState.Instance;

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

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

            // 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()));
            }

            // 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))
                )
            {
                new NpgsqlCommand("SET CLIENT_ENCODING TO UTF8", this).ExecuteBlind();
            }

            if (!string.IsNullOrEmpty(settings.SearchPath))
            {
                /*NpgsqlParameter p = new NpgsqlParameter("p", DbType.String);
                 * p.Value = settings.SearchPath;
                 * NpgsqlCommand commandSearchPath = new NpgsqlCommand("SET SEARCH_PATH TO :p,public", this);
                 * commandSearchPath.Parameters.Add(p);
                 * commandSearchPath.ExecuteNonQuery();*/

                /*NpgsqlParameter p = new NpgsqlParameter("p", DbType.String);
                 * p.Value = settings.SearchPath;
                 * NpgsqlCommand commandSearchPath = new NpgsqlCommand("SET SEARCH_PATH TO :p,public", this);
                 * commandSearchPath.Parameters.Add(p);
                 * commandSearchPath.ExecuteNonQuery();*/

                // 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
                NpgsqlCommand commandSearchPath = new NpgsqlCommand("SET SEARCH_PATH=" + settings.SearchPath, this);
                commandSearchPath.ExecuteBlind();
            }



            /*
             * 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.
             */



            try

            {
                NpgsqlCommand commandSslrenegotiation = new NpgsqlCommand("SET ssl_renegotiation_limit=0", this);

                commandSslrenegotiation.ExecuteBlind();
            }

            catch {}



            // 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.
            _oidToNameMapping = NpgsqlTypesHelper.CreateAndLoadInitialTypesMapping(this).Clone();

            ProcessServerVersion();

            // 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;
        }