mirror of
https://github.com/jackc/pgx.git
synced 2025-07-09 12:08:16 +00:00
Replace DSN with keyword/value in comments and documentation
The term DSN is not used in the PostgreSQL documentation. I'm not sure why it was originally used. Use the correct PostgreSQL terminology.
This commit is contained in:
parent
cf50c60869
commit
a966716860
11
doc.go
11
doc.go
@ -11,9 +11,10 @@ The primary way of establishing a connection is with [pgx.Connect]:
|
|||||||
|
|
||||||
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
|
conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))
|
||||||
|
|
||||||
The database connection string can be in URL or DSN format. Both PostgreSQL settings and pgx settings can be specified
|
The database connection string can be in URL or key/value format. Both PostgreSQL settings and pgx settings can be
|
||||||
here. In addition, a config struct can be created by [ParseConfig] and modified before establishing the connection with
|
specified here. In addition, a config struct can be created by [ParseConfig] and modified before establishing the
|
||||||
[ConnectConfig] to configure settings such as tracing that cannot be configured with a connection string.
|
connection with [ConnectConfig] to configure settings such as tracing that cannot be configured with a connection
|
||||||
|
string.
|
||||||
|
|
||||||
Connection Pool
|
Connection Pool
|
||||||
|
|
||||||
@ -23,8 +24,8 @@ github.com/jackc/pgx/v5/pgxpool for a concurrency safe connection pool.
|
|||||||
Query Interface
|
Query Interface
|
||||||
|
|
||||||
pgx implements Query in the familiar database/sql style. However, pgx provides generic functions such as CollectRows and
|
pgx implements Query in the familiar database/sql style. However, pgx provides generic functions such as CollectRows and
|
||||||
ForEachRow that are a simpler and safer way of processing rows than manually calling defer rows.Close(), rows.Next(), rows.Scan, and
|
ForEachRow that are a simpler and safer way of processing rows than manually calling defer rows.Close(), rows.Next(),
|
||||||
rows.Err().
|
rows.Scan, and rows.Err().
|
||||||
|
|
||||||
CollectRows can be used collect all returned rows into a slice.
|
CollectRows can be used collect all returned rows into a slice.
|
||||||
|
|
||||||
|
@ -160,11 +160,11 @@ func NetworkAddress(host string, port uint16) (network, address string) {
|
|||||||
|
|
||||||
// ParseConfig builds a *Config from connString with similar behavior to the PostgreSQL standard C library libpq. It
|
// ParseConfig builds a *Config from connString with similar behavior to the PostgreSQL standard C library libpq. It
|
||||||
// uses the same defaults as libpq (e.g. port=5432) and understands most PG* environment variables. ParseConfig closely
|
// uses the same defaults as libpq (e.g. port=5432) and understands most PG* environment variables. ParseConfig closely
|
||||||
// matches the parsing behavior of libpq. connString may either be in URL format or keyword = value format (DSN style).
|
// matches the parsing behavior of libpq. connString may either be in URL format or keyword = value format. See
|
||||||
// See https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING for details. connString also may be
|
// https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING for details. connString also may be empty
|
||||||
// empty to only read from the environment. If a password is not supplied it will attempt to read the .pgpass file.
|
// to only read from the environment. If a password is not supplied it will attempt to read the .pgpass file.
|
||||||
//
|
//
|
||||||
// # Example DSN
|
// # Example Keyword/Value
|
||||||
// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca
|
// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca
|
||||||
//
|
//
|
||||||
// # Example URL
|
// # Example URL
|
||||||
@ -183,7 +183,7 @@ func NetworkAddress(host string, port uint16) (network, address string) {
|
|||||||
// postgres://jack:secret@foo.example.com:5432,bar.example.com:5432/mydb
|
// postgres://jack:secret@foo.example.com:5432,bar.example.com:5432/mydb
|
||||||
//
|
//
|
||||||
// ParseConfig currently recognizes the following environment variable and their parameter key word equivalents passed
|
// ParseConfig currently recognizes the following environment variable and their parameter key word equivalents passed
|
||||||
// via database URL or DSN:
|
// via database URL or keyword/value:
|
||||||
//
|
//
|
||||||
// PGHOST
|
// PGHOST
|
||||||
// PGPORT
|
// PGPORT
|
||||||
@ -247,16 +247,16 @@ func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Con
|
|||||||
connStringSettings := make(map[string]string)
|
connStringSettings := make(map[string]string)
|
||||||
if connString != "" {
|
if connString != "" {
|
||||||
var err error
|
var err error
|
||||||
// connString may be a database URL or a DSN
|
// connString may be a database URL or in PostgreSQL keyword/value format
|
||||||
if strings.HasPrefix(connString, "postgres://") || strings.HasPrefix(connString, "postgresql://") {
|
if strings.HasPrefix(connString, "postgres://") || strings.HasPrefix(connString, "postgresql://") {
|
||||||
connStringSettings, err = parseURLSettings(connString)
|
connStringSettings, err = parseURLSettings(connString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &ParseConfigError{ConnString: connString, msg: "failed to parse as URL", err: err}
|
return nil, &ParseConfigError{ConnString: connString, msg: "failed to parse as URL", err: err}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
connStringSettings, err = parseDSNSettings(connString)
|
connStringSettings, err = parseKeywordValueSettings(connString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &ParseConfigError{ConnString: connString, msg: "failed to parse as DSN", err: err}
|
return nil, &ParseConfigError{ConnString: connString, msg: "failed to parse as keyword/value", err: err}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,7 +534,7 @@ func isIPOnly(host string) bool {
|
|||||||
|
|
||||||
var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
|
var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
|
||||||
|
|
||||||
func parseDSNSettings(s string) (map[string]string, error) {
|
func parseKeywordValueSettings(s string) (map[string]string, error) {
|
||||||
settings := make(map[string]string)
|
settings := make(map[string]string)
|
||||||
|
|
||||||
nameMap := map[string]string{
|
nameMap := map[string]string{
|
||||||
@ -545,7 +545,7 @@ func parseDSNSettings(s string) (map[string]string, error) {
|
|||||||
var key, val string
|
var key, val string
|
||||||
eqIdx := strings.IndexRune(s, '=')
|
eqIdx := strings.IndexRune(s, '=')
|
||||||
if eqIdx < 0 {
|
if eqIdx < 0 {
|
||||||
return nil, errors.New("invalid dsn")
|
return nil, errors.New("invalid keyword/value")
|
||||||
}
|
}
|
||||||
|
|
||||||
key = strings.Trim(s[:eqIdx], " \t\n\r\v\f")
|
key = strings.Trim(s[:eqIdx], " \t\n\r\v\f")
|
||||||
@ -597,7 +597,7 @@ func parseDSNSettings(s string) (map[string]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if key == "" {
|
if key == "" {
|
||||||
return nil, errors.New("invalid dsn")
|
return nil, errors.New("invalid keyword/value")
|
||||||
}
|
}
|
||||||
|
|
||||||
settings[key] = val
|
settings[key] = val
|
||||||
|
@ -336,7 +336,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN everything",
|
name: "Key/value everything",
|
||||||
connString: "user=jack password=secret host=localhost port=5432 dbname=mydb sslmode=disable application_name=pgxtest search_path=myschema connect_timeout=5",
|
connString: "user=jack password=secret host=localhost port=5432 dbname=mydb sslmode=disable application_name=pgxtest search_path=myschema connect_timeout=5",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack",
|
User: "jack",
|
||||||
@ -353,7 +353,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN with escaped single quote",
|
name: "Key/value with escaped single quote",
|
||||||
connString: "user=jack\\'s password=secret host=localhost port=5432 dbname=mydb sslmode=disable",
|
connString: "user=jack\\'s password=secret host=localhost port=5432 dbname=mydb sslmode=disable",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack's",
|
User: "jack's",
|
||||||
@ -366,7 +366,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN with escaped backslash",
|
name: "Key/value with escaped backslash",
|
||||||
connString: "user=jack password=sooper\\\\secret host=localhost port=5432 dbname=mydb sslmode=disable",
|
connString: "user=jack password=sooper\\\\secret host=localhost port=5432 dbname=mydb sslmode=disable",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack",
|
User: "jack",
|
||||||
@ -379,7 +379,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN with single quoted values",
|
name: "Key/value with single quoted values",
|
||||||
connString: "user='jack' host='localhost' dbname='mydb' sslmode='disable'",
|
connString: "user='jack' host='localhost' dbname='mydb' sslmode='disable'",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack",
|
User: "jack",
|
||||||
@ -391,7 +391,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN with single quoted value with escaped single quote",
|
name: "Key/value with single quoted value with escaped single quote",
|
||||||
connString: "user='jack\\'s' host='localhost' dbname='mydb' sslmode='disable'",
|
connString: "user='jack\\'s' host='localhost' dbname='mydb' sslmode='disable'",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack's",
|
User: "jack's",
|
||||||
@ -403,7 +403,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN with empty single quoted value",
|
name: "Key/value with empty single quoted value",
|
||||||
connString: "user='jack' password='' host='localhost' dbname='mydb' sslmode='disable'",
|
connString: "user='jack' password='' host='localhost' dbname='mydb' sslmode='disable'",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack",
|
User: "jack",
|
||||||
@ -415,7 +415,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN with space between key and value",
|
name: "Key/value with space between key and value",
|
||||||
connString: "user = 'jack' password = '' host = 'localhost' dbname = 'mydb' sslmode='disable'",
|
connString: "user = 'jack' password = '' host = 'localhost' dbname = 'mydb' sslmode='disable'",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack",
|
User: "jack",
|
||||||
@ -491,7 +491,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN multiple hosts one port",
|
name: "Key/value multiple hosts one port",
|
||||||
connString: "user=jack password=secret host=foo,bar,baz port=5432 dbname=mydb sslmode=disable",
|
connString: "user=jack password=secret host=foo,bar,baz port=5432 dbname=mydb sslmode=disable",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack",
|
User: "jack",
|
||||||
@ -516,7 +516,7 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "DSN multiple hosts multiple ports",
|
name: "Key/value multiple hosts multiple ports",
|
||||||
connString: "user=jack password=secret host=foo,bar,baz port=1,2,3 dbname=mydb sslmode=disable",
|
connString: "user=jack password=secret host=foo,bar,baz port=1,2,3 dbname=mydb sslmode=disable",
|
||||||
config: &pgconn.Config{
|
config: &pgconn.Config{
|
||||||
User: "jack",
|
User: "jack",
|
||||||
@ -772,18 +772,18 @@ func TestParseConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/jackc/pgconn/issues/47
|
// https://github.com/jackc/pgconn/issues/47
|
||||||
func TestParseConfigDSNWithTrailingEmptyEqualDoesNotPanic(t *testing.T) {
|
func TestParseConfigKVWithTrailingEmptyEqualDoesNotPanic(t *testing.T) {
|
||||||
_, err := pgconn.ParseConfig("host= user= password= port= database=")
|
_, err := pgconn.ParseConfig("host= user= password= port= database=")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseConfigDSNLeadingEqual(t *testing.T) {
|
func TestParseConfigKVLeadingEqual(t *testing.T) {
|
||||||
_, err := pgconn.ParseConfig("= user=jack")
|
_, err := pgconn.ParseConfig("= user=jack")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/jackc/pgconn/issues/49
|
// https://github.com/jackc/pgconn/issues/49
|
||||||
func TestParseConfigDSNTrailingBackslash(t *testing.T) {
|
func TestParseConfigKVTrailingBackslash(t *testing.T) {
|
||||||
_, err := pgconn.ParseConfig(`x=x\`)
|
_, err := pgconn.ParseConfig(`x=x\`)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), "invalid backslash")
|
assert.Contains(t, err.Error(), "invalid backslash")
|
||||||
|
@ -5,8 +5,8 @@ nearly the same level is the C library libpq.
|
|||||||
|
|
||||||
Establishing a Connection
|
Establishing a Connection
|
||||||
|
|
||||||
Use Connect to establish a connection. It accepts a connection string in URL or DSN and will read the environment for
|
Use Connect to establish a connection. It accepts a connection string in URL or keyword/value format and will read the
|
||||||
libpq style environment variables.
|
environment for libpq style environment variables.
|
||||||
|
|
||||||
Executing a Query
|
Executing a Query
|
||||||
|
|
||||||
|
@ -211,10 +211,10 @@ func redactPW(connString string) string {
|
|||||||
return redactURL(u)
|
return redactURL(u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
quotedDSN := regexp.MustCompile(`password='[^']*'`)
|
quotedKV := regexp.MustCompile(`password='[^']*'`)
|
||||||
connString = quotedDSN.ReplaceAllLiteralString(connString, "password=xxxxx")
|
connString = quotedKV.ReplaceAllLiteralString(connString, "password=xxxxx")
|
||||||
plainDSN := regexp.MustCompile(`password=[^ ]*`)
|
plainKV := regexp.MustCompile(`password=[^ ]*`)
|
||||||
connString = plainDSN.ReplaceAllLiteralString(connString, "password=xxxxx")
|
connString = plainKV.ReplaceAllLiteralString(connString, "password=xxxxx")
|
||||||
brokenURL := regexp.MustCompile(`:[^:@]+?@`)
|
brokenURL := regexp.MustCompile(`:[^:@]+?@`)
|
||||||
connString = brokenURL.ReplaceAllLiteralString(connString, ":xxxxxx@")
|
connString = brokenURL.ReplaceAllLiteralString(connString, ":xxxxxx@")
|
||||||
return connString
|
return connString
|
||||||
|
@ -19,12 +19,12 @@ func TestConfigError(t *testing.T) {
|
|||||||
expectedMsg: "cannot parse `postgresql://foo:xxxxx@host`: msg",
|
expectedMsg: "cannot parse `postgresql://foo:xxxxx@host`: msg",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "dsn with password unquoted",
|
name: "keyword/value with password unquoted",
|
||||||
err: pgconn.NewParseConfigError("host=host password=password user=user", "msg", nil),
|
err: pgconn.NewParseConfigError("host=host password=password user=user", "msg", nil),
|
||||||
expectedMsg: "cannot parse `host=host password=xxxxx user=user`: msg",
|
expectedMsg: "cannot parse `host=host password=xxxxx user=user`: msg",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "dsn with password quoted",
|
name: "keyword/value with password quoted",
|
||||||
err: pgconn.NewParseConfigError("host=host password='pass word' user=user", "msg", nil),
|
err: pgconn.NewParseConfigError("host=host password='pass word' user=user", "msg", nil),
|
||||||
expectedMsg: "cannot parse `host=host password=xxxxx user=user`: msg",
|
expectedMsg: "cannot parse `host=host password=xxxxx user=user`: msg",
|
||||||
},
|
},
|
||||||
|
@ -105,8 +105,9 @@ type PgConn struct {
|
|||||||
cleanupDone chan struct{}
|
cleanupDone chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect establishes a connection to a PostgreSQL server using the environment and connString (in URL or DSN format)
|
// Connect establishes a connection to a PostgreSQL server using the environment and connString (in URL or keyword/value
|
||||||
// to provide configuration. See documentation for [ParseConfig] for details. ctx can be used to cancel a connect attempt.
|
// format) to provide configuration. See documentation for [ParseConfig] for details. ctx can be used to cancel a
|
||||||
|
// connect attempt.
|
||||||
func Connect(ctx context.Context, connString string) (*PgConn, error) {
|
func Connect(ctx context.Context, connString string) (*PgConn, error) {
|
||||||
config, err := ParseConfig(connString)
|
config, err := ParseConfig(connString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -116,9 +117,9 @@ func Connect(ctx context.Context, connString string) (*PgConn, error) {
|
|||||||
return ConnectConfig(ctx, config)
|
return ConnectConfig(ctx, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect establishes a connection to a PostgreSQL server using the environment and connString (in URL or DSN format)
|
// Connect establishes a connection to a PostgreSQL server using the environment and connString (in URL or keyword/value
|
||||||
// and ParseConfigOptions to provide additional configuration. See documentation for [ParseConfig] for details. ctx can be
|
// format) and ParseConfigOptions to provide additional configuration. See documentation for [ParseConfig] for details.
|
||||||
// used to cancel a connect attempt.
|
// ctx can be used to cancel a connect attempt.
|
||||||
func ConnectWithOptions(ctx context.Context, connString string, parseConfigOptions ParseConfigOptions) (*PgConn, error) {
|
func ConnectWithOptions(ctx context.Context, connString string, parseConfigOptions ParseConfigOptions) (*PgConn, error) {
|
||||||
config, err := ParseConfigWithOptions(connString, parseConfigOptions)
|
config, err := ParseConfigWithOptions(connString, parseConfigOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -8,7 +8,7 @@ The primary way of creating a pool is with [pgxpool.New]:
|
|||||||
|
|
||||||
pool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL"))
|
pool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL"))
|
||||||
|
|
||||||
The database connection string can be in URL or DSN format. PostgreSQL settings, pgx settings, and pool settings can be
|
The database connection string can be in URL or keyword/value format. PostgreSQL settings, pgx settings, and pool settings can be
|
||||||
specified here. In addition, a config struct can be created by [ParseConfig].
|
specified here. In addition, a config struct can be created by [ParseConfig].
|
||||||
|
|
||||||
config, err := pgxpool.ParseConfig(os.Getenv("DATABASE_URL"))
|
config, err := pgxpool.ParseConfig(os.Getenv("DATABASE_URL"))
|
||||||
|
@ -279,7 +279,7 @@ func NewWithConfig(ctx context.Context, config *Config) (*Pool, error) {
|
|||||||
//
|
//
|
||||||
// See Config for definitions of these arguments.
|
// See Config for definitions of these arguments.
|
||||||
//
|
//
|
||||||
// # Example DSN
|
// # Example Keyword/Value
|
||||||
// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca pool_max_conns=10
|
// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca pool_max_conns=10
|
||||||
//
|
//
|
||||||
// # Example URL
|
// # Example URL
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Or from a DSN string.
|
// Or from a keyword/value string.
|
||||||
//
|
//
|
||||||
// db, err := sql.Open("pgx", "user=postgres password=secret host=localhost port=5432 database=pgx_test sslmode=disable")
|
// db, err := sql.Open("pgx", "user=postgres password=secret host=localhost port=5432 database=pgx_test sslmode=disable")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user