ce5be947b4
Revert fixture fixes for postgres Use postgres connection string with spaces instead of url Fix label order Make postgres tests in ci less verbose Add sequence update script Skip resets in postgres Remove option to skip resets in postgres Make postgres tests in ci verboseq Update test fixtures database Fix file tests on postgres Add postgres options to sample config Make sure tests init test fixtures before running the actual tests Fix issues with IDs too big to fit in an int Fix duplicate auto incremented IDs Refactor / Fix team tests Refactor team member tests Fix team member create Fix label test Fix getting labels Fix test fixtures for postgresql Fix connection string params Disable ssl mode on postgres integration tests Disable ssl mode on postgres tests Use sprintf to create the connection string for postgresql fixup! Add postgres support Add postgres support Added generate as a make dependency for make build Clarify docs on building Co-authored-by: kolaente <k@knt.li> Co-authored-by: Jan Tojnar <jtojnar@gmail.com> Reviewed-on: https://kolaente.dev/vikunja/api/pulls/135
110 lines
3.3 KiB
Go
110 lines
3.3 KiB
Go
package pq
|
|
|
|
import (
|
|
"context"
|
|
"database/sql/driver"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// Connector represents a fixed configuration for the pq driver with a given
|
|
// name. Connector satisfies the database/sql/driver Connector interface and
|
|
// can be used to create any number of DB Conn's via the database/sql OpenDB
|
|
// function.
|
|
//
|
|
// See https://golang.org/pkg/database/sql/driver/#Connector.
|
|
// See https://golang.org/pkg/database/sql/#OpenDB.
|
|
type Connector struct {
|
|
opts values
|
|
dialer Dialer
|
|
}
|
|
|
|
// Connect returns a connection to the database using the fixed configuration
|
|
// of this Connector. Context is not used.
|
|
func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
|
|
return c.open(ctx)
|
|
}
|
|
|
|
// Driver returnst the underlying driver of this Connector.
|
|
func (c *Connector) Driver() driver.Driver {
|
|
return &Driver{}
|
|
}
|
|
|
|
// NewConnector returns a connector for the pq driver in a fixed configuration
|
|
// with the given dsn. The returned connector can be used to create any number
|
|
// of equivalent Conn's. The returned connector is intended to be used with
|
|
// database/sql.OpenDB.
|
|
//
|
|
// See https://golang.org/pkg/database/sql/driver/#Connector.
|
|
// See https://golang.org/pkg/database/sql/#OpenDB.
|
|
func NewConnector(dsn string) (*Connector, error) {
|
|
var err error
|
|
o := make(values)
|
|
|
|
// A number of defaults are applied here, in this order:
|
|
//
|
|
// * Very low precedence defaults applied in every situation
|
|
// * Environment variables
|
|
// * Explicitly passed connection information
|
|
o["host"] = "localhost"
|
|
o["port"] = "5432"
|
|
// N.B.: Extra float digits should be set to 3, but that breaks
|
|
// Postgres 8.4 and older, where the max is 2.
|
|
o["extra_float_digits"] = "2"
|
|
for k, v := range parseEnviron(os.Environ()) {
|
|
o[k] = v
|
|
}
|
|
|
|
if strings.HasPrefix(dsn, "postgres://") || strings.HasPrefix(dsn, "postgresql://") {
|
|
dsn, err = ParseURL(dsn)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if err := parseOpts(dsn, o); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Use the "fallback" application name if necessary
|
|
if fallback, ok := o["fallback_application_name"]; ok {
|
|
if _, ok := o["application_name"]; !ok {
|
|
o["application_name"] = fallback
|
|
}
|
|
}
|
|
|
|
// We can't work with any client_encoding other than UTF-8 currently.
|
|
// However, we have historically allowed the user to set it to UTF-8
|
|
// explicitly, and there's no reason to break such programs, so allow that.
|
|
// Note that the "options" setting could also set client_encoding, but
|
|
// parsing its value is not worth it. Instead, we always explicitly send
|
|
// client_encoding as a separate run-time parameter, which should override
|
|
// anything set in options.
|
|
if enc, ok := o["client_encoding"]; ok && !isUTF8(enc) {
|
|
return nil, errors.New("client_encoding must be absent or 'UTF8'")
|
|
}
|
|
o["client_encoding"] = "UTF8"
|
|
// DateStyle needs a similar treatment.
|
|
if datestyle, ok := o["datestyle"]; ok {
|
|
if datestyle != "ISO, MDY" {
|
|
return nil, fmt.Errorf("setting datestyle must be absent or %v; got %v", "ISO, MDY", datestyle)
|
|
}
|
|
} else {
|
|
o["datestyle"] = "ISO, MDY"
|
|
}
|
|
|
|
// If a user is not provided by any other means, the last
|
|
// resort is to use the current operating system provided user
|
|
// name.
|
|
if _, ok := o["user"]; !ok {
|
|
u, err := userCurrent()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
o["user"] = u
|
|
}
|
|
|
|
return &Connector{opts: o, dialer: defaultDialer{}}, nil
|
|
}
|