bump lib/pq
This commit is contained in:
		
				
					committed by
					
						
						Stephan Renatus
					
				
			
			
				
	
			
			
			
						parent
						
							d91f9fbc51
						
					
				
				
					commit
					badbc8c738
				
			
							
								
								
									
										6
									
								
								glide.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								glide.lock
									
									
									
										generated
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
hash: e5972bbdf15ad612d99ce8cd34e19537b9eacb5ff53688f339e0da285eb8ec22
 | 
			
		||||
updated: 2018-11-12T19:38:56.235070564+01:00
 | 
			
		||||
hash: 70e399f3424964c1535cefb66bce0e47af25ea6bb0f32a254e83e91bd774b5f2
 | 
			
		||||
updated: 2018-11-20T09:49:19.83565589-05:00
 | 
			
		||||
imports:
 | 
			
		||||
- name: github.com/beevik/etree
 | 
			
		||||
  version: 4cd0dd976db869f817248477718071a28e978df0
 | 
			
		||||
@@ -54,7 +54,7 @@ imports:
 | 
			
		||||
  - diff
 | 
			
		||||
  - pretty
 | 
			
		||||
- name: github.com/lib/pq
 | 
			
		||||
  version: 50761b0867bd1d9d069276790bcd4a3bccf2324a
 | 
			
		||||
  version: 9eb73efc1fcc404148b56765b0d3f61d9a5ef8ee
 | 
			
		||||
  subpackages:
 | 
			
		||||
  - oid
 | 
			
		||||
- name: github.com/mattn/go-sqlite3
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ import:
 | 
			
		||||
- package: github.com/mattn/go-sqlite3
 | 
			
		||||
  version: 3fb7a0e792edd47bf0cf1e919dfc14e2be412e15
 | 
			
		||||
- package: github.com/lib/pq
 | 
			
		||||
  version: 50761b0867bd1d9d069276790bcd4a3bccf2324a
 | 
			
		||||
  version: 9eb73efc1fcc404148b56765b0d3f61d9a5ef8ee
 | 
			
		||||
 | 
			
		||||
# etcd driver
 | 
			
		||||
- package: github.com/coreos/etcd
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								vendor/github.com/lib/pq/array.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/lib/pq/array.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -13,7 +13,7 @@ import (
 | 
			
		||||
 | 
			
		||||
var typeByteSlice = reflect.TypeOf([]byte{})
 | 
			
		||||
var typeDriverValuer = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
 | 
			
		||||
var typeSqlScanner = reflect.TypeOf((*sql.Scanner)(nil)).Elem()
 | 
			
		||||
var typeSQLScanner = reflect.TypeOf((*sql.Scanner)(nil)).Elem()
 | 
			
		||||
 | 
			
		||||
// Array returns the optimal driver.Valuer and sql.Scanner for an array or
 | 
			
		||||
// slice of any dimension.
 | 
			
		||||
@@ -70,6 +70,9 @@ func (a *BoolArray) Scan(src interface{}) error {
 | 
			
		||||
		return a.scanBytes(src)
 | 
			
		||||
	case string:
 | 
			
		||||
		return a.scanBytes([]byte(src))
 | 
			
		||||
	case nil:
 | 
			
		||||
		*a = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Errorf("pq: cannot convert %T to BoolArray", src)
 | 
			
		||||
@@ -80,7 +83,7 @@ func (a *BoolArray) scanBytes(src []byte) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if len(elems) == 0 {
 | 
			
		||||
	if *a != nil && len(elems) == 0 {
 | 
			
		||||
		*a = (*a)[:0]
 | 
			
		||||
	} else {
 | 
			
		||||
		b := make(BoolArray, len(elems))
 | 
			
		||||
@@ -141,6 +144,9 @@ func (a *ByteaArray) Scan(src interface{}) error {
 | 
			
		||||
		return a.scanBytes(src)
 | 
			
		||||
	case string:
 | 
			
		||||
		return a.scanBytes([]byte(src))
 | 
			
		||||
	case nil:
 | 
			
		||||
		*a = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Errorf("pq: cannot convert %T to ByteaArray", src)
 | 
			
		||||
@@ -151,7 +157,7 @@ func (a *ByteaArray) scanBytes(src []byte) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if len(elems) == 0 {
 | 
			
		||||
	if *a != nil && len(elems) == 0 {
 | 
			
		||||
		*a = (*a)[:0]
 | 
			
		||||
	} else {
 | 
			
		||||
		b := make(ByteaArray, len(elems))
 | 
			
		||||
@@ -210,6 +216,9 @@ func (a *Float64Array) Scan(src interface{}) error {
 | 
			
		||||
		return a.scanBytes(src)
 | 
			
		||||
	case string:
 | 
			
		||||
		return a.scanBytes([]byte(src))
 | 
			
		||||
	case nil:
 | 
			
		||||
		*a = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Errorf("pq: cannot convert %T to Float64Array", src)
 | 
			
		||||
@@ -220,7 +229,7 @@ func (a *Float64Array) scanBytes(src []byte) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if len(elems) == 0 {
 | 
			
		||||
	if *a != nil && len(elems) == 0 {
 | 
			
		||||
		*a = (*a)[:0]
 | 
			
		||||
	} else {
 | 
			
		||||
		b := make(Float64Array, len(elems))
 | 
			
		||||
@@ -269,7 +278,7 @@ func (GenericArray) evaluateDestination(rt reflect.Type) (reflect.Type, func([]b
 | 
			
		||||
	// TODO calculate the assign function for other types
 | 
			
		||||
	// TODO repeat this section on the element type of arrays or slices (multidimensional)
 | 
			
		||||
	{
 | 
			
		||||
		if reflect.PtrTo(rt).Implements(typeSqlScanner) {
 | 
			
		||||
		if reflect.PtrTo(rt).Implements(typeSQLScanner) {
 | 
			
		||||
			// dest is always addressable because it is an element of a slice.
 | 
			
		||||
			assign = func(src []byte, dest reflect.Value) (err error) {
 | 
			
		||||
				ss := dest.Addr().Interface().(sql.Scanner)
 | 
			
		||||
@@ -320,6 +329,11 @@ func (a GenericArray) Scan(src interface{}) error {
 | 
			
		||||
		return a.scanBytes(src, dv)
 | 
			
		||||
	case string:
 | 
			
		||||
		return a.scanBytes([]byte(src), dv)
 | 
			
		||||
	case nil:
 | 
			
		||||
		if dv.Kind() == reflect.Slice {
 | 
			
		||||
			dv.Set(reflect.Zero(dv.Type()))
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Errorf("pq: cannot convert %T to %s", src, dv.Type())
 | 
			
		||||
@@ -386,7 +400,13 @@ func (a GenericArray) Value() (driver.Value, error) {
 | 
			
		||||
 | 
			
		||||
	rv := reflect.ValueOf(a.A)
 | 
			
		||||
 | 
			
		||||
	if k := rv.Kind(); k != reflect.Array && k != reflect.Slice {
 | 
			
		||||
	switch rv.Kind() {
 | 
			
		||||
	case reflect.Slice:
 | 
			
		||||
		if rv.IsNil() {
 | 
			
		||||
			return nil, nil
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Array:
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("pq: Unable to convert %T to array", a.A)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -412,6 +432,9 @@ func (a *Int64Array) Scan(src interface{}) error {
 | 
			
		||||
		return a.scanBytes(src)
 | 
			
		||||
	case string:
 | 
			
		||||
		return a.scanBytes([]byte(src))
 | 
			
		||||
	case nil:
 | 
			
		||||
		*a = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Errorf("pq: cannot convert %T to Int64Array", src)
 | 
			
		||||
@@ -422,7 +445,7 @@ func (a *Int64Array) scanBytes(src []byte) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if len(elems) == 0 {
 | 
			
		||||
	if *a != nil && len(elems) == 0 {
 | 
			
		||||
		*a = (*a)[:0]
 | 
			
		||||
	} else {
 | 
			
		||||
		b := make(Int64Array, len(elems))
 | 
			
		||||
@@ -470,6 +493,9 @@ func (a *StringArray) Scan(src interface{}) error {
 | 
			
		||||
		return a.scanBytes(src)
 | 
			
		||||
	case string:
 | 
			
		||||
		return a.scanBytes([]byte(src))
 | 
			
		||||
	case nil:
 | 
			
		||||
		*a = nil
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Errorf("pq: cannot convert %T to StringArray", src)
 | 
			
		||||
@@ -480,7 +506,7 @@ func (a *StringArray) scanBytes(src []byte) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if len(elems) == 0 {
 | 
			
		||||
	if *a != nil && len(elems) == 0 {
 | 
			
		||||
		*a = (*a)[:0]
 | 
			
		||||
	} else {
 | 
			
		||||
		b := make(StringArray, len(elems))
 | 
			
		||||
@@ -561,7 +587,7 @@ func appendArrayElement(b []byte, rv reflect.Value) ([]byte, string, error) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var del string = ","
 | 
			
		||||
	var del = ","
 | 
			
		||||
	var err error
 | 
			
		||||
	var iv interface{} = rv.Interface()
 | 
			
		||||
 | 
			
		||||
@@ -639,6 +665,9 @@ Element:
 | 
			
		||||
	for i < len(src) {
 | 
			
		||||
		switch src[i] {
 | 
			
		||||
		case '{':
 | 
			
		||||
			if depth == len(dims) {
 | 
			
		||||
				break Element
 | 
			
		||||
			}
 | 
			
		||||
			depth++
 | 
			
		||||
			dims[depth-1] = 0
 | 
			
		||||
			i++
 | 
			
		||||
@@ -680,11 +709,11 @@ Element:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i < len(src) {
 | 
			
		||||
		if bytes.HasPrefix(src[i:], del) {
 | 
			
		||||
		if bytes.HasPrefix(src[i:], del) && depth > 0 {
 | 
			
		||||
			dims[depth-1]++
 | 
			
		||||
			i += len(del)
 | 
			
		||||
			goto Element
 | 
			
		||||
		} else if src[i] == '}' {
 | 
			
		||||
		} else if src[i] == '}' && depth > 0 {
 | 
			
		||||
			dims[depth-1]++
 | 
			
		||||
			depth--
 | 
			
		||||
			i++
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										556
									
								
								vendor/github.com/lib/pq/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										556
									
								
								vendor/github.com/lib/pq/conn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										129
									
								
								vendor/github.com/lib/pq/conn_go18.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								vendor/github.com/lib/pq/conn_go18.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
package pq
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"database/sql/driver"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 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))
 | 
			
		||||
	for i, nv := range args {
 | 
			
		||||
		list[i] = nv.Value
 | 
			
		||||
	}
 | 
			
		||||
	finish := cn.watchCancel(ctx)
 | 
			
		||||
	r, err := cn.query(query, list)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if finish != nil {
 | 
			
		||||
			finish()
 | 
			
		||||
		}
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	r.finish = finish
 | 
			
		||||
	return r, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implement the "ExecerContext" interface
 | 
			
		||||
func (cn *conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
 | 
			
		||||
	list := make([]driver.Value, len(args))
 | 
			
		||||
	for i, nv := range args {
 | 
			
		||||
		list[i] = nv.Value
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if finish := cn.watchCancel(ctx); finish != nil {
 | 
			
		||||
		defer finish()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cn.Exec(query, list)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implement the "ConnBeginTx" interface
 | 
			
		||||
func (cn *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
 | 
			
		||||
	var mode string
 | 
			
		||||
 | 
			
		||||
	switch sql.IsolationLevel(opts.Isolation) {
 | 
			
		||||
	case sql.LevelDefault:
 | 
			
		||||
		// Don't touch mode: use the server's default
 | 
			
		||||
	case sql.LevelReadUncommitted:
 | 
			
		||||
		mode = " ISOLATION LEVEL READ UNCOMMITTED"
 | 
			
		||||
	case sql.LevelReadCommitted:
 | 
			
		||||
		mode = " ISOLATION LEVEL READ COMMITTED"
 | 
			
		||||
	case sql.LevelRepeatableRead:
 | 
			
		||||
		mode = " ISOLATION LEVEL REPEATABLE READ"
 | 
			
		||||
	case sql.LevelSerializable:
 | 
			
		||||
		mode = " ISOLATION LEVEL SERIALIZABLE"
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("pq: isolation level not supported: %d", opts.Isolation)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if opts.ReadOnly {
 | 
			
		||||
		mode += " READ ONLY"
 | 
			
		||||
	} else {
 | 
			
		||||
		mode += " READ WRITE"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tx, err := cn.begin(mode)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	cn.txnFinish = cn.watchCancel(ctx)
 | 
			
		||||
	return tx, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cn *conn) watchCancel(ctx context.Context) func() {
 | 
			
		||||
	if done := ctx.Done(); done != nil {
 | 
			
		||||
		finished := make(chan struct{})
 | 
			
		||||
		go func() {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-done:
 | 
			
		||||
				_ = cn.cancel()
 | 
			
		||||
				finished <- struct{}{}
 | 
			
		||||
			case <-finished:
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
		return func() {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-finished:
 | 
			
		||||
			case finished <- struct{}{}:
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cn *conn) cancel() error {
 | 
			
		||||
	c, err := dial(cn.dialer, cn.opts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer c.Close()
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		can := conn{
 | 
			
		||||
			c: c,
 | 
			
		||||
		}
 | 
			
		||||
		err = can.ssl(cn.opts)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		w := can.writeBuf(0)
 | 
			
		||||
		w.int32(80877102) // cancel request code
 | 
			
		||||
		w.int32(cn.processID)
 | 
			
		||||
		w.int32(cn.secretKey)
 | 
			
		||||
 | 
			
		||||
		if err := can.sendStartupPacket(w); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Read until EOF to ensure that the server received the cancel.
 | 
			
		||||
	{
 | 
			
		||||
		_, err := io.Copy(ioutil.Discard, c)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								vendor/github.com/lib/pq/connector.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/lib/pq/connector.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								vendor/github.com/lib/pq/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/lib/pq/copy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -13,6 +13,7 @@ var (
 | 
			
		||||
	errBinaryCopyNotSupported     = errors.New("pq: only text format supported for COPY")
 | 
			
		||||
	errCopyToNotSupported         = errors.New("pq: COPY TO is not supported")
 | 
			
		||||
	errCopyNotSupportedOutsideTxn = errors.New("pq: COPY is only allowed inside a transaction")
 | 
			
		||||
	errCopyInProgress             = errors.New("pq: COPY in progress")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CopyIn creates a COPY FROM statement which can be prepared with
 | 
			
		||||
@@ -96,13 +97,13 @@ awaitCopyInResponse:
 | 
			
		||||
			err = parseError(r)
 | 
			
		||||
		case 'Z':
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				cn.bad = true
 | 
			
		||||
				ci.setBad()
 | 
			
		||||
				errorf("unexpected ReadyForQuery in response to COPY")
 | 
			
		||||
			}
 | 
			
		||||
			cn.processReadyForQuery(r)
 | 
			
		||||
			return nil, err
 | 
			
		||||
		default:
 | 
			
		||||
			cn.bad = true
 | 
			
		||||
			ci.setBad()
 | 
			
		||||
			errorf("unknown response for copy query: %q", t)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -121,7 +122,7 @@ awaitCopyInResponse:
 | 
			
		||||
			cn.processReadyForQuery(r)
 | 
			
		||||
			return nil, err
 | 
			
		||||
		default:
 | 
			
		||||
			cn.bad = true
 | 
			
		||||
			ci.setBad()
 | 
			
		||||
			errorf("unknown response for CopyFail: %q", t)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -142,7 +143,7 @@ func (ci *copyin) resploop() {
 | 
			
		||||
		var r readBuf
 | 
			
		||||
		t, err := ci.cn.recvMessage(&r)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ci.cn.bad = true
 | 
			
		||||
			ci.setBad()
 | 
			
		||||
			ci.setError(err)
 | 
			
		||||
			ci.done <- true
 | 
			
		||||
			return
 | 
			
		||||
@@ -160,7 +161,7 @@ func (ci *copyin) resploop() {
 | 
			
		||||
			err := parseError(&r)
 | 
			
		||||
			ci.setError(err)
 | 
			
		||||
		default:
 | 
			
		||||
			ci.cn.bad = true
 | 
			
		||||
			ci.setBad()
 | 
			
		||||
			ci.setError(fmt.Errorf("unknown response during CopyIn: %q", t))
 | 
			
		||||
			ci.done <- true
 | 
			
		||||
			return
 | 
			
		||||
@@ -168,6 +169,19 @@ func (ci *copyin) resploop() {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ci *copyin) setBad() {
 | 
			
		||||
	ci.Lock()
 | 
			
		||||
	ci.cn.bad = true
 | 
			
		||||
	ci.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ci *copyin) isBad() bool {
 | 
			
		||||
	ci.Lock()
 | 
			
		||||
	b := ci.cn.bad
 | 
			
		||||
	ci.Unlock()
 | 
			
		||||
	return b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ci *copyin) isErrorSet() bool {
 | 
			
		||||
	ci.Lock()
 | 
			
		||||
	isSet := (ci.err != nil)
 | 
			
		||||
@@ -205,7 +219,7 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {
 | 
			
		||||
		return nil, errCopyInClosed
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ci.cn.bad {
 | 
			
		||||
	if ci.isBad() {
 | 
			
		||||
		return nil, driver.ErrBadConn
 | 
			
		||||
	}
 | 
			
		||||
	defer ci.cn.errRecover(&err)
 | 
			
		||||
@@ -243,7 +257,7 @@ func (ci *copyin) Close() (err error) {
 | 
			
		||||
	}
 | 
			
		||||
	ci.closed = true
 | 
			
		||||
 | 
			
		||||
	if ci.cn.bad {
 | 
			
		||||
	if ci.isBad() {
 | 
			
		||||
		return driver.ErrBadConn
 | 
			
		||||
	}
 | 
			
		||||
	defer ci.cn.errRecover(&err)
 | 
			
		||||
@@ -258,6 +272,7 @@ func (ci *copyin) Close() (err error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	<-ci.done
 | 
			
		||||
	ci.cn.inCopy = false
 | 
			
		||||
 | 
			
		||||
	if ci.isErrorSet() {
 | 
			
		||||
		err = ci.err
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								vendor/github.com/lib/pq/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/github.com/lib/pq/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,7 +11,8 @@ using this package directly. For example:
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	func main() {
 | 
			
		||||
		db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
 | 
			
		||||
		connStr := "user=pqgotest dbname=pqgotest sslmode=verify-full"
 | 
			
		||||
		db, err := sql.Open("postgres", connStr)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
@@ -23,7 +24,8 @@ using this package directly. For example:
 | 
			
		||||
 | 
			
		||||
You can also connect to a database using a URL. For example:
 | 
			
		||||
 | 
			
		||||
	db, err := sql.Open("postgres", "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full")
 | 
			
		||||
	connStr := "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full"
 | 
			
		||||
	db, err := sql.Open("postgres", connStr)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Connection String Parameters
 | 
			
		||||
@@ -43,21 +45,28 @@ supported:
 | 
			
		||||
	* dbname - The name of the database to connect to
 | 
			
		||||
	* user - The user to sign in as
 | 
			
		||||
	* password - The user's password
 | 
			
		||||
	* host - The host to connect to. Values that start with / are for unix domain sockets. (default is localhost)
 | 
			
		||||
	* host - The host to connect to. Values that start with / are for unix
 | 
			
		||||
	  domain sockets. (default is localhost)
 | 
			
		||||
	* port - The port to bind to. (default is 5432)
 | 
			
		||||
	* sslmode - Whether or not to use SSL (default is require, this is not the default for libpq)
 | 
			
		||||
	* sslmode - Whether or not to use SSL (default is require, this is not
 | 
			
		||||
	  the default for libpq)
 | 
			
		||||
	* fallback_application_name - An application_name to fall back to if one isn't provided.
 | 
			
		||||
	* connect_timeout - Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.
 | 
			
		||||
	* connect_timeout - Maximum wait for connection, in seconds. Zero or
 | 
			
		||||
	  not specified means wait indefinitely.
 | 
			
		||||
	* sslcert - Cert 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 must contain PEM encoded data.
 | 
			
		||||
	* sslrootcert - The location of the root certificate file. The file
 | 
			
		||||
	  must contain PEM encoded data.
 | 
			
		||||
 | 
			
		||||
Valid values for sslmode are:
 | 
			
		||||
 | 
			
		||||
	* disable - No SSL
 | 
			
		||||
	* require - Always SSL (skip verification)
 | 
			
		||||
	* verify-ca - Always SSL (verify that the certificate presented by the server was signed by a trusted CA)
 | 
			
		||||
	* verify-full - Always SSL (verify that the certification presented by the server was signed by a trusted CA and the server host name matches the one in the certificate)
 | 
			
		||||
	* verify-ca - Always SSL (verify that the certificate presented by the
 | 
			
		||||
	  server was signed by a trusted CA)
 | 
			
		||||
	* verify-full - Always SSL (verify that the certification presented by
 | 
			
		||||
	  the server was signed by a trusted CA and the server host name
 | 
			
		||||
	  matches the one in the certificate)
 | 
			
		||||
 | 
			
		||||
See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
 | 
			
		||||
for more information about connection string parameters.
 | 
			
		||||
@@ -68,7 +77,7 @@ Use single quotes for values that contain whitespace:
 | 
			
		||||
 | 
			
		||||
A backslash will escape the next character in values:
 | 
			
		||||
 | 
			
		||||
    "user=space\ man password='it\'s valid'
 | 
			
		||||
    "user=space\ man password='it\'s valid'"
 | 
			
		||||
 | 
			
		||||
Note that the connection parameter client_encoding (which sets the
 | 
			
		||||
text encoding for the connection) may be set but must be "UTF8",
 | 
			
		||||
@@ -89,8 +98,10 @@ provided connection parameters.
 | 
			
		||||
The pgpass mechanism as described in http://www.postgresql.org/docs/current/static/libpq-pgpass.html
 | 
			
		||||
is supported, but on Windows PGPASSFILE must be specified explicitly.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Queries
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
database/sql does not dictate any specific format for parameter
 | 
			
		||||
markers in query strings, and pq uses the Postgres-native ordinal markers,
 | 
			
		||||
as shown above. The same marker can be reused for the same parameter:
 | 
			
		||||
@@ -114,8 +125,30 @@ For more details on RETURNING, see the Postgres documentation:
 | 
			
		||||
 | 
			
		||||
For additional instructions on querying see the documentation for the database/sql package.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Data Types
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Parameters pass through driver.DefaultParameterConverter before they are handled
 | 
			
		||||
by this package. When the binary_parameters connection option is enabled,
 | 
			
		||||
[]byte values are sent directly to the backend as data in binary format.
 | 
			
		||||
 | 
			
		||||
This package returns the following types for values from the PostgreSQL backend:
 | 
			
		||||
 | 
			
		||||
	- integer types smallint, integer, and bigint are returned as int64
 | 
			
		||||
	- floating-point types real and double precision are returned as float64
 | 
			
		||||
	- character types char, varchar, and text are returned as string
 | 
			
		||||
	- temporal types date, time, timetz, timestamp, and timestamptz are
 | 
			
		||||
	  returned as time.Time
 | 
			
		||||
	- the boolean type is returned as bool
 | 
			
		||||
	- the bytea type is returned as []byte
 | 
			
		||||
 | 
			
		||||
All other types are returned directly from the backend as []byte values in text format.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Errors
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pq may return errors of type *pq.Error which can be interrogated for error details:
 | 
			
		||||
 | 
			
		||||
        if err, ok := err.(*pq.Error); ok {
 | 
			
		||||
@@ -206,7 +239,7 @@ for more information).  Note that the channel name will be truncated to 63
 | 
			
		||||
bytes by the PostgreSQL server.
 | 
			
		||||
 | 
			
		||||
You can find a complete, working example of Listener usage at
 | 
			
		||||
http://godoc.org/github.com/lib/pq/listen_example.
 | 
			
		||||
https://godoc.org/github.com/lib/pq/example/listen.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
package pq
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/lib/pq/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/lib/pq/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -76,6 +76,12 @@ func binaryDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) inter
 | 
			
		||||
		return int64(int32(binary.BigEndian.Uint32(s)))
 | 
			
		||||
	case oid.T_int2:
 | 
			
		||||
		return int64(int16(binary.BigEndian.Uint16(s)))
 | 
			
		||||
	case oid.T_uuid:
 | 
			
		||||
		b, err := decodeUUIDBinary(s)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
		return b
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		errorf("don't know how to decode binary parameter of type %d", uint32(typ))
 | 
			
		||||
@@ -361,8 +367,15 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
 | 
			
		||||
	timeSep := daySep + 3
 | 
			
		||||
	day := p.mustAtoi(str, daySep+1, timeSep)
 | 
			
		||||
 | 
			
		||||
	minLen := monSep + len("01-01") + 1
 | 
			
		||||
 | 
			
		||||
	isBC := strings.HasSuffix(str, " BC")
 | 
			
		||||
	if isBC {
 | 
			
		||||
		minLen += 3
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var hour, minute, second int
 | 
			
		||||
	if len(str) > monSep+len("01-01")+1 {
 | 
			
		||||
	if len(str) > minLen {
 | 
			
		||||
		p.expect(str, ' ', timeSep)
 | 
			
		||||
		minSep := timeSep + 3
 | 
			
		||||
		p.expect(str, ':', minSep)
 | 
			
		||||
@@ -418,7 +431,8 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
 | 
			
		||||
		tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec)
 | 
			
		||||
	}
 | 
			
		||||
	var isoYear int
 | 
			
		||||
	if remainderIdx+3 <= len(str) && str[remainderIdx:remainderIdx+3] == " BC" {
 | 
			
		||||
 | 
			
		||||
	if isBC {
 | 
			
		||||
		isoYear = 1 - year
 | 
			
		||||
		remainderIdx += 3
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -471,7 +485,7 @@ func FormatTimestamp(t time.Time) []byte {
 | 
			
		||||
		t = t.AddDate((-t.Year())*2+1, 0, 0)
 | 
			
		||||
		bc = true
 | 
			
		||||
	}
 | 
			
		||||
	b := []byte(t.Format(time.RFC3339Nano))
 | 
			
		||||
	b := []byte(t.Format("2006-01-02 15:04:05.999999999Z07:00"))
 | 
			
		||||
 | 
			
		||||
	_, offset := t.Zone()
 | 
			
		||||
	offset = offset % 60
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/lib/pq/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/lib/pq/error.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								vendor/github.com/lib/pq/notify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/github.com/lib/pq/notify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -60,7 +60,7 @@ type ListenerConn struct {
 | 
			
		||||
	replyChan chan message
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Creates a new ListenerConn.  Use NewListener instead.
 | 
			
		||||
// NewListenerConn creates a new ListenerConn. Use NewListener instead.
 | 
			
		||||
func NewListenerConn(name string, notificationChan chan<- *Notification) (*ListenerConn, error) {
 | 
			
		||||
	return newDialListenerConn(defaultDialer{}, name, notificationChan)
 | 
			
		||||
}
 | 
			
		||||
@@ -214,17 +214,17 @@ func (l *ListenerConn) listenerConnMain() {
 | 
			
		||||
	// this ListenerConn is done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Send a LISTEN query to the server.  See ExecSimpleQuery.
 | 
			
		||||
// Listen sends a LISTEN query to the server. See ExecSimpleQuery.
 | 
			
		||||
func (l *ListenerConn) Listen(channel string) (bool, error) {
 | 
			
		||||
	return l.ExecSimpleQuery("LISTEN " + QuoteIdentifier(channel))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Send an UNLISTEN query to the server.  See ExecSimpleQuery.
 | 
			
		||||
// Unlisten sends an UNLISTEN query to the server. See ExecSimpleQuery.
 | 
			
		||||
func (l *ListenerConn) Unlisten(channel string) (bool, error) {
 | 
			
		||||
	return l.ExecSimpleQuery("UNLISTEN " + QuoteIdentifier(channel))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Send `UNLISTEN *` to the server.  See ExecSimpleQuery.
 | 
			
		||||
// UnlistenAll sends an `UNLISTEN *` query to the server. See ExecSimpleQuery.
 | 
			
		||||
func (l *ListenerConn) UnlistenAll() (bool, error) {
 | 
			
		||||
	return l.ExecSimpleQuery("UNLISTEN *")
 | 
			
		||||
}
 | 
			
		||||
@@ -267,8 +267,8 @@ func (l *ListenerConn) sendSimpleQuery(q string) (err error) {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Execute a "simple query" (i.e. one with no bindable parameters) on the
 | 
			
		||||
// connection.  The possible return values are:
 | 
			
		||||
// ExecSimpleQuery executes a "simple query" (i.e. one with no bindable
 | 
			
		||||
// parameters) on the connection. The possible return values are:
 | 
			
		||||
//   1) "executed" is true; the query was executed to completion on the
 | 
			
		||||
//      database server.  If the query failed, err will be set to the error
 | 
			
		||||
//      returned by the database, otherwise err will be nil.
 | 
			
		||||
@@ -333,6 +333,7 @@ func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close closes the connection.
 | 
			
		||||
func (l *ListenerConn) Close() error {
 | 
			
		||||
	l.connectionLock.Lock()
 | 
			
		||||
	if l.err != nil {
 | 
			
		||||
@@ -346,7 +347,7 @@ func (l *ListenerConn) Close() error {
 | 
			
		||||
	return l.cn.c.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Err() returns the reason the connection was closed.  It is not safe to call
 | 
			
		||||
// Err returns the reason the connection was closed. It is not safe to call
 | 
			
		||||
// this function until l.Notify has been closed.
 | 
			
		||||
func (l *ListenerConn) Err() error {
 | 
			
		||||
	return l.err
 | 
			
		||||
@@ -354,32 +355,43 @@ func (l *ListenerConn) Err() error {
 | 
			
		||||
 | 
			
		||||
var errListenerClosed = errors.New("pq: Listener has been closed")
 | 
			
		||||
 | 
			
		||||
// ErrChannelAlreadyOpen is returned from Listen when a channel is already
 | 
			
		||||
// open.
 | 
			
		||||
var ErrChannelAlreadyOpen = errors.New("pq: channel is already open")
 | 
			
		||||
 | 
			
		||||
// ErrChannelNotOpen is returned from Unlisten when a channel is not open.
 | 
			
		||||
var ErrChannelNotOpen = errors.New("pq: channel is not open")
 | 
			
		||||
 | 
			
		||||
// ListenerEventType is an enumeration of listener event types.
 | 
			
		||||
type ListenerEventType int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Emitted only when the database connection has been initially
 | 
			
		||||
	// initialized.  err will always be nil.
 | 
			
		||||
	// ListenerEventConnected is emitted only when the database connection
 | 
			
		||||
	// has been initially initialized. The err argument of the callback
 | 
			
		||||
	// will always be nil.
 | 
			
		||||
	ListenerEventConnected ListenerEventType = iota
 | 
			
		||||
 | 
			
		||||
	// Emitted after a database connection has been lost, either because of an
 | 
			
		||||
	// error or because Close has been called.  err will be set to the reason
 | 
			
		||||
	// the database connection was lost.
 | 
			
		||||
	// ListenerEventDisconnected is emitted after a database connection has
 | 
			
		||||
	// been lost, either because of an error or because Close has been
 | 
			
		||||
	// called. The err argument will be set to the reason the database
 | 
			
		||||
	// connection was lost.
 | 
			
		||||
	ListenerEventDisconnected
 | 
			
		||||
 | 
			
		||||
	// Emitted after a database connection has been re-established after
 | 
			
		||||
	// connection loss.  err will always be nil.  After this event has been
 | 
			
		||||
	// emitted, a nil pq.Notification is sent on the Listener.Notify channel.
 | 
			
		||||
	// ListenerEventReconnected is emitted after a database connection has
 | 
			
		||||
	// been re-established after connection loss. The err argument of the
 | 
			
		||||
	// callback will always be nil. After this event has been emitted, a
 | 
			
		||||
	// nil pq.Notification is sent on the Listener.Notify channel.
 | 
			
		||||
	ListenerEventReconnected
 | 
			
		||||
 | 
			
		||||
	// Emitted after a connection to the database was attempted, but failed.
 | 
			
		||||
	// err will be set to an error describing why the connection attempt did
 | 
			
		||||
	// not succeed.
 | 
			
		||||
	// ListenerEventConnectionAttemptFailed is emitted after a connection
 | 
			
		||||
	// to the database was attempted, but failed. The err argument will be
 | 
			
		||||
	// set to an error describing why the connection attempt did not
 | 
			
		||||
	// succeed.
 | 
			
		||||
	ListenerEventConnectionAttemptFailed
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// EventCallbackType is the event callback type. See also ListenerEventType
 | 
			
		||||
// constants' documentation.
 | 
			
		||||
type EventCallbackType func(event ListenerEventType, err error)
 | 
			
		||||
 | 
			
		||||
// Listener provides an interface for listening to notifications from a
 | 
			
		||||
@@ -454,9 +466,9 @@ func NewDialListener(d Dialer,
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns the notification channel for this listener.  This is the same
 | 
			
		||||
// channel as Notify, and will not be recreated during the life time of the
 | 
			
		||||
// Listener.
 | 
			
		||||
// NotificationChannel returns the notification channel for this listener.
 | 
			
		||||
// This is the same channel as Notify, and will not be recreated during the
 | 
			
		||||
// life time of the Listener.
 | 
			
		||||
func (l *Listener) NotificationChannel() <-chan *Notification {
 | 
			
		||||
	return l.Notify
 | 
			
		||||
}
 | 
			
		||||
@@ -625,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().
 | 
			
		||||
@@ -639,14 +651,14 @@ func (l *Listener) resync(cn *ListenerConn, notificationChan <-chan *Notificatio
 | 
			
		||||
			// close and then return the error message from the connection, as
 | 
			
		||||
			// per ListenerConn's interface.
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				for _ = range notificationChan {
 | 
			
		||||
				for range notificationChan {
 | 
			
		||||
				}
 | 
			
		||||
				doneChan <- cn.Err()
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		doneChan <- nil
 | 
			
		||||
	}()
 | 
			
		||||
	}(notificationChan)
 | 
			
		||||
 | 
			
		||||
	// Ignore notifications while synchronization is going on to avoid
 | 
			
		||||
	// deadlocks.  We have to send a nil notification over Notify anyway as
 | 
			
		||||
@@ -713,6 +725,9 @@ func (l *Listener) Close() error {
 | 
			
		||||
	}
 | 
			
		||||
	l.isClosed = true
 | 
			
		||||
 | 
			
		||||
	// Unblock calls to Listen()
 | 
			
		||||
	l.reconnectCond.Broadcast()
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -772,7 +787,7 @@ func (l *Listener) listenerConnLoop() {
 | 
			
		||||
		}
 | 
			
		||||
		l.emitEvent(ListenerEventDisconnected, err)
 | 
			
		||||
 | 
			
		||||
		time.Sleep(nextReconnect.Sub(time.Now()))
 | 
			
		||||
		time.Sleep(time.Until(nextReconnect))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/github.com/lib/pq/oid/gen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/lib/pq/oid/gen.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -10,10 +10,22 @@ import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	_ "github.com/lib/pq"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// OID represent a postgres Object Identifier Type.
 | 
			
		||||
type OID struct {
 | 
			
		||||
	ID   int
 | 
			
		||||
	Type string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name returns an upper case version of the oid type.
 | 
			
		||||
func (o OID) Name() string {
 | 
			
		||||
	return strings.ToUpper(o.Type)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	datname := os.Getenv("PGDATABASE")
 | 
			
		||||
	sslmode := os.Getenv("PGSSLMODE")
 | 
			
		||||
@@ -30,6 +42,25 @@ func main() {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	rows, err := db.Query(`
 | 
			
		||||
		SELECT typname, oid
 | 
			
		||||
		FROM pg_type WHERE oid < 10000
 | 
			
		||||
		ORDER BY oid;
 | 
			
		||||
	`)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	oids := make([]*OID, 0)
 | 
			
		||||
	for rows.Next() {
 | 
			
		||||
		var oid OID
 | 
			
		||||
		if err = rows.Scan(&oid.Type, &oid.ID); err != nil {
 | 
			
		||||
			log.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
		oids = append(oids, &oid)
 | 
			
		||||
	}
 | 
			
		||||
	if err = rows.Err(); err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	cmd := exec.Command("gofmt")
 | 
			
		||||
	cmd.Stderr = os.Stderr
 | 
			
		||||
	w, err := cmd.StdinPipe()
 | 
			
		||||
@@ -45,30 +76,18 @@ func main() {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintln(w, "// generated by 'go run gen.go'; do not edit")
 | 
			
		||||
	fmt.Fprintln(w, "// Code generated by gen.go. DO NOT EDIT.")
 | 
			
		||||
	fmt.Fprintln(w, "\npackage oid")
 | 
			
		||||
	fmt.Fprintln(w, "const (")
 | 
			
		||||
	rows, err := db.Query(`
 | 
			
		||||
		SELECT typname, oid
 | 
			
		||||
		FROM pg_type WHERE oid < 10000
 | 
			
		||||
		ORDER BY oid;
 | 
			
		||||
	`)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	var name string
 | 
			
		||||
	var oid int
 | 
			
		||||
	for rows.Next() {
 | 
			
		||||
		err = rows.Scan(&name, &oid)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatal(err)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintf(w, "T_%s Oid = %d\n", name, oid)
 | 
			
		||||
	}
 | 
			
		||||
	if err = rows.Err(); err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
	for _, oid := range oids {
 | 
			
		||||
		fmt.Fprintf(w, "T_%s Oid = %d\n", oid.Type, oid.ID)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintln(w, ")")
 | 
			
		||||
	fmt.Fprintln(w, "var TypeName = map[Oid]string{")
 | 
			
		||||
	for _, oid := range oids {
 | 
			
		||||
		fmt.Fprintf(w, "T_%s: \"%s\",\n", oid.Type, oid.Name())
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintln(w, "}")
 | 
			
		||||
	w.Close()
 | 
			
		||||
	cmd.Wait()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										184
									
								
								vendor/github.com/lib/pq/oid/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										184
									
								
								vendor/github.com/lib/pq/oid/types.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
// generated by 'go run gen.go'; do not edit
 | 
			
		||||
// Code generated by gen.go. DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package oid
 | 
			
		||||
 | 
			
		||||
@@ -18,6 +18,7 @@ const (
 | 
			
		||||
	T_xid              Oid = 28
 | 
			
		||||
	T_cid              Oid = 29
 | 
			
		||||
	T_oidvector        Oid = 30
 | 
			
		||||
	T_pg_ddl_command   Oid = 32
 | 
			
		||||
	T_pg_type          Oid = 71
 | 
			
		||||
	T_pg_attribute     Oid = 75
 | 
			
		||||
	T_pg_proc          Oid = 81
 | 
			
		||||
@@ -28,6 +29,7 @@ const (
 | 
			
		||||
	T_pg_node_tree     Oid = 194
 | 
			
		||||
	T__json            Oid = 199
 | 
			
		||||
	T_smgr             Oid = 210
 | 
			
		||||
	T_index_am_handler Oid = 325
 | 
			
		||||
	T_point            Oid = 600
 | 
			
		||||
	T_lseg             Oid = 601
 | 
			
		||||
	T_path             Oid = 602
 | 
			
		||||
@@ -133,6 +135,9 @@ const (
 | 
			
		||||
	T__uuid            Oid = 2951
 | 
			
		||||
	T_txid_snapshot    Oid = 2970
 | 
			
		||||
	T_fdw_handler      Oid = 3115
 | 
			
		||||
	T_pg_lsn           Oid = 3220
 | 
			
		||||
	T__pg_lsn          Oid = 3221
 | 
			
		||||
	T_tsm_handler      Oid = 3310
 | 
			
		||||
	T_anyenum          Oid = 3500
 | 
			
		||||
	T_tsvector         Oid = 3614
 | 
			
		||||
	T_tsquery          Oid = 3615
 | 
			
		||||
@@ -144,6 +149,8 @@ const (
 | 
			
		||||
	T__regconfig       Oid = 3735
 | 
			
		||||
	T_regdictionary    Oid = 3769
 | 
			
		||||
	T__regdictionary   Oid = 3770
 | 
			
		||||
	T_jsonb            Oid = 3802
 | 
			
		||||
	T__jsonb           Oid = 3807
 | 
			
		||||
	T_anyrange         Oid = 3831
 | 
			
		||||
	T_event_trigger    Oid = 3838
 | 
			
		||||
	T_int4range        Oid = 3904
 | 
			
		||||
@@ -158,4 +165,179 @@ const (
 | 
			
		||||
	T__daterange       Oid = 3913
 | 
			
		||||
	T_int8range        Oid = 3926
 | 
			
		||||
	T__int8range       Oid = 3927
 | 
			
		||||
	T_pg_shseclabel    Oid = 4066
 | 
			
		||||
	T_regnamespace     Oid = 4089
 | 
			
		||||
	T__regnamespace    Oid = 4090
 | 
			
		||||
	T_regrole          Oid = 4096
 | 
			
		||||
	T__regrole         Oid = 4097
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var TypeName = map[Oid]string{
 | 
			
		||||
	T_bool:             "BOOL",
 | 
			
		||||
	T_bytea:            "BYTEA",
 | 
			
		||||
	T_char:             "CHAR",
 | 
			
		||||
	T_name:             "NAME",
 | 
			
		||||
	T_int8:             "INT8",
 | 
			
		||||
	T_int2:             "INT2",
 | 
			
		||||
	T_int2vector:       "INT2VECTOR",
 | 
			
		||||
	T_int4:             "INT4",
 | 
			
		||||
	T_regproc:          "REGPROC",
 | 
			
		||||
	T_text:             "TEXT",
 | 
			
		||||
	T_oid:              "OID",
 | 
			
		||||
	T_tid:              "TID",
 | 
			
		||||
	T_xid:              "XID",
 | 
			
		||||
	T_cid:              "CID",
 | 
			
		||||
	T_oidvector:        "OIDVECTOR",
 | 
			
		||||
	T_pg_ddl_command:   "PG_DDL_COMMAND",
 | 
			
		||||
	T_pg_type:          "PG_TYPE",
 | 
			
		||||
	T_pg_attribute:     "PG_ATTRIBUTE",
 | 
			
		||||
	T_pg_proc:          "PG_PROC",
 | 
			
		||||
	T_pg_class:         "PG_CLASS",
 | 
			
		||||
	T_json:             "JSON",
 | 
			
		||||
	T_xml:              "XML",
 | 
			
		||||
	T__xml:             "_XML",
 | 
			
		||||
	T_pg_node_tree:     "PG_NODE_TREE",
 | 
			
		||||
	T__json:            "_JSON",
 | 
			
		||||
	T_smgr:             "SMGR",
 | 
			
		||||
	T_index_am_handler: "INDEX_AM_HANDLER",
 | 
			
		||||
	T_point:            "POINT",
 | 
			
		||||
	T_lseg:             "LSEG",
 | 
			
		||||
	T_path:             "PATH",
 | 
			
		||||
	T_box:              "BOX",
 | 
			
		||||
	T_polygon:          "POLYGON",
 | 
			
		||||
	T_line:             "LINE",
 | 
			
		||||
	T__line:            "_LINE",
 | 
			
		||||
	T_cidr:             "CIDR",
 | 
			
		||||
	T__cidr:            "_CIDR",
 | 
			
		||||
	T_float4:           "FLOAT4",
 | 
			
		||||
	T_float8:           "FLOAT8",
 | 
			
		||||
	T_abstime:          "ABSTIME",
 | 
			
		||||
	T_reltime:          "RELTIME",
 | 
			
		||||
	T_tinterval:        "TINTERVAL",
 | 
			
		||||
	T_unknown:          "UNKNOWN",
 | 
			
		||||
	T_circle:           "CIRCLE",
 | 
			
		||||
	T__circle:          "_CIRCLE",
 | 
			
		||||
	T_money:            "MONEY",
 | 
			
		||||
	T__money:           "_MONEY",
 | 
			
		||||
	T_macaddr:          "MACADDR",
 | 
			
		||||
	T_inet:             "INET",
 | 
			
		||||
	T__bool:            "_BOOL",
 | 
			
		||||
	T__bytea:           "_BYTEA",
 | 
			
		||||
	T__char:            "_CHAR",
 | 
			
		||||
	T__name:            "_NAME",
 | 
			
		||||
	T__int2:            "_INT2",
 | 
			
		||||
	T__int2vector:      "_INT2VECTOR",
 | 
			
		||||
	T__int4:            "_INT4",
 | 
			
		||||
	T__regproc:         "_REGPROC",
 | 
			
		||||
	T__text:            "_TEXT",
 | 
			
		||||
	T__tid:             "_TID",
 | 
			
		||||
	T__xid:             "_XID",
 | 
			
		||||
	T__cid:             "_CID",
 | 
			
		||||
	T__oidvector:       "_OIDVECTOR",
 | 
			
		||||
	T__bpchar:          "_BPCHAR",
 | 
			
		||||
	T__varchar:         "_VARCHAR",
 | 
			
		||||
	T__int8:            "_INT8",
 | 
			
		||||
	T__point:           "_POINT",
 | 
			
		||||
	T__lseg:            "_LSEG",
 | 
			
		||||
	T__path:            "_PATH",
 | 
			
		||||
	T__box:             "_BOX",
 | 
			
		||||
	T__float4:          "_FLOAT4",
 | 
			
		||||
	T__float8:          "_FLOAT8",
 | 
			
		||||
	T__abstime:         "_ABSTIME",
 | 
			
		||||
	T__reltime:         "_RELTIME",
 | 
			
		||||
	T__tinterval:       "_TINTERVAL",
 | 
			
		||||
	T__polygon:         "_POLYGON",
 | 
			
		||||
	T__oid:             "_OID",
 | 
			
		||||
	T_aclitem:          "ACLITEM",
 | 
			
		||||
	T__aclitem:         "_ACLITEM",
 | 
			
		||||
	T__macaddr:         "_MACADDR",
 | 
			
		||||
	T__inet:            "_INET",
 | 
			
		||||
	T_bpchar:           "BPCHAR",
 | 
			
		||||
	T_varchar:          "VARCHAR",
 | 
			
		||||
	T_date:             "DATE",
 | 
			
		||||
	T_time:             "TIME",
 | 
			
		||||
	T_timestamp:        "TIMESTAMP",
 | 
			
		||||
	T__timestamp:       "_TIMESTAMP",
 | 
			
		||||
	T__date:            "_DATE",
 | 
			
		||||
	T__time:            "_TIME",
 | 
			
		||||
	T_timestamptz:      "TIMESTAMPTZ",
 | 
			
		||||
	T__timestamptz:     "_TIMESTAMPTZ",
 | 
			
		||||
	T_interval:         "INTERVAL",
 | 
			
		||||
	T__interval:        "_INTERVAL",
 | 
			
		||||
	T__numeric:         "_NUMERIC",
 | 
			
		||||
	T_pg_database:      "PG_DATABASE",
 | 
			
		||||
	T__cstring:         "_CSTRING",
 | 
			
		||||
	T_timetz:           "TIMETZ",
 | 
			
		||||
	T__timetz:          "_TIMETZ",
 | 
			
		||||
	T_bit:              "BIT",
 | 
			
		||||
	T__bit:             "_BIT",
 | 
			
		||||
	T_varbit:           "VARBIT",
 | 
			
		||||
	T__varbit:          "_VARBIT",
 | 
			
		||||
	T_numeric:          "NUMERIC",
 | 
			
		||||
	T_refcursor:        "REFCURSOR",
 | 
			
		||||
	T__refcursor:       "_REFCURSOR",
 | 
			
		||||
	T_regprocedure:     "REGPROCEDURE",
 | 
			
		||||
	T_regoper:          "REGOPER",
 | 
			
		||||
	T_regoperator:      "REGOPERATOR",
 | 
			
		||||
	T_regclass:         "REGCLASS",
 | 
			
		||||
	T_regtype:          "REGTYPE",
 | 
			
		||||
	T__regprocedure:    "_REGPROCEDURE",
 | 
			
		||||
	T__regoper:         "_REGOPER",
 | 
			
		||||
	T__regoperator:     "_REGOPERATOR",
 | 
			
		||||
	T__regclass:        "_REGCLASS",
 | 
			
		||||
	T__regtype:         "_REGTYPE",
 | 
			
		||||
	T_record:           "RECORD",
 | 
			
		||||
	T_cstring:          "CSTRING",
 | 
			
		||||
	T_any:              "ANY",
 | 
			
		||||
	T_anyarray:         "ANYARRAY",
 | 
			
		||||
	T_void:             "VOID",
 | 
			
		||||
	T_trigger:          "TRIGGER",
 | 
			
		||||
	T_language_handler: "LANGUAGE_HANDLER",
 | 
			
		||||
	T_internal:         "INTERNAL",
 | 
			
		||||
	T_opaque:           "OPAQUE",
 | 
			
		||||
	T_anyelement:       "ANYELEMENT",
 | 
			
		||||
	T__record:          "_RECORD",
 | 
			
		||||
	T_anynonarray:      "ANYNONARRAY",
 | 
			
		||||
	T_pg_authid:        "PG_AUTHID",
 | 
			
		||||
	T_pg_auth_members:  "PG_AUTH_MEMBERS",
 | 
			
		||||
	T__txid_snapshot:   "_TXID_SNAPSHOT",
 | 
			
		||||
	T_uuid:             "UUID",
 | 
			
		||||
	T__uuid:            "_UUID",
 | 
			
		||||
	T_txid_snapshot:    "TXID_SNAPSHOT",
 | 
			
		||||
	T_fdw_handler:      "FDW_HANDLER",
 | 
			
		||||
	T_pg_lsn:           "PG_LSN",
 | 
			
		||||
	T__pg_lsn:          "_PG_LSN",
 | 
			
		||||
	T_tsm_handler:      "TSM_HANDLER",
 | 
			
		||||
	T_anyenum:          "ANYENUM",
 | 
			
		||||
	T_tsvector:         "TSVECTOR",
 | 
			
		||||
	T_tsquery:          "TSQUERY",
 | 
			
		||||
	T_gtsvector:        "GTSVECTOR",
 | 
			
		||||
	T__tsvector:        "_TSVECTOR",
 | 
			
		||||
	T__gtsvector:       "_GTSVECTOR",
 | 
			
		||||
	T__tsquery:         "_TSQUERY",
 | 
			
		||||
	T_regconfig:        "REGCONFIG",
 | 
			
		||||
	T__regconfig:       "_REGCONFIG",
 | 
			
		||||
	T_regdictionary:    "REGDICTIONARY",
 | 
			
		||||
	T__regdictionary:   "_REGDICTIONARY",
 | 
			
		||||
	T_jsonb:            "JSONB",
 | 
			
		||||
	T__jsonb:           "_JSONB",
 | 
			
		||||
	T_anyrange:         "ANYRANGE",
 | 
			
		||||
	T_event_trigger:    "EVENT_TRIGGER",
 | 
			
		||||
	T_int4range:        "INT4RANGE",
 | 
			
		||||
	T__int4range:       "_INT4RANGE",
 | 
			
		||||
	T_numrange:         "NUMRANGE",
 | 
			
		||||
	T__numrange:        "_NUMRANGE",
 | 
			
		||||
	T_tsrange:          "TSRANGE",
 | 
			
		||||
	T__tsrange:         "_TSRANGE",
 | 
			
		||||
	T_tstzrange:        "TSTZRANGE",
 | 
			
		||||
	T__tstzrange:       "_TSTZRANGE",
 | 
			
		||||
	T_daterange:        "DATERANGE",
 | 
			
		||||
	T__daterange:       "_DATERANGE",
 | 
			
		||||
	T_int8range:        "INT8RANGE",
 | 
			
		||||
	T__int8range:       "_INT8RANGE",
 | 
			
		||||
	T_pg_shseclabel:    "PG_SHSECLABEL",
 | 
			
		||||
	T_regnamespace:     "REGNAMESPACE",
 | 
			
		||||
	T__regnamespace:    "_REGNAMESPACE",
 | 
			
		||||
	T_regrole:          "REGROLE",
 | 
			
		||||
	T__regrole:         "_REGROLE",
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										93
									
								
								vendor/github.com/lib/pq/rows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/lib/pq/rows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
			
		||||
package pq
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/lib/pq/oid"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const headerSize = 4
 | 
			
		||||
 | 
			
		||||
type fieldDesc struct {
 | 
			
		||||
	// The object ID of the data type.
 | 
			
		||||
	OID oid.Oid
 | 
			
		||||
	// The data type size (see pg_type.typlen).
 | 
			
		||||
	// Note that negative values denote variable-width types.
 | 
			
		||||
	Len int
 | 
			
		||||
	// The type modifier (see pg_attribute.atttypmod).
 | 
			
		||||
	// The meaning of the modifier is type-specific.
 | 
			
		||||
	Mod int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fd fieldDesc) Type() reflect.Type {
 | 
			
		||||
	switch fd.OID {
 | 
			
		||||
	case oid.T_int8:
 | 
			
		||||
		return reflect.TypeOf(int64(0))
 | 
			
		||||
	case oid.T_int4:
 | 
			
		||||
		return reflect.TypeOf(int32(0))
 | 
			
		||||
	case oid.T_int2:
 | 
			
		||||
		return reflect.TypeOf(int16(0))
 | 
			
		||||
	case oid.T_varchar, oid.T_text:
 | 
			
		||||
		return reflect.TypeOf("")
 | 
			
		||||
	case oid.T_bool:
 | 
			
		||||
		return reflect.TypeOf(false)
 | 
			
		||||
	case oid.T_date, oid.T_time, oid.T_timetz, oid.T_timestamp, oid.T_timestamptz:
 | 
			
		||||
		return reflect.TypeOf(time.Time{})
 | 
			
		||||
	case oid.T_bytea:
 | 
			
		||||
		return reflect.TypeOf([]byte(nil))
 | 
			
		||||
	default:
 | 
			
		||||
		return reflect.TypeOf(new(interface{})).Elem()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fd fieldDesc) Name() string {
 | 
			
		||||
	return oid.TypeName[fd.OID]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fd fieldDesc) Length() (length int64, ok bool) {
 | 
			
		||||
	switch fd.OID {
 | 
			
		||||
	case oid.T_text, oid.T_bytea:
 | 
			
		||||
		return math.MaxInt64, true
 | 
			
		||||
	case oid.T_varchar, oid.T_bpchar:
 | 
			
		||||
		return int64(fd.Mod - headerSize), true
 | 
			
		||||
	default:
 | 
			
		||||
		return 0, false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fd fieldDesc) PrecisionScale() (precision, scale int64, ok bool) {
 | 
			
		||||
	switch fd.OID {
 | 
			
		||||
	case oid.T_numeric, oid.T__numeric:
 | 
			
		||||
		mod := fd.Mod - headerSize
 | 
			
		||||
		precision = int64((mod >> 16) & 0xffff)
 | 
			
		||||
		scale = int64(mod & 0xffff)
 | 
			
		||||
		return precision, scale, true
 | 
			
		||||
	default:
 | 
			
		||||
		return 0, 0, false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ColumnTypeScanType returns the value type that can be used to scan types into.
 | 
			
		||||
func (rs *rows) ColumnTypeScanType(index int) reflect.Type {
 | 
			
		||||
	return rs.colTyps[index].Type()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ColumnTypeDatabaseTypeName return the database system type name.
 | 
			
		||||
func (rs *rows) ColumnTypeDatabaseTypeName(index int) string {
 | 
			
		||||
	return rs.colTyps[index].Name()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ColumnTypeLength returns the length of the column type if the column is a
 | 
			
		||||
// variable length type. If the column is not a variable length type ok
 | 
			
		||||
// should return false.
 | 
			
		||||
func (rs *rows) ColumnTypeLength(index int) (length int64, ok bool) {
 | 
			
		||||
	return rs.colTyps[index].Length()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ColumnTypePrecisionScale should return the precision and scale for decimal
 | 
			
		||||
// types. If not applicable, ok should be false.
 | 
			
		||||
func (rs *rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
 | 
			
		||||
	return rs.colTyps[index].PrecisionScale()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								vendor/github.com/lib/pq/ssl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								vendor/github.com/lib/pq/ssl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
package pq
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"crypto/x509"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/user"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 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, error), error) {
 | 
			
		||||
	verifyCaOnly := false
 | 
			
		||||
	tlsConf := tls.Config{}
 | 
			
		||||
	switch mode := o["sslmode"]; mode {
 | 
			
		||||
	// "require" is the default.
 | 
			
		||||
	case "", "require":
 | 
			
		||||
		// We must skip TLS's own verification since it requires full
 | 
			
		||||
		// verification since Go 1.3.
 | 
			
		||||
		tlsConf.InsecureSkipVerify = true
 | 
			
		||||
 | 
			
		||||
		// From http://www.postgresql.org/docs/current/static/libpq-ssl.html:
 | 
			
		||||
		//
 | 
			
		||||
		// Note: For backwards compatibility with earlier versions of
 | 
			
		||||
		// PostgreSQL, if a root CA file exists, the behavior of
 | 
			
		||||
		// sslmode=require will be the same as that of verify-ca, meaning the
 | 
			
		||||
		// server certificate is validated against the CA. Relying on this
 | 
			
		||||
		// behavior is discouraged, and applications that need certificate
 | 
			
		||||
		// validation should always use verify-ca or verify-full.
 | 
			
		||||
		if sslrootcert, ok := o["sslrootcert"]; ok {
 | 
			
		||||
			if _, err := os.Stat(sslrootcert); err == nil {
 | 
			
		||||
				verifyCaOnly = true
 | 
			
		||||
			} else {
 | 
			
		||||
				delete(o, "sslrootcert")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	case "verify-ca":
 | 
			
		||||
		// We must skip TLS's own verification since it requires full
 | 
			
		||||
		// verification since Go 1.3.
 | 
			
		||||
		tlsConf.InsecureSkipVerify = true
 | 
			
		||||
		verifyCaOnly = true
 | 
			
		||||
	case "verify-full":
 | 
			
		||||
		tlsConf.ServerName = o["host"]
 | 
			
		||||
	case "disable":
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmterrorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := sslClientCertificates(&tlsConf, o)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	err = sslCertificateAuthority(&tlsConf, o)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Accept renegotiation requests initiated by the backend.
 | 
			
		||||
	//
 | 
			
		||||
	// Renegotiation was deprecated then removed from PostgreSQL 9.5, but
 | 
			
		||||
	// the default configuration of older versions has it enabled. Redshift
 | 
			
		||||
	// also initiates renegotiations and cannot be reconfigured.
 | 
			
		||||
	tlsConf.Renegotiation = tls.RenegotiateFreelyAsClient
 | 
			
		||||
 | 
			
		||||
	return func(conn net.Conn) (net.Conn, error) {
 | 
			
		||||
		client := tls.Client(conn, &tlsConf)
 | 
			
		||||
		if verifyCaOnly {
 | 
			
		||||
			err := sslVerifyCertificateAuthority(client, &tlsConf)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		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) 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.
 | 
			
		||||
	user, _ := user.Current()
 | 
			
		||||
 | 
			
		||||
	// In libpq, the client 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#L1036-L1037
 | 
			
		||||
	sslcert := o["sslcert"]
 | 
			
		||||
	if len(sslcert) == 0 && user != nil {
 | 
			
		||||
		sslcert = filepath.Join(user.HomeDir, ".postgresql", "postgresql.crt")
 | 
			
		||||
	}
 | 
			
		||||
	// https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1045
 | 
			
		||||
	if len(sslcert) == 0 {
 | 
			
		||||
		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 nil
 | 
			
		||||
	} else if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// In libpq, the ssl key 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#L1123-L1222
 | 
			
		||||
	sslkey := o["sslkey"]
 | 
			
		||||
	if len(sslkey) == 0 && user != nil {
 | 
			
		||||
		sslkey = filepath.Join(user.HomeDir, ".postgresql", "postgresql.key")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(sslkey) > 0 {
 | 
			
		||||
		if err := sslKeyPermissions(sslkey); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cert, err := tls.LoadX509KeyPair(sslcert, sslkey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		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) 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
 | 
			
		||||
	if sslrootcert := o["sslrootcert"]; len(sslrootcert) > 0 {
 | 
			
		||||
		tlsConf.RootCAs = x509.NewCertPool()
 | 
			
		||||
 | 
			
		||||
		cert, err := ioutil.ReadFile(sslrootcert)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !tlsConf.RootCAs.AppendCertsFromPEM(cert) {
 | 
			
		||||
			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) error {
 | 
			
		||||
	err := client.Handshake()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	certs := client.ConnectionState().PeerCertificates
 | 
			
		||||
	opts := x509.VerifyOptions{
 | 
			
		||||
		DNSName:       client.ConnectionState().ServerName,
 | 
			
		||||
		Intermediates: x509.NewCertPool(),
 | 
			
		||||
		Roots:         tlsConf.RootCAs,
 | 
			
		||||
	}
 | 
			
		||||
	for i, cert := range certs {
 | 
			
		||||
		if i == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		opts.Intermediates.AddCert(cert)
 | 
			
		||||
	}
 | 
			
		||||
	_, err = certs[0].Verify(opts)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/lib/pq/ssl_permissions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/lib/pq/ssl_permissions.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// +build !windows
 | 
			
		||||
 | 
			
		||||
package pq
 | 
			
		||||
 | 
			
		||||
import "os"
 | 
			
		||||
 | 
			
		||||
// sslKeyPermissions checks the permissions on user-supplied ssl key files.
 | 
			
		||||
// The key file should have very little access.
 | 
			
		||||
//
 | 
			
		||||
// libpq does not check key file permissions on Windows.
 | 
			
		||||
func sslKeyPermissions(sslkey string) error {
 | 
			
		||||
	info, err := os.Stat(sslkey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if info.Mode().Perm()&0077 != 0 {
 | 
			
		||||
		return ErrSSLKeyHasWorldPermissions
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/lib/pq/ssl_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/lib/pq/ssl_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package pq
 | 
			
		||||
 | 
			
		||||
// sslKeyPermissions checks the permissions on user-supplied ssl key files.
 | 
			
		||||
// The key file should have very little access.
 | 
			
		||||
//
 | 
			
		||||
// libpq does not check key file permissions on Windows.
 | 
			
		||||
func sslKeyPermissions(string) error { return nil }
 | 
			
		||||
							
								
								
									
										23
									
								
								vendor/github.com/lib/pq/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/lib/pq/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
package pq
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// decodeUUIDBinary interprets the binary format of a uuid, returning it in text format.
 | 
			
		||||
func decodeUUIDBinary(src []byte) ([]byte, error) {
 | 
			
		||||
	if len(src) != 16 {
 | 
			
		||||
		return nil, fmt.Errorf("pq: unable to decode uuid; bad length: %d", len(src))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dst := make([]byte, 36)
 | 
			
		||||
	dst[8], dst[13], dst[18], dst[23] = '-', '-', '-', '-'
 | 
			
		||||
	hex.Encode(dst[0:], src[0:4])
 | 
			
		||||
	hex.Encode(dst[9:], src[4:6])
 | 
			
		||||
	hex.Encode(dst[14:], src[6:8])
 | 
			
		||||
	hex.Encode(dst[19:], src[8:10])
 | 
			
		||||
	hex.Encode(dst[24:], src[10:16])
 | 
			
		||||
 | 
			
		||||
	return dst, nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user