bump lib/pq
This commit is contained in:
		
							
								
								
									
										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