mirror of https://github.com/jackc/pgx.git
Add simple protocol suuport with (Query|Exec)Ex
parent
68fd815778
commit
7ff405ff84
17
cid_test.go
17
cid_test.go
|
@ -8,10 +8,23 @@ import (
|
|||
)
|
||||
|
||||
func TestCidTranscode(t *testing.T) {
|
||||
testSuccessfulTranscode(t, "cid", []interface{}{
|
||||
pgTypeName := "cid"
|
||||
values := []interface{}{
|
||||
pgtype.Cid{Uint: 42, Status: pgtype.Present},
|
||||
pgtype.Cid{Status: pgtype.Null},
|
||||
})
|
||||
}
|
||||
eqFunc := func(a, b interface{}) bool {
|
||||
return reflect.DeepEqual(a, b)
|
||||
}
|
||||
|
||||
testPgxSuccessfulTranscodeEqFunc(t, pgTypeName, values, eqFunc)
|
||||
|
||||
// No direct conversion from int to cid, convert through text
|
||||
testPgxSimpleProtocolSuccessfulTranscodeEqFunc(t, "text::"+pgTypeName, values, eqFunc)
|
||||
|
||||
for _, driverName := range []string{"github.com/lib/pq", "github.com/jackc/pgx/stdlib"} {
|
||||
testDatabaseSQLSuccessfulTranscodeEqFunc(t, driverName, pgTypeName, values, eqFunc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCidSet(t *testing.T) {
|
||||
|
|
2
json.go
2
json.go
|
@ -145,7 +145,7 @@ func (dst *Json) Scan(src interface{}) error {
|
|||
func (src Json) Value() (driver.Value, error) {
|
||||
switch src.Status {
|
||||
case Present:
|
||||
return src.Bytes, nil
|
||||
return string(src.Bytes), nil
|
||||
case Null:
|
||||
return nil, nil
|
||||
default:
|
||||
|
|
21
numeric.go
21
numeric.go
|
@ -121,13 +121,13 @@ func (src *Numeric) AssignTo(dst interface{}) error {
|
|||
case Present:
|
||||
switch v := dst.(type) {
|
||||
case *float32:
|
||||
f, err := strconv.ParseFloat(src.Int.String(), 64)
|
||||
f, err := src.toFloat64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return float64AssignTo(f, src.Status, dst)
|
||||
case *float64:
|
||||
f, err := strconv.ParseFloat(src.Int.String(), 64)
|
||||
f, err := src.toFloat64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -283,6 +283,23 @@ func (dst *Numeric) toBigInt() (*big.Int, error) {
|
|||
return num, nil
|
||||
}
|
||||
|
||||
func (src *Numeric) toFloat64() (float64, error) {
|
||||
f, err := strconv.ParseFloat(src.Int.String(), 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if src.Exp > 0 {
|
||||
for i := 0; i < int(src.Exp); i++ {
|
||||
f *= 10
|
||||
}
|
||||
} else if src.Exp < 0 {
|
||||
for i := 0; i > int(src.Exp); i-- {
|
||||
f /= 10
|
||||
}
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (dst *Numeric) DecodeText(ci *ConnInfo, src []byte) error {
|
||||
if src == nil {
|
||||
*dst = Numeric{Status: Null}
|
||||
|
|
|
@ -247,9 +247,12 @@ func TestNumericAssignTo(t *testing.T) {
|
|||
}{
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &f32, expected: float32(42)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &f64, expected: float64(42)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Exp: -1, Status: pgtype.Present}, dst: &f32, expected: float32(4.2)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Exp: -1, Status: pgtype.Present}, dst: &f64, expected: float64(4.2)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &i16, expected: int16(42)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &i32, expected: int32(42)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &i64, expected: int64(42)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Exp: 3, Status: pgtype.Present}, dst: &i64, expected: int64(42000)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &i, expected: int(42)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &ui8, expected: uint8(42)},
|
||||
{src: &pgtype.Numeric{Int: big.NewInt(42), Status: pgtype.Present}, dst: &ui16, expected: uint16(42)},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package pgtype_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -125,6 +126,7 @@ func testSuccessfulTranscode(t testing.TB, pgTypeName string, values []interface
|
|||
|
||||
func testSuccessfulTranscodeEqFunc(t testing.TB, pgTypeName string, values []interface{}, eqFunc func(a, b interface{}) bool) {
|
||||
testPgxSuccessfulTranscodeEqFunc(t, pgTypeName, values, eqFunc)
|
||||
testPgxSimpleProtocolSuccessfulTranscodeEqFunc(t, pgTypeName, values, eqFunc)
|
||||
for _, driverName := range []string{"github.com/lib/pq", "github.com/jackc/pgx/stdlib"} {
|
||||
testDatabaseSQLSuccessfulTranscodeEqFunc(t, driverName, pgTypeName, values, eqFunc)
|
||||
}
|
||||
|
@ -175,6 +177,35 @@ func testPgxSuccessfulTranscodeEqFunc(t testing.TB, pgTypeName string, values []
|
|||
}
|
||||
}
|
||||
|
||||
func testPgxSimpleProtocolSuccessfulTranscodeEqFunc(t testing.TB, pgTypeName string, values []interface{}, eqFunc func(a, b interface{}) bool) {
|
||||
conn := mustConnectPgx(t)
|
||||
defer mustClose(t, conn)
|
||||
|
||||
for i, v := range values {
|
||||
// Derefence value if it is a pointer
|
||||
derefV := v
|
||||
refVal := reflect.ValueOf(v)
|
||||
if refVal.Kind() == reflect.Ptr {
|
||||
derefV = refVal.Elem().Interface()
|
||||
}
|
||||
|
||||
result := reflect.New(reflect.TypeOf(derefV))
|
||||
err := conn.QueryRowEx(
|
||||
context.Background(),
|
||||
fmt.Sprintf("select ($1)::%s", pgTypeName),
|
||||
&pgx.QueryExOptions{SimpleProtocol: true},
|
||||
v,
|
||||
).Scan(result.Interface())
|
||||
if err != nil {
|
||||
t.Errorf("Simple protocol %d: %v", i, err)
|
||||
}
|
||||
|
||||
if !eqFunc(result.Elem().Interface(), derefV) {
|
||||
t.Errorf("Simple protocol %d: expected %v, got %v", i, derefV, result.Elem().Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testDatabaseSQLSuccessfulTranscodeEqFunc(t testing.TB, driverName, pgTypeName string, values []interface{}, eqFunc func(a, b interface{}) bool) {
|
||||
conn := mustConnectDatabaseSQL(t, driverName)
|
||||
defer mustClose(t, conn)
|
||||
|
|
17
xid_test.go
17
xid_test.go
|
@ -8,10 +8,23 @@ import (
|
|||
)
|
||||
|
||||
func TestXidTranscode(t *testing.T) {
|
||||
testSuccessfulTranscode(t, "xid", []interface{}{
|
||||
pgTypeName := "xid"
|
||||
values := []interface{}{
|
||||
pgtype.Xid{Uint: 42, Status: pgtype.Present},
|
||||
pgtype.Xid{Status: pgtype.Null},
|
||||
})
|
||||
}
|
||||
eqFunc := func(a, b interface{}) bool {
|
||||
return reflect.DeepEqual(a, b)
|
||||
}
|
||||
|
||||
testPgxSuccessfulTranscodeEqFunc(t, pgTypeName, values, eqFunc)
|
||||
|
||||
// No direct conversion from int to xid, convert through text
|
||||
testPgxSimpleProtocolSuccessfulTranscodeEqFunc(t, "text::"+pgTypeName, values, eqFunc)
|
||||
|
||||
for _, driverName := range []string{"github.com/lib/pq", "github.com/jackc/pgx/stdlib"} {
|
||||
testDatabaseSQLSuccessfulTranscodeEqFunc(t, driverName, pgTypeName, values, eqFunc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestXidSet(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue