using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.Common;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
namespace Npgsql
{
///
/// Provides a simple way to create and manage the contents of connection strings used by
/// the class.
///
public sealed class NpgsqlConnectionStringBuilder : DbConnectionStringBuilder, IDictionary
{
#region Fields
///
/// Makes all valid keywords for a property to that property (e.g. User Name -> Username, UserId -> Username...)
///
static readonly Dictionary PropertiesByKeyword;
///
/// Maps CLR property names (e.g. BufferSize) to their canonical keyword name, which is the
/// property's [DisplayName] (e.g. Buffer Size)
///
static readonly Dictionary PropertyNameToCanonicalKeyword;
///
/// Maps each property to its [DefaultValue]
///
static readonly Dictionary PropertyDefaults;
///
/// Cached DataSource value to reduce allocations on NpgsqlConnection.DataSource.get
///
string? _dataSourceCached;
internal string DataSourceCached => _dataSourceCached ??= $"tcp://{_host}:{_port}";
#endregion
#region Constructors
///
/// Initializes a new instance of the NpgsqlConnectionStringBuilder class.
///
public NpgsqlConnectionStringBuilder() { Init(); }
///
/// Initializes a new instance of the NpgsqlConnectionStringBuilder class, optionally using ODBC rules for quoting values.
///
/// true to use {} to delimit fields; false to use quotation marks.
public NpgsqlConnectionStringBuilder(bool useOdbcRules) : base(useOdbcRules) { Init(); }
///
/// Initializes a new instance of the NpgsqlConnectionStringBuilder class and sets its .
///
public NpgsqlConnectionStringBuilder(string connectionString)
{
Init();
ConnectionString = connectionString;
}
void Init()
{
// Set the strongly-typed properties to their default values
foreach (var kv in PropertyDefaults)
kv.Key.SetValue(this, kv.Value);
// Setting the strongly-typed properties here also set the string-based properties in the base class.
// Clear them (default settings = empty connection string)
base.Clear();
}
#endregion
#region Static initialization
static NpgsqlConnectionStringBuilder()
{
var properties = typeof(NpgsqlConnectionStringBuilder)
.GetProperties()
.Where(p => p.GetCustomAttribute() != null)
.ToArray();
Debug.Assert(properties.All(p => p.CanRead && p.CanWrite));
Debug.Assert(properties.All(p => p.GetCustomAttribute() != null));
PropertiesByKeyword = (
from p in properties
let displayName = p.GetCustomAttribute()!.DisplayName.ToUpperInvariant()
let propertyName = p.Name.ToUpperInvariant()
from k in new[] { displayName }
.Concat(propertyName != displayName ? new[] { propertyName } : EmptyStringArray )
.Concat(p.GetCustomAttribute()!.Synonyms
.Select(a => a.ToUpperInvariant())
)
.Select(k => new { Property = p, Keyword = k })
select k
).ToDictionary(t => t.Keyword, t => t.Property);
PropertyNameToCanonicalKeyword = properties.ToDictionary(
p => p.Name,
p => p.GetCustomAttribute()!.DisplayName
);
PropertyDefaults = properties
.Where(p => p.GetCustomAttribute() == null)
.ToDictionary(
p => p,
p => p.GetCustomAttribute() != null
? p.GetCustomAttribute()!.Value
: (p.PropertyType.GetTypeInfo().IsValueType ? Activator.CreateInstance(p.PropertyType) : null)
);
}
#endregion
#region Non-static property handling
///
/// Gets or sets the value associated with the specified key.
///
/// The key of the item to get or set.
/// The value associated with the specified key.
#nullable disable
public override object this[string keyword]
#nullable restore
{
get
{
if (!TryGetValue(keyword, out var value))
throw new ArgumentException("Keyword not supported: " + keyword, nameof(keyword));
return value;
}
set
{
if (value == null)
{
Remove(keyword);
return;
}
var p = GetProperty(keyword);
try
{
var convertedValue = p.PropertyType.GetTypeInfo().IsEnum && value is string str
? Enum.Parse(p.PropertyType, str)
: Convert.ChangeType(value, p.PropertyType);
p.SetValue(this, convertedValue);
}
catch (Exception e)
{
throw new ArgumentException("Couldn't set " + keyword, keyword, e);
}
}
}
object? IDictionary.this[string keyword]
{
get => this[keyword];
set => this[keyword] = value!;
}
///
/// Adds an item to the .
///
/// The key-value pair to be added.
public void Add(KeyValuePair item)
=> this[item.Key] = item.Value!;
///
/// Removes the entry with the specified key from the DbConnectionStringBuilder instance.
///
/// The key of the key/value pair to be removed from the connection string in this DbConnectionStringBuilder.
/// true if the key existed within the connection string and was removed; false if the key did not exist.
public override bool Remove(string keyword)
{
var p = GetProperty(keyword);
var canonicalName = PropertyNameToCanonicalKeyword[p.Name];
var removed = base.ContainsKey(canonicalName);
// Note that string property setters call SetValue, which itself calls base.Remove().
p.SetValue(this, PropertyDefaults[p]);
base.Remove(canonicalName);
return removed;
}
///
/// Removes the entry from the DbConnectionStringBuilder instance.
///
/// The key/value pair to be removed from the connection string in this DbConnectionStringBuilder.
/// true if the key existed within the connection string and was removed; false if the key did not exist.
public bool Remove(KeyValuePair item)
=> Remove(item.Key);
///
/// Clears the contents of the instance.
///
public override void Clear()
{
Debug.Assert(Keys != null);
foreach (var k in Keys.ToArray()) {
Remove(k);
}
}
///
/// Determines whether the contains a specific key.
///
/// The key to locate in the .
/// true if the contains an entry with the specified key; otherwise false.
public override bool ContainsKey(string keyword)
=> keyword is null
? throw new ArgumentNullException(nameof(keyword))
: PropertiesByKeyword.ContainsKey(keyword.ToUpperInvariant());
///
/// Determines whether the contains a specific key-value pair.
///
/// The item to locate in the .
/// true if the contains the entry; otherwise false.
public bool Contains(KeyValuePair item)
=> TryGetValue(item.Key, out var value) &&
((value == null && item.Value == null) || (value != null && value.Equals(item.Value)));
PropertyInfo GetProperty(string keyword)
=> PropertiesByKeyword.TryGetValue(keyword.ToUpperInvariant(), out var p)
? p
: throw new ArgumentException("Keyword not supported: " + keyword, nameof(keyword));
///
/// Retrieves a value corresponding to the supplied key from this .
///
/// The key of the item to retrieve.
/// The value corresponding to the key.
/// true if keyword was found within the connection string, false otherwise.
public override bool TryGetValue(string keyword, [NotNullWhen(true)] out object? value)
{
if (keyword == null)
throw new ArgumentNullException(nameof(keyword));
if (!PropertiesByKeyword.ContainsKey(keyword.ToUpperInvariant()))
{
value = null;
return false;
}
value = GetProperty(keyword).GetValue(this) ?? "";
return true;
}
void SetValue(string propertyName, object? value)
{
var canonicalKeyword = PropertyNameToCanonicalKeyword[propertyName];
if (value == null)
base.Remove(canonicalKeyword);
else
base[canonicalKeyword] = value;
}
#endregion
#region Properties - Connection
///
/// The hostname or IP address of the PostgreSQL server to connect to.
///
[Category("Connection")]
[Description("The hostname or IP address of the PostgreSQL server to connect to.")]
[DisplayName("Host")]
[NpgsqlConnectionStringProperty("Server")]
public string? Host
{
get => _host;
set
{
_host = value;
SetValue(nameof(Host), value);
_dataSourceCached = null;
}
}
string? _host;
///
/// The TCP/IP port of the PostgreSQL server.
///
[Category("Connection")]
[Description("The TCP port of the PostgreSQL server.")]
[DisplayName("Port")]
[NpgsqlConnectionStringProperty]
[DefaultValue(NpgsqlConnection.DefaultPort)]
public int Port
{
get => _port;
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException(nameof(value), value, "Invalid port: " + value);
_port = value;
SetValue(nameof(Port), value);
_dataSourceCached = null;
}
}
int _port;
///
/// The PostgreSQL database to connect to.
///
[Category("Connection")]
[Description("The PostgreSQL database to connect to.")]
[DisplayName("Database")]
[NpgsqlConnectionStringProperty("DB")]
public string? Database
{
get => _database;
set
{
_database = value;
SetValue(nameof(Database), value);
}
}
string? _database;
///
/// The username to connect with. Not required if using IntegratedSecurity.
///
[Category("Connection")]
[Description("The username to connect with. Not required if using IntegratedSecurity.")]
[DisplayName("Username")]
[NpgsqlConnectionStringProperty("User Name", "UserId", "User Id", "UID")]
public string? Username
{
get => _username;
set
{
_username = value;
SetValue(nameof(Username), value);
}
}
string? _username;
///
/// The password to connect with. Not required if using IntegratedSecurity.
///
[Category("Connection")]
[Description("The password to connect with. Not required if using IntegratedSecurity.")]
[PasswordPropertyText(true)]
[DisplayName("Password")]
[NpgsqlConnectionStringProperty("PSW", "PWD")]
public string? Password
{
get => _password;
set
{
_password = value;
SetValue(nameof(Password), value);
}
}
string? _password;
///
/// Path to a PostgreSQL password file (PGPASSFILE), from which the password would be taken.
///
[Category("Connection")]
[Description("Path to a PostgreSQL password file (PGPASSFILE), from which the password would be taken.")]
[DisplayName("Passfile")]
[NpgsqlConnectionStringProperty]
public string? Passfile
{
get => _passfile;
set
{
_passfile = value;
SetValue(nameof(Passfile), value);
}
}
string? _passfile;
///
/// The optional application name parameter to be sent to the backend during connection initiation.
///
[Category("Connection")]
[Description("The optional application name parameter to be sent to the backend during connection initiation")]
[DisplayName("Application Name")]
[NpgsqlConnectionStringProperty]
public string? ApplicationName
{
get => _applicationName;
set
{
_applicationName = value;
SetValue(nameof(ApplicationName), value);
}
}
string? _applicationName;
///
/// Whether to enlist in an ambient TransactionScope.
///
[Category("Connection")]
[Description("Whether to enlist in an ambient TransactionScope.")]
[DisplayName("Enlist")]
[DefaultValue(true)]
[NpgsqlConnectionStringProperty]
public bool Enlist
{
get => _enlist;
set
{
_enlist = value;
SetValue(nameof(Enlist), value);
}
}
bool _enlist;
///
/// Gets or sets the schema search path.
///
[Category("Connection")]
[Description("Gets or sets the schema search path.")]
[DisplayName("Search Path")]
[NpgsqlConnectionStringProperty]
public string? SearchPath
{
get => _searchPath;
set
{
_searchPath = value;
SetValue(nameof(SearchPath), value);
}
}
string? _searchPath;
///
/// Gets or sets the client_encoding parameter.
///
[Category("Connection")]
[Description("Gets or sets the client_encoding parameter.")]
[DisplayName("Client Encoding")]
[NpgsqlConnectionStringProperty]
public string? ClientEncoding
{
get => _clientEncoding;
set
{
_clientEncoding = value;
SetValue(nameof(ClientEncoding), value);
}
}
string? _clientEncoding;
///
/// Gets or sets the .NET encoding that will be used to encode/decode PostgreSQL string data.
///
[Category("Connection")]
[Description("Gets or sets the .NET encoding that will be used to encode/decode PostgreSQL string data.")]
[DisplayName("Encoding")]
[DefaultValue("UTF8")]
[NpgsqlConnectionStringProperty]
public string Encoding
{
get => _encoding;
set
{
_encoding = value;
SetValue(nameof(Encoding), value);
}
}
string _encoding = "UTF8";
///
/// Gets or sets the PostgreSQL session timezone, in Olson/IANA database format.
///
[Category("Connection")]
[Description("Gets or sets the PostgreSQL session timezone, in Olson/IANA database format.")]
[DisplayName("Timezone")]
[NpgsqlConnectionStringProperty]
public string? Timezone
{
get => _timezone;
set
{
_timezone = value;
SetValue(nameof(Timezone), value);
}
}
string? _timezone;
#endregion
#region Properties - Security
///
/// Controls whether SSL is required, disabled or preferred, depending on server support.
///
[Category("Security")]
[Description("Controls whether SSL is required, disabled or preferred, depending on server support.")]
[DisplayName("SSL Mode")]
[NpgsqlConnectionStringProperty]
public SslMode SslMode
{
get => _sslmode;
set
{
_sslmode = value;
SetValue(nameof(SslMode), value);
}
}
SslMode _sslmode;
///
/// Whether to trust the server certificate without validating it.
///
[Category("Security")]
[Description("Whether to trust the server certificate without validating it.")]
[DisplayName("Trust Server Certificate")]
[NpgsqlConnectionStringProperty]
public bool TrustServerCertificate
{
get => _trustServerCertificate;
set
{
_trustServerCertificate = value;
SetValue(nameof(TrustServerCertificate), value);
}
}
bool _trustServerCertificate;
///
/// Whether to check the certificate revocation list during authentication.
/// False by default.
///
[Category("Security")]
[Description("Whether to check the certificate revocation list during authentication.")]
[DisplayName("Check Certificate Revocation")]
[NpgsqlConnectionStringProperty]
public bool CheckCertificateRevocation
{
get => _checkCertificateRevocation;
set
{
_checkCertificateRevocation = value;
SetValue(nameof(CheckCertificateRevocation), value);
}
}
bool _checkCertificateRevocation;
///
/// Whether to use Windows integrated security to log in.
///
[Category("Security")]
[Description("Whether to use Windows integrated security to log in.")]
[DisplayName("Integrated Security")]
[NpgsqlConnectionStringProperty]
public bool IntegratedSecurity
{
get => _integratedSecurity;
set
{
// No integrated security if we're on mono and .NET 4.5 because of ClaimsIdentity,
// see https://github.com/npgsql/Npgsql/issues/133
if (value && Type.GetType("Mono.Runtime") != null)
throw new NotSupportedException("IntegratedSecurity is currently unsupported on mono and .NET 4.5 (see https://github.com/npgsql/Npgsql/issues/133)");
_integratedSecurity = value;
SetValue(nameof(IntegratedSecurity), value);
}
}
bool _integratedSecurity;
///
/// The Kerberos service name to be used for authentication.
///
[Category("Security")]
[Description("The Kerberos service name to be used for authentication.")]
[DisplayName("Kerberos Service Name")]
[NpgsqlConnectionStringProperty("Krbsrvname")]
[DefaultValue("postgres")]
public string KerberosServiceName
{
get => _kerberosServiceName;
set
{
_kerberosServiceName = value;
SetValue(nameof(KerberosServiceName), value);
}
}
string _kerberosServiceName = "postgres";
///
/// The Kerberos realm to be used for authentication.
///
[Category("Security")]
[Description("The Kerberos realm to be used for authentication.")]
[DisplayName("Include Realm")]
[NpgsqlConnectionStringProperty]
public bool IncludeRealm
{
get => _includeRealm;
set
{
_includeRealm = value;
SetValue(nameof(IncludeRealm), value);
}
}
bool _includeRealm;
///
/// Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state.
///
[Category("Security")]
[Description("Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state.")]
[DisplayName("Persist Security Info")]
[NpgsqlConnectionStringProperty]
public bool PersistSecurityInfo
{
get => _persistSecurityInfo;
set
{
_persistSecurityInfo = value;
SetValue(nameof(PersistSecurityInfo), value);
}
}
bool _persistSecurityInfo;
#endregion
#region Properties - Pooling
///
/// Whether connection pooling should be used.
///
[Category("Pooling")]
[Description("Whether connection pooling should be used.")]
[DisplayName("Pooling")]
[NpgsqlConnectionStringProperty]
[DefaultValue(true)]
public bool Pooling
{
get => _pooling;
set
{
_pooling = value;
SetValue(nameof(Pooling), value);
}
}
bool _pooling;
///
/// The minimum connection pool size.
///
[Category("Pooling")]
[Description("The minimum connection pool size.")]
[DisplayName("Minimum Pool Size")]
[NpgsqlConnectionStringProperty]
[DefaultValue(0)]
public int MinPoolSize
{
get => _minPoolSize;
set
{
if (value < 0 || value > ConnectorPool.PoolSizeLimit)
throw new ArgumentOutOfRangeException(nameof(value), value, "MinPoolSize must be between 0 and " + ConnectorPool.PoolSizeLimit);
_minPoolSize = value;
SetValue(nameof(MinPoolSize), value);
}
}
int _minPoolSize;
///
/// The maximum connection pool size.
///
[Category("Pooling")]
[Description("The maximum connection pool size.")]
[DisplayName("Maximum Pool Size")]
[NpgsqlConnectionStringProperty]
[DefaultValue(100)]
public int MaxPoolSize
{
get => _maxPoolSize;
set
{
if (value < 0 || value > ConnectorPool.PoolSizeLimit)
throw new ArgumentOutOfRangeException(nameof(value), value, "MaxPoolSize must be between 0 and " + ConnectorPool.PoolSizeLimit);
_maxPoolSize = value;
SetValue(nameof(MaxPoolSize), value);
}
}
int _maxPoolSize;
///
/// The time to wait before closing idle connections in the pool if the count
/// of all connections exceeds MinPoolSize.
///
/// The time (in seconds) to wait. The default value is 300.
[Category("Pooling")]
[Description("The time to wait before closing unused connections in the pool if the count of all connections exceeds MinPoolSize.")]
[DisplayName("Connection Idle Lifetime")]
[NpgsqlConnectionStringProperty]
[DefaultValue(300)]
public int ConnectionIdleLifetime
{
get => _connectionIdleLifetime;
set
{
_connectionIdleLifetime = value;
SetValue(nameof(ConnectionIdleLifetime), value);
}
}
int _connectionIdleLifetime;
///
/// How many seconds the pool waits before attempting to prune idle connections that are beyond
/// idle lifetime (.
///
/// The interval (in seconds). The default value is 10.
[Category("Pooling")]
[Description("How many seconds the pool waits before attempting to prune idle connections that are beyond idle lifetime.")]
[DisplayName("Connection Pruning Interval")]
[NpgsqlConnectionStringProperty]
[DefaultValue(10)]
public int ConnectionPruningInterval
{
get => _connectionPruningInterval;
set
{
_connectionPruningInterval = value;
SetValue(nameof(ConnectionPruningInterval), value);
}
}
int _connectionPruningInterval;
#endregion
#region Properties - Timeouts
///
/// The time to wait (in seconds) while trying to establish a connection before terminating the attempt and generating an error.
/// Defaults to 15 seconds.
///
[Category("Timeouts")]
[Description("The time to wait (in seconds) while trying to establish a connection before terminating the attempt and generating an error.")]
[DisplayName("Timeout")]
[NpgsqlConnectionStringProperty]
[DefaultValue(DefaultTimeout)]
public int Timeout
{
get => _timeout;
set
{
if (value < 0 || value > NpgsqlConnection.TimeoutLimit)
throw new ArgumentOutOfRangeException(nameof(value), value, "Timeout must be between 0 and " + NpgsqlConnection.TimeoutLimit);
_timeout = value;
SetValue(nameof(Timeout), value);
}
}
int _timeout;
internal const int DefaultTimeout = 15;
///
/// The time to wait (in seconds) while trying to execute a command before terminating the attempt and generating an error.
/// Defaults to 30 seconds.
///
[Category("Timeouts")]
[Description("The time to wait (in seconds) while trying to execute a command before terminating the attempt and generating an error. Set to zero for infinity.")]
[DisplayName("Command Timeout")]
[NpgsqlConnectionStringProperty]
[DefaultValue(NpgsqlCommand.DefaultTimeout)]
public int CommandTimeout
{
get => _commandTimeout;
set
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), value, "CommandTimeout can't be negative");
_commandTimeout = value;
SetValue(nameof(CommandTimeout), value);
}
}
int _commandTimeout;
///
/// The time to wait (in seconds) while trying to execute a an internal command before terminating the attempt and generating an error.
///
[Category("Timeouts")]
[Description("The time to wait (in seconds) while trying to execute a an internal command before terminating the attempt and generating an error. -1 uses CommandTimeout, 0 means no timeout.")]
[DisplayName("Internal Command Timeout")]
[NpgsqlConnectionStringProperty]
[DefaultValue(-1)]
public int InternalCommandTimeout
{
get => _internalCommandTimeout;
set
{
if (value != 0 && value != -1 && value < NpgsqlConnector.MinimumInternalCommandTimeout)
throw new ArgumentOutOfRangeException(nameof(value), value,
$"InternalCommandTimeout must be >= {NpgsqlConnector.MinimumInternalCommandTimeout}, 0 (infinite) or -1 (use CommandTimeout)");
_internalCommandTimeout = value;
SetValue(nameof(InternalCommandTimeout), value);
}
}
int _internalCommandTimeout;
#endregion
#region Properties - Entity Framework
///
/// The database template to specify when creating a database in Entity Framework. If not specified,
/// PostgreSQL defaults to "template1".
///
///
/// http://www.postgresql.org/docs/current/static/manage-ag-templatedbs.html
///
[Category("Entity Framework")]
[Description("The database template to specify when creating a database in Entity Framework. If not specified, PostgreSQL defaults to \"template1\".")]
[DisplayName("EF Template Database")]
[NpgsqlConnectionStringProperty]
public string? EntityTemplateDatabase
{
get => _entityTemplateDatabase;
set
{
_entityTemplateDatabase = value;
SetValue(nameof(EntityTemplateDatabase), value);
}
}
string? _entityTemplateDatabase;
///
/// The database admin to specify when creating and dropping a database in Entity Framework. This is needed because
/// Npgsql needs to connect to a database in order to send the create/drop database command.
/// If not specified, defaults to "template1". Check NpgsqlServices.UsingPostgresDBConnection for more information.
///
[Category("Entity Framework")]
[Description("The database admin to specify when creating and dropping a database in Entity Framework. If not specified, defaults to \"template1\".")]
[DisplayName("EF Admin Database")]
[NpgsqlConnectionStringProperty]
public string? EntityAdminDatabase
{
get => _entityAdminDatabase;
set
{
_entityAdminDatabase = value;
SetValue(nameof(EntityAdminDatabase), value);
}
}
string? _entityAdminDatabase;
#endregion
#region Properties - Advanced
///
/// The number of seconds of connection inactivity before Npgsql sends a keepalive query.
/// Set to 0 (the default) to disable.
///
[Category("Advanced")]
[Description("The number of seconds of connection inactivity before Npgsql sends a keepalive query.")]
[DisplayName("Keepalive")]
[NpgsqlConnectionStringProperty]
public int KeepAlive
{
get => _keepAlive;
set
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), value, "KeepAlive can't be negative");
_keepAlive = value;
SetValue(nameof(KeepAlive), value);
}
}
int _keepAlive;
///
/// Whether to use TCP keepalive with system defaults if overrides isn't specified.
///
[Category("Advanced")]
[Description("Whether to use TCP keepalive with system defaults if overrides isn't specified.")]
[DisplayName("TCP Keepalive")]
[NpgsqlConnectionStringProperty]
public bool TcpKeepAlive
{
get => _tcpKeepAlive;
set
{
_tcpKeepAlive = value;
SetValue(nameof(TcpKeepAlive), value);
}
}
bool _tcpKeepAlive;
///
/// The number of seconds of connection inactivity before a TCP keepalive query is sent.
/// Use of this option is discouraged, use instead if possible.
/// Set to 0 (the default) to disable. Supported only on Windows.
///
[Category("Advanced")]
[Description("The number of milliseconds of connection inactivity before a TCP keepalive query is sent.")]
[DisplayName("TCP Keepalive Time")]
[NpgsqlConnectionStringProperty]
public int TcpKeepAliveTime
{
get => _tcpKeepAliveTime;
set
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), value, "TcpKeepAliveTime can't be negative");
_tcpKeepAliveTime = value;
SetValue(nameof(TcpKeepAliveTime), value);
}
}
int _tcpKeepAliveTime;
///
/// The interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received.
/// Defaults to the value of . must be non-zero as well.
/// Supported only on Windows.
///
[Category("Advanced")]
[Description("The interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received.")]
[DisplayName("TCP Keepalive Interval")]
[NpgsqlConnectionStringProperty]
public int TcpKeepAliveInterval
{
get => _tcpKeepAliveInterval;
set
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), value, "TcpKeepAliveInterval can't be negative");
_tcpKeepAliveInterval = value;
SetValue(nameof(TcpKeepAliveInterval), value);
}
}
int _tcpKeepAliveInterval;
///
/// Determines the size of the internal buffer Npgsql uses when reading. Increasing may improve performance if transferring large values from the database.
///
[Category("Advanced")]
[Description("Determines the size of the internal buffer Npgsql uses when reading. Increasing may improve performance if transferring large values from the database.")]
[DisplayName("Read Buffer Size")]
[NpgsqlConnectionStringProperty]
[DefaultValue(NpgsqlReadBuffer.DefaultSize)]
public int ReadBufferSize
{
get => _readBufferSize;
set
{
_readBufferSize = value;
SetValue(nameof(ReadBufferSize), value);
}
}
int _readBufferSize;
///
/// Determines the size of the internal buffer Npgsql uses when writing. Increasing may improve performance if transferring large values to the database.
///
[Category("Advanced")]
[Description("Determines the size of the internal buffer Npgsql uses when writing. Increasing may improve performance if transferring large values to the database.")]
[DisplayName("Write Buffer Size")]
[NpgsqlConnectionStringProperty]
[DefaultValue(NpgsqlWriteBuffer.DefaultSize)]
public int WriteBufferSize
{
get => _writeBufferSize;
set
{
_writeBufferSize = value;
SetValue(nameof(WriteBufferSize), value);
}
}
int _writeBufferSize;
///
/// Determines the size of socket read buffer.
///
[Category("Advanced")]
[Description("Determines the size of socket receive buffer.")]
[DisplayName("Socket Receive Buffer Size")]
[NpgsqlConnectionStringProperty]
public int SocketReceiveBufferSize
{
get => _socketReceiveBufferSize;
set
{
_socketReceiveBufferSize = value;
SetValue(nameof(SocketReceiveBufferSize), value);
}
}
int _socketReceiveBufferSize;
///
/// Determines the size of socket send buffer.
///
[Category("Advanced")]
[Description("Determines the size of socket send buffer.")]
[DisplayName("Socket Send Buffer Size")]
[NpgsqlConnectionStringProperty]
public int SocketSendBufferSize
{
get => _socketSendBufferSize;
set
{
_socketSendBufferSize = value;
SetValue(nameof(SocketSendBufferSize), value);
}
}
int _socketSendBufferSize;
///
/// The maximum number SQL statements that can be automatically prepared at any given point.
/// Beyond this number the least-recently-used statement will be recycled.
/// Zero (the default) disables automatic preparation.
///
[Category("Advanced")]
[Description("The maximum number SQL statements that can be automatically prepared at any given point. Beyond this number the least-recently-used statement will be recycled. Zero (the default) disables automatic preparation.")]
[DisplayName("Max Auto Prepare")]
[NpgsqlConnectionStringProperty]
public int MaxAutoPrepare
{
get => _maxAutoPrepare;
set
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value), value, $"{nameof(MaxAutoPrepare)} cannot be negative");
_maxAutoPrepare = value;
SetValue(nameof(MaxAutoPrepare), value);
}
}
int _maxAutoPrepare;
///
/// The minimum number of usages an SQL statement is used before it's automatically prepared.
/// Defaults to 5.
///
[Category("Advanced")]
[Description("The minimum number of usages an SQL statement is used before it's automatically prepared. Defaults to 5.")]
[DisplayName("Auto Prepare Min Usages")]
[NpgsqlConnectionStringProperty]
[DefaultValue(5)]
public int AutoPrepareMinUsages
{
get => _autoPrepareMinUsages;
set
{
if (value < 1)
throw new ArgumentOutOfRangeException(nameof(value), value, $"{nameof(AutoPrepareMinUsages)} must be 1 or greater");
_autoPrepareMinUsages = value;
SetValue(nameof(AutoPrepareMinUsages), value);
}
}
int _autoPrepareMinUsages;
///
/// Writes connection performance information to performance counters.
///
[Category("Advanced")]
[Description("Writes connection performance information to performance counters.")]
[DisplayName("Use Perf Counters")]
[NpgsqlConnectionStringProperty]
public bool UsePerfCounters
{
get => _usePerfCounters;
set
{
_usePerfCounters = value;
SetValue(nameof(UsePerfCounters), value);
}
}
bool _usePerfCounters;
///
/// If set to true, a pool connection's state won't be reset when it is closed (improves performance).
/// Do not specify this unless you know what you're doing.
///
[Category("Advanced")]
[Description("If set to true, a pool connection's state won't be reset when it is closed (improves performance). Do not specify this unless you know what you're doing.")]
[DisplayName("No Reset On Close")]
[NpgsqlConnectionStringProperty]
public bool NoResetOnClose
{
get => _noResetOnClose;
set
{
_noResetOnClose = value;
SetValue(nameof(NoResetOnClose), value);
}
}
bool _noResetOnClose;
///
/// Load table composite type definitions, and not just free-standing composite types.
///
[Category("Advanced")]
[Description("Load table composite type definitions, and not just free-standing composite types.")]
[DisplayName("Load Table Composites")]
[NpgsqlConnectionStringProperty]
public bool LoadTableComposites
{
get => _loadTableComposites;
set
{
_loadTableComposites = value;
SetValue(nameof(LoadTableComposites), value);
}
}
bool _loadTableComposites;
#endregion
#region Properties - Compatibility
///
/// A compatibility mode for special PostgreSQL server types.
///
[Category("Compatibility")]
[Description("A compatibility mode for special PostgreSQL server types.")]
[DisplayName("Server Compatibility Mode")]
[NpgsqlConnectionStringProperty]
public ServerCompatibilityMode ServerCompatibilityMode
{
get => _serverCompatibilityMode;
set
{
_serverCompatibilityMode = value;
SetValue(nameof(ServerCompatibilityMode), value);
}
}
ServerCompatibilityMode _serverCompatibilityMode;
///
/// Makes MaxValue and MinValue timestamps and dates readable as infinity and negative infinity.
///
[Category("Compatibility")]
[Description("Makes MaxValue and MinValue timestamps and dates readable as infinity and negative infinity.")]
[DisplayName("Convert Infinity DateTime")]
[NpgsqlConnectionStringProperty]
public bool ConvertInfinityDateTime
{
get => _convertInfinityDateTime;
set
{
_convertInfinityDateTime = value;
SetValue(nameof(ConvertInfinityDateTime), value);
}
}
bool _convertInfinityDateTime;
#endregion
#region Properties - Obsolete
///
/// Obsolete, see http://www.npgsql.org/doc/release-notes/3.1.html
///
[Category("Obsolete")]
[Description("Obsolete, see http://www.npgsql.org/doc/release-notes/3.1.html")]
[DisplayName("Connection Lifetime")]
[NpgsqlConnectionStringProperty]
[Obsolete("The ConnectionLifeTime parameter is no longer supported")]
public int ConnectionLifeTime
{
get => 0;
set => throw new NotSupportedException("The ConnectionLifeTime parameter is no longer supported. Please see http://www.npgsql.org/doc/release-notes/3.1.html");
}
///
/// Obsolete, see http://www.npgsql.org/doc/release-notes/3.1.html
///
[Category("Obsolete")]
[Description("Obsolete, see http://www.npgsql.org/doc/release-notes/3.1.html")]
[DisplayName("Continuous Processing")]
[NpgsqlConnectionStringProperty]
[Obsolete("The ContinuousProcessing parameter is no longer supported.")]
public bool ContinuousProcessing
{
get => false;
set => throw new NotSupportedException("The ContinuousProcessing parameter is no longer supported. Please see http://www.npgsql.org/doc/release-notes/3.1.html");
}
///
/// Obsolete, see http://www.npgsql.org/doc/release-notes/3.1.html
///
[Category("Obsolete")]
[Description("Obsolete, see http://www.npgsql.org/doc/release-notes/3.1.html")]
[DisplayName("Backend Timeouts")]
[NpgsqlConnectionStringProperty]
[Obsolete("The BackendTimeouts parameter is no longer supported")]
public bool BackendTimeouts
{
get => false;
set => throw new NotSupportedException("The BackendTimeouts parameter is no longer supported. Please see http://www.npgsql.org/doc/release-notes/3.1.html");
}
///
/// Obsolete, see http://www.npgsql.org/doc/release-notes/3.0.html
///
[Category("Obsolete")]
[Description("Obsolete, see http://www.npgsql.org/doc/v/3.0.html")]
[DisplayName("Preload Reader")]
[NpgsqlConnectionStringProperty]
[Obsolete("The PreloadReader parameter is no longer supported")]
public bool PreloadReader
{
get => false;
set => throw new NotSupportedException("The PreloadReader parameter is no longer supported. Please see http://www.npgsql.org/doc/release-notes/3.0.html");
}
///
/// Obsolete, see http://www.npgsql.org/doc/release-notes/3.0.html
///
[Category("Obsolete")]
[Description("Obsolete, see http://www.npgsql.org/doc/release-notes/3.0.html")]
[DisplayName("Use Extended Types")]
[NpgsqlConnectionStringProperty]
[Obsolete("The UseExtendedTypes parameter is no longer supported")]
public bool UseExtendedTypes
{
get => false;
set => throw new NotSupportedException("The UseExtendedTypes parameter is no longer supported. Please see http://www.npgsql.org/doc/release-notes/3.0.html");
}
///
/// Obsolete, see http://www.npgsql.org/doc/release-notes/4.1.html
///
[Category("Obsolete")]
[Description("Obsolete, see http://www.npgsql.org/doc/release-notes/4.1.html")]
[DisplayName("Use Ssl Stream")]
[NpgsqlConnectionStringProperty]
[Obsolete("The UseSslStream parameter is no longer supported (always true)")]
public bool UseSslStream
{
get => true;
set => throw new NotSupportedException("The UseSslStream parameter is no longer supported (SslStream is always used). Please see http://www.npgsql.org/doc/release-notes/4.1.html");
}
#endregion
#region Misc
internal string ToStringWithoutPassword()
{
var clone = Clone();
clone.Password = null;
return clone.ToString();
}
internal NpgsqlConnectionStringBuilder Clone() => new NpgsqlConnectionStringBuilder(ConnectionString);
///
/// Determines whether the specified object is equal to the current object.
///
public override bool Equals(object? obj)
=> obj is NpgsqlConnectionStringBuilder o && EquivalentTo(o);
///
/// Hash function.
///
///
public override int GetHashCode() => Host?.GetHashCode() ?? 0;
#endregion
#region IDictionary
///
/// Gets an ICollection{string} containing the keys of the .
///
public new ICollection Keys => base.Keys.Cast().ToArray();
///
/// Gets an ICollection{string} containing the values in the .
///
public new ICollection