pq -> v1.7.0 (#11905)

Co-authored-by: Lauris BH <lauris@nix.lv>
release/v1.15
techknowlogick 2020-06-16 07:57:38 -04:00 committed by GitHub
parent 80a3745fc8
commit 6a4de37f7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 310 additions and 120 deletions

2
go.mod
View File

@ -61,7 +61,7 @@ require (
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
github.com/klauspost/compress v1.10.2 github.com/klauspost/compress v1.10.2
github.com/lafriks/xormstore v1.3.2 github.com/lafriks/xormstore v1.3.2
github.com/lib/pq v1.2.0 github.com/lib/pq v1.7.0
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
github.com/mailru/easyjson v0.7.0 // indirect github.com/mailru/easyjson v0.7.0 // indirect
github.com/markbates/goth v1.61.2 github.com/markbates/goth v1.61.2

2
go.sum
View File

@ -437,6 +437,8 @@ github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/Y
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY= github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY=
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:mmIfjCSQlGYXmJ95jFN84AkQFnVABtKuJL8IrzwvUKQ= github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:mmIfjCSQlGYXmJ95jFN84AkQFnVABtKuJL8IrzwvUKQ=
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk= github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=

View File

@ -1,8 +1,8 @@
language: go language: go
go: go:
- 1.11.x - 1.13.x
- 1.12.x - 1.14.x
- master - master
sudo: true sudo: true
@ -27,7 +27,7 @@ before_install:
- ./.travis.sh client_configure - ./.travis.sh client_configure
- go get golang.org/x/tools/cmd/goimports - go get golang.org/x/tools/cmd/goimports
- go get golang.org/x/lint/golint - go get golang.org/x/lint/golint
- GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@2019.2.1 - GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@2020.1.3
before_script: before_script:
- createdb pqgotest - createdb pqgotest
@ -38,7 +38,7 @@ script:
- > - >
goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }' goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
- go vet ./... - go vet ./...
- staticcheck -go 1.11 ./... - staticcheck -go 1.13 ./...
- golint ./... - golint ./...
- PQTEST_BINARY_PARAMETERS=no go test -race -v ./... - PQTEST_BINARY_PARAMETERS=no go test -race -v ./...
- PQTEST_BINARY_PARAMETERS=yes go test -race -v ./... - PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...

View File

@ -1,29 +0,0 @@
## Contributing to pq
`pq` has a backlog of pull requests, but contributions are still very
much welcome. You can help with patch review, submitting bug reports,
or adding new functionality. There is no formal style guide, but
please conform to the style of existing code and general Go formatting
conventions when submitting patches.
### Patch review
Help review existing open pull requests by commenting on the code or
proposed functionality.
### Bug reports
We appreciate any bug reports, but especially ones with self-contained
(doesn't depend on code outside of pq), minimal (can't be simplified
further) test cases. It's especially helpful if you can submit a pull
request with just the failing test case (you'll probably want to
pattern it after the tests in
[conn_test.go](https://github.com/lib/pq/blob/master/conn_test.go).
### New functionality
There are a number of pending patches for new functionality, so
additional feature patches will take a while to merge. Still, patches
are generally reviewed based on usefulness and complexity in addition
to time-in-queue, so if you have a knockout idea, take a shot. Feel
free to open an issue discussion your proposed patch beforehand.

78
vendor/github.com/lib/pq/README.md generated vendored
View File

@ -1,21 +1,11 @@
# pq - A pure Go postgres driver for Go's database/sql package # pq - A pure Go postgres driver for Go's database/sql package
[![GoDoc](https://godoc.org/github.com/lib/pq?status.svg)](https://godoc.org/github.com/lib/pq) [![GoDoc](https://godoc.org/github.com/lib/pq?status.svg)](https://pkg.go.dev/github.com/lib/pq?tab=doc)
[![Build Status](https://travis-ci.org/lib/pq.svg?branch=master)](https://travis-ci.org/lib/pq)
## Install ## Install
go get github.com/lib/pq go get github.com/lib/pq
## Docs
For detailed documentation and basic usage examples, please see the package
documentation at <https://godoc.org/github.com/lib/pq>.
## Tests
`go test` is used for testing. See [TESTS.md](TESTS.md) for more details.
## Features ## Features
* SSL * SSL
@ -30,66 +20,14 @@ documentation at <https://godoc.org/github.com/lib/pq>.
* Notifications: `LISTEN`/`NOTIFY` * Notifications: `LISTEN`/`NOTIFY`
* pgpass support * pgpass support
## Future / Things you can help with ## Optional Features
* Better COPY FROM / COPY TO (see discussion in #181) * GSS (Kerberos) auth (to use, see GoDoc)
## Thank you (alphabetical) ## Tests
Some of these contributors are from the original library `bmizerany/pq.go` whose `go test` is used for testing. See [TESTS.md](TESTS.md) for more details.
code still exists in here.
* Andy Balholm (andybalholm) ## Status
* Ben Berkert (benburkert)
* Benjamin Heatwole (bheatwole) This package is effectively in maintenance mode and is not actively developed. Small patches and features are only rarely reviewed and merged. We recommend using [pgx](https://github.com/jackc/pgx) which is actively maintained.
* Bill Mill (llimllib)
* Bjørn Madsen (aeons)
* Blake Gentry (bgentry)
* Brad Fitzpatrick (bradfitz)
* Charlie Melbye (cmelbye)
* Chris Bandy (cbandy)
* Chris Gilling (cgilling)
* Chris Walsh (cwds)
* Dan Sosedoff (sosedoff)
* Daniel Farina (fdr)
* Eric Chlebek (echlebek)
* Eric Garrido (minusnine)
* Eric Urban (hydrogen18)
* Everyone at The Go Team
* Evan Shaw (edsrzf)
* Ewan Chou (coocood)
* Fazal Majid (fazalmajid)
* Federico Romero (federomero)
* Fumin (fumin)
* Gary Burd (garyburd)
* Heroku (heroku)
* James Pozdena (jpoz)
* Jason McVetta (jmcvetta)
* Jeremy Jay (pbnjay)
* Joakim Sernbrant (serbaut)
* John Gallagher (jgallagher)
* Jonathan Rudenberg (titanous)
* Joël Stemmer (jstemmer)
* Kamil Kisiel (kisielk)
* Kelly Dunn (kellydunn)
* Keith Rarick (kr)
* Kir Shatrov (kirs)
* Lann Martin (lann)
* Maciek Sakrejda (uhoh-itsmaciek)
* Marc Brinkmann (mbr)
* Marko Tiikkaja (johto)
* Matt Newberry (MattNewberry)
* Matt Robenolt (mattrobenolt)
* Martin Olsen (martinolsen)
* Mike Lewis (mikelikespie)
* Nicolas Patry (Narsil)
* Oliver Tonnhofer (olt)
* Patrick Hayes (phayes)
* Paul Hammond (paulhammond)
* Ryan Smith (ryandotsmith)
* Samuel Stauffer (samuel)
* Timothée Peignier (cyberdelia)
* Travis Cline (tmc)
* TruongSinh Tran-Nguyen (truongsinh)
* Yaismel Miranda (ympons)
* notedit (notedit)

89
vendor/github.com/lib/pq/conn.go generated vendored
View File

@ -149,6 +149,15 @@ type conn struct {
// If true this connection is in the middle of a COPY // If true this connection is in the middle of a COPY
inCopy bool inCopy bool
// If not nil, notices will be synchronously sent here
noticeHandler func(*Error)
// If not nil, notifications will be synchronously sent here
notificationHandler func(*Notification)
// GSSAPI context
gss GSS
} }
// Handle driver-side settings in parsed connection string. // Handle driver-side settings in parsed connection string.
@ -329,10 +338,6 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) {
func dial(ctx context.Context, d Dialer, o values) (net.Conn, error) { func dial(ctx context.Context, d Dialer, o values) (net.Conn, error) {
network, address := network(o) network, address := network(o)
// SSL is not necessary or supported over UNIX domain sockets
if network == "unix" {
o["sslmode"] = "disable"
}
// Zero or not specified means wait indefinitely. // Zero or not specified means wait indefinitely.
if timeout, ok := o["connect_timeout"]; ok && timeout != "0" { if timeout, ok := o["connect_timeout"]; ok && timeout != "0" {
@ -971,7 +976,13 @@ func (cn *conn) recv() (t byte, r *readBuf) {
case 'E': case 'E':
panic(parseError(r)) panic(parseError(r))
case 'N': case 'N':
// ignore if n := cn.noticeHandler; n != nil {
n(parseError(r))
}
case 'A':
if n := cn.notificationHandler; n != nil {
n(recvNotification(r))
}
default: default:
return return
} }
@ -988,8 +999,14 @@ func (cn *conn) recv1Buf(r *readBuf) byte {
} }
switch t { switch t {
case 'A', 'N': case 'A':
// ignore if n := cn.notificationHandler; n != nil {
n(recvNotification(r))
}
case 'N':
if n := cn.noticeHandler; n != nil {
n(parseError(r))
}
case 'S': case 'S':
cn.processParameterStatus(r) cn.processParameterStatus(r)
default: default:
@ -1057,7 +1074,10 @@ func isDriverSetting(key string) bool {
return true return true
case "binary_parameters": case "binary_parameters":
return true return true
case "service":
return true
case "spn":
return true
default: default:
return false return false
} }
@ -1137,6 +1157,59 @@ func (cn *conn) auth(r *readBuf, o values) {
if r.int32() != 0 { if r.int32() != 0 {
errorf("unexpected authentication response: %q", t) errorf("unexpected authentication response: %q", t)
} }
case 7: // GSSAPI, startup
if newGss == nil {
errorf("kerberos error: no GSSAPI provider registered (import github.com/lib/pq/auth/kerberos if you need Kerberos support)")
}
cli, err := newGss()
if err != nil {
errorf("kerberos error: %s", err.Error())
}
var token []byte
if spn, ok := o["spn"]; ok {
// Use the supplied SPN if provided..
token, err = cli.GetInitTokenFromSpn(spn)
} else {
// Allow the kerberos service name to be overridden
service := "postgres"
if val, ok := o["service"]; ok {
service = val
}
token, err = cli.GetInitToken(o["host"], service)
}
if err != nil {
errorf("failed to get Kerberos ticket: %q", err)
}
w := cn.writeBuf('p')
w.bytes(token)
cn.send(w)
// Store for GSSAPI continue message
cn.gss = cli
case 8: // GSSAPI continue
if cn.gss == nil {
errorf("GSSAPI protocol error")
}
b := []byte(*r)
done, tokOut, err := cn.gss.Continue(b)
if err == nil && !done {
w := cn.writeBuf('p')
w.bytes(tokOut)
cn.send(w)
}
// Errors fall through and read the more detailed message
// from the server..
case 10: case 10:
sc := scram.NewClient(sha256.New, o["user"], o["password"]) sc := scram.NewClient(sha256.New, o["user"], o["password"])
sc.Step(nil) sc.Step(nil)

View File

@ -79,7 +79,7 @@ func (cn *conn) Ping(ctx context.Context) error {
if finish := cn.watchCancel(ctx); finish != nil { if finish := cn.watchCancel(ctx); finish != nil {
defer finish() defer finish()
} }
rows, err := cn.simpleQuery("SELECT 'lib/pq ping test';") rows, err := cn.simpleQuery(";")
if err != nil { if err != nil {
return driver.ErrBadConn // https://golang.org/pkg/database/sql/driver/#Pinger return driver.ErrBadConn // https://golang.org/pkg/database/sql/driver/#Pinger
} }

View File

@ -106,5 +106,10 @@ func NewConnector(dsn string) (*Connector, error) {
o["user"] = u o["user"] = u
} }
// SSL is not necessary or supported over UNIX domain sockets
if network, _ := network(o); network == "unix" {
o["sslmode"] = "disable"
}
return &Connector{opts: o, dialer: defaultDialer{}}, nil return &Connector{opts: o, dialer: defaultDialer{}}, nil
} }

6
vendor/github.com/lib/pq/copy.go generated vendored
View File

@ -152,7 +152,9 @@ func (ci *copyin) resploop() {
case 'C': case 'C':
// complete // complete
case 'N': case 'N':
// NoticeResponse if n := ci.cn.noticeHandler; n != nil {
n(parseError(&r))
}
case 'Z': case 'Z':
ci.cn.processReadyForQuery(&r) ci.cn.processReadyForQuery(&r)
ci.done <- true ci.done <- true
@ -229,7 +231,7 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
} }
if len(v) == 0 { if len(v) == 0 {
return nil, ci.Close() return driver.RowsAffected(0), ci.Close()
} }
numValues := len(v) numValues := len(v)

18
vendor/github.com/lib/pq/doc.go generated vendored
View File

@ -57,6 +57,8 @@ supported:
* sslkey - Key file location. The file must contain PEM encoded data. * sslkey - Key file location. The file must contain PEM encoded data.
* sslrootcert - The location of the root certificate file. The file * sslrootcert - The location of the root certificate file. The file
must contain PEM encoded data. must contain PEM encoded data.
* spn - Configures GSS (Kerberos) SPN.
* service - GSS (Kerberos) service name to use when constructing the SPN (default is `postgres`).
Valid values for sslmode are: Valid values for sslmode are:
@ -241,5 +243,21 @@ bytes by the PostgreSQL server.
You can find a complete, working example of Listener usage at You can find a complete, working example of Listener usage at
https://godoc.org/github.com/lib/pq/example/listen. https://godoc.org/github.com/lib/pq/example/listen.
Kerberos Support
If you need support for Kerberos authentication, add the following to your main
package:
import "github.com/lib/pq/auth/kerberos"
func init() {
pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() })
}
This package is in a separate module so that users who don't need Kerberos
don't have to download unnecessary dependencies.
*/ */
package pq package pq

22
vendor/github.com/lib/pq/encode.go generated vendored
View File

@ -8,6 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math" "math"
"regexp"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -16,6 +17,8 @@ import (
"github.com/lib/pq/oid" "github.com/lib/pq/oid"
) )
var time2400Regex = regexp.MustCompile(`^(24:00(?::00(?:\.0+)?)?)(?:[Z+-].*)?$`)
func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte { func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte {
switch v := x.(type) { switch v := x.(type) {
case []byte: case []byte:
@ -202,10 +205,27 @@ func mustParse(f string, typ oid.Oid, s []byte) time.Time {
str[len(str)-3] == ':' { str[len(str)-3] == ':' {
f += ":00" f += ":00"
} }
// Special case for 24:00 time.
// Unfortunately, golang does not parse 24:00 as a proper time.
// In this case, we want to try "round to the next day", to differentiate.
// As such, we find if the 24:00 time matches at the beginning; if so,
// we default it back to 00:00 but add a day later.
var is2400Time bool
switch typ {
case oid.T_timetz, oid.T_time:
if matches := time2400Regex.FindStringSubmatch(str); matches != nil {
// Concatenate timezone information at the back.
str = "00:00:00" + str[len(matches[1]):]
is2400Time = true
}
}
t, err := time.Parse(f, str) t, err := time.Parse(f, str)
if err != nil { if err != nil {
errorf("decode: %s", err) errorf("decode: %s", err)
} }
if is2400Time {
t = t.Add(24 * time.Hour)
}
return t return t
} }
@ -487,7 +507,7 @@ func FormatTimestamp(t time.Time) []byte {
b := []byte(t.Format("2006-01-02 15:04:05.999999999Z07:00")) b := []byte(t.Format("2006-01-02 15:04:05.999999999Z07:00"))
_, offset := t.Zone() _, offset := t.Zone()
offset = offset % 60 offset %= 60
if offset != 0 { if offset != 0 {
// RFC3339Nano already printed the minus sign // RFC3339Nano already printed the minus sign
if offset < 0 { if offset < 0 {

2
vendor/github.com/lib/pq/go.mod generated vendored
View File

@ -1 +1,3 @@
module github.com/lib/pq module github.com/lib/pq
go 1.13

27
vendor/github.com/lib/pq/krb.go generated vendored Normal file
View File

@ -0,0 +1,27 @@
package pq
// NewGSSFunc creates a GSS authentication provider, for use with
// RegisterGSSProvider.
type NewGSSFunc func() (GSS, error)
var newGss NewGSSFunc
// RegisterGSSProvider registers a GSS authentication provider. For example, if
// you need to use Kerberos to authenticate with your server, add this to your
// main package:
//
// import "github.com/lib/pq/auth/kerberos"
//
// func init() {
// pq.RegisterGSSProvider(func() (pq.GSS, error) { return kerberos.NewGSS() })
// }
func RegisterGSSProvider(newGssArg NewGSSFunc) {
newGss = newGssArg
}
// GSS provides GSSAPI authentication (e.g., Kerberos).
type GSS interface {
GetInitToken(host string, service string) ([]byte, error)
GetInitTokenFromSpn(spn string) ([]byte, error)
Continue(inToken []byte) (done bool, outToken []byte, err error)
}

71
vendor/github.com/lib/pq/notice.go generated vendored Normal file
View File

@ -0,0 +1,71 @@
// +build go1.10
package pq
import (
"context"
"database/sql/driver"
)
// NoticeHandler returns the notice handler on the given connection, if any. A
// runtime panic occurs if c is not a pq connection. This is rarely used
// directly, use ConnectorNoticeHandler and ConnectorWithNoticeHandler instead.
func NoticeHandler(c driver.Conn) func(*Error) {
return c.(*conn).noticeHandler
}
// SetNoticeHandler sets the given notice handler on the given connection. A
// runtime panic occurs if c is not a pq connection. A nil handler may be used
// to unset it. This is rarely used directly, use ConnectorNoticeHandler and
// ConnectorWithNoticeHandler instead.
//
// Note: Notice handlers are executed synchronously by pq meaning commands
// won't continue to be processed until the handler returns.
func SetNoticeHandler(c driver.Conn, handler func(*Error)) {
c.(*conn).noticeHandler = handler
}
// NoticeHandlerConnector wraps a regular connector and sets a notice handler
// on it.
type NoticeHandlerConnector struct {
driver.Connector
noticeHandler func(*Error)
}
// Connect calls the underlying connector's connect method and then sets the
// notice handler.
func (n *NoticeHandlerConnector) Connect(ctx context.Context) (driver.Conn, error) {
c, err := n.Connector.Connect(ctx)
if err == nil {
SetNoticeHandler(c, n.noticeHandler)
}
return c, err
}
// ConnectorNoticeHandler returns the currently set notice handler, if any. If
// the given connector is not a result of ConnectorWithNoticeHandler, nil is
// returned.
func ConnectorNoticeHandler(c driver.Connector) func(*Error) {
if c, ok := c.(*NoticeHandlerConnector); ok {
return c.noticeHandler
}
return nil
}
// ConnectorWithNoticeHandler creates or sets the given handler for the given
// connector. If the given connector is a result of calling this function
// previously, it is simply set on the given connector and returned. Otherwise,
// this returns a new connector wrapping the given one and setting the notice
// handler. A nil notice handler may be used to unset it.
//
// The returned connector is intended to be used with database/sql.OpenDB.
//
// Note: Notice handlers are executed synchronously by pq meaning commands
// won't continue to be processed until the handler returns.
func ConnectorWithNoticeHandler(c driver.Connector, handler func(*Error)) *NoticeHandlerConnector {
if c, ok := c.(*NoticeHandlerConnector); ok {
c.noticeHandler = handler
return c
}
return &NoticeHandlerConnector{Connector: c, noticeHandler: handler}
}

63
vendor/github.com/lib/pq/notify.go generated vendored
View File

@ -4,6 +4,8 @@ package pq
// This module contains support for Postgres LISTEN/NOTIFY. // This module contains support for Postgres LISTEN/NOTIFY.
import ( import (
"context"
"database/sql/driver"
"errors" "errors"
"fmt" "fmt"
"sync" "sync"
@ -29,6 +31,61 @@ func recvNotification(r *readBuf) *Notification {
return &Notification{bePid, channel, extra} return &Notification{bePid, channel, extra}
} }
// SetNotificationHandler sets the given notification handler on the given
// connection. A runtime panic occurs if c is not a pq connection. A nil handler
// may be used to unset it.
//
// Note: Notification handlers are executed synchronously by pq meaning commands
// won't continue to be processed until the handler returns.
func SetNotificationHandler(c driver.Conn, handler func(*Notification)) {
c.(*conn).notificationHandler = handler
}
// NotificationHandlerConnector wraps a regular connector and sets a notification handler
// on it.
type NotificationHandlerConnector struct {
driver.Connector
notificationHandler func(*Notification)
}
// Connect calls the underlying connector's connect method and then sets the
// notification handler.
func (n *NotificationHandlerConnector) Connect(ctx context.Context) (driver.Conn, error) {
c, err := n.Connector.Connect(ctx)
if err == nil {
SetNotificationHandler(c, n.notificationHandler)
}
return c, err
}
// ConnectorNotificationHandler returns the currently set notification handler, if any. If
// the given connector is not a result of ConnectorWithNotificationHandler, nil is
// returned.
func ConnectorNotificationHandler(c driver.Connector) func(*Notification) {
if c, ok := c.(*NotificationHandlerConnector); ok {
return c.notificationHandler
}
return nil
}
// ConnectorWithNotificationHandler creates or sets the given handler for the given
// connector. If the given connector is a result of calling this function
// previously, it is simply set on the given connector and returned. Otherwise,
// this returns a new connector wrapping the given one and setting the notification
// handler. A nil notification handler may be used to unset it.
//
// The returned connector is intended to be used with database/sql.OpenDB.
//
// Note: Notification handlers are executed synchronously by pq meaning commands
// won't continue to be processed until the handler returns.
func ConnectorWithNotificationHandler(c driver.Connector, handler func(*Notification)) *NotificationHandlerConnector {
if c, ok := c.(*NotificationHandlerConnector); ok {
c.notificationHandler = handler
return c
}
return &NotificationHandlerConnector{Connector: c, notificationHandler: handler}
}
const ( const (
connStateIdle int32 = iota connStateIdle int32 = iota
connStateExpectResponse connStateExpectResponse
@ -174,8 +231,12 @@ func (l *ListenerConn) listenerConnLoop() (err error) {
} }
l.replyChan <- message{t, nil} l.replyChan <- message{t, nil}
case 'N', 'S': case 'S':
// ignore // ignore
case 'N':
if n := l.cn.noticeHandler; n != nil {
n(parseError(r))
}
default: default:
return fmt.Errorf("unexpected message %q from server in listenerConnLoop", t) return fmt.Errorf("unexpected message %q from server in listenerConnLoop", t)
} }

View File

@ -94,7 +94,7 @@ func (c *Client) Out() []byte {
return c.out.Bytes() return c.out.Bytes()
} }
// Err returns the error that ocurred, or nil if there were no errors. // Err returns the error that occurred, or nil if there were no errors.
func (c *Client) Err() error { func (c *Client) Err() error {
return c.err return c.err
} }

View File

@ -1,6 +1,6 @@
// Package pq is a pure Go Postgres driver for the database/sql package. // Package pq is a pure Go Postgres driver for the database/sql package.
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris rumprun // +build aix darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris rumprun
package pq package pq

2
vendor/modules.txt vendored
View File

@ -451,7 +451,7 @@ github.com/kr/text
## explicit ## explicit
github.com/lafriks/xormstore github.com/lafriks/xormstore
github.com/lafriks/xormstore/util github.com/lafriks/xormstore/util
# github.com/lib/pq v1.2.0 # github.com/lib/pq v1.7.0
## explicit ## explicit
github.com/lib/pq github.com/lib/pq
github.com/lib/pq/oid github.com/lib/pq/oid