Skip to content
Permalink
Browse files

[CALCITE-3320] Use transitional x/xerrors package when working with e…

…rrors
  • Loading branch information...
F21 committed Sep 18, 2019
1 parent 1ff0ccf commit e2f87a36b43e873e6a894713a3221b4df5305b56
Showing with 68 additions and 56 deletions.
  1. +2 −2 class_mappings.go
  2. +3 −2 compat_go18.go
  3. +4 −1 connection.go
  4. +10 −10 connection_go18.go
  5. +4 −4 driver.go
  6. +15 −14 dsn.go
  7. +1 −0 go.mod
  8. +2 −0 go.sum
  9. +10 −9 http_client.go
  10. +7 −7 http_client_wrappers.go
  11. +4 −2 result.go
  12. +2 −2 statement.go
  13. +4 −3 statement_go18.go
@@ -18,11 +18,11 @@
package avatica

import (
"fmt"
"strings"

avaticaMessage "github.com/apache/calcite-avatica-go/v4/message"
"github.com/golang/protobuf/proto"
"golang.org/x/xerrors"
)

const (
@@ -117,6 +117,6 @@ func responseFromClassName(className string) (proto.Message, error) {
case "SyncResultsResponse":
return &avaticaMessage.SyncResultsResponse{}, nil
default:
return nil, fmt.Errorf("Unable to create response from the string: %s", className)
return nil, xerrors.Errorf("unable to create response from the string: %s", className)
}
}
@@ -21,7 +21,8 @@ package avatica

import (
"database/sql/driver"
"fmt"

"golang.org/x/xerrors"
)

func driverNamedValueToNamedValue(values []driver.NamedValue) ([]namedValue, error) {
@@ -31,7 +32,7 @@ func driverNamedValueToNamedValue(values []driver.NamedValue) ([]namedValue, err
list[i] = namedValue(nv)

if nv.Name != "" {
return list, fmt.Errorf("named parameters are not supported: %s given", nv.Name)
return list, xerrors.Errorf("named parameters are not supported: %s given", nv.Name)
}
}

@@ -23,6 +23,7 @@ import (

"github.com/apache/calcite-avatica-go/v4/errors"
"github.com/apache/calcite-avatica-go/v4/message"
"golang.org/x/xerrors"
)

type conn struct {
@@ -206,7 +207,9 @@ func (c *conn) query(ctx context.Context, query string, args []namedValue) (driv

func (c *conn) avaticaErrorToResponseErrorOrError(err error) error {

avaticaErr, ok := err.(avaticaError)
var avaticaErr avaticaError

ok := xerrors.As(err, &avaticaErr)

if !ok {
return err
@@ -23,14 +23,14 @@ import (
"context"
"database/sql"
"database/sql/driver"
"errors"
"fmt"

"golang.org/x/xerrors"
)

func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {

if opts.ReadOnly {
return nil, errors.New("Read-only transactions are not supported")
return nil, xerrors.New("read-only transactions are not supported")
}

var isolation isoLevel
@@ -43,17 +43,17 @@ func (c *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, e
case sql.LevelReadCommitted:
isolation = isolationReadComitted
case sql.LevelWriteCommitted:
return nil, errors.New("LevelWriteCommitted isolation level is not supported")
return nil, xerrors.New("LevelWriteCommitted isolation level is not supported")
case sql.LevelRepeatableRead:
isolation = isolationRepeatableRead
case sql.LevelSnapshot:
return nil, errors.New("LevelSnapshot isolation level is not supported")
return nil, xerrors.New("LevelSnapshot isolation level is not supported")
case sql.LevelSerializable:
isolation = isolationSerializable
case sql.LevelLinearizable:
return nil, errors.New("LevelLinearizable isolation level is not supported")
return nil, xerrors.New("LevelLinearizable isolation level is not supported")
default:
return nil, fmt.Errorf("Unsupported transaction isolation level: %d", opts.Isolation)
return nil, xerrors.Errorf("unsupported transaction isolation level: %d", opts.Isolation)
}

return c.begin(ctx, isolation)
@@ -67,7 +67,7 @@ func (c *conn) ExecContext(ctx context.Context, query string, args []driver.Name
list, err := driverNamedValueToNamedValue(args)

if err != nil {
return nil, fmt.Errorf("could not execute statement: %s", err)
return nil, xerrors.Errorf("could not execute statement: %v", err)
}

return c.exec(ctx, query, list)
@@ -78,7 +78,7 @@ func (c *conn) Ping(ctx context.Context) error {
_, err := c.ExecContext(ctx, c.adapter.GetPingStatement(), []driver.NamedValue{})

if err != nil {
return fmt.Errorf("Error pinging database: %s", err)
return xerrors.Errorf("error pinging database: %v", err)
}

return nil
@@ -88,7 +88,7 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
list, err := driverNamedValueToNamedValue(args)

if err != nil {
return nil, fmt.Errorf("could not execute query: %s", err)
return nil, xerrors.Errorf("could not execute query: %v", err)
}

return c.query(ctx, query, list)
@@ -35,14 +35,14 @@ import (
"context"
"database/sql"
"database/sql/driver"
"fmt"
"net/http"

"github.com/apache/calcite-avatica-go/v4/generic"
"github.com/apache/calcite-avatica-go/v4/hsqldb"
"github.com/apache/calcite-avatica-go/v4/message"
"github.com/apache/calcite-avatica-go/v4/phoenix"
"github.com/hashicorp/go-uuid"
"golang.org/x/xerrors"
)

// Driver is exported to allow it to be used directly.
@@ -66,18 +66,18 @@ func (c *Connector) Connect(context.Context) (driver.Conn, error) {
config, err := ParseDSN(c.dsn)

if err != nil {
return nil, fmt.Errorf("Unable to open connection: %s", err)
return nil, xerrors.Errorf("unable to open connection: %v", err)
}

httpClient, err := NewHTTPClient(config.endpoint, c.Client, config)

if err != nil {
return nil, fmt.Errorf("Unable to create HTTP client: %s", err)
return nil, xerrors.Errorf("unable to create HTTP client: %v", err)
}

connectionId, err := uuid.GenerateUUID()
if err != nil {
return nil, fmt.Errorf("Error generating connection id: %s", err)
return nil, xerrors.Errorf("error generating connection id: %v", err)
}

info := map[string]string{
29 dsn.go
@@ -18,11 +18,12 @@
package avatica

import (
"fmt"
"net/url"
"strconv"
"strings"
"time"

"golang.org/x/xerrors"
)

type authentication int
@@ -70,7 +71,7 @@ func ParseDSN(dsn string) (*Config, error) {
parsed, err := url.ParseRequestURI(dsn)

if err != nil {
return nil, fmt.Errorf("Unable to parse DSN: %s", err)
return nil, xerrors.Errorf("unable to parse DSN: %v", err)
}

queries := parsed.Query()
@@ -80,7 +81,7 @@ func ParseDSN(dsn string) (*Config, error) {
maxRowTotal, err := strconv.Atoi(v)

if err != nil {
return nil, fmt.Errorf("Invalid value for maxRowsTotal: %s", err)
return nil, xerrors.Errorf("invalid value for maxRowsTotal: %v", err)
}

conf.maxRowsTotal = int64(maxRowTotal)
@@ -91,7 +92,7 @@ func ParseDSN(dsn string) (*Config, error) {
maxRowTotal, err := strconv.Atoi(v)

if err != nil {
return nil, fmt.Errorf("Invalid value for frameMaxSize: %s", err)
return nil, xerrors.Errorf("invalid value for frameMaxSize: %v", err)
}

conf.frameMaxSize = int32(maxRowTotal)
@@ -102,7 +103,7 @@ func ParseDSN(dsn string) (*Config, error) {
loc, err := time.LoadLocation(v)

if err != nil {
return nil, fmt.Errorf("Invalid value for location: %s", err)
return nil, xerrors.Errorf("invalid value for location: %v", err)
}

conf.location = loc
@@ -113,11 +114,11 @@ func ParseDSN(dsn string) (*Config, error) {
isolation, err := strconv.Atoi(v)

if err != nil {
return nil, fmt.Errorf("Invalid value for transactionIsolation: %s", err)
return nil, xerrors.Errorf("invalid value for transactionIsolation: %v", err)
}

if isolation < 0 || isolation > 8 || isolation&(isolation-1) != 0 {
return nil, fmt.Errorf("transactionIsolation must be 0, 1, 2, 4 or 8, %d given", isolation)
return nil, xerrors.Errorf("transactionIsolation must be 0, 1, 2, 4 or 8, %d given", isolation)
}

conf.transactionIsolation = uint32(isolation)
@@ -134,23 +135,23 @@ func ParseDSN(dsn string) (*Config, error) {
} else if auth == "SPNEGO" {
conf.authentication = spnego
} else {
return nil, fmt.Errorf("authentication must be either BASIC, DIGEST or SPNEGO")
return nil, xerrors.New("authentication must be either BASIC, DIGEST or SPNEGO")
}

if conf.authentication == basic || conf.authentication == digest {

user := queries.Get("avaticaUser")

if user == "" {
return nil, fmt.Errorf("authentication is set to %s, but avaticaUser is empty", v)
return nil, xerrors.Errorf("authentication is set to %s, but avaticaUser is empty", v)
}

conf.avaticaUser = user

pass := queries.Get("avaticaPassword")

if pass == "" {
return nil, fmt.Errorf("authentication is set to %s, but avaticaPassword is empty", v)
return nil, xerrors.Errorf("authentication is set to %s, but avaticaPassword is empty", v)
}

conf.avaticaPassword = pass
@@ -165,23 +166,23 @@ func ParseDSN(dsn string) (*Config, error) {
krb5CredentialCache := queries.Get("krb5CredentialCache")

if principal == "" && keytab == "" && krb5Conf == "" && krb5CredentialCache == "" {
return nil, fmt.Errorf("when using SPNEGO authetication, you must provide the principal, keytab and krb5Conf parameters or a krb5TicketCache parameter")
return nil, xerrors.New("when using SPNEGO authetication, you must provide the principal, keytab and krb5Conf parameters or a krb5TicketCache parameter")
}

if !((principal != "" && keytab != "" && krb5Conf != "") || (principal == "" && keytab == "" && krb5Conf == "")) {
return nil, fmt.Errorf("when using SPNEGO authentication with a principal and keytab, the principal, keytab and krb5Conf parameters are required")
return nil, xerrors.New("when using SPNEGO authentication with a principal and keytab, the principal, keytab and krb5Conf parameters are required")
}

if (principal != "" || keytab != "" || krb5Conf != "") && krb5CredentialCache != "" {
return nil, fmt.Errorf("ambigious configuration for SPNEGO authentication: use either principal, keytab and krb5Conf or krb5TicketCache")
return nil, xerrors.New("ambigious configuration for SPNEGO authentication: use either principal, keytab and krb5Conf or krb5TicketCache")
}

if principal != "" {

splittedPrincipal := strings.Split(principal, "@")

if len(splittedPrincipal) != 2 {
return nil, fmt.Errorf("invalid kerberos principal (%s): the principal should be in the format primary/instance@realm where instance is optional", principal)
return nil, xerrors.Errorf("invalid kerberos principal (%s): the principal should be in the format primary/instance@realm where instance is optional", principal)
}

conf.principal = krb5Principal{
1 go.mod
@@ -9,6 +9,7 @@ require (
github.com/stretchr/testify v1.3.0 // indirect
github.com/xinsnake/go-http-digest-auth-client v0.4.0
golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d // indirect
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect
gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect
2 go.sum
@@ -20,6 +20,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
@@ -31,6 +31,7 @@ import (

avaticaMessage "github.com/apache/calcite-avatica-go/v4/message"
"github.com/golang/protobuf/proto"
"golang.org/x/xerrors"
)

var (
@@ -80,7 +81,7 @@ func NewHTTPClient(host string, baseClient *http.Client, config *Config) (*httpC
realm := config.principal.realm
cli, err := WithKerberosAuth(baseClient, user, realm, config.keytab, config.krb5Conf, config.krb5CredentialCache)
if err != nil {
return nil, err
return nil, xerrors.Errorf("can't add kerberos authentication to http client: %v", err)
}
baseClient = cli
}
@@ -100,7 +101,7 @@ func (c *httpClient) post(ctx context.Context, message proto.Message) (proto.Mes
wrapped, err := proto.Marshal(message)

if err != nil {
return nil, err
return nil, xerrors.Errorf("error marshaling request message to protobuf: %v", err)
}

wire := &avaticaMessage.WireMessage{
@@ -111,13 +112,13 @@ func (c *httpClient) post(ctx context.Context, message proto.Message) (proto.Mes
body, err := proto.Marshal(wire)

if err != nil {
return nil, err
return nil, xerrors.Errorf("error marshaling wire message to protobuf: %v", err)
}

req, err := http.NewRequest("POST", c.host, bytes.NewReader(body))

if err != nil {
return nil, err
return nil, xerrors.Errorf("error creating http request: %v", err)
}

req.Header.Set("Content-Type", "application/x-google-protobuf")
@@ -127,35 +128,35 @@ func (c *httpClient) post(ctx context.Context, message proto.Message) (proto.Mes
res, err := c.httpClient.Do(req)

if err != nil {
return nil, err
return nil, xerrors.Errorf("error executing http request: %v", err)
}

defer res.Body.Close()

response, err := ioutil.ReadAll(res.Body)

if err != nil {
return nil, err
return nil, xerrors.Errorf("error reading response body: %v", err)
}

result := &avaticaMessage.WireMessage{}

err = proto.Unmarshal(response, result)

if err != nil {
return nil, err
return nil, xerrors.Errorf("error unmarshaling wire message: %v", err)
}

inner, err := responseFromClassName(result.Name)

if err != nil {
return nil, err
return nil, xerrors.Errorf("error getting wrapped response from wire message: %v", err)
}

err = proto.Unmarshal(result.WrappedMessage, inner)

if err != nil {
return nil, err
return nil, xerrors.Errorf("error unmarshaling wrapped message: %v", err)
}

if v, ok := inner.(*avaticaMessage.ErrorResponse); ok {

0 comments on commit e2f87a3

Please sign in to comment.
You can’t perform that action at this time.