Update dependencies (#5518)
This commit is contained in:
110
vendor/github.com/lib/pq/conn_go18.go
generated
vendored
110
vendor/github.com/lib/pq/conn_go18.go
generated
vendored
@@ -10,6 +10,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
watchCancelDialContextTimeout = time.Second * 10
|
||||
)
|
||||
|
||||
// Implement the "QueryerContext" interface
|
||||
func (cn *conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
|
||||
list := make([]driver.Value, len(args))
|
||||
@@ -42,6 +46,14 @@ func (cn *conn) ExecContext(ctx context.Context, query string, args []driver.Nam
|
||||
return cn.Exec(query, list)
|
||||
}
|
||||
|
||||
// Implement the "ConnPrepareContext" interface
|
||||
func (cn *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
|
||||
if finish := cn.watchCancel(ctx); finish != nil {
|
||||
defer finish()
|
||||
}
|
||||
return cn.Prepare(query)
|
||||
}
|
||||
|
||||
// Implement the "ConnBeginTx" interface
|
||||
func (cn *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||
var mode string
|
||||
@@ -79,7 +91,7 @@ func (cn *conn) Ping(ctx context.Context) error {
|
||||
if finish := cn.watchCancel(ctx); finish != nil {
|
||||
defer finish()
|
||||
}
|
||||
rows, err := cn.simpleQuery("SELECT 'lib/pq ping test';")
|
||||
rows, err := cn.simpleQuery(";")
|
||||
if err != nil {
|
||||
return driver.ErrBadConn // https://golang.org/pkg/database/sql/driver/#Pinger
|
||||
}
|
||||
@@ -89,25 +101,37 @@ func (cn *conn) Ping(ctx context.Context) error {
|
||||
|
||||
func (cn *conn) watchCancel(ctx context.Context) func() {
|
||||
if done := ctx.Done(); done != nil {
|
||||
finished := make(chan struct{})
|
||||
finished := make(chan struct{}, 1)
|
||||
go func() {
|
||||
select {
|
||||
case <-done:
|
||||
select {
|
||||
case finished <- struct{}{}:
|
||||
default:
|
||||
// We raced with the finish func, let the next query handle this with the
|
||||
// context.
|
||||
return
|
||||
}
|
||||
|
||||
// Set the connection state to bad so it does not get reused.
|
||||
cn.err.set(ctx.Err())
|
||||
|
||||
// At this point the function level context is canceled,
|
||||
// so it must not be used for the additional network
|
||||
// request to cancel the query.
|
||||
// Create a new context to pass into the dial.
|
||||
ctxCancel, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
ctxCancel, cancel := context.WithTimeout(context.Background(), watchCancelDialContextTimeout)
|
||||
defer cancel()
|
||||
|
||||
_ = cn.cancel(ctxCancel)
|
||||
finished <- struct{}{}
|
||||
case <-finished:
|
||||
}
|
||||
}()
|
||||
return func() {
|
||||
select {
|
||||
case <-finished:
|
||||
cn.err.set(ctx.Err())
|
||||
cn.Close()
|
||||
case finished <- struct{}{}:
|
||||
}
|
||||
}
|
||||
@@ -116,7 +140,16 @@ func (cn *conn) watchCancel(ctx context.Context) func() {
|
||||
}
|
||||
|
||||
func (cn *conn) cancel(ctx context.Context) error {
|
||||
c, err := dial(ctx, cn.dialer, cn.opts)
|
||||
// Create a new values map (copy). This makes sure the connection created
|
||||
// in this method cannot write to the same underlying data, which could
|
||||
// cause a concurrent map write panic. This is necessary because cancel
|
||||
// is called from a goroutine in watchCancel.
|
||||
o := make(values)
|
||||
for k, v := range cn.opts {
|
||||
o[k] = v
|
||||
}
|
||||
|
||||
c, err := dial(ctx, cn.dialer, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -126,7 +159,7 @@ func (cn *conn) cancel(ctx context.Context) error {
|
||||
can := conn{
|
||||
c: c,
|
||||
}
|
||||
err = can.ssl(cn.opts)
|
||||
err = can.ssl(o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -147,3 +180,68 @@ func (cn *conn) cancel(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the "StmtQueryContext" interface
|
||||
func (st *stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
|
||||
list := make([]driver.Value, len(args))
|
||||
for i, nv := range args {
|
||||
list[i] = nv.Value
|
||||
}
|
||||
finish := st.watchCancel(ctx)
|
||||
r, err := st.query(list)
|
||||
if err != nil {
|
||||
if finish != nil {
|
||||
finish()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
r.finish = finish
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Implement the "StmtExecContext" interface
|
||||
func (st *stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
|
||||
list := make([]driver.Value, len(args))
|
||||
for i, nv := range args {
|
||||
list[i] = nv.Value
|
||||
}
|
||||
|
||||
if finish := st.watchCancel(ctx); finish != nil {
|
||||
defer finish()
|
||||
}
|
||||
|
||||
return st.Exec(list)
|
||||
}
|
||||
|
||||
// watchCancel is implemented on stmt in order to not mark the parent conn as bad
|
||||
func (st *stmt) watchCancel(ctx context.Context) func() {
|
||||
if done := ctx.Done(); done != nil {
|
||||
finished := make(chan struct{})
|
||||
go func() {
|
||||
select {
|
||||
case <-done:
|
||||
// At this point the function level context is canceled,
|
||||
// so it must not be used for the additional network
|
||||
// request to cancel the query.
|
||||
// Create a new context to pass into the dial.
|
||||
ctxCancel, cancel := context.WithTimeout(context.Background(), watchCancelDialContextTimeout)
|
||||
defer cancel()
|
||||
|
||||
_ = st.cancel(ctxCancel)
|
||||
finished <- struct{}{}
|
||||
case <-finished:
|
||||
}
|
||||
}()
|
||||
return func() {
|
||||
select {
|
||||
case <-finished:
|
||||
case finished <- struct{}{}:
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *stmt) cancel(ctx context.Context) error {
|
||||
return st.cn.cancel(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user