Improve simple protocol / text format
Increased data type support for simple protocol. Improved test coverage of simple protocol. This has the additional advantage of exercising the text encoders and decoders.
This commit is contained in:
+27
-82
@@ -98,11 +98,10 @@ func TestConnectWithPreferSimpleProtocol(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
|
func TestConnectConfigRequiresConnConfigFromParseConfig(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
config := &pgx.ConnConfig{}
|
config := &pgx.ConnConfig{}
|
||||||
|
require.PanicsWithValue(t, "config must be created by ParseConfig", func() {
|
||||||
require.PanicsWithValue(t, "config must be created by ParseConfig", func() { pgx.ConnectConfig(context.Background(), config) })
|
pgx.ConnectConfig(context.Background(), config)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseConfigExtractsStatementCacheOptions(t *testing.T) {
|
func TestParseConfigExtractsStatementCacheOptions(t *testing.T) {
|
||||||
@@ -140,9 +139,7 @@ func TestParseConfigExtractsStatementCacheOptions(t *testing.T) {
|
|||||||
func TestExec(t *testing.T) {
|
func TestExec(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
if results := mustExec(t, conn, "create temporary table foo(id integer primary key);"); string(results) != "CREATE TABLE" {
|
if results := mustExec(t, conn, "create temporary table foo(id integer primary key);"); string(results) != "CREATE TABLE" {
|
||||||
t.Error("Unexpected results from Exec")
|
t.Error("Unexpected results from Exec")
|
||||||
}
|
}
|
||||||
@@ -170,14 +167,13 @@ func TestExec(t *testing.T) {
|
|||||||
if results := mustExec(t, conn, "--;"); string(results) != "" {
|
if results := mustExec(t, conn, "--;"); string(results) != "" {
|
||||||
t.Errorf("Unexpected results from Exec: %v", results)
|
t.Errorf("Unexpected results from Exec: %v", results)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecFailure(t *testing.T) {
|
func TestExecFailure(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
if _, err := conn.Exec(context.Background(), "selct;"); err == nil {
|
if _, err := conn.Exec(context.Background(), "selct;"); err == nil {
|
||||||
t.Fatal("Expected SQL syntax error")
|
t.Fatal("Expected SQL syntax error")
|
||||||
}
|
}
|
||||||
@@ -187,14 +183,13 @@ func TestExecFailure(t *testing.T) {
|
|||||||
if rows.Err() != nil {
|
if rows.Err() != nil {
|
||||||
t.Fatalf("Exec failure appears to have broken connection: %v", rows.Err())
|
t.Fatalf("Exec failure appears to have broken connection: %v", rows.Err())
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecFailureWithArguments(t *testing.T) {
|
func TestExecFailureWithArguments(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
_, err := conn.Exec(context.Background(), "selct $1;", 1)
|
_, err := conn.Exec(context.Background(), "selct $1;", 1)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected SQL syntax error")
|
t.Fatal("Expected SQL syntax error")
|
||||||
@@ -202,18 +197,14 @@ func TestExecFailureWithArguments(t *testing.T) {
|
|||||||
assert.False(t, pgconn.SafeToRetry(err))
|
assert.False(t, pgconn.SafeToRetry(err))
|
||||||
|
|
||||||
_, err = conn.Exec(context.Background(), "select $1::varchar(1);", "1", "2")
|
_, err = conn.Exec(context.Background(), "select $1::varchar(1);", "1", "2")
|
||||||
if err == nil {
|
require.Error(t, err)
|
||||||
t.Fatal("Expected pgx arguments count error", err)
|
})
|
||||||
}
|
|
||||||
assert.Equal(t, "expected 1 arguments, got 2", err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecContextWithoutCancelation(t *testing.T) {
|
func TestExecContextWithoutCancelation(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
|
|
||||||
@@ -225,14 +216,13 @@ func TestExecContextWithoutCancelation(t *testing.T) {
|
|||||||
t.Fatalf("Unexpected results from Exec: %v", commandTag)
|
t.Fatalf("Unexpected results from Exec: %v", commandTag)
|
||||||
}
|
}
|
||||||
assert.False(t, pgconn.SafeToRetry(err))
|
assert.False(t, pgconn.SafeToRetry(err))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecContextFailureWithoutCancelation(t *testing.T) {
|
func TestExecContextFailureWithoutCancelation(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
|
|
||||||
@@ -248,15 +238,13 @@ func TestExecContextFailureWithoutCancelation(t *testing.T) {
|
|||||||
t.Fatalf("ExecEx failure appears to have broken connection: %v", rows.Err())
|
t.Fatalf("ExecEx failure appears to have broken connection: %v", rows.Err())
|
||||||
}
|
}
|
||||||
assert.False(t, pgconn.SafeToRetry(err))
|
assert.False(t, pgconn.SafeToRetry(err))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecContextFailureWithoutCancelationWithArguments(t *testing.T) {
|
func TestExecContextFailureWithoutCancelationWithArguments(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
|
|
||||||
@@ -265,6 +253,7 @@ func TestExecContextFailureWithoutCancelationWithArguments(t *testing.T) {
|
|||||||
t.Fatal("Expected SQL syntax error")
|
t.Fatal("Expected SQL syntax error")
|
||||||
}
|
}
|
||||||
assert.False(t, pgconn.SafeToRetry(err))
|
assert.False(t, pgconn.SafeToRetry(err))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecFailureCloseBefore(t *testing.T) {
|
func TestExecFailureCloseBefore(t *testing.T) {
|
||||||
@@ -278,38 +267,6 @@ func TestExecFailureCloseBefore(t *testing.T) {
|
|||||||
assert.True(t, pgconn.SafeToRetry(err))
|
assert.True(t, pgconn.SafeToRetry(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecExtendedProtocol(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
|
||||||
defer cancelFunc()
|
|
||||||
|
|
||||||
commandTag, err := conn.Exec(ctx, "create temporary table foo(name varchar primary key);")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(commandTag) != "CREATE TABLE" {
|
|
||||||
t.Fatalf("Unexpected results from Exec: %v", commandTag)
|
|
||||||
}
|
|
||||||
|
|
||||||
commandTag, err = conn.Exec(
|
|
||||||
ctx,
|
|
||||||
"insert into foo(name) values($1);",
|
|
||||||
"bar",
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if string(commandTag) != "INSERT 0 1" {
|
|
||||||
t.Fatalf("Unexpected results from ExecEx: %v", commandTag)
|
|
||||||
}
|
|
||||||
|
|
||||||
ensureConnValid(t, conn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExecStatementCacheModes(t *testing.T) {
|
func TestExecStatementCacheModes(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -360,7 +317,7 @@ func TestExecStatementCacheModes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecSimpleProtocol(t *testing.T) {
|
func TestExecPerQuerySimpleProtocol(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
||||||
@@ -692,9 +649,7 @@ func TestFatalTxError(t *testing.T) {
|
|||||||
func TestInsertBoolArray(t *testing.T) {
|
func TestInsertBoolArray(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
if results := mustExec(t, conn, "create temporary table foo(spice bool[]);"); string(results) != "CREATE TABLE" {
|
if results := mustExec(t, conn, "create temporary table foo(spice bool[]);"); string(results) != "CREATE TABLE" {
|
||||||
t.Error("Unexpected results from Exec")
|
t.Error("Unexpected results from Exec")
|
||||||
}
|
}
|
||||||
@@ -703,14 +658,13 @@ func TestInsertBoolArray(t *testing.T) {
|
|||||||
if results := mustExec(t, conn, "insert into foo(spice) values($1)", []bool{true, false, true}); string(results) != "INSERT 0 1" {
|
if results := mustExec(t, conn, "insert into foo(spice) values($1)", []bool{true, false, true}); string(results) != "INSERT 0 1" {
|
||||||
t.Errorf("Unexpected results from Exec: %v", results)
|
t.Errorf("Unexpected results from Exec: %v", results)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInsertTimestampArray(t *testing.T) {
|
func TestInsertTimestampArray(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
if results := mustExec(t, conn, "create temporary table foo(spice timestamp[]);"); string(results) != "CREATE TABLE" {
|
if results := mustExec(t, conn, "create temporary table foo(spice timestamp[]);"); string(results) != "CREATE TABLE" {
|
||||||
t.Error("Unexpected results from Exec")
|
t.Error("Unexpected results from Exec")
|
||||||
}
|
}
|
||||||
@@ -719,6 +673,7 @@ func TestInsertTimestampArray(t *testing.T) {
|
|||||||
if results := mustExec(t, conn, "insert into foo(spice) values($1)", []time.Time{time.Unix(1419143667, 0), time.Unix(1419143672, 0)}); string(results) != "INSERT 0 1" {
|
if results := mustExec(t, conn, "insert into foo(spice) values($1)", []time.Time{time.Unix(1419143667, 0), time.Unix(1419143672, 0)}); string(results) != "INSERT 0 1" {
|
||||||
t.Errorf("Unexpected results from Exec: %v", results)
|
t.Errorf("Unexpected results from Exec: %v", results)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type testLog struct {
|
type testLog struct {
|
||||||
@@ -833,9 +788,7 @@ func TestConnInitConnInfo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUnregisteredTypeUsableAsStringArgumentAndBaseResult(t *testing.T) {
|
func TestUnregisteredTypeUsableAsStringArgumentAndBaseResult(t *testing.T) {
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
var n uint64
|
var n uint64
|
||||||
err := conn.QueryRow(context.Background(), "select $1::uint64", "42").Scan(&n)
|
err := conn.QueryRow(context.Background(), "select $1::uint64", "42").Scan(&n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -845,24 +798,17 @@ func TestUnregisteredTypeUsableAsStringArgumentAndBaseResult(t *testing.T) {
|
|||||||
if n != 42 {
|
if n != 42 {
|
||||||
t.Fatalf("Expected n to be 42, but was %v", n)
|
t.Fatalf("Expected n to be 42, but was %v", n)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureConnValid(t, conn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDomainType(t *testing.T) {
|
func TestDomainType(t *testing.T) {
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
var n uint64
|
var n uint64
|
||||||
|
|
||||||
// Domain type uint64 is a PostgreSQL domain of underlying type numeric.
|
// Domain type uint64 is a PostgreSQL domain of underlying type numeric.
|
||||||
|
|
||||||
// Since it is not registered, pgx does not know how to encode Go uint64 argument.
|
err := conn.QueryRow(context.Background(), "select $1::uint64", uint64(24)).Scan(&n)
|
||||||
err = conn.QueryRow(context.Background(), "select $1::uint64", uint64(24)).Scan(&n)
|
require.NoError(t, err)
|
||||||
if err == nil {
|
|
||||||
t.Fatal("expected error encoding uint64 into unregistered domain")
|
|
||||||
}
|
|
||||||
|
|
||||||
// A string can be used. But a string cannot be the result because the describe result from the PostgreSQL server gives
|
// A string can be used. But a string cannot be the result because the describe result from the PostgreSQL server gives
|
||||||
// the underlying type of numeric.
|
// the underlying type of numeric.
|
||||||
@@ -898,6 +844,5 @@ func TestDomainType(t *testing.T) {
|
|||||||
if n != 24 {
|
if n != 24 {
|
||||||
t.Fatalf("Expected n to be 24, but was %v", n)
|
t.Fatalf("Expected n to be 24, but was %v", n)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureConnValid(t, conn)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,28 @@ func (eqb *extendedQueryBuilder) encodeExtendedParamValue(ci *pgtype.ConnInfo, o
|
|||||||
return eqb.encodeExtendedParamValue(ci, oid, value)
|
return eqb.encodeExtendedParamValue(ci, oid, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There is no data type registered for the destination OID, but maybe there is data type registered for the arg
|
||||||
|
// type. If so use it's text encoder (if available).
|
||||||
|
if dt, ok := ci.DataTypeForValue(arg); ok {
|
||||||
|
value := dt.Value
|
||||||
|
if textEncoder, ok := value.(pgtype.TextEncoder); ok {
|
||||||
|
err := value.Set(arg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err = textEncoder.EncodeText(ci, eqb.paramValueBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if buf == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
eqb.paramValueBytes = buf
|
||||||
|
return eqb.paramValueBytes[pos:], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if strippedArg, ok := stripNamedType(&refVal); ok {
|
if strippedArg, ok := stripNamedType(&refVal); ok {
|
||||||
return eqb.encodeExtendedParamValue(ci, oid, strippedArg)
|
return eqb.encodeExtendedParamValue(ci, oid, strippedArg)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,18 @@ go 1.12
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cockroachdb/apd v1.1.0
|
github.com/cockroachdb/apd v1.1.0
|
||||||
|
github.com/go-stack/stack v1.8.0 // indirect
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible
|
github.com/gofrs/uuid v3.2.0+incompatible
|
||||||
github.com/jackc/pgconn v1.5.0
|
github.com/jackc/pgconn v1.5.0
|
||||||
github.com/jackc/pgio v1.0.0
|
github.com/jackc/pgio v1.0.0
|
||||||
github.com/jackc/pgproto3/v2 v2.0.1
|
github.com/jackc/pgproto3/v2 v2.0.1
|
||||||
github.com/jackc/pgtype v1.3.1-0.20200505182314-3b7c47a2a7da
|
github.com/jackc/pgtype v1.3.1-0.20200508211315-97bbe6ae20e2
|
||||||
github.com/jackc/puddle v1.1.1
|
github.com/jackc/puddle v1.1.1
|
||||||
github.com/rs/zerolog v1.15.0
|
github.com/rs/zerolog v1.15.0
|
||||||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc
|
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc
|
||||||
github.com/sirupsen/logrus v1.4.2
|
github.com/sirupsen/logrus v1.4.2
|
||||||
github.com/stretchr/testify v1.5.1
|
github.com/stretchr/testify v1.5.1
|
||||||
|
go.uber.org/multierr v1.5.0 // indirect
|
||||||
go.uber.org/zap v1.10.0
|
go.uber.org/zap v1.10.0
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
|
||||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec
|
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
@@ -11,6 +12,7 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
|||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.0 h1:DUwgMQuuPnS0rhMXenUtZpqZqrR/30NWY+qQvTpSvEs=
|
github.com/jackc/chunkreader/v2 v2.0.0 h1:DUwgMQuuPnS0rhMXenUtZpqZqrR/30NWY+qQvTpSvEs=
|
||||||
@@ -53,6 +55,8 @@ github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrU
|
|||||||
github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
|
github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
|
||||||
github.com/jackc/pgtype v1.3.1-0.20200505182314-3b7c47a2a7da h1:ZbfsOjqJ1nHsryU03mdXZy6ZEsymYvihkXxN9tUx1YU=
|
github.com/jackc/pgtype v1.3.1-0.20200505182314-3b7c47a2a7da h1:ZbfsOjqJ1nHsryU03mdXZy6ZEsymYvihkXxN9tUx1YU=
|
||||||
github.com/jackc/pgtype v1.3.1-0.20200505182314-3b7c47a2a7da/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
|
github.com/jackc/pgtype v1.3.1-0.20200505182314-3b7c47a2a7da/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
|
||||||
|
github.com/jackc/pgtype v1.3.1-0.20200508211315-97bbe6ae20e2 h1:Y6cErz3hUojOwnjUEWoZPRCBQcB7avM9ntGiYkB0wJo=
|
||||||
|
github.com/jackc/pgtype v1.3.1-0.20200508211315-97bbe6ae20e2/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
|
||||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||||
@@ -65,6 +69,7 @@ github.com/jackc/puddle v1.1.0 h1:musOWczZC/rSbqut475Vfcczg7jJsdUQf0D6oKPLgNU=
|
|||||||
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
github.com/jackc/puddle v1.1.1 h1:PJAw7H/9hoWC4Kf3J8iNmL1SwA6E8vfsLqBiL+F6CtI=
|
github.com/jackc/puddle v1.1.1 h1:PJAw7H/9hoWC4Kf3J8iNmL1SwA6E8vfsLqBiL+F6CtI=
|
||||||
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||||
@@ -97,6 +102,7 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
|||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
github.com/rs/zerolog v1.13.0 h1:hSNcYHyxDWycfePW7pUI8swuFkcSMPKh3E63Pokg1Hk=
|
github.com/rs/zerolog v1.13.0 h1:hSNcYHyxDWycfePW7pUI8swuFkcSMPKh3E63Pokg1Hk=
|
||||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
@@ -127,8 +133,13 @@ go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
|||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||||
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
|
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||||
|
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
||||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||||
@@ -136,11 +147,14 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a h1:Igim7XhdOpBnWPuYJ70XcNpq8q3BCACtVgNfoJxOV7g=
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a h1:Igim7XhdOpBnWPuYJ70XcNpq8q3BCACtVgNfoJxOV7g=
|
||||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
|
||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
|
||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@@ -163,8 +177,12 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373 h1:PPwnA7z1Pjf7XYaBP9GL1VAMZmcIWyFz7QCMSIIa3Bg=
|
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373 h1:PPwnA7z1Pjf7XYaBP9GL1VAMZmcIWyFz7QCMSIIa3Bg=
|
||||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 h1:bhOzK9QyoD0ogCnFro1m2mz41+Ib0oOhfJnBp5MR4K4=
|
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522 h1:bhOzK9QyoD0ogCnFro1m2mz41+Ib0oOhfJnBp5MR4K4=
|
||||||
@@ -176,7 +194,9 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A=
|
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A=
|
||||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package pgx_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/jackc/pgconn"
|
"github.com/jackc/pgconn"
|
||||||
@@ -9,6 +10,45 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func testWithAndWithoutPreferSimpleProtocol(t *testing.T, f func(t *testing.T, conn *pgx.Conn)) {
|
||||||
|
t.Run("SimpleProto",
|
||||||
|
func(t *testing.T) {
|
||||||
|
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
config.PreferSimpleProtocol = true
|
||||||
|
conn, err := pgx.ConnectConfig(context.Background(), config)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() {
|
||||||
|
err := conn.Close(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
f(t, conn)
|
||||||
|
|
||||||
|
ensureConnValid(t, conn)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Run("DefaultProto",
|
||||||
|
func(t *testing.T) {
|
||||||
|
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
conn, err := pgx.ConnectConfig(context.Background(), config)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() {
|
||||||
|
err := conn.Close(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
f(t, conn)
|
||||||
|
|
||||||
|
ensureConnValid(t, conn)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func mustConnectString(t testing.TB, connString string) *pgx.Conn {
|
func mustConnectString(t testing.TB, connString string) *pgx.Conn {
|
||||||
conn, err := pgx.Connect(context.Background(), connString)
|
conn, err := pgx.Connect(context.Background(), connString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+93
-123
@@ -30,6 +30,43 @@ func closeDB(t testing.TB, db *sql.DB) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testWithAndWithoutPreferSimpleProtocol(t *testing.T, f func(t *testing.T, db *sql.DB)) {
|
||||||
|
t.Run("SimpleProto",
|
||||||
|
func(t *testing.T) {
|
||||||
|
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
config.PreferSimpleProtocol = true
|
||||||
|
db := stdlib.OpenDB(*config)
|
||||||
|
defer func() {
|
||||||
|
err := db.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
f(t, db)
|
||||||
|
|
||||||
|
ensureDBValid(t, db)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Run("DefaultProto",
|
||||||
|
func(t *testing.T) {
|
||||||
|
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
db := stdlib.OpenDB(*config)
|
||||||
|
defer func() {
|
||||||
|
err := db.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
f(t, db)
|
||||||
|
|
||||||
|
ensureDBValid(t, db)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Do a simple query to ensure the DB is still usable. This is of less use in stdlib as the connection pool should
|
// Do a simple query to ensure the DB is still usable. This is of less use in stdlib as the connection pool should
|
||||||
// cover an broken connections.
|
// cover an broken connections.
|
||||||
func ensureDBValid(t testing.TB, db *sql.DB) {
|
func ensureDBValid(t testing.TB, db *sql.DB) {
|
||||||
@@ -182,9 +219,7 @@ func TestQueryCloseRowsEarly(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestConnExec(t *testing.T) {
|
func TestConnExec(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
_, err := db.Exec("create temporary table t(a varchar not null)")
|
_, err := db.Exec("create temporary table t(a varchar not null)")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -194,14 +229,11 @@ func TestConnExec(t *testing.T) {
|
|||||||
n, err := result.RowsAffected()
|
n, err := result.RowsAffected()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, 1, n)
|
require.EqualValues(t, 1, n)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQuery(t *testing.T) {
|
func TestConnQuery(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
rows, err := db.Query("select 'foo', n from generate_series($1::int, $2::int) n", int32(1), int32(10))
|
rows, err := db.Query("select 'foo', n from generate_series($1::int, $2::int) n", int32(1), int32(10))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -226,14 +258,11 @@ func TestConnQuery(t *testing.T) {
|
|||||||
|
|
||||||
err = rows.Close()
|
err = rows.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQueryNull(t *testing.T) {
|
func TestConnQueryNull(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
rows, err := db.Query("select $1::int", nil)
|
rows, err := db.Query("select $1::int", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -254,41 +283,32 @@ func TestConnQueryNull(t *testing.T) {
|
|||||||
|
|
||||||
err = rows.Close()
|
err = rows.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQueryRowByteSlice(t *testing.T) {
|
func TestConnQueryRowByteSlice(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
expected := []byte{222, 173, 190, 239}
|
expected := []byte{222, 173, 190, 239}
|
||||||
var actual []byte
|
var actual []byte
|
||||||
|
|
||||||
err := db.QueryRow(`select E'\\xdeadbeef'::bytea`).Scan(&actual)
|
err := db.QueryRow(`select E'\\xdeadbeef'::bytea`).Scan(&actual)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, expected, actual)
|
require.EqualValues(t, expected, actual)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQueryFailure(t *testing.T) {
|
func TestConnQueryFailure(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
_, err := db.Query("select 'foo")
|
_, err := db.Query("select 'foo")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.IsType(t, new(pgconn.PgError), err)
|
require.IsType(t, new(pgconn.PgError), err)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test type that pgx would handle natively in binary, but since it is not a
|
// Test type that pgx would handle natively in binary, but since it is not a
|
||||||
// database/sql native type should be passed through as a string
|
// database/sql native type should be passed through as a string
|
||||||
func TestConnQueryRowPgxBinary(t *testing.T) {
|
func TestConnQueryRowPgxBinary(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
sql := "select $1::int4[]"
|
sql := "select $1::int4[]"
|
||||||
expected := "{1,2,3}"
|
expected := "{1,2,3}"
|
||||||
var actual string
|
var actual string
|
||||||
@@ -296,14 +316,11 @@ func TestConnQueryRowPgxBinary(t *testing.T) {
|
|||||||
err := db.QueryRow(sql, expected).Scan(&actual)
|
err := db.QueryRow(sql, expected).Scan(&actual)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, expected, actual)
|
require.EqualValues(t, expected, actual)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQueryRowUnknownType(t *testing.T) {
|
func TestConnQueryRowUnknownType(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
sql := "select $1::point"
|
sql := "select $1::point"
|
||||||
expected := "(1,2)"
|
expected := "(1,2)"
|
||||||
var actual string
|
var actual string
|
||||||
@@ -311,14 +328,11 @@ func TestConnQueryRowUnknownType(t *testing.T) {
|
|||||||
err := db.QueryRow(sql, expected).Scan(&actual)
|
err := db.QueryRow(sql, expected).Scan(&actual)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, expected, actual)
|
require.EqualValues(t, expected, actual)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQueryJSONIntoByteSlice(t *testing.T) {
|
func TestConnQueryJSONIntoByteSlice(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
_, err := db.Exec(`
|
_, err := db.Exec(`
|
||||||
create temporary table docs(
|
create temporary table docs(
|
||||||
body json not null
|
body json not null
|
||||||
@@ -343,11 +357,13 @@ func TestConnQueryJSONIntoByteSlice(t *testing.T) {
|
|||||||
|
|
||||||
_, err = db.Exec(`drop table docs`)
|
_, err = db.Exec(`drop table docs`)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnExecInsertByteSliceIntoJSON(t *testing.T) {
|
func TestConnExecInsertByteSliceIntoJSON(t *testing.T) {
|
||||||
|
// Not testing with simple protocol because there is no way for that to work. A []byte will be considered binary data
|
||||||
|
// that needs to escape. No way to know whether the destination is really a text compatible or a bytea.
|
||||||
|
|
||||||
db := openDB(t)
|
db := openDB(t)
|
||||||
defer closeDB(t, db)
|
defer closeDB(t, db)
|
||||||
|
|
||||||
@@ -373,14 +389,10 @@ func TestConnExecInsertByteSliceIntoJSON(t *testing.T) {
|
|||||||
|
|
||||||
_, err = db.Exec(`drop table docs`)
|
_, err = db.Exec(`drop table docs`)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTransactionLifeCycle(t *testing.T) {
|
func TestTransactionLifeCycle(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
_, err := db.Exec("create temporary table t(a varchar not null)")
|
_, err := db.Exec("create temporary table t(a varchar not null)")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -410,14 +422,11 @@ func TestTransactionLifeCycle(t *testing.T) {
|
|||||||
err = db.QueryRow("select count(*) from t").Scan(&n)
|
err = db.QueryRow("select count(*) from t").Scan(&n)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, 1, n)
|
require.EqualValues(t, 1, n)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnBeginTxIsolation(t *testing.T) {
|
func TestConnBeginTxIsolation(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
var defaultIsoLevel string
|
var defaultIsoLevel string
|
||||||
err := db.QueryRow("show transaction_isolation").Scan(&defaultIsoLevel)
|
err := db.QueryRow("show transaction_isolation").Scan(&defaultIsoLevel)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -467,14 +476,11 @@ func TestConnBeginTxIsolation(t *testing.T) {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnBeginTxReadOnly(t *testing.T) {
|
func TestConnBeginTxReadOnly(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{ReadOnly: true})
|
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{ReadOnly: true})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
@@ -488,14 +494,11 @@ func TestConnBeginTxReadOnly(t *testing.T) {
|
|||||||
if pgReadOnly != "on" {
|
if pgReadOnly != "on" {
|
||||||
t.Errorf("pgReadOnly => %s, want %s", pgReadOnly, "on")
|
t.Errorf("pgReadOnly => %s, want %s", pgReadOnly, "on")
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBeginTxContextCancel(t *testing.T) {
|
func TestBeginTxContextCancel(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
_, err := db.Exec("drop table if exists t")
|
_, err := db.Exec("drop table if exists t")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -519,14 +522,11 @@ func TestBeginTxContextCancel(t *testing.T) {
|
|||||||
if pgErr, ok := err.(*pgconn.PgError); !ok || pgErr.Code != "42P01" {
|
if pgErr, ok := err.(*pgconn.PgError); !ok || pgErr.Code != "42P01" {
|
||||||
t.Fatalf(`err => %v, want PgError{Code: "42P01"}`, err)
|
t.Fatalf(`err => %v, want PgError{Code: "42P01"}`, err)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAcquireConn(t *testing.T) {
|
func TestAcquireConn(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
var conns []*pgx.Conn
|
var conns []*pgx.Conn
|
||||||
|
|
||||||
for i := 1; i < 6; i++ {
|
for i := 1; i < 6; i++ {
|
||||||
@@ -558,15 +558,12 @@ func TestAcquireConn(t *testing.T) {
|
|||||||
t.Errorf("%d. stdlib.ReleaseConn failed: %v", i, err)
|
t.Errorf("%d. stdlib.ReleaseConn failed: %v", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/jackc/pgx/issues/673
|
// https://github.com/jackc/pgx/issues/673
|
||||||
func TestReleaseConnWithTxInProgress(t *testing.T) {
|
func TestReleaseConnWithTxInProgress(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
c1, err := stdlib.AcquireConn(db)
|
c1, err := stdlib.AcquireConn(db)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -591,45 +588,34 @@ func TestReleaseConnWithTxInProgress(t *testing.T) {
|
|||||||
// Releasing a conn with a tx in progress should close the connection
|
// Releasing a conn with a tx in progress should close the connection
|
||||||
stats := db.Stats()
|
stats := db.Stats()
|
||||||
require.Equal(t, 1, stats.OpenConnections)
|
require.Equal(t, 1, stats.OpenConnections)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnPingContextSuccess(t *testing.T) {
|
func TestConnPingContextSuccess(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
err := db.PingContext(context.Background())
|
err := db.PingContext(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnPrepareContextSuccess(t *testing.T) {
|
func TestConnPrepareContextSuccess(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
stmt, err := db.PrepareContext(context.Background(), "select now()")
|
stmt, err := db.PrepareContext(context.Background(), "select now()")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
stmt.Close()
|
err = stmt.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
ensureDBValid(t, db)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnExecContextSuccess(t *testing.T) {
|
func TestConnExecContextSuccess(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
_, err := db.ExecContext(context.Background(), "create temporary table exec_context_test(id serial primary key)")
|
_, err := db.ExecContext(context.Background(), "create temporary table exec_context_test(id serial primary key)")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnExecContextFailureRetry(t *testing.T) {
|
func TestConnExecContextFailureRetry(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
// we get a connection, immediately close it, and then get it back
|
// we get a connection, immediately close it, and then get it back
|
||||||
{
|
{
|
||||||
conn, err := stdlib.AcquireConn(db)
|
conn, err := stdlib.AcquireConn(db)
|
||||||
@@ -641,12 +627,11 @@ func TestConnExecContextFailureRetry(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = conn.ExecContext(context.Background(), "select 1")
|
_, err = conn.ExecContext(context.Background(), "select 1")
|
||||||
require.EqualValues(t, driver.ErrBadConn, err)
|
require.EqualValues(t, driver.ErrBadConn, err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQueryContextSuccess(t *testing.T) {
|
func TestConnQueryContextSuccess(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
rows, err := db.QueryContext(context.Background(), "select * from generate_series(1,10) n")
|
rows, err := db.QueryContext(context.Background(), "select * from generate_series(1,10) n")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -656,14 +641,11 @@ func TestConnQueryContextSuccess(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
require.NoError(t, rows.Err())
|
require.NoError(t, rows.Err())
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConnQueryContextFailureRetry(t *testing.T) {
|
func TestConnQueryContextFailureRetry(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
// we get a connection, immediately close it, and then get it back
|
// we get a connection, immediately close it, and then get it back
|
||||||
{
|
{
|
||||||
conn, err := stdlib.AcquireConn(db)
|
conn, err := stdlib.AcquireConn(db)
|
||||||
@@ -676,12 +658,11 @@ func TestConnQueryContextFailureRetry(t *testing.T) {
|
|||||||
|
|
||||||
_, err = conn.QueryContext(context.Background(), "select 1")
|
_, err = conn.QueryContext(context.Background(), "select 1")
|
||||||
require.EqualValues(t, driver.ErrBadConn, err)
|
require.EqualValues(t, driver.ErrBadConn, err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRowsColumnTypeDatabaseTypeName(t *testing.T) {
|
func TestRowsColumnTypeDatabaseTypeName(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
rows, err := db.Query("select * from generate_series(1,10) n")
|
rows, err := db.Query("select * from generate_series(1,10) n")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -693,9 +674,9 @@ func TestRowsColumnTypeDatabaseTypeName(t *testing.T) {
|
|||||||
t.Errorf("columnTypes[0].DatabaseTypeName() => %v, want %v", columnTypes[0].DatabaseTypeName(), "INT4")
|
t.Errorf("columnTypes[0].DatabaseTypeName() => %v, want %v", columnTypes[0].DatabaseTypeName(), "INT4")
|
||||||
}
|
}
|
||||||
|
|
||||||
rows.Close()
|
err = rows.Close()
|
||||||
|
require.NoError(t, err)
|
||||||
ensureDBValid(t, db)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStmtExecContextSuccess(t *testing.T) {
|
func TestStmtExecContextSuccess(t *testing.T) {
|
||||||
@@ -763,6 +744,7 @@ func TestStmtQueryContextSuccess(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRowsColumnTypes(t *testing.T) {
|
func TestRowsColumnTypes(t *testing.T) {
|
||||||
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
columnTypesTests := []struct {
|
columnTypesTests := []struct {
|
||||||
Name string
|
Name string
|
||||||
TypeName string
|
TypeName string
|
||||||
@@ -840,9 +822,6 @@ func TestRowsColumnTypes(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
db := openDB(t)
|
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
rows, err := db.Query("SELECT 1 AS a, text 'bar' AS bar, 1.28::numeric(9, 2) AS dec")
|
rows, err := db.Query("SELECT 1 AS a, text 'bar' AS bar, 1.28::numeric(9, 2) AS dec")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -881,16 +860,11 @@ func TestRowsColumnTypes(t *testing.T) {
|
|||||||
t.Errorf("(%d) got: %v, want: %v", i, c.ScanType(), tt.ScanType)
|
t.Errorf("(%d) got: %v, want: %v", i, c.ScanType(), tt.ScanType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSimpleQueryLifeCycle(t *testing.T) {
|
func TestQueryLifeCycle(t *testing.T) {
|
||||||
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
require.NoError(t, err)
|
|
||||||
config.PreferSimpleProtocol = true
|
|
||||||
|
|
||||||
db := stdlib.OpenDB(*config)
|
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
rows, err := db.Query("SELECT 'foo', n FROM generate_series($1::int, $2::int) n WHERE 3 = $3", 1, 10, 3)
|
rows, err := db.Query("SELECT 'foo', n FROM generate_series($1::int, $2::int) n WHERE 3 = $3", 1, 10, 3)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -932,22 +906,18 @@ func TestSimpleQueryLifeCycle(t *testing.T) {
|
|||||||
|
|
||||||
err = rows.Close()
|
err = rows.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/jackc/pgx/issues/409
|
// https://github.com/jackc/pgx/issues/409
|
||||||
func TestScanJSONIntoJSONRawMessage(t *testing.T) {
|
func TestScanJSONIntoJSONRawMessage(t *testing.T) {
|
||||||
db := openDB(t)
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, db *sql.DB) {
|
||||||
defer closeDB(t, db)
|
|
||||||
|
|
||||||
var msg json.RawMessage
|
var msg json.RawMessage
|
||||||
|
|
||||||
err := db.QueryRow("select '{}'::json").Scan(&msg)
|
err := db.QueryRow("select '{}'::json").Scan(&msg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, []byte("{}"), []byte(msg))
|
require.EqualValues(t, []byte("{}"), []byte(msg))
|
||||||
|
})
|
||||||
ensureDBValid(t, db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type testLog struct {
|
type testLog struct {
|
||||||
|
|||||||
@@ -30,23 +30,10 @@ func convertSimpleArgument(ci *pgtype.ConnInfo, arg interface{}) (interface{}, e
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
setArgAndEncodeTextToString := func(t interface {
|
refVal := reflect.ValueOf(arg)
|
||||||
pgtype.Value
|
if refVal.Kind() == reflect.Ptr && refVal.IsNil() {
|
||||||
pgtype.TextEncoder
|
|
||||||
}) (interface{}, error) {
|
|
||||||
err := t.Set(arg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
buf, err := t.EncodeText(ci, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if buf == nil {
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return string(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch arg := arg.(type) {
|
switch arg := arg.(type) {
|
||||||
|
|
||||||
@@ -124,36 +111,25 @@ func convertSimpleArgument(ci *pgtype.ConnInfo, arg interface{}) (interface{}, e
|
|||||||
return nil, errors.Errorf("arg too big for int64: %v", arg)
|
return nil, errors.Errorf("arg too big for int64: %v", arg)
|
||||||
}
|
}
|
||||||
return int64(arg), nil
|
return int64(arg), nil
|
||||||
case []string:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.TextArray{})
|
|
||||||
case []float32:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Float4Array{})
|
|
||||||
case []float64:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Float8Array{})
|
|
||||||
case []int16:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
case []int32:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
case []int64:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
case []int:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
case []uint16:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
case []uint32:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
case []uint64:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
case []uint:
|
|
||||||
return setArgAndEncodeTextToString(&pgtype.Int8Array{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refVal := reflect.ValueOf(arg)
|
if dt, found := ci.DataTypeForValue(arg); found {
|
||||||
|
v := dt.Value
|
||||||
if refVal.Kind() == reflect.Ptr {
|
err := v.Set(arg)
|
||||||
if refVal.IsNil() {
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
buf, err := v.(pgtype.TextEncoder).EncodeText(ci, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if buf == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
return string(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if refVal.Kind() == reflect.Ptr {
|
||||||
arg = refVal.Elem().Interface()
|
arg = refVal.Elem().Interface()
|
||||||
return convertSimpleArgument(ci, arg)
|
return convertSimpleArgument(ci, arg)
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-53
@@ -10,14 +10,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v4"
|
"github.com/jackc/pgx/v4"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDateTranscode(t *testing.T) {
|
func TestDateTranscode(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
dates := []time.Time{
|
dates := []time.Time{
|
||||||
time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),
|
time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC),
|
time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
@@ -50,14 +50,13 @@ func TestDateTranscode(t *testing.T) {
|
|||||||
t.Errorf("Did not transcode date successfully: %v is not %v", d, actualDate)
|
t.Errorf("Did not transcode date successfully: %v is not %v", d, actualDate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimestampTzTranscode(t *testing.T) {
|
func TestTimestampTzTranscode(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
inputTime := time.Date(2013, 1, 2, 3, 4, 5, 6000, time.Local)
|
inputTime := time.Date(2013, 1, 2, 3, 4, 5, 6000, time.Local)
|
||||||
|
|
||||||
var outputTime time.Time
|
var outputTime time.Time
|
||||||
@@ -69,6 +68,7 @@ func TestTimestampTzTranscode(t *testing.T) {
|
|||||||
if !inputTime.Equal(outputTime) {
|
if !inputTime.Equal(outputTime) {
|
||||||
t.Errorf("Did not transcode time successfully: %v is not %v", outputTime, inputTime)
|
t.Errorf("Did not transcode time successfully: %v is not %v", outputTime, inputTime)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - move these tests to pgtype
|
// TODO - move these tests to pgtype
|
||||||
@@ -76,6 +76,21 @@ func TestTimestampTzTranscode(t *testing.T) {
|
|||||||
func TestJSONAndJSONBTranscode(t *testing.T) {
|
func TestJSONAndJSONBTranscode(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
|
for _, typename := range []string{"json", "jsonb"} {
|
||||||
|
if _, ok := conn.ConnInfo().DataTypeForName(typename); !ok {
|
||||||
|
continue // No JSON/JSONB type -- must be running against old PostgreSQL
|
||||||
|
}
|
||||||
|
|
||||||
|
testJSONString(t, conn, typename)
|
||||||
|
testJSONStringPointer(t, conn, typename)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJSONAndJSONBTranscodeExtendedOnly(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
||||||
defer closeConn(t, conn)
|
defer closeConn(t, conn)
|
||||||
|
|
||||||
@@ -83,9 +98,6 @@ func TestJSONAndJSONBTranscode(t *testing.T) {
|
|||||||
if _, ok := conn.ConnInfo().DataTypeForName(typename); !ok {
|
if _, ok := conn.ConnInfo().DataTypeForName(typename); !ok {
|
||||||
continue // No JSON/JSONB type -- must be running against old PostgreSQL
|
continue // No JSON/JSONB type -- must be running against old PostgreSQL
|
||||||
}
|
}
|
||||||
|
|
||||||
testJSONString(t, conn, typename)
|
|
||||||
testJSONStringPointer(t, conn, typename)
|
|
||||||
testJSONSingleLevelStringMap(t, conn, typename)
|
testJSONSingleLevelStringMap(t, conn, typename)
|
||||||
testJSONNestedMap(t, conn, typename)
|
testJSONNestedMap(t, conn, typename)
|
||||||
testJSONStringArray(t, conn, typename)
|
testJSONStringArray(t, conn, typename)
|
||||||
@@ -93,6 +105,7 @@ func TestJSONAndJSONBTranscode(t *testing.T) {
|
|||||||
testJSONInt16ArrayFailureDueToOverflow(t, conn, typename)
|
testJSONInt16ArrayFailureDueToOverflow(t, conn, typename)
|
||||||
testJSONStruct(t, conn, typename)
|
testJSONStruct(t, conn, typename)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testJSONString(t *testing.T, conn *pgx.Conn, typename string) {
|
func testJSONString(t *testing.T, conn *pgx.Conn, typename string) {
|
||||||
@@ -231,9 +244,7 @@ func mustParseCIDR(t *testing.T, s string) *net.IPNet {
|
|||||||
func TestStringToNotTextTypeTranscode(t *testing.T) {
|
func TestStringToNotTextTypeTranscode(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
input := "01086ee0-4963-4e35-9116-30c173a8d0bd"
|
input := "01086ee0-4963-4e35-9116-30c173a8d0bd"
|
||||||
|
|
||||||
var output string
|
var output string
|
||||||
@@ -252,14 +263,13 @@ func TestStringToNotTextTypeTranscode(t *testing.T) {
|
|||||||
if input != output {
|
if input != output {
|
||||||
t.Errorf("uuid: Did not transcode pointer to string successfully: %s is not %s", input, output)
|
t.Errorf("uuid: Did not transcode pointer to string successfully: %s is not %s", input, output)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInetCIDRTranscodeIPNet(t *testing.T) {
|
func TestInetCIDRTranscodeIPNet(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value *net.IPNet
|
value *net.IPNet
|
||||||
@@ -298,17 +308,14 @@ func TestInetCIDRTranscodeIPNet(t *testing.T) {
|
|||||||
if actual.String() != tt.value.String() {
|
if actual.String() != tt.value.String() {
|
||||||
t.Errorf("%d. Expected %v, got %v (sql -> %v)", i, tt.value, actual, tt.sql)
|
t.Errorf("%d. Expected %v, got %v (sql -> %v)", i, tt.value, actual, tt.sql)
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureConnValid(t, conn)
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInetCIDRTranscodeIP(t *testing.T) {
|
func TestInetCIDRTranscodeIP(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value net.IP
|
value net.IP
|
||||||
@@ -361,14 +368,13 @@ func TestInetCIDRTranscodeIP(t *testing.T) {
|
|||||||
|
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInetCIDRArrayTranscodeIPNet(t *testing.T) {
|
func TestInetCIDRArrayTranscodeIPNet(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value []*net.IPNet
|
value []*net.IPNet
|
||||||
@@ -420,14 +426,13 @@ func TestInetCIDRArrayTranscodeIPNet(t *testing.T) {
|
|||||||
|
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInetCIDRArrayTranscodeIP(t *testing.T) {
|
func TestInetCIDRArrayTranscodeIP(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value []net.IP
|
value []net.IP
|
||||||
@@ -463,8 +468,9 @@ func TestInetCIDRArrayTranscodeIP(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(actual, tt.value) {
|
assert.Equal(t, len(tt.value), len(actual), "%d", i)
|
||||||
t.Errorf("%d. Expected %v, got %v (sql -> %v)", i, tt.value, actual, tt.sql)
|
for j := range actual {
|
||||||
|
assert.True(t, actual[j].Equal(tt.value[j]), "%d", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
@@ -501,14 +507,13 @@ func TestInetCIDRArrayTranscodeIP(t *testing.T) {
|
|||||||
|
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInetCIDRTranscodeWithJustIP(t *testing.T) {
|
func TestInetCIDRTranscodeWithJustIP(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value string
|
value string
|
||||||
@@ -543,14 +548,13 @@ func TestInetCIDRTranscodeWithJustIP(t *testing.T) {
|
|||||||
|
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayDecoding(t *testing.T) {
|
func TestArrayDecoding(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
query interface{}
|
query interface{}
|
||||||
@@ -624,8 +628,11 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"select $1::timestamptz[]", []time.Time{time.Unix(323232, 0), time.Unix(3239949334, 00)}, &[]time.Time{},
|
"select $1::timestamptz[]", []time.Time{time.Unix(323232, 0), time.Unix(3239949334, 00)}, &[]time.Time{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t *testing.T, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]time.Time))) {
|
queryTimeSlice := query.([]time.Time)
|
||||||
t.Errorf("failed to encode time.Time[] to timestamptz[]")
|
scanTimeSlice := *(scan.(*[]time.Time))
|
||||||
|
require.Equal(t, len(queryTimeSlice), len(scanTimeSlice))
|
||||||
|
for i := range queryTimeSlice {
|
||||||
|
assert.Truef(t, queryTimeSlice[i].Equal(scanTimeSlice[i]), "%d", i)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -657,14 +664,13 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
tt.assert(t, tt.query, tt.scan)
|
tt.assert(t, tt.query, tt.scan)
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyArrayDecoding(t *testing.T) {
|
func TestEmptyArrayDecoding(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
var val []string
|
var val []string
|
||||||
|
|
||||||
err := conn.QueryRow(context.Background(), "select array[]::text[]").Scan(&val)
|
err := conn.QueryRow(context.Background(), "select array[]::text[]").Scan(&val)
|
||||||
@@ -703,16 +709,13 @@ func TestEmptyArrayDecoding(t *testing.T) {
|
|||||||
t.Errorf(`error reading array: %v`, err)
|
t.Errorf(`error reading array: %v`, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureConnValid(t, conn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPointerPointer(t *testing.T) {
|
func TestPointerPointer(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
type allTypes struct {
|
type allTypes struct {
|
||||||
s *string
|
s *string
|
||||||
i16 *int16
|
i16 *int16
|
||||||
@@ -783,14 +786,13 @@ func TestPointerPointer(t *testing.T) {
|
|||||||
|
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPointerPointerNonZero(t *testing.T) {
|
func TestPointerPointerNonZero(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
f := "foo"
|
f := "foo"
|
||||||
dest := &f
|
dest := &f
|
||||||
|
|
||||||
@@ -801,14 +803,13 @@ func TestPointerPointerNonZero(t *testing.T) {
|
|||||||
if dest != nil {
|
if dest != nil {
|
||||||
t.Errorf("Expected dest to be nil, got %#v", dest)
|
t.Errorf("Expected dest to be nil, got %#v", dest)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEncodeTypeRename(t *testing.T) {
|
func TestEncodeTypeRename(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) {
|
||||||
defer closeConn(t, conn)
|
|
||||||
|
|
||||||
type _int int
|
type _int int
|
||||||
inInt := _int(1)
|
inInt := _int(1)
|
||||||
var outInt _int
|
var outInt _int
|
||||||
@@ -903,11 +904,10 @@ func TestEncodeTypeRename(t *testing.T) {
|
|||||||
if inString != outString {
|
if inString != outString {
|
||||||
t.Errorf("string rename: expected %v, got %v", inString, outString)
|
t.Errorf("string rename: expected %v, got %v", inString, outString)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
ensureConnValid(t, conn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRowDecode(t *testing.T) {
|
func TestRowDecodeBinary(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE"))
|
||||||
|
|||||||
Reference in New Issue
Block a user