mirror of
https://github.com/documize/community.git
synced 2025-07-21 06:09:42 +02:00
Bump version to 5.11.0
This commit is contained in:
parent
a32510b8e6
commit
510e1bd0bd
370 changed files with 18825 additions and 5454 deletions
71
vendor/github.com/lib/pq/.travis.sh
generated
vendored
71
vendor/github.com/lib/pq/.travis.sh
generated
vendored
|
@ -1,71 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eux
|
||||
|
||||
client_configure() {
|
||||
sudo chmod 600 $PQSSLCERTTEST_PATH/postgresql.key
|
||||
}
|
||||
|
||||
pgdg_repository() {
|
||||
curl -sS 'https://www.postgresql.org/media/keys/ACCC4CF8.asc' | sudo apt-key add -
|
||||
echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
|
||||
sudo apt-get update
|
||||
}
|
||||
|
||||
postgresql_configure() {
|
||||
sudo tee /etc/postgresql/$PGVERSION/main/pg_hba.conf > /dev/null <<-config
|
||||
local all all trust
|
||||
hostnossl all pqgossltest 127.0.0.1/32 reject
|
||||
hostnossl all pqgosslcert 127.0.0.1/32 reject
|
||||
hostssl all pqgossltest 127.0.0.1/32 trust
|
||||
hostssl all pqgosslcert 127.0.0.1/32 cert
|
||||
host all all 127.0.0.1/32 trust
|
||||
hostnossl all pqgossltest ::1/128 reject
|
||||
hostnossl all pqgosslcert ::1/128 reject
|
||||
hostssl all pqgossltest ::1/128 trust
|
||||
hostssl all pqgosslcert ::1/128 cert
|
||||
host all all ::1/128 trust
|
||||
config
|
||||
|
||||
xargs sudo install -o postgres -g postgres -m 600 -t /var/lib/postgresql/$PGVERSION/main/ <<-certificates
|
||||
certs/root.crt
|
||||
certs/server.crt
|
||||
certs/server.key
|
||||
certificates
|
||||
|
||||
sort -VCu <<-versions ||
|
||||
$PGVERSION
|
||||
9.2
|
||||
versions
|
||||
sudo tee -a /etc/postgresql/$PGVERSION/main/postgresql.conf > /dev/null <<-config
|
||||
ssl_ca_file = 'root.crt'
|
||||
ssl_cert_file = 'server.crt'
|
||||
ssl_key_file = 'server.key'
|
||||
config
|
||||
|
||||
echo 127.0.0.1 postgres | sudo tee -a /etc/hosts > /dev/null
|
||||
|
||||
sudo service postgresql restart
|
||||
}
|
||||
|
||||
postgresql_install() {
|
||||
xargs sudo apt-get -y install <<-packages
|
||||
postgresql-$PGVERSION
|
||||
postgresql-client-$PGVERSION
|
||||
postgresql-server-dev-$PGVERSION
|
||||
packages
|
||||
}
|
||||
|
||||
postgresql_uninstall() {
|
||||
sudo service postgresql stop
|
||||
xargs sudo apt-get -y --purge remove <<-packages
|
||||
libpq-dev
|
||||
libpq5
|
||||
postgresql
|
||||
postgresql-client-common
|
||||
postgresql-common
|
||||
packages
|
||||
sudo rm -rf /var/lib/postgresql
|
||||
}
|
||||
|
||||
$1
|
45
vendor/github.com/lib/pq/.travis.yml
generated
vendored
45
vendor/github.com/lib/pq/.travis.yml
generated
vendored
|
@ -1,45 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.14.x
|
||||
- 1.15.x
|
||||
- 1.16.x
|
||||
|
||||
sudo: true
|
||||
|
||||
env:
|
||||
global:
|
||||
- PGUSER=postgres
|
||||
- PQGOSSLTESTS=1
|
||||
- PQSSLCERTTEST_PATH=$PWD/certs
|
||||
- PGHOST=127.0.0.1
|
||||
- GODEBUG=x509ignoreCN=0
|
||||
matrix:
|
||||
- PGVERSION=10
|
||||
- PGVERSION=9.6
|
||||
- PGVERSION=9.5
|
||||
- PGVERSION=9.4
|
||||
|
||||
before_install:
|
||||
- ./.travis.sh postgresql_uninstall
|
||||
- ./.travis.sh pgdg_repository
|
||||
- ./.travis.sh postgresql_install
|
||||
- ./.travis.sh postgresql_configure
|
||||
- ./.travis.sh client_configure
|
||||
- go get golang.org/x/tools/cmd/goimports
|
||||
- go get golang.org/x/lint/golint
|
||||
- GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@2020.1.3
|
||||
|
||||
before_script:
|
||||
- createdb pqgotest
|
||||
- createuser -DRS pqgossltest
|
||||
- createuser -DRS pqgosslcert
|
||||
|
||||
script:
|
||||
- >
|
||||
goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
|
||||
- go vet ./...
|
||||
- staticcheck -go 1.13 ./...
|
||||
- golint ./...
|
||||
- PQTEST_BINARY_PARAMETERS=no go test -race -v ./...
|
||||
- PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...
|
8
vendor/github.com/lib/pq/README.md
generated
vendored
8
vendor/github.com/lib/pq/README.md
generated
vendored
|
@ -27,4 +27,10 @@
|
|||
|
||||
## Status
|
||||
|
||||
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.
|
||||
This package is currently in maintenance mode, which means:
|
||||
1. It generally does not accept new features.
|
||||
2. It does accept bug fixes and version compatability changes provided by the community.
|
||||
3. Maintainers usually do not resolve reported issues.
|
||||
4. Community members are encouraged to help each other with reported issues.
|
||||
|
||||
For users that require new features or reliable resolution of reported bugs, we recommend using [pgx](https://github.com/jackc/pgx) which is under active development.
|
||||
|
|
4
vendor/github.com/lib/pq/array.go
generated
vendored
4
vendor/github.com/lib/pq/array.go
generated
vendored
|
@ -587,8 +587,8 @@ func (a *Int32Array) scanBytes(src []byte) error {
|
|||
} else {
|
||||
b := make(Int32Array, len(elems))
|
||||
for i, v := range elems {
|
||||
var x int
|
||||
if x, err = strconv.Atoi(string(v)); err != nil {
|
||||
x, err := strconv.ParseInt(string(v), 10, 32)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pq: parsing array element index %d: %v", i, err)
|
||||
}
|
||||
b[i] = int32(x)
|
||||
|
|
301
vendor/github.com/lib/pq/conn.go
generated
vendored
301
vendor/github.com/lib/pq/conn.go
generated
vendored
|
@ -2,6 +2,7 @@ package pq
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/sha256"
|
||||
|
@ -18,7 +19,7 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
|
@ -31,8 +32,10 @@ var (
|
|||
ErrNotSupported = errors.New("pq: Unsupported command")
|
||||
ErrInFailedTransaction = errors.New("pq: Could not complete operation in a failed transaction")
|
||||
ErrSSLNotSupported = errors.New("pq: SSL is not enabled on the server")
|
||||
ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key file has group or world access. Permissions should be u=rw (0600) or less")
|
||||
ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly")
|
||||
ErrSSLKeyUnknownOwnership = errors.New("pq: Could not get owner information for private key, may not be properly protected")
|
||||
ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key has world access. Permissions should be u=rw,g=r (0640) if owned by root, or u=rw (0600), or less")
|
||||
|
||||
ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly")
|
||||
|
||||
errUnexpectedReady = errors.New("unexpected ReadyForQuery")
|
||||
errNoRowsAffected = errors.New("no RowsAffected available after the empty statement")
|
||||
|
@ -110,7 +113,9 @@ type defaultDialer struct {
|
|||
func (d defaultDialer) Dial(network, address string) (net.Conn, error) {
|
||||
return d.d.Dial(network, address)
|
||||
}
|
||||
func (d defaultDialer) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
||||
func (d defaultDialer) DialTimeout(
|
||||
network, address string, timeout time.Duration,
|
||||
) (net.Conn, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
return d.DialContext(ctx, network, address)
|
||||
|
@ -140,9 +145,10 @@ type conn struct {
|
|||
saveMessageType byte
|
||||
saveMessageBuffer []byte
|
||||
|
||||
// If true, this connection is bad and all public-facing functions should
|
||||
// return ErrBadConn.
|
||||
bad *atomic.Value
|
||||
// If an error is set, this connection is bad and all public-facing
|
||||
// functions should return the appropriate error by calling get()
|
||||
// (ErrBadConn) or getForNext().
|
||||
err syncErr
|
||||
|
||||
// If set, this connection should never use the binary format when
|
||||
// receiving query results from prepared statements. Only provided for
|
||||
|
@ -166,6 +172,40 @@ type conn struct {
|
|||
gss GSS
|
||||
}
|
||||
|
||||
type syncErr struct {
|
||||
err error
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
// Return ErrBadConn if connection is bad.
|
||||
func (e *syncErr) get() error {
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
if e.err != nil {
|
||||
return driver.ErrBadConn
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return the error set on the connection. Currently only used by rows.Next.
|
||||
func (e *syncErr) getForNext() error {
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
return e.err
|
||||
}
|
||||
|
||||
// Set error, only if it isn't set yet.
|
||||
func (e *syncErr) set(err error) {
|
||||
if err == nil {
|
||||
panic("attempt to set nil err")
|
||||
}
|
||||
e.Lock()
|
||||
defer e.Unlock()
|
||||
if e.err == nil {
|
||||
e.err = err
|
||||
}
|
||||
}
|
||||
|
||||
// Handle driver-side settings in parsed connection string.
|
||||
func (cn *conn) handleDriverSettings(o values) (err error) {
|
||||
boolSetting := func(key string, val *bool) error {
|
||||
|
@ -223,47 +263,56 @@ func (cn *conn) handlePgpass(o values) {
|
|||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(io.Reader(file))
|
||||
// From: https://github.com/tg/pgpass/blob/master/reader.go
|
||||
for scanner.Scan() {
|
||||
if scanText(scanner.Text(), o) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetFields is a helper function for scanText.
|
||||
func getFields(s string) []string {
|
||||
fs := make([]string, 0, 5)
|
||||
f := make([]rune, 0, len(s))
|
||||
|
||||
var esc bool
|
||||
for _, c := range s {
|
||||
switch {
|
||||
case esc:
|
||||
f = append(f, c)
|
||||
esc = false
|
||||
case c == '\\':
|
||||
esc = true
|
||||
case c == ':':
|
||||
fs = append(fs, string(f))
|
||||
f = f[:0]
|
||||
default:
|
||||
f = append(f, c)
|
||||
}
|
||||
}
|
||||
return append(fs, string(f))
|
||||
}
|
||||
|
||||
// ScanText assists HandlePgpass in it's objective.
|
||||
func scanText(line string, o values) bool {
|
||||
hostname := o["host"]
|
||||
ntw, _ := network(o)
|
||||
port := o["port"]
|
||||
db := o["dbname"]
|
||||
username := o["user"]
|
||||
// From: https://github.com/tg/pgpass/blob/master/reader.go
|
||||
getFields := func(s string) []string {
|
||||
fs := make([]string, 0, 5)
|
||||
f := make([]rune, 0, len(s))
|
||||
|
||||
var esc bool
|
||||
for _, c := range s {
|
||||
switch {
|
||||
case esc:
|
||||
f = append(f, c)
|
||||
esc = false
|
||||
case c == '\\':
|
||||
esc = true
|
||||
case c == ':':
|
||||
fs = append(fs, string(f))
|
||||
f = f[:0]
|
||||
default:
|
||||
f = append(f, c)
|
||||
}
|
||||
}
|
||||
return append(fs, string(f))
|
||||
if len(line) == 0 || line[0] == '#' {
|
||||
return false
|
||||
}
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if len(line) == 0 || line[0] == '#' {
|
||||
continue
|
||||
}
|
||||
split := getFields(line)
|
||||
if len(split) != 5 {
|
||||
continue
|
||||
}
|
||||
if (split[0] == "*" || split[0] == hostname || (split[0] == "localhost" && (hostname == "" || ntw == "unix"))) && (split[1] == "*" || split[1] == port) && (split[2] == "*" || split[2] == db) && (split[3] == "*" || split[3] == username) {
|
||||
o["password"] = split[4]
|
||||
return
|
||||
}
|
||||
split := getFields(line)
|
||||
if len(split) != 5 {
|
||||
return false
|
||||
}
|
||||
if (split[0] == "*" || split[0] == hostname || (split[0] == "localhost" && (hostname == "" || ntw == "unix"))) && (split[1] == "*" || split[1] == port) && (split[2] == "*" || split[2] == db) && (split[3] == "*" || split[3] == username) {
|
||||
o["password"] = split[4]
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (cn *conn) writeBuf(b byte) *writeBuf {
|
||||
|
@ -287,7 +336,7 @@ func DialOpen(d Dialer, dsn string) (_ driver.Conn, err error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.dialer = d
|
||||
c.Dialer(d)
|
||||
return c.open(context.Background())
|
||||
}
|
||||
|
||||
|
@ -306,12 +355,9 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) {
|
|||
o[k] = v
|
||||
}
|
||||
|
||||
bad := &atomic.Value{}
|
||||
bad.Store(false)
|
||||
cn = &conn{
|
||||
opts: o,
|
||||
dialer: c.dialer,
|
||||
bad: bad,
|
||||
}
|
||||
err = cn.handleDriverSettings(o)
|
||||
if err != nil {
|
||||
|
@ -516,22 +562,9 @@ func (cn *conn) isInTransaction() bool {
|
|||
cn.txnStatus == txnStatusInFailedTransaction
|
||||
}
|
||||
|
||||
func (cn *conn) setBad() {
|
||||
if cn.bad != nil {
|
||||
cn.bad.Store(true)
|
||||
}
|
||||
}
|
||||
|
||||
func (cn *conn) getBad() bool {
|
||||
if cn.bad != nil {
|
||||
return cn.bad.Load().(bool)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (cn *conn) checkIsInTransaction(intxn bool) {
|
||||
if cn.isInTransaction() != intxn {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected transaction status %v", cn.txnStatus)
|
||||
}
|
||||
}
|
||||
|
@ -541,8 +574,8 @@ func (cn *conn) Begin() (_ driver.Tx, err error) {
|
|||
}
|
||||
|
||||
func (cn *conn) begin(mode string) (_ driver.Tx, err error) {
|
||||
if cn.getBad() {
|
||||
return nil, driver.ErrBadConn
|
||||
if err := cn.err.get(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cn.errRecover(&err)
|
||||
|
||||
|
@ -552,11 +585,11 @@ func (cn *conn) begin(mode string) (_ driver.Tx, err error) {
|
|||
return nil, err
|
||||
}
|
||||
if commandTag != "BEGIN" {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
return nil, fmt.Errorf("unexpected command tag %s", commandTag)
|
||||
}
|
||||
if cn.txnStatus != txnStatusIdleInTransaction {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
return nil, fmt.Errorf("unexpected transaction status %v", cn.txnStatus)
|
||||
}
|
||||
return cn, nil
|
||||
|
@ -570,8 +603,8 @@ func (cn *conn) closeTxn() {
|
|||
|
||||
func (cn *conn) Commit() (err error) {
|
||||
defer cn.closeTxn()
|
||||
if cn.getBad() {
|
||||
return driver.ErrBadConn
|
||||
if err := cn.err.get(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer cn.errRecover(&err)
|
||||
|
||||
|
@ -592,12 +625,12 @@ func (cn *conn) Commit() (err error) {
|
|||
_, commandTag, err := cn.simpleExec("COMMIT")
|
||||
if err != nil {
|
||||
if cn.isInTransaction() {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
}
|
||||
return err
|
||||
}
|
||||
if commandTag != "COMMIT" {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
return fmt.Errorf("unexpected command tag %s", commandTag)
|
||||
}
|
||||
cn.checkIsInTransaction(false)
|
||||
|
@ -606,8 +639,8 @@ func (cn *conn) Commit() (err error) {
|
|||
|
||||
func (cn *conn) Rollback() (err error) {
|
||||
defer cn.closeTxn()
|
||||
if cn.getBad() {
|
||||
return driver.ErrBadConn
|
||||
if err := cn.err.get(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer cn.errRecover(&err)
|
||||
return cn.rollback()
|
||||
|
@ -618,7 +651,7 @@ func (cn *conn) rollback() (err error) {
|
|||
_, commandTag, err := cn.simpleExec("ROLLBACK")
|
||||
if err != nil {
|
||||
if cn.isInTransaction() {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -658,7 +691,7 @@ func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err
|
|||
case 'T', 'D':
|
||||
// ignore any results
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unknown response for simple query: %q", t)
|
||||
}
|
||||
}
|
||||
|
@ -680,7 +713,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
|
|||
// the user can close, though, to avoid connections from being
|
||||
// leaked. A "rows" with done=true works fine for that purpose.
|
||||
if err != nil {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected message %q in simple query execution", t)
|
||||
}
|
||||
if res == nil {
|
||||
|
@ -707,7 +740,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
|
|||
err = parseError(r)
|
||||
case 'D':
|
||||
if res == nil {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected DataRow in simple query execution")
|
||||
}
|
||||
// the query didn't fail; kick off to Next
|
||||
|
@ -722,7 +755,7 @@ func (cn *conn) simpleQuery(q string) (res *rows, err error) {
|
|||
// To work around a bug in QueryRow in Go 1.2 and earlier, wait
|
||||
// until the first DataRow has been received.
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unknown response for simple query: %q", t)
|
||||
}
|
||||
}
|
||||
|
@ -744,7 +777,9 @@ func (noRows) RowsAffected() (int64, error) {
|
|||
|
||||
// Decides which column formats to use for a prepared statement. The input is
|
||||
// an array of type oids, one element per result column.
|
||||
func decideColumnFormats(colTyps []fieldDesc, forceText bool) (colFmts []format, colFmtData []byte) {
|
||||
func decideColumnFormats(
|
||||
colTyps []fieldDesc, forceText bool,
|
||||
) (colFmts []format, colFmtData []byte) {
|
||||
if len(colTyps) == 0 {
|
||||
return nil, colFmtDataAllText
|
||||
}
|
||||
|
@ -815,8 +850,8 @@ func (cn *conn) prepareTo(q, stmtName string) *stmt {
|
|||
}
|
||||
|
||||
func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) {
|
||||
if cn.getBad() {
|
||||
return nil, driver.ErrBadConn
|
||||
if err := cn.err.get(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cn.errRecover(&err)
|
||||
|
||||
|
@ -854,8 +889,8 @@ func (cn *conn) Query(query string, args []driver.Value) (driver.Rows, error) {
|
|||
}
|
||||
|
||||
func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) {
|
||||
if cn.getBad() {
|
||||
return nil, driver.ErrBadConn
|
||||
if err := cn.err.get(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cn.inCopy {
|
||||
return nil, errCopyInProgress
|
||||
|
@ -888,8 +923,8 @@ func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) {
|
|||
|
||||
// Implement the optional "Execer" interface for one-shot queries
|
||||
func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) {
|
||||
if cn.getBad() {
|
||||
return nil, driver.ErrBadConn
|
||||
if err := cn.err.get(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cn.errRecover(&err)
|
||||
|
||||
|
@ -960,7 +995,7 @@ func (cn *conn) sendSimpleMessage(typ byte) (err error) {
|
|||
// the message yourself.
|
||||
func (cn *conn) saveMessage(typ byte, buf *readBuf) {
|
||||
if cn.saveMessageType != 0 {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected saveMessageType %d", cn.saveMessageType)
|
||||
}
|
||||
cn.saveMessageType = typ
|
||||
|
@ -1106,7 +1141,7 @@ func isDriverSetting(key string) bool {
|
|||
return true
|
||||
case "password":
|
||||
return true
|
||||
case "sslmode", "sslcert", "sslkey", "sslrootcert", "sslinline":
|
||||
case "sslmode", "sslcert", "sslkey", "sslrootcert", "sslinline", "sslsni":
|
||||
return true
|
||||
case "fallback_application_name":
|
||||
return true
|
||||
|
@ -1330,8 +1365,8 @@ func (st *stmt) Close() (err error) {
|
|||
if st.closed {
|
||||
return nil
|
||||
}
|
||||
if st.cn.getBad() {
|
||||
return driver.ErrBadConn
|
||||
if err := st.cn.err.get(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer st.cn.errRecover(&err)
|
||||
|
||||
|
@ -1344,14 +1379,14 @@ func (st *stmt) Close() (err error) {
|
|||
|
||||
t, _ := st.cn.recv1()
|
||||
if t != '3' {
|
||||
st.cn.setBad()
|
||||
st.cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected close response: %q", t)
|
||||
}
|
||||
st.closed = true
|
||||
|
||||
t, r := st.cn.recv1()
|
||||
if t != 'Z' {
|
||||
st.cn.setBad()
|
||||
st.cn.err.set(driver.ErrBadConn)
|
||||
errorf("expected ready for query, but got: %q", t)
|
||||
}
|
||||
st.cn.processReadyForQuery(r)
|
||||
|
@ -1360,8 +1395,12 @@ func (st *stmt) Close() (err error) {
|
|||
}
|
||||
|
||||
func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) {
|
||||
if st.cn.getBad() {
|
||||
return nil, driver.ErrBadConn
|
||||
return st.query(v)
|
||||
}
|
||||
|
||||
func (st *stmt) query(v []driver.Value) (r *rows, err error) {
|
||||
if err := st.cn.err.get(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer st.cn.errRecover(&err)
|
||||
|
||||
|
@ -1373,8 +1412,8 @@ func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) {
|
|||
}
|
||||
|
||||
func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) {
|
||||
if st.cn.getBad() {
|
||||
return nil, driver.ErrBadConn
|
||||
if err := st.cn.err.get(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer st.cn.errRecover(&err)
|
||||
|
||||
|
@ -1460,7 +1499,7 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) {
|
|||
if affectedRows == nil && strings.HasPrefix(commandTag, "INSERT ") {
|
||||
parts := strings.Split(commandTag, " ")
|
||||
if len(parts) != 3 {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected INSERT command tag %s", commandTag)
|
||||
}
|
||||
affectedRows = &parts[len(parts)-1]
|
||||
|
@ -1472,7 +1511,7 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) {
|
|||
}
|
||||
n, err := strconv.ParseInt(*affectedRows, 10, 64)
|
||||
if err != nil {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("could not parse commandTag: %s", err)
|
||||
}
|
||||
return driver.RowsAffected(n), commandTag
|
||||
|
@ -1539,8 +1578,8 @@ func (rs *rows) Next(dest []driver.Value) (err error) {
|
|||
}
|
||||
|
||||
conn := rs.cn
|
||||
if conn.getBad() {
|
||||
return driver.ErrBadConn
|
||||
if err := conn.err.getForNext(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.errRecover(&err)
|
||||
|
||||
|
@ -1564,7 +1603,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) {
|
|||
case 'D':
|
||||
n := rs.rb.int16()
|
||||
if err != nil {
|
||||
conn.setBad()
|
||||
conn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected DataRow after error %s", err)
|
||||
}
|
||||
if n < len(dest) {
|
||||
|
@ -1606,10 +1645,10 @@ func (rs *rows) NextResultSet() error {
|
|||
// QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be
|
||||
// used as part of an SQL statement. For example:
|
||||
//
|
||||
// tblname := "my_table"
|
||||
// data := "my_data"
|
||||
// quoted := pq.QuoteIdentifier(tblname)
|
||||
// err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data)
|
||||
// tblname := "my_table"
|
||||
// data := "my_data"
|
||||
// quoted := pq.QuoteIdentifier(tblname)
|
||||
// err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data)
|
||||
//
|
||||
// Any double quotes in name will be escaped. The quoted identifier will be
|
||||
// case sensitive when used in a query. If the input string contains a zero
|
||||
|
@ -1622,12 +1661,24 @@ func QuoteIdentifier(name string) string {
|
|||
return `"` + strings.Replace(name, `"`, `""`, -1) + `"`
|
||||
}
|
||||
|
||||
// BufferQuoteIdentifier satisfies the same purpose as QuoteIdentifier, but backed by a
|
||||
// byte buffer.
|
||||
func BufferQuoteIdentifier(name string, buffer *bytes.Buffer) {
|
||||
end := strings.IndexRune(name, 0)
|
||||
if end > -1 {
|
||||
name = name[:end]
|
||||
}
|
||||
buffer.WriteRune('"')
|
||||
buffer.WriteString(strings.Replace(name, `"`, `""`, -1))
|
||||
buffer.WriteRune('"')
|
||||
}
|
||||
|
||||
// QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal
|
||||
// to DDL and other statements that do not accept parameters) to be used as part
|
||||
// of an SQL statement. For example:
|
||||
//
|
||||
// exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z")
|
||||
// err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))
|
||||
// exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z")
|
||||
// err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))
|
||||
//
|
||||
// Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be
|
||||
// replaced by two backslashes (i.e. "\\") and the C-style escape identifier
|
||||
|
@ -1758,7 +1809,7 @@ func (cn *conn) readReadyForQuery() {
|
|||
cn.processReadyForQuery(r)
|
||||
return
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected message %q; expected ReadyForQuery", t)
|
||||
}
|
||||
}
|
||||
|
@ -1778,12 +1829,16 @@ func (cn *conn) readParseResponse() {
|
|||
cn.readReadyForQuery()
|
||||
panic(err)
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected Parse response %q", t)
|
||||
}
|
||||
}
|
||||
|
||||
func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames []string, colTyps []fieldDesc) {
|
||||
func (cn *conn) readStatementDescribeResponse() (
|
||||
paramTyps []oid.Oid,
|
||||
colNames []string,
|
||||
colTyps []fieldDesc,
|
||||
) {
|
||||
for {
|
||||
t, r := cn.recv1()
|
||||
switch t {
|
||||
|
@ -1803,7 +1858,7 @@ func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames [
|
|||
cn.readReadyForQuery()
|
||||
panic(err)
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected Describe statement response %q", t)
|
||||
}
|
||||
}
|
||||
|
@ -1821,7 +1876,7 @@ func (cn *conn) readPortalDescribeResponse() rowsHeader {
|
|||
cn.readReadyForQuery()
|
||||
panic(err)
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected Describe response %q", t)
|
||||
}
|
||||
panic("not reached")
|
||||
|
@ -1837,7 +1892,7 @@ func (cn *conn) readBindResponse() {
|
|||
cn.readReadyForQuery()
|
||||
panic(err)
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected Bind response %q", t)
|
||||
}
|
||||
}
|
||||
|
@ -1864,20 +1919,22 @@ func (cn *conn) postExecuteWorkaround() {
|
|||
cn.saveMessage(t, r)
|
||||
return
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected message during extended query execution: %q", t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only for Exec(), since we ignore the returned data
|
||||
func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, commandTag string, err error) {
|
||||
func (cn *conn) readExecuteResponse(
|
||||
protocolState string,
|
||||
) (res driver.Result, commandTag string, err error) {
|
||||
for {
|
||||
t, r := cn.recv1()
|
||||
switch t {
|
||||
case 'C':
|
||||
if err != nil {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected CommandComplete after error %s", err)
|
||||
}
|
||||
res, commandTag = cn.parseComplete(r.string())
|
||||
|
@ -1891,7 +1948,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co
|
|||
err = parseError(r)
|
||||
case 'T', 'D', 'I':
|
||||
if err != nil {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unexpected %q after error %s", t, err)
|
||||
}
|
||||
if t == 'I' {
|
||||
|
@ -1899,7 +1956,7 @@ func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, co
|
|||
}
|
||||
// ignore any results
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
errorf("unknown %s response: %q", protocolState, t)
|
||||
}
|
||||
}
|
||||
|
@ -1995,6 +2052,8 @@ func parseEnviron(env []string) (out map[string]string) {
|
|||
accrue("sslkey")
|
||||
case "PGSSLROOTCERT":
|
||||
accrue("sslrootcert")
|
||||
case "PGSSLSNI":
|
||||
accrue("sslsni")
|
||||
case "PGREQUIRESSL", "PGSSLCRL":
|
||||
unsupported()
|
||||
case "PGREQUIREPEER":
|
||||
|
@ -2035,3 +2094,19 @@ func alnumLowerASCII(ch rune) rune {
|
|||
}
|
||||
return -1 // discard
|
||||
}
|
||||
|
||||
// The database/sql/driver package says:
|
||||
// All Conn implementations should implement the following interfaces: Pinger, SessionResetter, and Validator.
|
||||
var _ driver.Pinger = &conn{}
|
||||
var _ driver.SessionResetter = &conn{}
|
||||
|
||||
func (cn *conn) ResetSession(ctx context.Context) error {
|
||||
// Ensure bad connections are reported: From database/sql/driver:
|
||||
// If a connection is never returned to the connection pool but immediately reused, then
|
||||
// ResetSession is called prior to reuse but IsValid is not called.
|
||||
return cn.err.get()
|
||||
}
|
||||
|
||||
func (cn *conn) IsValid() bool {
|
||||
return cn.err.get() == nil
|
||||
}
|
||||
|
|
8
vendor/github.com/lib/pq/conn_go115.go
generated
vendored
Normal file
8
vendor/github.com/lib/pq/conn_go115.go
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
//go:build go1.15
|
||||
// +build go1.15
|
||||
|
||||
package pq
|
||||
|
||||
import "database/sql/driver"
|
||||
|
||||
var _ driver.Validator = &conn{}
|
89
vendor/github.com/lib/pq/conn_go18.go
generated
vendored
89
vendor/github.com/lib/pq/conn_go18.go
generated
vendored
|
@ -7,10 +7,13 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sync/atomic"
|
||||
"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))
|
||||
|
@ -43,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
|
||||
|
@ -103,13 +114,13 @@ func (cn *conn) watchCancel(ctx context.Context) func() {
|
|||
}
|
||||
|
||||
// Set the connection state to bad so it does not get reused.
|
||||
cn.setBad()
|
||||
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)
|
||||
|
@ -119,7 +130,7 @@ func (cn *conn) watchCancel(ctx context.Context) func() {
|
|||
return func() {
|
||||
select {
|
||||
case <-finished:
|
||||
cn.setBad()
|
||||
cn.err.set(ctx.Err())
|
||||
cn.Close()
|
||||
case finished <- struct{}{}:
|
||||
}
|
||||
|
@ -145,11 +156,8 @@ func (cn *conn) cancel(ctx context.Context) error {
|
|||
defer c.Close()
|
||||
|
||||
{
|
||||
bad := &atomic.Value{}
|
||||
bad.Store(false)
|
||||
can := conn{
|
||||
c: c,
|
||||
bad: bad,
|
||||
c: c,
|
||||
}
|
||||
err = can.ssl(o)
|
||||
if err != nil {
|
||||
|
@ -172,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)
|
||||
}
|
||||
|
|
5
vendor/github.com/lib/pq/connector.go
generated
vendored
5
vendor/github.com/lib/pq/connector.go
generated
vendored
|
@ -27,6 +27,11 @@ func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
|
|||
return c.open(ctx)
|
||||
}
|
||||
|
||||
// Dialer allows change the dialer used to open connections.
|
||||
func (c *Connector) Dialer(dialer Dialer) {
|
||||
c.dialer = dialer
|
||||
}
|
||||
|
||||
// Driver returns the underlying driver of this Connector.
|
||||
func (c *Connector) Driver() driver.Driver {
|
||||
return &Driver{}
|
||||
|
|
149
vendor/github.com/lib/pq/copy.go
generated
vendored
149
vendor/github.com/lib/pq/copy.go
generated
vendored
|
@ -1,6 +1,8 @@
|
|||
package pq
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
@ -19,29 +21,35 @@ var (
|
|||
// CopyIn creates a COPY FROM statement which can be prepared with
|
||||
// Tx.Prepare(). The target table should be visible in search_path.
|
||||
func CopyIn(table string, columns ...string) string {
|
||||
stmt := "COPY " + QuoteIdentifier(table) + " ("
|
||||
buffer := bytes.NewBufferString("COPY ")
|
||||
BufferQuoteIdentifier(table, buffer)
|
||||
buffer.WriteString(" (")
|
||||
makeStmt(buffer, columns...)
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// MakeStmt makes the stmt string for CopyIn and CopyInSchema.
|
||||
func makeStmt(buffer *bytes.Buffer, columns ...string) {
|
||||
//s := bytes.NewBufferString()
|
||||
for i, col := range columns {
|
||||
if i != 0 {
|
||||
stmt += ", "
|
||||
buffer.WriteString(", ")
|
||||
}
|
||||
stmt += QuoteIdentifier(col)
|
||||
BufferQuoteIdentifier(col, buffer)
|
||||
}
|
||||
stmt += ") FROM STDIN"
|
||||
return stmt
|
||||
buffer.WriteString(") FROM STDIN")
|
||||
}
|
||||
|
||||
// CopyInSchema creates a COPY FROM statement which can be prepared with
|
||||
// Tx.Prepare().
|
||||
func CopyInSchema(schema, table string, columns ...string) string {
|
||||
stmt := "COPY " + QuoteIdentifier(schema) + "." + QuoteIdentifier(table) + " ("
|
||||
for i, col := range columns {
|
||||
if i != 0 {
|
||||
stmt += ", "
|
||||
}
|
||||
stmt += QuoteIdentifier(col)
|
||||
}
|
||||
stmt += ") FROM STDIN"
|
||||
return stmt
|
||||
buffer := bytes.NewBufferString("COPY ")
|
||||
BufferQuoteIdentifier(schema, buffer)
|
||||
buffer.WriteRune('.')
|
||||
BufferQuoteIdentifier(table, buffer)
|
||||
buffer.WriteString(" (")
|
||||
makeStmt(buffer, columns...)
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
type copyin struct {
|
||||
|
@ -49,12 +57,14 @@ type copyin struct {
|
|||
buffer []byte
|
||||
rowData chan []byte
|
||||
done chan bool
|
||||
driver.Result
|
||||
|
||||
closed bool
|
||||
|
||||
sync.Mutex // guards err
|
||||
err error
|
||||
mu struct {
|
||||
sync.Mutex
|
||||
err error
|
||||
driver.Result
|
||||
}
|
||||
}
|
||||
|
||||
const ciBufferSize = 64 * 1024
|
||||
|
@ -98,13 +108,13 @@ awaitCopyInResponse:
|
|||
err = parseError(r)
|
||||
case 'Z':
|
||||
if err == nil {
|
||||
ci.setBad()
|
||||
ci.setBad(driver.ErrBadConn)
|
||||
errorf("unexpected ReadyForQuery in response to COPY")
|
||||
}
|
||||
cn.processReadyForQuery(r)
|
||||
return nil, err
|
||||
default:
|
||||
ci.setBad()
|
||||
ci.setBad(driver.ErrBadConn)
|
||||
errorf("unknown response for copy query: %q", t)
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +133,7 @@ awaitCopyInResponse:
|
|||
cn.processReadyForQuery(r)
|
||||
return nil, err
|
||||
default:
|
||||
ci.setBad()
|
||||
ci.setBad(driver.ErrBadConn)
|
||||
errorf("unknown response for CopyFail: %q", t)
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +154,7 @@ func (ci *copyin) resploop() {
|
|||
var r readBuf
|
||||
t, err := ci.cn.recvMessage(&r)
|
||||
if err != nil {
|
||||
ci.setBad()
|
||||
ci.setBad(driver.ErrBadConn)
|
||||
ci.setError(err)
|
||||
ci.done <- true
|
||||
return
|
||||
|
@ -166,7 +176,7 @@ func (ci *copyin) resploop() {
|
|||
err := parseError(&r)
|
||||
ci.setError(err)
|
||||
default:
|
||||
ci.setBad()
|
||||
ci.setBad(driver.ErrBadConn)
|
||||
ci.setError(fmt.Errorf("unknown response during CopyIn: %q", t))
|
||||
ci.done <- true
|
||||
return
|
||||
|
@ -174,46 +184,41 @@ func (ci *copyin) resploop() {
|
|||
}
|
||||
}
|
||||
|
||||
func (ci *copyin) setBad() {
|
||||
ci.Lock()
|
||||
ci.cn.setBad()
|
||||
ci.Unlock()
|
||||
func (ci *copyin) setBad(err error) {
|
||||
ci.cn.err.set(err)
|
||||
}
|
||||
|
||||
func (ci *copyin) isBad() bool {
|
||||
ci.Lock()
|
||||
b := ci.cn.getBad()
|
||||
ci.Unlock()
|
||||
return b
|
||||
func (ci *copyin) getBad() error {
|
||||
return ci.cn.err.get()
|
||||
}
|
||||
|
||||
func (ci *copyin) isErrorSet() bool {
|
||||
ci.Lock()
|
||||
isSet := (ci.err != nil)
|
||||
ci.Unlock()
|
||||
return isSet
|
||||
func (ci *copyin) err() error {
|
||||
ci.mu.Lock()
|
||||
err := ci.mu.err
|
||||
ci.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
// setError() sets ci.err if one has not been set already. Caller must not be
|
||||
// holding ci.Mutex.
|
||||
func (ci *copyin) setError(err error) {
|
||||
ci.Lock()
|
||||
if ci.err == nil {
|
||||
ci.err = err
|
||||
ci.mu.Lock()
|
||||
if ci.mu.err == nil {
|
||||
ci.mu.err = err
|
||||
}
|
||||
ci.Unlock()
|
||||
ci.mu.Unlock()
|
||||
}
|
||||
|
||||
func (ci *copyin) setResult(result driver.Result) {
|
||||
ci.Lock()
|
||||
ci.Result = result
|
||||
ci.Unlock()
|
||||
ci.mu.Lock()
|
||||
ci.mu.Result = result
|
||||
ci.mu.Unlock()
|
||||
}
|
||||
|
||||
func (ci *copyin) getResult() driver.Result {
|
||||
ci.Lock()
|
||||
result := ci.Result
|
||||
ci.Unlock()
|
||||
ci.mu.Lock()
|
||||
result := ci.mu.Result
|
||||
ci.mu.Unlock()
|
||||
if result == nil {
|
||||
return driver.RowsAffected(0)
|
||||
}
|
||||
|
@ -240,13 +245,13 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
|
|||
return nil, errCopyInClosed
|
||||
}
|
||||
|
||||
if ci.isBad() {
|
||||
return nil, driver.ErrBadConn
|
||||
if err := ci.getBad(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer ci.cn.errRecover(&err)
|
||||
|
||||
if ci.isErrorSet() {
|
||||
return nil, ci.err
|
||||
if err := ci.err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(v) == 0 {
|
||||
|
@ -276,14 +281,51 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
|
|||
return driver.RowsAffected(0), nil
|
||||
}
|
||||
|
||||
// CopyData inserts a raw string into the COPY stream. The insert is
|
||||
// asynchronous and CopyData can return errors from previous CopyData calls to
|
||||
// the same COPY stmt.
|
||||
//
|
||||
// You need to call Exec(nil) to sync the COPY stream and to get any
|
||||
// errors from pending data, since Stmt.Close() doesn't return errors
|
||||
// to the user.
|
||||
func (ci *copyin) CopyData(ctx context.Context, line string) (r driver.Result, err error) {
|
||||
if ci.closed {
|
||||
return nil, errCopyInClosed
|
||||
}
|
||||
|
||||
if finish := ci.cn.watchCancel(ctx); finish != nil {
|
||||
defer finish()
|
||||
}
|
||||
|
||||
if err := ci.getBad(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer ci.cn.errRecover(&err)
|
||||
|
||||
if err := ci.err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ci.buffer = append(ci.buffer, []byte(line)...)
|
||||
ci.buffer = append(ci.buffer, '\n')
|
||||
|
||||
if len(ci.buffer) > ciBufferFlushSize {
|
||||
ci.flush(ci.buffer)
|
||||
// reset buffer, keep bytes for message identifier and length
|
||||
ci.buffer = ci.buffer[:5]
|
||||
}
|
||||
|
||||
return driver.RowsAffected(0), nil
|
||||
}
|
||||
|
||||
func (ci *copyin) Close() (err error) {
|
||||
if ci.closed { // Don't do anything, we're already closed
|
||||
return nil
|
||||
}
|
||||
ci.closed = true
|
||||
|
||||
if ci.isBad() {
|
||||
return driver.ErrBadConn
|
||||
if err := ci.getBad(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer ci.cn.errRecover(&err)
|
||||
|
||||
|
@ -299,8 +341,7 @@ func (ci *copyin) Close() (err error) {
|
|||
<-ci.done
|
||||
ci.cn.inCopy = false
|
||||
|
||||
if ci.isErrorSet() {
|
||||
err = ci.err
|
||||
if err := ci.err(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
10
vendor/github.com/lib/pq/encode.go
generated
vendored
10
vendor/github.com/lib/pq/encode.go
generated
vendored
|
@ -422,7 +422,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
|
|||
|
||||
if remainderIdx < len(str) && str[remainderIdx] == '.' {
|
||||
fracStart := remainderIdx + 1
|
||||
fracOff := strings.IndexAny(str[fracStart:], "-+ ")
|
||||
fracOff := strings.IndexAny(str[fracStart:], "-+Z ")
|
||||
if fracOff < 0 {
|
||||
fracOff = len(str) - fracStart
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
|
|||
remainderIdx += fracOff + 1
|
||||
}
|
||||
if tzStart := remainderIdx; tzStart < len(str) && (str[tzStart] == '-' || str[tzStart] == '+') {
|
||||
// time zone separator is always '-' or '+' (UTC is +00)
|
||||
// time zone separator is always '-' or '+' or 'Z' (UTC is +00)
|
||||
var tzSign int
|
||||
switch c := str[tzStart]; c {
|
||||
case '-':
|
||||
|
@ -454,7 +454,11 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
|
|||
remainderIdx += 3
|
||||
}
|
||||
tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec)
|
||||
} else if tzStart < len(str) && str[tzStart] == 'Z' {
|
||||
// time zone Z separator indicates UTC is +00
|
||||
remainderIdx += 1
|
||||
}
|
||||
|
||||
var isoYear int
|
||||
|
||||
if isBC {
|
||||
|
@ -559,7 +563,7 @@ func parseBytea(s []byte) (result []byte, err error) {
|
|||
if len(s) < 4 {
|
||||
return nil, fmt.Errorf("invalid bytea sequence %v", s)
|
||||
}
|
||||
r, err := strconv.ParseInt(string(s[1:4]), 8, 9)
|
||||
r, err := strconv.ParseUint(string(s[1:4]), 8, 8)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse bytea value: %s", err.Error())
|
||||
}
|
||||
|
|
19
vendor/github.com/lib/pq/error.go
generated
vendored
19
vendor/github.com/lib/pq/error.go
generated
vendored
|
@ -402,6 +402,11 @@ func (err *Error) Fatal() bool {
|
|||
return err.Severity == Efatal
|
||||
}
|
||||
|
||||
// SQLState returns the SQLState of the error.
|
||||
func (err *Error) SQLState() string {
|
||||
return string(err.Code)
|
||||
}
|
||||
|
||||
// Get implements the legacy PGError interface. New code should use the fields
|
||||
// of the Error struct directly.
|
||||
func (err *Error) Get(k byte) (v string) {
|
||||
|
@ -444,7 +449,7 @@ func (err *Error) Get(k byte) (v string) {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (err Error) Error() string {
|
||||
func (err *Error) Error() string {
|
||||
return "pq: " + err.Message
|
||||
}
|
||||
|
||||
|
@ -484,7 +489,7 @@ func (cn *conn) errRecover(err *error) {
|
|||
case nil:
|
||||
// Do nothing
|
||||
case runtime.Error:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
panic(v)
|
||||
case *Error:
|
||||
if v.Fatal() {
|
||||
|
@ -493,26 +498,26 @@ func (cn *conn) errRecover(err *error) {
|
|||
*err = v
|
||||
}
|
||||
case *net.OpError:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
*err = v
|
||||
case *safeRetryError:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
*err = driver.ErrBadConn
|
||||
case error:
|
||||
if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
|
||||
if v == io.EOF || v.Error() == "remote error: handshake failure" {
|
||||
*err = driver.ErrBadConn
|
||||
} else {
|
||||
*err = v
|
||||
}
|
||||
|
||||
default:
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
panic(fmt.Sprintf("unknown error: %#v", e))
|
||||
}
|
||||
|
||||
// Any time we return ErrBadConn, we need to remember it since *Tx doesn't
|
||||
// mark the connection bad in database/sql.
|
||||
if *err == driver.ErrBadConn {
|
||||
cn.setBad()
|
||||
cn.err.set(driver.ErrBadConn)
|
||||
}
|
||||
}
|
||||
|
|
1
vendor/github.com/lib/pq/notice.go
generated
vendored
1
vendor/github.com/lib/pq/notice.go
generated
vendored
|
@ -1,3 +1,4 @@
|
|||
//go:build go1.10
|
||||
// +build go1.10
|
||||
|
||||
package pq
|
||||
|
|
11
vendor/github.com/lib/pq/ssl.go
generated
vendored
11
vendor/github.com/lib/pq/ssl.go
generated
vendored
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ssl generates a function to upgrade a net.Conn based on the "sslmode" and
|
||||
|
@ -50,6 +51,16 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) {
|
|||
return nil, fmterrorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode)
|
||||
}
|
||||
|
||||
// Set Server Name Indication (SNI), if enabled by connection parameters.
|
||||
// By default SNI is on, any value which is not starting with "1" disables
|
||||
// SNI -- that is the same check vanilla libpq uses.
|
||||
if sslsni := o["sslsni"]; sslsni == "" || strings.HasPrefix(sslsni, "1") {
|
||||
// RFC 6066 asks to not set SNI if the host is a literal IP address (IPv4
|
||||
// or IPv6). This check is coded already crypto.tls.hostnameInSNI, so
|
||||
// just always set ServerName here and let crypto/tls do the filtering.
|
||||
tlsConf.ServerName = o["host"]
|
||||
}
|
||||
|
||||
err := sslClientCertificates(&tlsConf, o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
81
vendor/github.com/lib/pq/ssl_permissions.go
generated
vendored
81
vendor/github.com/lib/pq/ssl_permissions.go
generated
vendored
|
@ -1,8 +1,30 @@
|
|||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package pq
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const (
|
||||
rootUserID = uint32(0)
|
||||
|
||||
// The maximum permissions that a private key file owned by a regular user
|
||||
// is allowed to have. This translates to u=rw.
|
||||
maxUserOwnedKeyPermissions os.FileMode = 0600
|
||||
|
||||
// The maximum permissions that a private key file owned by root is allowed
|
||||
// to have. This translates to u=rw,g=r.
|
||||
maxRootOwnedKeyPermissions os.FileMode = 0640
|
||||
)
|
||||
|
||||
var (
|
||||
errSSLKeyHasUnacceptableUserPermissions = errors.New("permissions for files not owned by root should be u=rw (0600) or less")
|
||||
errSSLKeyHasUnacceptableRootPermissions = errors.New("permissions for root owned files should be u=rw,g=r (0640) or less")
|
||||
)
|
||||
|
||||
// sslKeyPermissions checks the permissions on user-supplied ssl key files.
|
||||
// The key file should have very little access.
|
||||
|
@ -13,8 +35,59 @@ func sslKeyPermissions(sslkey string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Mode().Perm()&0077 != 0 {
|
||||
return ErrSSLKeyHasWorldPermissions
|
||||
|
||||
err = hasCorrectPermissions(info)
|
||||
|
||||
// return ErrSSLKeyHasWorldPermissions for backwards compatability with
|
||||
// existing code.
|
||||
if err == errSSLKeyHasUnacceptableUserPermissions || err == errSSLKeyHasUnacceptableRootPermissions {
|
||||
err = ErrSSLKeyHasWorldPermissions
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// hasCorrectPermissions checks the file info (and the unix-specific stat_t
|
||||
// output) to verify that the permissions on the file are correct.
|
||||
//
|
||||
// If the file is owned by the same user the process is running as,
|
||||
// the file should only have 0600 (u=rw). If the file is owned by root,
|
||||
// and the group matches the group that the process is running in, the
|
||||
// permissions cannot be more than 0640 (u=rw,g=r). The file should
|
||||
// never have world permissions.
|
||||
//
|
||||
// Returns an error when the permission check fails.
|
||||
func hasCorrectPermissions(info os.FileInfo) error {
|
||||
// if file's permission matches 0600, allow access.
|
||||
userPermissionMask := (os.FileMode(0777) ^ maxUserOwnedKeyPermissions)
|
||||
|
||||
// regardless of if we're running as root or not, 0600 is acceptable,
|
||||
// so we return if we match the regular user permission mask.
|
||||
if info.Mode().Perm()&userPermissionMask == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// We need to pull the Unix file information to get the file's owner.
|
||||
// If we can't access it, there's some sort of operating system level error
|
||||
// and we should fail rather than attempting to use faulty information.
|
||||
sysInfo := info.Sys()
|
||||
if sysInfo == nil {
|
||||
return ErrSSLKeyUnknownOwnership
|
||||
}
|
||||
|
||||
unixStat, ok := sysInfo.(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return ErrSSLKeyUnknownOwnership
|
||||
}
|
||||
|
||||
// if the file is owned by root, we allow 0640 (u=rw,g=r) to match what
|
||||
// Postgres does.
|
||||
if unixStat.Uid == rootUserID {
|
||||
rootPermissionMask := (os.FileMode(0777) ^ maxRootOwnedKeyPermissions)
|
||||
if info.Mode().Perm()&rootPermissionMask != 0 {
|
||||
return errSSLKeyHasUnacceptableRootPermissions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return errSSLKeyHasUnacceptableUserPermissions
|
||||
}
|
||||
|
|
1
vendor/github.com/lib/pq/ssl_windows.go
generated
vendored
1
vendor/github.com/lib/pq/ssl_windows.go
generated
vendored
|
@ -1,3 +1,4 @@
|
|||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package pq
|
||||
|
|
3
vendor/github.com/lib/pq/user_other.go
generated
vendored
3
vendor/github.com/lib/pq/user_other.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
// Package pq is a pure Go Postgres driver for the database/sql package.
|
||||
|
||||
// +build js android hurd illumos zos
|
||||
//go:build js || android || hurd || zos
|
||||
// +build js android hurd zos
|
||||
|
||||
package pq
|
||||
|
||||
|
|
3
vendor/github.com/lib/pq/user_posix.go
generated
vendored
3
vendor/github.com/lib/pq/user_posix.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
// Package pq is a pure Go Postgres driver for the database/sql package.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris rumprun
|
||||
//go:build aix || darwin || dragonfly || freebsd || (linux && !android) || nacl || netbsd || openbsd || plan9 || solaris || rumprun || illumos
|
||||
// +build aix darwin dragonfly freebsd linux,!android nacl netbsd openbsd plan9 solaris rumprun illumos
|
||||
|
||||
package pq
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue