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); } } } }
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); }
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); } }
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; } }
/// <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); }
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); } } }
/// <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); }
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); } } } }
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) { }
/*/// <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; }
/// <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)); }
/// <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; }
/// <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); }
private FieldData BuildFieldData(Stream stream, NpgsqlBackendTypeMapping typeMapping) { return(new FieldData(stream, typeMapping)); }
/// <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; }
/*/// <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; }