aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/lib/pq
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/lib/pq')
-rwxr-xr-xvendor/github.com/lib/pq/.travis.sh12
-rw-r--r--vendor/github.com/lib/pq/.travis.yml16
-rw-r--r--vendor/github.com/lib/pq/README.md13
-rw-r--r--vendor/github.com/lib/pq/TESTS.md33
-rw-r--r--vendor/github.com/lib/pq/bench_test.go5
-rw-r--r--vendor/github.com/lib/pq/conn.go39
-rw-r--r--vendor/github.com/lib/pq/conn_go18.go5
-rw-r--r--vendor/github.com/lib/pq/conn_test.go67
-rw-r--r--vendor/github.com/lib/pq/connector.go43
-rw-r--r--vendor/github.com/lib/pq/connector_example_test.go33
-rw-r--r--vendor/github.com/lib/pq/connector_test.go67
-rw-r--r--vendor/github.com/lib/pq/copy_test.go15
-rw-r--r--vendor/github.com/lib/pq/encode_test.go27
-rw-r--r--vendor/github.com/lib/pq/error.go9
-rw-r--r--vendor/github.com/lib/pq/go18_test.go4
-rw-r--r--vendor/github.com/lib/pq/notify.go6
-rw-r--r--vendor/github.com/lib/pq/ssl.go57
17 files changed, 351 insertions, 100 deletions
diff --git a/vendor/github.com/lib/pq/.travis.sh b/vendor/github.com/lib/pq/.travis.sh
index ead01df..a297dc4 100755
--- a/vendor/github.com/lib/pq/.travis.sh
+++ b/vendor/github.com/lib/pq/.travis.sh
@@ -71,12 +71,6 @@ postgresql_uninstall() {
}
megacheck_install() {
- # Megacheck is Go 1.6+, so skip if Go 1.5.
- if [[ "$(go version)" =~ "go1.5" ]]
- then
- echo "megacheck not supported, skipping installation"
- return 0
- fi
# Lock megacheck version at $MEGACHECK_VERSION to prevent spontaneous
# new error messages in old code.
go get -d honnef.co/go/tools/...
@@ -86,12 +80,6 @@ megacheck_install() {
}
golint_install() {
- # Golint is Go 1.6+, so skip if Go 1.5.
- if [[ "$(go version)" =~ "go1.5" ]]
- then
- echo "golint not supported, skipping installation"
- return 0
- fi
go get github.com/golang/lint/golint
}
diff --git a/vendor/github.com/lib/pq/.travis.yml b/vendor/github.com/lib/pq/.travis.yml
index 4e34e88..18556e0 100644
--- a/vendor/github.com/lib/pq/.travis.yml
+++ b/vendor/github.com/lib/pq/.travis.yml
@@ -1,11 +1,9 @@
language: go
go:
- - 1.5.x
- - 1.6.x
- - 1.7.x
- 1.8.x
- 1.9.x
+ - 1.10.x
- master
sudo: true
@@ -16,7 +14,7 @@ env:
- PQGOSSLTESTS=1
- PQSSLCERTTEST_PATH=$PWD/certs
- PGHOST=127.0.0.1
- - MEGACHECK_VERSION=2017.2.1
+ - MEGACHECK_VERSION=2017.2.2
matrix:
- PGVERSION=10
- PGVERSION=9.6
@@ -46,13 +44,7 @@ script:
- >
goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
- go vet ./...
- # For compatibility with Go 1.5, launch only if megacheck is present.
- - >
- which megacheck > /dev/null && megacheck -go 1.5 ./...
- || echo 'megacheck is not supported, skipping check'
- # For compatibility with Go 1.5, launch only if golint is present.
- - >
- which golint > /dev/null && golint ./...
- || echo 'golint is not supported, skipping check'
+ - megacheck -go 1.8 ./...
+ - golint ./...
- PQTEST_BINARY_PARAMETERS=no go test -race -v ./...
- PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...
diff --git a/vendor/github.com/lib/pq/README.md b/vendor/github.com/lib/pq/README.md
index 781c89e..d71f3c2 100644
--- a/vendor/github.com/lib/pq/README.md
+++ b/vendor/github.com/lib/pq/README.md
@@ -14,18 +14,7 @@ documentation at <http://godoc.org/github.com/lib/pq>.
## Tests
-`go test` is used for testing. A running PostgreSQL server is
-required, with the ability to log in. The default database to connect
-to test with is "pqgotest," but it can be overridden using environment
-variables.
-
-Example:
-
- PGHOST=/run/postgresql go test github.com/lib/pq
-
-Optionally, a benchmark suite can be run as part of the tests:
-
- PGHOST=/run/postgresql go test -bench .
+`go test` is used for testing. See [TESTS.md](TESTS.md) for more details.
## Features
diff --git a/vendor/github.com/lib/pq/TESTS.md b/vendor/github.com/lib/pq/TESTS.md
new file mode 100644
index 0000000..f050211
--- /dev/null
+++ b/vendor/github.com/lib/pq/TESTS.md
@@ -0,0 +1,33 @@
+# Tests
+
+## Running Tests
+
+`go test` is used for testing. A running PostgreSQL
+server is required, with the ability to log in. The
+database to connect to test with is "pqgotest," on
+"localhost" but these can be overridden using [environment
+variables](https://www.postgresql.org/docs/9.3/static/libpq-envars.html).
+
+Example:
+
+ PGHOST=/run/postgresql go test
+
+## Benchmarks
+
+A benchmark suite can be run as part of the tests:
+
+ go test -bench .
+
+## Example setup (Docker)
+
+Run a postgres container:
+
+```
+docker run --expose 5432:5432 postgres
+```
+
+Run tests:
+
+```
+PGHOST=localhost PGPORT=5432 PGUSER=postgres PGSSLMODE=disable PGDATABASE=postgres go test
+```
diff --git a/vendor/github.com/lib/pq/bench_test.go b/vendor/github.com/lib/pq/bench_test.go
index e71f41d..33d7a02 100644
--- a/vendor/github.com/lib/pq/bench_test.go
+++ b/vendor/github.com/lib/pq/bench_test.go
@@ -5,6 +5,7 @@ package pq
import (
"bufio"
"bytes"
+ "context"
"database/sql"
"database/sql/driver"
"io"
@@ -156,7 +157,7 @@ func benchMockQuery(b *testing.B, c *conn, query string) {
b.Fatal(err)
}
defer stmt.Close()
- rows, err := stmt.Query(nil)
+ rows, err := stmt.(driver.StmtQueryContext).QueryContext(context.Background(), nil)
if err != nil {
b.Fatal(err)
}
@@ -266,7 +267,7 @@ func BenchmarkMockPreparedSelectSeries(b *testing.B) {
}
func benchPreparedMockQuery(b *testing.B, c *conn, stmt driver.Stmt) {
- rows, err := stmt.Query(nil)
+ rows, err := stmt.(driver.StmtQueryContext).QueryContext(context.Background(), nil)
if err != nil {
b.Fatal(err)
}
diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go
index fadb88e..43c8df2 100644
--- a/vendor/github.com/lib/pq/conn.go
+++ b/vendor/github.com/lib/pq/conn.go
@@ -339,7 +339,20 @@ func DialOpen(d Dialer, name string) (_ driver.Conn, err error) {
if err != nil {
return nil, err
}
- cn.ssl(o)
+
+ err = cn.ssl(o)
+ if err != nil {
+ return nil, err
+ }
+
+ // cn.startup panics on error. Make sure we don't leak cn.c.
+ panicking := true
+ defer func() {
+ if panicking {
+ cn.c.Close()
+ }
+ }()
+
cn.buf = bufio.NewReader(cn.c)
cn.startup(o)
@@ -347,6 +360,7 @@ func DialOpen(d Dialer, name string) (_ driver.Conn, err error) {
if timeout, ok := o["connect_timeout"]; ok && timeout != "0" {
err = cn.c.SetDeadline(time.Time{})
}
+ panicking = false
return cn, err
}
@@ -1019,30 +1033,35 @@ func (cn *conn) recv1() (t byte, r *readBuf) {
return t, r
}
-func (cn *conn) ssl(o values) {
- upgrade := ssl(o)
+func (cn *conn) ssl(o values) error {
+ upgrade, err := ssl(o)
+ if err != nil {
+ return err
+ }
+
if upgrade == nil {
// Nothing to do
- return
+ return nil
}
w := cn.writeBuf(0)
w.int32(80877103)
- if err := cn.sendStartupPacket(w); err != nil {
- panic(err)
+ if err = cn.sendStartupPacket(w); err != nil {
+ return err
}
b := cn.scratch[:1]
- _, err := io.ReadFull(cn.c, b)
+ _, err = io.ReadFull(cn.c, b)
if err != nil {
- panic(err)
+ return err
}
if b[0] != 'S' {
- panic(ErrSSLNotSupported)
+ return ErrSSLNotSupported
}
- cn.c = upgrade(cn.c)
+ cn.c, err = upgrade(cn.c)
+ return err
}
// isDriverSetting returns true iff a setting is purely for configuring the
diff --git a/vendor/github.com/lib/pq/conn_go18.go b/vendor/github.com/lib/pq/conn_go18.go
index ab97a10..a5254f2 100644
--- a/vendor/github.com/lib/pq/conn_go18.go
+++ b/vendor/github.com/lib/pq/conn_go18.go
@@ -108,7 +108,10 @@ func (cn *conn) cancel() error {
can := conn{
c: c,
}
- can.ssl(cn.opts)
+ err = can.ssl(cn.opts)
+ if err != nil {
+ return err
+ }
w := can.writeBuf(0)
w.int32(80877102) // cancel request code
diff --git a/vendor/github.com/lib/pq/conn_test.go b/vendor/github.com/lib/pq/conn_test.go
index 030a798..e654b85 100644
--- a/vendor/github.com/lib/pq/conn_test.go
+++ b/vendor/github.com/lib/pq/conn_test.go
@@ -1,6 +1,7 @@
package pq
import (
+ "context"
"database/sql"
"database/sql/driver"
"fmt"
@@ -28,7 +29,7 @@ func forceBinaryParameters() bool {
}
}
-func openTestConnConninfo(conninfo string) (*sql.DB, error) {
+func testConninfo(conninfo string) string {
defaultTo := func(envvar string, value string) {
if os.Getenv(envvar) == "" {
os.Setenv(envvar, value)
@@ -43,8 +44,11 @@ func openTestConnConninfo(conninfo string) (*sql.DB, error) {
!strings.HasPrefix(conninfo, "postgresql://") {
conninfo = conninfo + " binary_parameters=yes"
}
+ return conninfo
+}
- return sql.Open("postgres", conninfo)
+func openTestConnConninfo(conninfo string) (*sql.DB, error) {
+ return sql.Open("postgres", testConninfo(conninfo))
}
func openTestConn(t Fatalistic) *sql.DB {
@@ -637,6 +641,57 @@ func TestErrorDuringStartup(t *testing.T) {
}
}
+type testConn struct {
+ closed bool
+ net.Conn
+}
+
+func (c *testConn) Close() error {
+ c.closed = true
+ return c.Conn.Close()
+}
+
+type testDialer struct {
+ conns []*testConn
+}
+
+func (d *testDialer) Dial(ntw, addr string) (net.Conn, error) {
+ c, err := net.Dial(ntw, addr)
+ if err != nil {
+ return nil, err
+ }
+ tc := &testConn{Conn: c}
+ d.conns = append(d.conns, tc)
+ return tc, nil
+}
+
+func (d *testDialer) DialTimeout(ntw, addr string, timeout time.Duration) (net.Conn, error) {
+ c, err := net.DialTimeout(ntw, addr, timeout)
+ if err != nil {
+ return nil, err
+ }
+ tc := &testConn{Conn: c}
+ d.conns = append(d.conns, tc)
+ return tc, nil
+}
+
+func TestErrorDuringStartupClosesConn(t *testing.T) {
+ // Don't use the normal connection setup, this is intended to
+ // blow up in the startup packet from a non-existent user.
+ var d testDialer
+ c, err := DialOpen(&d, testConninfo("user=thisuserreallydoesntexist"))
+ if err == nil {
+ c.Close()
+ t.Fatal("expected dial error")
+ }
+ if len(d.conns) != 1 {
+ t.Fatalf("got len(d.conns) = %d, want = %d", len(d.conns), 1)
+ }
+ if !d.conns[0].closed {
+ t.Error("connection leaked")
+ }
+}
+
func TestBadConn(t *testing.T) {
var err error
@@ -1209,8 +1264,8 @@ func TestParseComplete(t *testing.T) {
// Test interface conformance.
var (
- _ driver.Execer = (*conn)(nil)
- _ driver.Queryer = (*conn)(nil)
+ _ driver.ExecerContext = (*conn)(nil)
+ _ driver.QueryerContext = (*conn)(nil)
)
func TestNullAfterNonNull(t *testing.T) {
@@ -1555,10 +1610,10 @@ func TestRowsResultTag(t *testing.T) {
t.Fatal(err)
}
defer conn.Close()
- q := conn.(driver.Queryer)
+ q := conn.(driver.QueryerContext)
for _, test := range tests {
- if rows, err := q.Query(test.query, nil); err != nil {
+ if rows, err := q.QueryContext(context.Background(), test.query, nil); err != nil {
t.Fatalf("%s: %s", test.query, err)
} else {
r := rows.(ResultTag)
diff --git a/vendor/github.com/lib/pq/connector.go b/vendor/github.com/lib/pq/connector.go
new file mode 100644
index 0000000..9e66eb5
--- /dev/null
+++ b/vendor/github.com/lib/pq/connector.go
@@ -0,0 +1,43 @@
+// +build go1.10
+
+package pq
+
+import (
+ "context"
+ "database/sql/driver"
+)
+
+// 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 {
+ name string
+}
+
+// Connect returns a connection to the database using the fixed configuration
+// of this Connector. Context is not used.
+func (c *connector) Connect(_ context.Context) (driver.Conn, error) {
+ return (&Driver{}).Open(c.name)
+}
+
+// Driver returnst the underlying driver of this Connector.
+func (c *connector) Driver() driver.Driver {
+ return &Driver{}
+}
+
+var _ driver.Connector = &connector{}
+
+// NewConnector returns a connector for the pq driver in a fixed configuration
+// with the given name. 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(name string) (driver.Connector, error) {
+ return &connector{name: name}, nil
+}
diff --git a/vendor/github.com/lib/pq/connector_example_test.go b/vendor/github.com/lib/pq/connector_example_test.go
new file mode 100644
index 0000000..5b66cf4
--- /dev/null
+++ b/vendor/github.com/lib/pq/connector_example_test.go
@@ -0,0 +1,33 @@
+// +build go1.10
+
+package pq_test
+
+import (
+ "database/sql"
+ "fmt"
+
+ "github.com/lib/pq"
+)
+
+func ExampleNewConnector() {
+ name := ""
+ connector, err := pq.NewConnector(name)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ db := sql.OpenDB(connector)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ defer db.Close()
+
+ // Use the DB
+ txn, err := db.Begin()
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ txn.Rollback()
+}
diff --git a/vendor/github.com/lib/pq/connector_test.go b/vendor/github.com/lib/pq/connector_test.go
new file mode 100644
index 0000000..3d2c67b
--- /dev/null
+++ b/vendor/github.com/lib/pq/connector_test.go
@@ -0,0 +1,67 @@
+// +build go1.10
+
+package pq
+
+import (
+ "context"
+ "database/sql"
+ "database/sql/driver"
+ "testing"
+)
+
+func TestNewConnector_WorksWithOpenDB(t *testing.T) {
+ name := ""
+ c, err := NewConnector(name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ db := sql.OpenDB(c)
+ defer db.Close()
+ // database/sql might not call our Open at all unless we do something with
+ // the connection
+ txn, err := db.Begin()
+ if err != nil {
+ t.Fatal(err)
+ }
+ txn.Rollback()
+}
+
+func TestNewConnector_Connect(t *testing.T) {
+ name := ""
+ c, err := NewConnector(name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ db, err := c.Connect(context.Background())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ // database/sql might not call our Open at all unless we do something with
+ // the connection
+ txn, err := db.(driver.ConnBeginTx).BeginTx(context.Background(), driver.TxOptions{})
+ if err != nil {
+ t.Fatal(err)
+ }
+ txn.Rollback()
+}
+
+func TestNewConnector_Driver(t *testing.T) {
+ name := ""
+ c, err := NewConnector(name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ db, err := c.Driver().Open(name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ // database/sql might not call our Open at all unless we do something with
+ // the connection
+ txn, err := db.(driver.ConnBeginTx).BeginTx(context.Background(), driver.TxOptions{})
+ if err != nil {
+ t.Fatal(err)
+ }
+ txn.Rollback()
+}
diff --git a/vendor/github.com/lib/pq/copy_test.go b/vendor/github.com/lib/pq/copy_test.go
index c1a3cd7..a888a89 100644
--- a/vendor/github.com/lib/pq/copy_test.go
+++ b/vendor/github.com/lib/pq/copy_test.go
@@ -4,6 +4,7 @@ import (
"bytes"
"database/sql"
"database/sql/driver"
+ "net"
"strings"
"testing"
)
@@ -400,15 +401,19 @@ func TestCopyRespLoopConnectionError(t *testing.T) {
if err == nil {
t.Fatalf("expected error")
}
- pge, ok := err.(*Error)
- if !ok {
+ switch pge := err.(type) {
+ case *Error:
+ if pge.Code.Name() != "admin_shutdown" {
+ t.Fatalf("expected admin_shutdown, got %s", pge.Code.Name())
+ }
+ case *net.OpError:
+ // ignore
+ default:
if err == driver.ErrBadConn {
// likely an EPIPE
} else {
- t.Fatalf("expected *pq.Error or driver.ErrBadConn, got %+#v", err)
+ t.Fatalf("unexpected error, got %+#v", err)
}
- } else if pge.Code.Name() != "admin_shutdown" {
- t.Fatalf("expected admin_shutdown, got %s", pge.Code.Name())
}
_ = stmt.Close()
diff --git a/vendor/github.com/lib/pq/encode_test.go b/vendor/github.com/lib/pq/encode_test.go
index 634a05c..d58798a 100644
--- a/vendor/github.com/lib/pq/encode_test.go
+++ b/vendor/github.com/lib/pq/encode_test.go
@@ -4,7 +4,7 @@ import (
"bytes"
"database/sql"
"fmt"
- "strings"
+ "regexp"
"testing"
"time"
@@ -304,24 +304,27 @@ func TestInfinityTimestamp(t *testing.T) {
var err error
var resultT time.Time
- expectedErrorStrPrefix := `sql: Scan error on column index 0: unsupported`
+ expectedErrorStrRegexp := regexp.MustCompile(
+ `^sql: Scan error on column index 0(, name "timestamp(tz)?"|): unsupported`)
+
type testCases []struct {
- Query string
- Param string
- ExpectedErrStrPrefix string
- ExpectedVal interface{}
+ Query string
+ Param string
+ ExpectedErrorStrRegexp *regexp.Regexp
+ ExpectedVal interface{}
}
tc := testCases{
- {"SELECT $1::timestamp", "-infinity", expectedErrorStrPrefix, "-infinity"},
- {"SELECT $1::timestamptz", "-infinity", expectedErrorStrPrefix, "-infinity"},
- {"SELECT $1::timestamp", "infinity", expectedErrorStrPrefix, "infinity"},
- {"SELECT $1::timestamptz", "infinity", expectedErrorStrPrefix, "infinity"},
+ {"SELECT $1::timestamp", "-infinity", expectedErrorStrRegexp, "-infinity"},
+ {"SELECT $1::timestamptz", "-infinity", expectedErrorStrRegexp, "-infinity"},
+ {"SELECT $1::timestamp", "infinity", expectedErrorStrRegexp, "infinity"},
+ {"SELECT $1::timestamptz", "infinity", expectedErrorStrRegexp, "infinity"},
}
// try to assert []byte to time.Time
for _, q := range tc {
err = db.QueryRow(q.Query, q.Param).Scan(&resultT)
- if !strings.HasPrefix(err.Error(), q.ExpectedErrStrPrefix) {
- t.Errorf("Scanning -/+infinity, expected error to have prefix %q, got %q", q.ExpectedErrStrPrefix, err)
+ if !q.ExpectedErrorStrRegexp.MatchString(err.Error()) {
+ t.Errorf("Scanning -/+infinity, expected error to match regexp %q, got %q",
+ q.ExpectedErrorStrRegexp, err)
}
}
// yield []byte
diff --git a/vendor/github.com/lib/pq/error.go b/vendor/github.com/lib/pq/error.go
index b4bb44c..96aae29 100644
--- a/vendor/github.com/lib/pq/error.go
+++ b/vendor/github.com/lib/pq/error.go
@@ -153,6 +153,7 @@ var errorCodeNames = map[ErrorCode]string{
"22004": "null_value_not_allowed",
"22002": "null_value_no_indicator_parameter",
"22003": "numeric_value_out_of_range",
+ "2200H": "sequence_generator_limit_exceeded",
"22026": "string_data_length_mismatch",
"22001": "string_data_right_truncation",
"22011": "substring_error",
@@ -459,6 +460,11 @@ func errorf(s string, args ...interface{}) {
panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)))
}
+// TODO(ainar-g) Rename to errorf after removing panics.
+func fmterrorf(s string, args ...interface{}) error {
+ return fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))
+}
+
func errRecoverNoErrBadConn(err *error) {
e := recover()
if e == nil {
@@ -487,7 +493,8 @@ func (c *conn) errRecover(err *error) {
*err = v
}
case *net.OpError:
- *err = driver.ErrBadConn
+ c.bad = true
+ *err = v
case error:
if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
*err = driver.ErrBadConn
diff --git a/vendor/github.com/lib/pq/go18_test.go b/vendor/github.com/lib/pq/go18_test.go
index 4bf6391..1a88a5b 100644
--- a/vendor/github.com/lib/pq/go18_test.go
+++ b/vendor/github.com/lib/pq/go18_test.go
@@ -228,7 +228,9 @@ func TestContextCancelBegin(t *testing.T) {
cancel()
if err != nil {
t.Fatal(err)
- } else if err := tx.Rollback(); err != nil && err != sql.ErrTxDone {
+ } else if err := tx.Rollback(); err != nil &&
+ err.Error() != "pq: canceling statement due to user request" &&
+ err != sql.ErrTxDone {
t.Fatal(err)
}
}()
diff --git a/vendor/github.com/lib/pq/notify.go b/vendor/github.com/lib/pq/notify.go
index 412c6ac..947d189 100644
--- a/vendor/github.com/lib/pq/notify.go
+++ b/vendor/github.com/lib/pq/notify.go
@@ -637,7 +637,7 @@ func (l *Listener) disconnectCleanup() error {
// after the connection has been established.
func (l *Listener) resync(cn *ListenerConn, notificationChan <-chan *Notification) error {
doneChan := make(chan error)
- go func() {
+ go func(notificationChan <-chan *Notification) {
for channel := range l.channels {
// If we got a response, return that error to our caller as it's
// going to be more descriptive than cn.Err().
@@ -658,7 +658,7 @@ func (l *Listener) resync(cn *ListenerConn, notificationChan <-chan *Notificatio
}
}
doneChan <- nil
- }()
+ }(notificationChan)
// Ignore notifications while synchronization is going on to avoid
// deadlocks. We have to send a nil notification over Notify anyway as
@@ -784,7 +784,7 @@ func (l *Listener) listenerConnLoop() {
}
l.emitEvent(ListenerEventDisconnected, err)
- time.Sleep(nextReconnect.Sub(time.Now()))
+ time.Sleep(time.Until(nextReconnect))
}
}
diff --git a/vendor/github.com/lib/pq/ssl.go b/vendor/github.com/lib/pq/ssl.go
index 7deb304..e1a326a 100644
--- a/vendor/github.com/lib/pq/ssl.go
+++ b/vendor/github.com/lib/pq/ssl.go
@@ -12,7 +12,7 @@ import (
// ssl generates a function to upgrade a net.Conn based on the "sslmode" and
// related settings. The function is nil when no upgrade should take place.
-func ssl(o values) func(net.Conn) net.Conn {
+func ssl(o values) (func(net.Conn) (net.Conn, error), error) {
verifyCaOnly := false
tlsConf := tls.Config{}
switch mode := o["sslmode"]; mode {
@@ -45,29 +45,38 @@ func ssl(o values) func(net.Conn) net.Conn {
case "verify-full":
tlsConf.ServerName = o["host"]
case "disable":
- return nil
+ return nil, nil
default:
- errorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode)
+ return nil, fmterrorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode)
}
- sslClientCertificates(&tlsConf, o)
- sslCertificateAuthority(&tlsConf, o)
+ err := sslClientCertificates(&tlsConf, o)
+ if err != nil {
+ return nil, err
+ }
+ err = sslCertificateAuthority(&tlsConf, o)
+ if err != nil {
+ return nil, err
+ }
sslRenegotiation(&tlsConf)
- return func(conn net.Conn) net.Conn {
+ return func(conn net.Conn) (net.Conn, error) {
client := tls.Client(conn, &tlsConf)
if verifyCaOnly {
- sslVerifyCertificateAuthority(client, &tlsConf)
+ err := sslVerifyCertificateAuthority(client, &tlsConf)
+ if err != nil {
+ return nil, err
+ }
}
- return client
- }
+ return client, nil
+ }, nil
}
// sslClientCertificates adds the certificate specified in the "sslcert" and
// "sslkey" settings, or if they aren't set, from the .postgresql directory
// in the user's home directory. The configured files must exist and have
// the correct permissions.
-func sslClientCertificates(tlsConf *tls.Config, o values) {
+func sslClientCertificates(tlsConf *tls.Config, o values) error {
// user.Current() might fail when cross-compiling. We have to ignore the
// error and continue without home directory defaults, since we wouldn't
// know from where to load them.
@@ -82,13 +91,13 @@ func sslClientCertificates(tlsConf *tls.Config, o values) {
}
// https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1045
if len(sslcert) == 0 {
- return
+ return nil
}
// https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1050:L1054
if _, err := os.Stat(sslcert); os.IsNotExist(err) {
- return
+ return nil
} else if err != nil {
- panic(err)
+ return err
}
// In libpq, the ssl key is only loaded if the setting is not blank.
@@ -101,19 +110,21 @@ func sslClientCertificates(tlsConf *tls.Config, o values) {
if len(sslkey) > 0 {
if err := sslKeyPermissions(sslkey); err != nil {
- panic(err)
+ return err
}
}
cert, err := tls.LoadX509KeyPair(sslcert, sslkey)
if err != nil {
- panic(err)
+ return err
}
+
tlsConf.Certificates = []tls.Certificate{cert}
+ return nil
}
// sslCertificateAuthority adds the RootCA specified in the "sslrootcert" setting.
-func sslCertificateAuthority(tlsConf *tls.Config, o values) {
+func sslCertificateAuthority(tlsConf *tls.Config, o values) error {
// In libpq, the root certificate is only loaded if the setting is not blank.
//
// https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L950-L951
@@ -122,22 +133,24 @@ func sslCertificateAuthority(tlsConf *tls.Config, o values) {
cert, err := ioutil.ReadFile(sslrootcert)
if err != nil {
- panic(err)
+ return err
}
if !tlsConf.RootCAs.AppendCertsFromPEM(cert) {
- errorf("couldn't parse pem in sslrootcert")
+ return fmterrorf("couldn't parse pem in sslrootcert")
}
}
+
+ return nil
}
// sslVerifyCertificateAuthority carries out a TLS handshake to the server and
// verifies the presented certificate against the CA, i.e. the one specified in
// sslrootcert or the system CA if sslrootcert was not specified.
-func sslVerifyCertificateAuthority(client *tls.Conn, tlsConf *tls.Config) {
+func sslVerifyCertificateAuthority(client *tls.Conn, tlsConf *tls.Config) error {
err := client.Handshake()
if err != nil {
- panic(err)
+ return err
}
certs := client.ConnectionState().PeerCertificates
opts := x509.VerifyOptions{
@@ -152,7 +165,5 @@ func sslVerifyCertificateAuthority(client *tls.Conn, tlsConf *tls.Config) {
opts.Intermediates.AddCert(cert)
}
_, err = certs[0].Verify(opts)
- if err != nil {
- panic(err)
- }
+ return err
}