mirror of
https://github.com/jackc/pgx.git
synced 2025-05-31 11:42:24 +00:00
Add DecodeValue to composites
This commit is contained in:
parent
3a94113118
commit
02372f1c3c
@ -209,11 +209,16 @@ func (c *CompositeCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// var n int64
|
switch format {
|
||||||
// err := c.PlanScan(ci, oid, format, &n, true).Scan(ci, oid, format, src, &n)
|
case TextFormatCode:
|
||||||
// return n, err
|
return string(src), nil
|
||||||
|
case BinaryFormatCode:
|
||||||
return nil, fmt.Errorf("not implemented")
|
buf := make([]byte, len(src))
|
||||||
|
copy(buf, src)
|
||||||
|
return buf, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown format code %d", format)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CompositeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) {
|
func (c *CompositeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) {
|
||||||
@ -221,11 +226,57 @@ func (c *CompositeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// var n int16
|
switch format {
|
||||||
// err := c.PlanScan(ci, oid, format, &n, true).Scan(ci, oid, format, src, &n)
|
case TextFormatCode:
|
||||||
// return n, err
|
scanner := NewCompositeTextScanner(ci, src)
|
||||||
|
values := make(map[string]interface{}, len(c.Fields))
|
||||||
|
for i := 0; scanner.Next() && i < len(c.Fields); i++ {
|
||||||
|
var v interface{}
|
||||||
|
fieldPlan := ci.PlanScan(c.Fields[i].DataType.OID, TextFormatCode, &v)
|
||||||
|
if fieldPlan == nil {
|
||||||
|
return nil, fmt.Errorf("unable to scan OID %d in text format into %v", c.Fields[i].DataType.OID, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := fieldPlan.Scan(scanner.Bytes(), &v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
values[c.Fields[i].Name] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
case BinaryFormatCode:
|
||||||
|
scanner := NewCompositeBinaryScanner(ci, src)
|
||||||
|
values := make(map[string]interface{}, len(c.Fields))
|
||||||
|
for i := 0; scanner.Next() && i < len(c.Fields); i++ {
|
||||||
|
var v interface{}
|
||||||
|
fieldPlan := ci.PlanScan(scanner.OID(), BinaryFormatCode, &v)
|
||||||
|
if fieldPlan == nil {
|
||||||
|
return nil, fmt.Errorf("unable to scan OID %d in binary format into %v", scanner.OID(), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := fieldPlan.Scan(scanner.Bytes(), &v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
values[c.Fields[i].Name] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown format code %d", format)
|
||||||
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("not implemented")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompositeBinaryScanner struct {
|
type CompositeBinaryScanner struct {
|
||||||
|
@ -162,3 +162,42 @@ create type point3d as (
|
|||||||
require.Equalf(t, input, output, "%v", format.name)
|
require.Equalf(t, input, output, "%v", format.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompositeCodecDecodeValue(t *testing.T) {
|
||||||
|
conn := testutil.MustConnectPgx(t)
|
||||||
|
defer testutil.MustCloseContext(t, conn)
|
||||||
|
|
||||||
|
_, err := conn.Exec(context.Background(), `drop type if exists point3d;
|
||||||
|
|
||||||
|
create type point3d as (
|
||||||
|
x float8,
|
||||||
|
y float8,
|
||||||
|
z float8
|
||||||
|
);`)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer conn.Exec(context.Background(), "drop type point3d")
|
||||||
|
|
||||||
|
dt, err := conn.LoadDataType(context.Background(), "point3d")
|
||||||
|
require.NoError(t, err)
|
||||||
|
conn.ConnInfo().RegisterDataType(*dt)
|
||||||
|
|
||||||
|
formats := []struct {
|
||||||
|
name string
|
||||||
|
code int16
|
||||||
|
}{
|
||||||
|
{name: "TextFormat", code: pgx.TextFormatCode},
|
||||||
|
{name: "BinaryFormat", code: pgx.BinaryFormatCode},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, format := range formats {
|
||||||
|
rows, err := conn.Query(context.Background(), "select '(1,2,3)'::point3d", pgx.QueryResultFormats{format.code})
|
||||||
|
require.NoErrorf(t, err, "%v", format.name)
|
||||||
|
require.True(t, rows.Next())
|
||||||
|
values, err := rows.Values()
|
||||||
|
require.NoErrorf(t, err, "%v", format.name)
|
||||||
|
require.Lenf(t, values, 1, "%v", format.name)
|
||||||
|
require.Equalf(t, map[string]interface{}{"x": 1.0, "y": 2.0, "z": 3.0}, values[0], "%v", format.name)
|
||||||
|
require.False(t, rows.Next())
|
||||||
|
require.NoErrorf(t, rows.Err(), "%v", format.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -75,7 +75,16 @@ func (RecordCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("not implemented")
|
switch format {
|
||||||
|
case TextFormatCode:
|
||||||
|
return string(src), nil
|
||||||
|
case BinaryFormatCode:
|
||||||
|
buf := make([]byte, len(src))
|
||||||
|
copy(buf, src)
|
||||||
|
return buf, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown format code %d", format)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (RecordCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) {
|
func (RecordCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user