From 1f2f239d097e983ce77bec7b53fd5254927bd527 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Mon, 21 Feb 2022 09:13:09 -0600 Subject: [PATCH] Renamed pgtype.ConnInfo to pgtype.Map --- bench_test.go | 2 +- conn.go | 28 ++-- conn_test.go | 8 +- copy_from.go | 2 +- copy_from_test.go | 2 +- extended_query_builder.go | 16 +- pgtype/array.go | 2 +- pgtype/array_codec.go | 50 +++--- pgtype/bits.go | 12 +- pgtype/bool.go | 12 +- pgtype/box.go | 12 +- pgtype/bytea.go | 12 +- pgtype/circle.go | 12 +- pgtype/composite.go | 72 ++++----- pgtype/composite_test.go | 8 +- pgtype/date.go | 12 +- pgtype/enum_codec.go | 10 +- pgtype/enum_codec_test.go | 4 +- pgtype/float4.go | 12 +- pgtype/float8.go | 12 +- pgtype/hstore.go | 12 +- pgtype/hstore_test.go | 2 +- pgtype/inet.go | 12 +- pgtype/int.go | 36 ++--- pgtype/int.go.erb | 12 +- pgtype/interval.go | 12 +- pgtype/json.go | 8 +- pgtype/jsonb.go | 16 +- pgtype/line.go | 12 +- pgtype/line_test.go | 2 +- pgtype/lseg.go | 12 +- pgtype/macaddr.go | 12 +- pgtype/numeric.go | 14 +- pgtype/path.go | 12 +- pgtype/pgtype.go | 316 +++++++++++++++++++------------------- pgtype/pgtype_test.go | 80 +++++----- pgtype/point.go | 12 +- pgtype/polygon.go | 12 +- pgtype/qchar.go | 12 +- pgtype/range_codec.go | 42 ++--- pgtype/record_codec.go | 20 +-- pgtype/text.go | 10 +- pgtype/tid.go | 12 +- pgtype/time.go | 12 +- pgtype/timestamp.go | 12 +- pgtype/timestamptz.go | 12 +- pgtype/uint32.go | 12 +- pgtype/uuid.go | 12 +- query_test.go | 2 +- rows.go | 18 +-- stdlib/sql.go | 30 ++-- values.go | 24 +-- values_test.go | 4 +- 53 files changed, 565 insertions(+), 563 deletions(-) diff --git a/bench_test.go b/bench_test.go index 587ce162..bd182ebd 100644 --- a/bench_test.go +++ b/bench_test.go @@ -918,7 +918,7 @@ func BenchmarkSelectManyRegisteredEnum(b *testing.B) { err = conn.QueryRow(context.Background(), "select oid from pg_type where typname=$1;", "color").Scan(&oid) require.NoError(b, err) - conn.ConnInfo().RegisterType(&pgtype.Type{Name: "color", OID: oid, Codec: &pgtype.EnumCodec{}}) + conn.TypeMap().RegisterType(&pgtype.Type{Name: "color", OID: oid, Codec: &pgtype.EnumCodec{}}) b.ResetTimer() var x, y, z string diff --git a/conn.go b/conn.go index 7a66b5e2..2a66a5ff 100644 --- a/conn.go +++ b/conn.go @@ -71,7 +71,7 @@ type Conn struct { doneChan chan struct{} closedChan chan error - connInfo *pgtype.ConnInfo + typeMap *pgtype.Map wbuf []byte eqb extendedQueryBuilder @@ -202,7 +202,7 @@ func connect(ctx context.Context, config *ConnConfig) (c *Conn, err error) { c = &Conn{ config: originalConfig, - connInfo: pgtype.NewConnInfo(), + typeMap: pgtype.NewMap(), logLevel: config.LogLevel, logger: config.Logger, } @@ -375,8 +375,8 @@ func (c *Conn) PgConn() *pgconn.PgConn { return c.pgConn } // StatementCache returns the statement cache used for this connection. func (c *Conn) StatementCache() stmtcache.Cache { return c.stmtcache } -// ConnInfo returns the connection info used for this connection. -func (c *Conn) ConnInfo() *pgtype.ConnInfo { return c.connInfo } +// TypeMap returns the connection info used for this connection. +func (c *Conn) TypeMap() *pgtype.Map { return c.typeMap } // Config returns a copy of config that was used to establish this connection. func (c *Conn) Config() *ConnConfig { return c.config.Copy() } @@ -476,14 +476,14 @@ func (c *Conn) execParamsAndPreparedPrefix(sd *pgconn.StatementDescription, argu } for i := range args { - err = c.eqb.AppendParam(c.connInfo, sd.ParamOIDs[i], args[i]) + err = c.eqb.AppendParam(c.typeMap, sd.ParamOIDs[i], args[i]) if err != nil { return err } } for i := range sd.Fields { - c.eqb.AppendResultFormat(c.ConnInfo().FormatCodeForOID(sd.Fields[i].DataTypeOID)) + c.eqb.AppendResultFormat(c.TypeMap().FormatCodeForOID(sd.Fields[i].DataTypeOID)) } return nil @@ -516,7 +516,7 @@ func (c *Conn) getRows(ctx context.Context, sql string, args []interface{}) *con r.ctx = ctx r.logger = c - r.connInfo = c.connInfo + r.typeMap = c.typeMap r.startTime = time.Now() r.sql = sql r.args = args @@ -622,7 +622,7 @@ optionLoop: } for i := range args { - err = c.eqb.AppendParam(c.connInfo, sd.ParamOIDs[i], args[i]) + err = c.eqb.AppendParam(c.typeMap, sd.ParamOIDs[i], args[i]) if err != nil { rows.fatal(err) return rows, rows.err @@ -638,7 +638,7 @@ optionLoop: if resultFormats == nil { for i := range sd.Fields { - c.eqb.AppendResultFormat(c.ConnInfo().FormatCodeForOID(sd.Fields[i].DataTypeOID)) + c.eqb.AppendResultFormat(c.TypeMap().FormatCodeForOID(sd.Fields[i].DataTypeOID)) } resultFormats = c.eqb.resultFormats @@ -781,14 +781,14 @@ func (c *Conn) SendBatch(ctx context.Context, b *Batch) BatchResults { } for i := range args { - err = c.eqb.AppendParam(c.connInfo, sd.ParamOIDs[i], args[i]) + err = c.eqb.AppendParam(c.typeMap, sd.ParamOIDs[i], args[i]) if err != nil { return &batchResults{ctx: ctx, conn: c, err: err} } } for i := range sd.Fields { - c.eqb.AppendResultFormat(c.ConnInfo().FormatCodeForOID(sd.Fields[i].DataTypeOID)) + c.eqb.AppendResultFormat(c.TypeMap().FormatCodeForOID(sd.Fields[i].DataTypeOID)) } if sd.Name == "" { @@ -823,7 +823,7 @@ func (c *Conn) sanitizeForSimpleQuery(sql string, args ...interface{}) (string, var err error valueArgs := make([]interface{}, len(args)) for i, a := range args { - valueArgs[i], err = convertSimpleArgument(c.connInfo, a) + valueArgs[i], err = convertSimpleArgument(c.typeMap, a) if err != nil { return "", err } @@ -855,7 +855,7 @@ func (c *Conn) LoadType(ctx context.Context, typeName string) (*pgtype.Type, err return nil, err } - dt, ok := c.ConnInfo().TypeForOID(elementOID) + dt, ok := c.TypeMap().TypeForOID(elementOID) if !ok { return nil, errors.New("array element OID not registered") } @@ -904,7 +904,7 @@ order by attnum`, []interface{}{typrelid}, []interface{}{&fieldName, &fieldOID}, func(qfr QueryFuncRow) error { - dt, ok := c.ConnInfo().TypeForOID(fieldOID) + dt, ok := c.TypeMap().TypeForOID(fieldOID) if !ok { return fmt.Errorf("unknown composite type field OID: %v", fieldOID) } diff --git a/conn_test.go b/conn_test.go index 22928a01..3240c954 100644 --- a/conn_test.go +++ b/conn_test.go @@ -829,7 +829,7 @@ func TestIdentifierSanitize(t *testing.T) { } } -func TestConnInitConnInfo(t *testing.T) { +func TestConnInitTypeMap(t *testing.T) { conn := mustConnectString(t, os.Getenv("PGX_TEST_DATABASE")) defer closeConn(t, conn) @@ -841,11 +841,11 @@ func TestConnInitConnInfo(t *testing.T) { "text": pgtype.TextOID, } for name, oid := range nameOIDs { - dtByName, ok := conn.ConnInfo().TypeForName(name) + dtByName, ok := conn.TypeMap().TypeForName(name) if !ok { t.Fatalf("Expected type named %v to be present", name) } - dtByOID, ok := conn.ConnInfo().TypeForOID(oid) + dtByOID, ok := conn.TypeMap().TypeForOID(oid) if !ok { t.Fatalf("Expected type OID %v to be present", oid) } @@ -891,7 +891,7 @@ func TestDomainType(t *testing.T) { if err != nil { t.Fatalf("did not find uint64 OID, %v", err) } - conn.ConnInfo().RegisterType(&pgtype.Type{Name: "uint64", OID: uint64OID, Codec: pgtype.NumericCodec{}}) + conn.TypeMap().RegisterType(&pgtype.Type{Name: "uint64", OID: uint64OID, Codec: pgtype.NumericCodec{}}) var n uint64 err = conn.QueryRow(context.Background(), "select $1::uint64", uint64(24)).Scan(&n) diff --git a/copy_from.go b/copy_from.go index 0bf3478f..8eb3c111 100644 --- a/copy_from.go +++ b/copy_from.go @@ -178,7 +178,7 @@ func (ct *copyFrom) buildCopyBuf(buf []byte, sd *pgconn.StatementDescription) (b buf = pgio.AppendInt16(buf, int16(len(ct.columnNames))) for i, val := range values { - buf, err = encodePreparedStatementArgument(ct.conn.connInfo, buf, sd.Fields[i].DataTypeOID, val) + buf, err = encodePreparedStatementArgument(ct.conn.typeMap, buf, sd.Fields[i].DataTypeOID, val) if err != nil { return false, nil, err } diff --git a/copy_from_test.go b/copy_from_test.go index 867b53af..5c22dc35 100644 --- a/copy_from_test.go +++ b/copy_from_test.go @@ -256,7 +256,7 @@ func TestConnCopyFromJSON(t *testing.T) { defer closeConn(t, conn) for _, typeName := range []string{"json", "jsonb"} { - if _, ok := conn.ConnInfo().TypeForName(typeName); !ok { + if _, ok := conn.TypeMap().TypeForName(typeName); !ok { return // No JSON/JSONB type -- must be running against old PostgreSQL } } diff --git a/extended_query_builder.go b/extended_query_builder.go index a28900c4..51759362 100644 --- a/extended_query_builder.go +++ b/extended_query_builder.go @@ -14,11 +14,11 @@ type extendedQueryBuilder struct { resultFormats []int16 } -func (eqb *extendedQueryBuilder) AppendParam(ci *pgtype.ConnInfo, oid uint32, arg interface{}) error { - f := chooseParameterFormatCode(ci, oid, arg) +func (eqb *extendedQueryBuilder) AppendParam(m *pgtype.Map, oid uint32, arg interface{}) error { + f := chooseParameterFormatCode(m, oid, arg) eqb.paramFormats = append(eqb.paramFormats, f) - v, err := eqb.encodeExtendedParamValue(ci, oid, f, arg) + v, err := eqb.encodeExtendedParamValue(m, oid, f, arg) if err != nil { return err } @@ -54,7 +54,7 @@ func (eqb *extendedQueryBuilder) Reset() { } } -func (eqb *extendedQueryBuilder) encodeExtendedParamValue(ci *pgtype.ConnInfo, oid uint32, formatCode int16, arg interface{}) ([]byte, error) { +func (eqb *extendedQueryBuilder) encodeExtendedParamValue(m *pgtype.Map, oid uint32, formatCode int16, arg interface{}) ([]byte, error) { if arg == nil { return nil, nil } @@ -80,11 +80,11 @@ func (eqb *extendedQueryBuilder) encodeExtendedParamValue(ci *pgtype.ConnInfo, o // We have already checked that arg is not pointing to nil, // so it is safe to dereference here. arg = refVal.Elem().Interface() - return eqb.encodeExtendedParamValue(ci, oid, formatCode, arg) + return eqb.encodeExtendedParamValue(m, oid, formatCode, arg) } - if _, ok := ci.TypeForOID(oid); ok { - buf, err := ci.Encode(oid, formatCode, arg, eqb.paramValueBytes) + if _, ok := m.TypeForOID(oid); ok { + buf, err := m.Encode(oid, formatCode, arg, eqb.paramValueBytes) if err != nil { return nil, err } @@ -96,7 +96,7 @@ func (eqb *extendedQueryBuilder) encodeExtendedParamValue(ci *pgtype.ConnInfo, o } if strippedArg, ok := stripNamedType(&refVal); ok { - return eqb.encodeExtendedParamValue(ci, oid, formatCode, strippedArg) + return eqb.encodeExtendedParamValue(m, oid, formatCode, strippedArg) } return nil, SerializationError(fmt.Sprintf("Cannot encode %T into oid %v - %T must implement Encoder or be converted to a string", arg, oid, arg)) } diff --git a/pgtype/array.go b/pgtype/array.go index d1a78e64..3648f385 100644 --- a/pgtype/array.go +++ b/pgtype/array.go @@ -42,7 +42,7 @@ func cardinality(dimensions []ArrayDimension) int { return elementCount } -func (dst *ArrayHeader) DecodeBinary(ci *ConnInfo, src []byte) (int, error) { +func (dst *ArrayHeader) DecodeBinary(m *Map, src []byte) (int, error) { if len(src) < 12 { return 0, fmt.Errorf("array header too short: %d", len(src)) } diff --git a/pgtype/array_codec.go b/pgtype/array_codec.go index 0b32b37f..dd14e83e 100644 --- a/pgtype/array_codec.go +++ b/pgtype/array_codec.go @@ -49,7 +49,7 @@ func (c *ArrayCodec) PreferredFormat() int16 { return c.ElementType.Codec.PreferredFormat() } -func (c *ArrayCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (c *ArrayCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { arrayValuer, ok := value.(ArrayGetter) if !ok { return nil @@ -57,16 +57,16 @@ func (c *ArrayCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value in elementType := arrayValuer.IndexType() - elementEncodePlan := ci.PlanEncode(c.ElementType.OID, format, elementType) + elementEncodePlan := m.PlanEncode(c.ElementType.OID, format, elementType) if elementEncodePlan == nil { return nil } switch format { case BinaryFormatCode: - return &encodePlanArrayCodecBinary{ac: c, ci: ci, oid: oid} + return &encodePlanArrayCodecBinary{ac: c, m: m, oid: oid} case TextFormatCode: - return &encodePlanArrayCodecText{ac: c, ci: ci, oid: oid} + return &encodePlanArrayCodecText{ac: c, m: m, oid: oid} } return nil @@ -74,7 +74,7 @@ func (c *ArrayCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value in type encodePlanArrayCodecText struct { ac *ArrayCodec - ci *ConnInfo + m *Map oid uint32 } @@ -124,7 +124,7 @@ func (p *encodePlanArrayCodecText) Encode(value interface{}, buf []byte) (newBuf elemType := reflect.TypeOf(elem) if lastElemType != elemType { lastElemType = elemType - encodePlan = p.ci.PlanEncode(p.ac.ElementType.OID, TextFormatCode, elem) + encodePlan = p.m.PlanEncode(p.ac.ElementType.OID, TextFormatCode, elem) if encodePlan == nil { return nil, fmt.Errorf("unable to encode %v", array.Index(i)) } @@ -153,7 +153,7 @@ func (p *encodePlanArrayCodecText) Encode(value interface{}, buf []byte) (newBuf type encodePlanArrayCodecBinary struct { ac *ArrayCodec - ci *ConnInfo + m *Map oid uint32 } @@ -188,7 +188,7 @@ func (p *encodePlanArrayCodecBinary) Encode(value interface{}, buf []byte) (newB elemType := reflect.TypeOf(elem) if lastElemType != elemType { lastElemType = elemType - encodePlan = p.ci.PlanEncode(p.ac.ElementType.OID, BinaryFormatCode, elem) + encodePlan = p.m.PlanEncode(p.ac.ElementType.OID, BinaryFormatCode, elem) if encodePlan == nil { return nil, fmt.Errorf("unable to encode %v", array.Index(i)) } @@ -210,7 +210,7 @@ func (p *encodePlanArrayCodecBinary) Encode(value interface{}, buf []byte) (newB return buf, nil } -func (c *ArrayCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (c *ArrayCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { arrayScanner, ok := target.(ArraySetter) if !ok { return nil @@ -218,22 +218,22 @@ func (c *ArrayCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target int elementType := arrayScanner.ScanIndexType() - elementScanPlan := ci.PlanScan(c.ElementType.OID, format, elementType) + elementScanPlan := m.PlanScan(c.ElementType.OID, format, elementType) if _, ok := elementScanPlan.(*scanPlanFail); ok { return nil } return &scanPlanArrayCodec{ arrayCodec: c, - ci: ci, + m: m, oid: oid, formatCode: format, } } -func (c *ArrayCodec) decodeBinary(ci *ConnInfo, arrayOID uint32, src []byte, array ArraySetter) error { +func (c *ArrayCodec) decodeBinary(m *Map, arrayOID uint32, src []byte, array ArraySetter) error { var arrayHeader ArrayHeader - rp, err := arrayHeader.DecodeBinary(ci, src) + rp, err := arrayHeader.DecodeBinary(m, src) if err != nil { return err } @@ -248,9 +248,9 @@ func (c *ArrayCodec) decodeBinary(ci *ConnInfo, arrayOID uint32, src []byte, arr return nil } - elementScanPlan := c.ElementType.Codec.PlanScan(ci, c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0), false) + elementScanPlan := c.ElementType.Codec.PlanScan(m, c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0), false) if elementScanPlan == nil { - elementScanPlan = ci.PlanScan(c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0)) + elementScanPlan = m.PlanScan(c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0)) } for i := 0; i < elementCount; i++ { @@ -271,7 +271,7 @@ func (c *ArrayCodec) decodeBinary(ci *ConnInfo, arrayOID uint32, src []byte, arr return nil } -func (c *ArrayCodec) decodeText(ci *ConnInfo, arrayOID uint32, src []byte, array ArraySetter) error { +func (c *ArrayCodec) decodeText(m *Map, arrayOID uint32, src []byte, array ArraySetter) error { uta, err := ParseUntypedTextArray(string(src)) if err != nil { return err @@ -286,9 +286,9 @@ func (c *ArrayCodec) decodeText(ci *ConnInfo, arrayOID uint32, src []byte, array return nil } - elementScanPlan := c.ElementType.Codec.PlanScan(ci, c.ElementType.OID, TextFormatCode, array.ScanIndex(0), false) + elementScanPlan := c.ElementType.Codec.PlanScan(m, c.ElementType.OID, TextFormatCode, array.ScanIndex(0), false) if elementScanPlan == nil { - elementScanPlan = ci.PlanScan(c.ElementType.OID, TextFormatCode, array.ScanIndex(0)) + elementScanPlan = m.PlanScan(c.ElementType.OID, TextFormatCode, array.ScanIndex(0)) } for i, s := range uta.Elements { @@ -309,7 +309,7 @@ func (c *ArrayCodec) decodeText(ci *ConnInfo, arrayOID uint32, src []byte, array type scanPlanArrayCodec struct { arrayCodec *ArrayCodec - ci *ConnInfo + m *Map oid uint32 formatCode int16 elementScanPlan ScanPlan @@ -317,7 +317,7 @@ type scanPlanArrayCodec struct { func (spac *scanPlanArrayCodec) Scan(src []byte, dst interface{}) error { c := spac.arrayCodec - ci := spac.ci + m := spac.m oid := spac.oid formatCode := spac.formatCode @@ -329,15 +329,15 @@ func (spac *scanPlanArrayCodec) Scan(src []byte, dst interface{}) error { switch formatCode { case BinaryFormatCode: - return c.decodeBinary(ci, oid, src, array) + return c.decodeBinary(m, oid, src, array) case TextFormatCode: - return c.decodeText(ci, oid, src, array) + return c.decodeText(m, oid, src, array) default: return fmt.Errorf("unknown format code %d", formatCode) } } -func (c *ArrayCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c *ArrayCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -354,13 +354,13 @@ func (c *ArrayCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int } } -func (c *ArrayCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c *ArrayCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var slice []interface{} - err := ci.PlanScan(oid, format, &slice).Scan(src, &slice) + err := m.PlanScan(oid, format, &slice).Scan(src, &slice) return slice, err } diff --git a/pgtype/bits.go b/pgtype/bits.go index 541a3a6b..8afd8d90 100644 --- a/pgtype/bits.go +++ b/pgtype/bits.go @@ -70,7 +70,7 @@ func (BitsCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (BitsCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (BitsCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(BitsValuer); !ok { return nil } @@ -126,7 +126,7 @@ func (encodePlanBitsCodecText) Encode(value interface{}, buf []byte) (newBuf []b return buf, nil } -func (BitsCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (BitsCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -144,17 +144,17 @@ func (BitsCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa return nil } -func (c BitsCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c BitsCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c BitsCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c BitsCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var box Bits - err := codecScan(c, ci, oid, format, src, &box) + err := codecScan(c, m, oid, format, src, &box) if err != nil { return nil, err } diff --git a/pgtype/bool.go b/pgtype/bool.go index 5aa06870..1158ad06 100644 --- a/pgtype/bool.go +++ b/pgtype/bool.go @@ -106,7 +106,7 @@ func (BoolCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (BoolCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (BoolCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -197,7 +197,7 @@ func (encodePlanBoolCodecTextBool) Encode(value interface{}, buf []byte) (newBuf return buf, nil } -func (BoolCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (BoolCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -219,17 +219,17 @@ func (BoolCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa return nil } -func (c BoolCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return c.DecodeValue(ci, oid, format, src) +func (c BoolCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) } -func (c BoolCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c BoolCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var b bool - err := codecScan(c, ci, oid, format, src, &b) + err := codecScan(c, m, oid, format, src, &b) if err != nil { return nil, err } diff --git a/pgtype/box.go b/pgtype/box.go index 6c637308..6e44c436 100644 --- a/pgtype/box.go +++ b/pgtype/box.go @@ -71,7 +71,7 @@ func (BoxCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (BoxCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (BoxCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(BoxValuer); !ok { return nil } @@ -126,7 +126,7 @@ func (encodePlanBoxCodecText) Encode(value interface{}, buf []byte) (newBuf []by return buf, nil } -func (BoxCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (BoxCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -220,17 +220,17 @@ func (scanPlanTextAnyToBoxScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanBox(Box{P: [2]Vec2{{x1, y1}, {x2, y2}}, Valid: true}) } -func (c BoxCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c BoxCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c BoxCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c BoxCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var box Box - err := codecScan(c, ci, oid, format, src, &box) + err := codecScan(c, m, oid, format, src, &box) if err != nil { return nil, err } diff --git a/pgtype/bytea.go b/pgtype/bytea.go index 58f3b348..eb865df0 100644 --- a/pgtype/bytea.go +++ b/pgtype/bytea.go @@ -72,7 +72,7 @@ func (ByteaCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (ByteaCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (ByteaCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -147,7 +147,7 @@ func (encodePlanBytesCodecTextBytesValuer) Encode(value interface{}, buf []byte) return buf, nil } -func (ByteaCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (ByteaCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -237,17 +237,17 @@ func decodeHexBytea(src []byte) ([]byte, error) { return buf, nil } -func (c ByteaCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c ByteaCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c ByteaCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c ByteaCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var buf []byte - err := codecScan(c, ci, oid, format, src, &buf) + err := codecScan(c, m, oid, format, src, &buf) if err != nil { return nil, err } diff --git a/pgtype/circle.go b/pgtype/circle.go index 8e06de88..6a83b41f 100644 --- a/pgtype/circle.go +++ b/pgtype/circle.go @@ -72,7 +72,7 @@ func (CircleCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (CircleCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (CircleCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(CircleValuer); !ok { return nil } @@ -125,7 +125,7 @@ func (encodePlanCircleCodecText) Encode(value interface{}, buf []byte) (newBuf [ return buf, nil } -func (CircleCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (CircleCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: switch target.(type) { @@ -142,17 +142,17 @@ func (CircleCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter return nil } -func (c CircleCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c CircleCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c CircleCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c CircleCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var circle Circle - err := codecScan(c, ci, oid, format, src, &circle) + err := codecScan(c, m, oid, format, src, &circle) if err != nil { return nil, err } diff --git a/pgtype/composite.go b/pgtype/composite.go index 1142a704..c538834d 100644 --- a/pgtype/composite.go +++ b/pgtype/composite.go @@ -54,16 +54,16 @@ func (c *CompositeCodec) PreferredFormat() int16 { return TextFormatCode } -func (c *CompositeCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (c *CompositeCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(CompositeIndexGetter); !ok { return nil } switch format { case BinaryFormatCode: - return &encodePlanCompositeCodecCompositeIndexGetterToBinary{cc: c, ci: ci} + return &encodePlanCompositeCodecCompositeIndexGetterToBinary{cc: c, m: m} case TextFormatCode: - return &encodePlanCompositeCodecCompositeIndexGetterToText{cc: c, ci: ci} + return &encodePlanCompositeCodecCompositeIndexGetterToText{cc: c, m: m} } return nil @@ -71,7 +71,7 @@ func (c *CompositeCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, valu type encodePlanCompositeCodecCompositeIndexGetterToBinary struct { cc *CompositeCodec - ci *ConnInfo + m *Map } func (plan *encodePlanCompositeCodecCompositeIndexGetterToBinary) Encode(value interface{}, buf []byte) (newBuf []byte, err error) { @@ -81,7 +81,7 @@ func (plan *encodePlanCompositeCodecCompositeIndexGetterToBinary) Encode(value i return nil, nil } - builder := NewCompositeBinaryBuilder(plan.ci, buf) + builder := NewCompositeBinaryBuilder(plan.m, buf) for i, field := range plan.cc.Fields { builder.AppendValue(field.Type.OID, getter.Index(i)) } @@ -91,7 +91,7 @@ func (plan *encodePlanCompositeCodecCompositeIndexGetterToBinary) Encode(value i type encodePlanCompositeCodecCompositeIndexGetterToText struct { cc *CompositeCodec - ci *ConnInfo + m *Map } func (plan *encodePlanCompositeCodecCompositeIndexGetterToText) Encode(value interface{}, buf []byte) (newBuf []byte, err error) { @@ -101,7 +101,7 @@ func (plan *encodePlanCompositeCodecCompositeIndexGetterToText) Encode(value int return nil, nil } - b := NewCompositeTextBuilder(plan.ci, buf) + b := NewCompositeTextBuilder(plan.m, buf) for i, field := range plan.cc.Fields { b.AppendValue(field.Type.OID, getter.Index(i)) } @@ -109,17 +109,17 @@ func (plan *encodePlanCompositeCodecCompositeIndexGetterToText) Encode(value int return b.Finish() } -func (c *CompositeCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (c *CompositeCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: switch target.(type) { case CompositeIndexScanner: - return &scanPlanBinaryCompositeToCompositeIndexScanner{cc: c, ci: ci} + return &scanPlanBinaryCompositeToCompositeIndexScanner{cc: c, m: m} } case TextFormatCode: switch target.(type) { case CompositeIndexScanner: - return &scanPlanTextCompositeToCompositeIndexScanner{cc: c, ci: ci} + return &scanPlanTextCompositeToCompositeIndexScanner{cc: c, m: m} } } @@ -128,7 +128,7 @@ func (c *CompositeCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target type scanPlanBinaryCompositeToCompositeIndexScanner struct { cc *CompositeCodec - ci *ConnInfo + m *Map } func (plan *scanPlanBinaryCompositeToCompositeIndexScanner) Scan(src []byte, target interface{}) error { @@ -138,12 +138,12 @@ func (plan *scanPlanBinaryCompositeToCompositeIndexScanner) Scan(src []byte, tar return targetScanner.ScanNull() } - scanner := NewCompositeBinaryScanner(plan.ci, src) + scanner := NewCompositeBinaryScanner(plan.m, src) for i, field := range plan.cc.Fields { if scanner.Next() { fieldTarget := targetScanner.ScanIndex(i) if fieldTarget != nil { - fieldPlan := plan.ci.PlanScan(field.Type.OID, BinaryFormatCode, fieldTarget) + fieldPlan := plan.m.PlanScan(field.Type.OID, BinaryFormatCode, fieldTarget) if fieldPlan == nil { return fmt.Errorf("unable to encode %v into OID %d in binary format", field, field.Type.OID) } @@ -167,7 +167,7 @@ func (plan *scanPlanBinaryCompositeToCompositeIndexScanner) Scan(src []byte, tar type scanPlanTextCompositeToCompositeIndexScanner struct { cc *CompositeCodec - ci *ConnInfo + m *Map } func (plan *scanPlanTextCompositeToCompositeIndexScanner) Scan(src []byte, target interface{}) error { @@ -177,12 +177,12 @@ func (plan *scanPlanTextCompositeToCompositeIndexScanner) Scan(src []byte, targe return targetScanner.ScanNull() } - scanner := NewCompositeTextScanner(plan.ci, src) + scanner := NewCompositeTextScanner(plan.m, src) for i, field := range plan.cc.Fields { if scanner.Next() { fieldTarget := targetScanner.ScanIndex(i) if fieldTarget != nil { - fieldPlan := plan.ci.PlanScan(field.Type.OID, TextFormatCode, fieldTarget) + fieldPlan := plan.m.PlanScan(field.Type.OID, TextFormatCode, fieldTarget) if fieldPlan == nil { return fmt.Errorf("unable to encode %v into OID %d in text format", field, field.Type.OID) } @@ -204,7 +204,7 @@ func (plan *scanPlanTextCompositeToCompositeIndexScanner) Scan(src []byte, targe return nil } -func (c *CompositeCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c *CompositeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -221,18 +221,18 @@ func (c *CompositeCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format } } -func (c *CompositeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c *CompositeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } switch format { case TextFormatCode: - scanner := NewCompositeTextScanner(ci, src) + scanner := NewCompositeTextScanner(m, 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].Type.OID, TextFormatCode, &v) + fieldPlan := m.PlanScan(c.Fields[i].Type.OID, TextFormatCode, &v) if fieldPlan == nil { return nil, fmt.Errorf("unable to scan OID %d in text format into %v", c.Fields[i].Type.OID, v) } @@ -251,11 +251,11 @@ func (c *CompositeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src return values, nil case BinaryFormatCode: - scanner := NewCompositeBinaryScanner(ci, src) + scanner := NewCompositeBinaryScanner(m, 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) + fieldPlan := m.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) } @@ -280,7 +280,7 @@ func (c *CompositeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src } type CompositeBinaryScanner struct { - ci *ConnInfo + m *Map rp int src []byte @@ -291,7 +291,7 @@ type CompositeBinaryScanner struct { } // NewCompositeBinaryScanner a scanner over a binary encoded composite balue. -func NewCompositeBinaryScanner(ci *ConnInfo, src []byte) *CompositeBinaryScanner { +func NewCompositeBinaryScanner(m *Map, src []byte) *CompositeBinaryScanner { rp := 0 if len(src[rp:]) < 4 { return &CompositeBinaryScanner{err: fmt.Errorf("Record incomplete %v", src)} @@ -301,7 +301,7 @@ func NewCompositeBinaryScanner(ci *ConnInfo, src []byte) *CompositeBinaryScanner rp += 4 return &CompositeBinaryScanner{ - ci: ci, + m: m, rp: rp, src: src, fieldCount: fieldCount, @@ -363,7 +363,7 @@ func (cfs *CompositeBinaryScanner) Err() error { } type CompositeTextScanner struct { - ci *ConnInfo + m *Map rp int src []byte @@ -372,7 +372,7 @@ type CompositeTextScanner struct { } // NewCompositeTextScanner a scanner over a text encoded composite value. -func NewCompositeTextScanner(ci *ConnInfo, src []byte) *CompositeTextScanner { +func NewCompositeTextScanner(m *Map, src []byte) *CompositeTextScanner { if len(src) < 2 { return &CompositeTextScanner{err: fmt.Errorf("Record incomplete %v", src)} } @@ -386,7 +386,7 @@ func NewCompositeTextScanner(ci *ConnInfo, src []byte) *CompositeTextScanner { } return &CompositeTextScanner{ - ci: ci, + m: m, rp: 1, src: src, } @@ -459,17 +459,17 @@ func (cfs *CompositeTextScanner) Err() error { } type CompositeBinaryBuilder struct { - ci *ConnInfo + m *Map buf []byte startIdx int fieldCount uint32 err error } -func NewCompositeBinaryBuilder(ci *ConnInfo, buf []byte) *CompositeBinaryBuilder { +func NewCompositeBinaryBuilder(m *Map, buf []byte) *CompositeBinaryBuilder { startIdx := len(buf) buf = append(buf, 0, 0, 0, 0) // allocate room for number of fields - return &CompositeBinaryBuilder{ci: ci, buf: buf, startIdx: startIdx} + return &CompositeBinaryBuilder{m: m, buf: buf, startIdx: startIdx} } func (b *CompositeBinaryBuilder) AppendValue(oid uint32, field interface{}) { @@ -484,7 +484,7 @@ func (b *CompositeBinaryBuilder) AppendValue(oid uint32, field interface{}) { return } - plan := b.ci.PlanEncode(oid, BinaryFormatCode, field) + plan := b.m.PlanEncode(oid, BinaryFormatCode, field) if plan == nil { b.err = fmt.Errorf("unable to encode %v into OID %d in binary format", field, oid) return @@ -516,7 +516,7 @@ func (b *CompositeBinaryBuilder) Finish() ([]byte, error) { } type CompositeTextBuilder struct { - ci *ConnInfo + m *Map buf []byte startIdx int fieldCount uint32 @@ -524,9 +524,9 @@ type CompositeTextBuilder struct { fieldBuf [32]byte } -func NewCompositeTextBuilder(ci *ConnInfo, buf []byte) *CompositeTextBuilder { +func NewCompositeTextBuilder(m *Map, buf []byte) *CompositeTextBuilder { buf = append(buf, '(') // allocate room for number of fields - return &CompositeTextBuilder{ci: ci, buf: buf} + return &CompositeTextBuilder{m: m, buf: buf} } func (b *CompositeTextBuilder) AppendValue(oid uint32, field interface{}) { @@ -539,7 +539,7 @@ func (b *CompositeTextBuilder) AppendValue(oid uint32, field interface{}) { return } - plan := b.ci.PlanEncode(oid, TextFormatCode, field) + plan := b.m.PlanEncode(oid, TextFormatCode, field) if plan == nil { b.err = fmt.Errorf("unable to encode %v into OID %d in text format", field, oid) return diff --git a/pgtype/composite_test.go b/pgtype/composite_test.go index f96a6470..d97f617b 100644 --- a/pgtype/composite_test.go +++ b/pgtype/composite_test.go @@ -26,7 +26,7 @@ create type ct_test as ( dt, err := conn.LoadType(context.Background(), "ct_test") require.NoError(t, err) - conn.ConnInfo().RegisterType(dt) + conn.TypeMap().RegisterType(dt) formats := []struct { name string @@ -105,7 +105,7 @@ create type point3d as ( dt, err := conn.LoadType(context.Background(), "point3d") require.NoError(t, err) - conn.ConnInfo().RegisterType(dt) + conn.TypeMap().RegisterType(dt) formats := []struct { name string @@ -140,7 +140,7 @@ create type point3d as ( dt, err := conn.LoadType(context.Background(), "point3d") require.NoError(t, err) - conn.ConnInfo().RegisterType(dt) + conn.TypeMap().RegisterType(dt) formats := []struct { name string @@ -179,7 +179,7 @@ create type point3d as ( dt, err := conn.LoadType(context.Background(), "point3d") require.NoError(t, err) - conn.ConnInfo().RegisterType(dt) + conn.TypeMap().RegisterType(dt) formats := []struct { name string diff --git a/pgtype/date.go b/pgtype/date.go index adfa0999..fe917a3e 100644 --- a/pgtype/date.go +++ b/pgtype/date.go @@ -126,7 +126,7 @@ func (DateCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (DateCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (DateCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(DateValuer); !ok { return nil } @@ -196,7 +196,7 @@ func (encodePlanDateCodecText) Encode(value interface{}, buf []byte) (newBuf []b return append(buf, s...), nil } -func (DateCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (DateCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -265,17 +265,17 @@ func (scanPlanTextAnyToDateScanner) Scan(src []byte, dst interface{}) error { } } -func (c DateCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c DateCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c DateCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c DateCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var date Date - err := codecScan(c, ci, oid, format, src, &date) + err := codecScan(c, m, oid, format, src, &date) if err != nil { return nil, err } diff --git a/pgtype/enum_codec.go b/pgtype/enum_codec.go index 970895d8..3dce4449 100644 --- a/pgtype/enum_codec.go +++ b/pgtype/enum_codec.go @@ -20,7 +20,7 @@ func (EnumCodec) PreferredFormat() int16 { return TextFormatCode } -func (EnumCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (EnumCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case TextFormatCode, BinaryFormatCode: switch value.(type) { @@ -38,7 +38,7 @@ func (EnumCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interf return nil } -func (c *EnumCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (c *EnumCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case TextFormatCode, BinaryFormatCode: switch target.(type) { @@ -56,11 +56,11 @@ func (c *EnumCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inte return nil } -func (c *EnumCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return c.DecodeValue(ci, oid, format, src) +func (c *EnumCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) } -func (c *EnumCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c *EnumCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } diff --git a/pgtype/enum_codec_test.go b/pgtype/enum_codec_test.go index f8dba1a0..afd062a2 100644 --- a/pgtype/enum_codec_test.go +++ b/pgtype/enum_codec_test.go @@ -21,7 +21,7 @@ create type enum_test as enum ('foo', 'bar', 'baz');`) dt, err := conn.LoadType(context.Background(), "enum_test") require.NoError(t, err) - conn.ConnInfo().RegisterType(dt) + conn.TypeMap().RegisterType(dt) var s string err = conn.QueryRow(context.Background(), `select 'foo'::enum_test`).Scan(&s) @@ -58,7 +58,7 @@ create type enum_test as enum ('foo', 'bar', 'baz');`) dt, err := conn.LoadType(context.Background(), "enum_test") require.NoError(t, err) - conn.ConnInfo().RegisterType(dt) + conn.TypeMap().RegisterType(dt) rows, err := conn.Query(context.Background(), `select 'foo'::enum_test`) require.NoError(t, err) diff --git a/pgtype/float4.go b/pgtype/float4.go index fd5f4523..9ca6fe6a 100644 --- a/pgtype/float4.go +++ b/pgtype/float4.go @@ -75,7 +75,7 @@ func (Float4Codec) PreferredFormat() int16 { return BinaryFormatCode } -func (Float4Codec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (Float4Codec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -145,7 +145,7 @@ func (encodePlanFloat4CodecBinaryInt64Valuer) Encode(value interface{}, buf []by return pgio.AppendUint32(buf, math.Float32bits(f)), nil } -func (Float4Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (Float4Codec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -247,26 +247,26 @@ func (scanPlanTextAnyToFloat32) Scan(src []byte, dst interface{}) error { return nil } -func (c Float4Codec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c Float4Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var n float64 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } return n, nil } -func (c Float4Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c Float4Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n float32 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } diff --git a/pgtype/float8.go b/pgtype/float8.go index 54b1796c..d5461ab0 100644 --- a/pgtype/float8.go +++ b/pgtype/float8.go @@ -83,7 +83,7 @@ func (Float8Codec) PreferredFormat() int16 { return BinaryFormatCode } -func (Float8Codec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (Float8Codec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -183,7 +183,7 @@ func (encodePlanTextInt64Valuer) Encode(value interface{}, buf []byte) (newBuf [ return append(buf, strconv.FormatInt(n.Int, 10)...), nil } -func (Float8Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (Float8Codec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -302,17 +302,17 @@ func (scanPlanTextAnyToFloat64Scanner) Scan(src []byte, dst interface{}) error { return s.ScanFloat64(Float8{Float: n, Valid: true}) } -func (c Float8Codec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return c.DecodeValue(ci, oid, format, src) +func (c Float8Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) } -func (c Float8Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c Float8Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n float64 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } diff --git a/pgtype/hstore.go b/pgtype/hstore.go index dc5caa84..a27330ae 100644 --- a/pgtype/hstore.go +++ b/pgtype/hstore.go @@ -72,7 +72,7 @@ func (HstoreCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (HstoreCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (HstoreCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(HstoreValuer); !ok { return nil } @@ -150,7 +150,7 @@ func (encodePlanHstoreCodecText) Encode(value interface{}, buf []byte) (newBuf [ return buf, nil } -func (HstoreCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (HstoreCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -254,17 +254,17 @@ func (scanPlanTextAnyToHstoreScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanHstore(m) } -func (c HstoreCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c HstoreCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c HstoreCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c HstoreCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var hstore Hstore - err := codecScan(c, ci, oid, format, src, &hstore) + err := codecScan(c, m, oid, format, src, &hstore) if err != nil { return nil, err } diff --git a/pgtype/hstore_test.go b/pgtype/hstore_test.go index 2437a240..8141687a 100644 --- a/pgtype/hstore_test.go +++ b/pgtype/hstore_test.go @@ -61,7 +61,7 @@ func TestHstoreCodec(t *testing.T) { t.Skipf("Skipping: cannot find hstore OID") } - conn.ConnInfo().RegisterType(&pgtype.Type{Name: "hstore", OID: hstoreOID, Codec: pgtype.HstoreCodec{}}) + conn.TypeMap().RegisterType(&pgtype.Type{Name: "hstore", OID: hstoreOID, Codec: pgtype.HstoreCodec{}}) formats := []struct { name string diff --git a/pgtype/inet.go b/pgtype/inet.go index 9530d1a2..ab4cff47 100644 --- a/pgtype/inet.go +++ b/pgtype/inet.go @@ -75,7 +75,7 @@ func (InetCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (InetCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (InetCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(InetValuer); !ok { return nil } @@ -140,7 +140,7 @@ func (encodePlanInetCodecText) Encode(value interface{}, buf []byte) (newBuf []b return append(buf, inet.IPNet.String()...), nil } -func (InetCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (InetCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -158,17 +158,17 @@ func (InetCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa return nil } -func (c InetCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c InetCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c InetCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c InetCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var inet Inet - err := codecScan(c, ci, oid, format, src, &inet) + err := codecScan(c, m, oid, format, src, &inet) if err != nil { return nil, err } diff --git a/pgtype/int.go b/pgtype/int.go index 237fe7e7..bfdb0184 100644 --- a/pgtype/int.go +++ b/pgtype/int.go @@ -127,7 +127,7 @@ func (Int2Codec) PreferredFormat() int16 { return BinaryFormatCode } -func (Int2Codec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (Int2Codec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -206,7 +206,7 @@ func (encodePlanInt2CodecTextInt64Valuer) Encode(value interface{}, buf []byte) return append(buf, strconv.FormatInt(n.Int, 10)...), nil } -func (Int2Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (Int2Codec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -264,26 +264,26 @@ func (Int2Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa return nil } -func (c Int2Codec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c Int2Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var n int64 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } return n, nil } -func (c Int2Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c Int2Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n int16 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } @@ -664,7 +664,7 @@ func (Int4Codec) PreferredFormat() int16 { return BinaryFormatCode } -func (Int4Codec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (Int4Codec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -743,7 +743,7 @@ func (encodePlanInt4CodecTextInt64Valuer) Encode(value interface{}, buf []byte) return append(buf, strconv.FormatInt(n.Int, 10)...), nil } -func (Int4Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (Int4Codec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -801,26 +801,26 @@ func (Int4Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa return nil } -func (c Int4Codec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c Int4Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var n int64 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } return n, nil } -func (c Int4Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c Int4Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n int32 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } @@ -1212,7 +1212,7 @@ func (Int8Codec) PreferredFormat() int16 { return BinaryFormatCode } -func (Int8Codec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (Int8Codec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -1291,7 +1291,7 @@ func (encodePlanInt8CodecTextInt64Valuer) Encode(value interface{}, buf []byte) return append(buf, strconv.FormatInt(n.Int, 10)...), nil } -func (Int8Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (Int8Codec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -1349,26 +1349,26 @@ func (Int8Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa return nil } -func (c Int8Codec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c Int8Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var n int64 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } return n, nil } -func (c Int8Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c Int8Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n int64 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } diff --git a/pgtype/int.go.erb b/pgtype/int.go.erb index 18e708fa..cec88984 100644 --- a/pgtype/int.go.erb +++ b/pgtype/int.go.erb @@ -128,7 +128,7 @@ func (Int<%= pg_byte_size %>Codec) PreferredFormat() int16 { return BinaryFormatCode } -func (Int<%= pg_byte_size %>Codec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (Int<%= pg_byte_size %>Codec) PlanEncode(m *TypeMap, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -207,7 +207,7 @@ func (encodePlanInt<%= pg_byte_size %>CodecTextInt64Valuer) Encode(value interfa return append(buf, strconv.FormatInt(n.Int, 10)...), nil } -func (Int<%= pg_byte_size %>Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (Int<%= pg_byte_size %>Codec) PlanScan(m *TypeMap, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -265,26 +265,26 @@ func (Int<%= pg_byte_size %>Codec) PlanScan(ci *ConnInfo, oid uint32, format int return nil } -func (c Int<%= pg_byte_size %>Codec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c Int<%= pg_byte_size %>Codec) DecodeDatabaseSQLValue(m *TypeMap, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var n int64 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } return n, nil } -func (c Int<%= pg_byte_size %>Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c Int<%= pg_byte_size %>Codec) DecodeValue(m *TypeMap, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n int<%= pg_bit_size %> - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } diff --git a/pgtype/interval.go b/pgtype/interval.go index a20266eb..a13969c3 100644 --- a/pgtype/interval.go +++ b/pgtype/interval.go @@ -80,7 +80,7 @@ func (IntervalCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (IntervalCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (IntervalCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(IntervalValuer); !ok { return nil } @@ -151,7 +151,7 @@ func (encodePlanIntervalCodecText) Encode(value interface{}, buf []byte) (newBuf return buf, nil } -func (IntervalCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (IntervalCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -274,17 +274,17 @@ func (scanPlanTextAnyToIntervalScanner) Scan(src []byte, dst interface{}) error return scanner.ScanInterval(Interval{Months: months, Days: days, Microseconds: microseconds, Valid: true}) } -func (c IntervalCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c IntervalCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c IntervalCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c IntervalCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var interval Interval - err := codecScan(c, ci, oid, format, src, &interval) + err := codecScan(c, m, oid, format, src, &interval) if err != nil { return nil, err } diff --git a/pgtype/json.go b/pgtype/json.go index cd8b8ec9..04ce6f6b 100644 --- a/pgtype/json.go +++ b/pgtype/json.go @@ -16,7 +16,7 @@ func (JSONCodec) PreferredFormat() int16 { return TextFormatCode } -func (JSONCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (JSONCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch value.(type) { case []byte: return encodePlanJSONCodecEitherFormatByteSlice{} @@ -49,7 +49,7 @@ func (encodePlanJSONCodecEitherFormatMarshal) Encode(value interface{}, buf []by return buf, nil } -func (JSONCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (JSONCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch target.(type) { case *string: return scanPlanAnyToString{} @@ -110,7 +110,7 @@ func (scanPlanJSONToJSONUnmarshal) Scan(src []byte, dst interface{}) error { return json.Unmarshal(src, dst) } -func (c JSONCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c JSONCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -120,7 +120,7 @@ func (c JSONCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16 return dstBuf, nil } -func (c JSONCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c JSONCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } diff --git a/pgtype/jsonb.go b/pgtype/jsonb.go index 07ea58bc..0504ee62 100644 --- a/pgtype/jsonb.go +++ b/pgtype/jsonb.go @@ -16,15 +16,15 @@ func (JSONBCodec) PreferredFormat() int16 { return TextFormatCode } -func (JSONBCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (JSONBCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: - plan := JSONCodec{}.PlanEncode(ci, oid, TextFormatCode, value) + plan := JSONCodec{}.PlanEncode(m, oid, TextFormatCode, value) if plan != nil { return &encodePlanJSONBCodecBinaryWrapper{textPlan: plan} } case TextFormatCode: - return JSONCodec{}.PlanEncode(ci, oid, format, value) + return JSONCodec{}.PlanEncode(m, oid, format, value) } return nil @@ -39,15 +39,15 @@ func (plan *encodePlanJSONBCodecBinaryWrapper) Encode(value interface{}, buf []b return plan.textPlan.Encode(value, buf) } -func (JSONBCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (JSONBCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: - plan := JSONCodec{}.PlanScan(ci, oid, TextFormatCode, target, actualTarget) + plan := JSONCodec{}.PlanScan(m, oid, TextFormatCode, target, actualTarget) if plan != nil { return &scanPlanJSONBCodecBinaryUnwrapper{textPlan: plan} } case TextFormatCode: - return JSONCodec{}.PlanScan(ci, oid, format, target, actualTarget) + return JSONCodec{}.PlanScan(m, oid, format, target, actualTarget) } return nil @@ -73,7 +73,7 @@ func (plan *scanPlanJSONBCodecBinaryUnwrapper) Scan(src []byte, dst interface{}) return plan.textPlan.Scan(src[1:], dst) } -func (c JSONBCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c JSONBCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -100,7 +100,7 @@ func (c JSONBCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int1 } } -func (c JSONBCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c JSONBCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } diff --git a/pgtype/line.go b/pgtype/line.go index acae903b..17acab81 100644 --- a/pgtype/line.go +++ b/pgtype/line.go @@ -75,7 +75,7 @@ func (LineCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (LineCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (LineCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(LineValuer); !ok { return nil } @@ -128,7 +128,7 @@ func (encodePlanLineCodecText) Encode(value interface{}, buf []byte) (newBuf []b return buf, nil } -func (LineCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (LineCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -207,17 +207,17 @@ func (scanPlanTextAnyToLineScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanLine(Line{A: a, B: b, C: c, Valid: true}) } -func (c LineCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c LineCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c LineCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c LineCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var line Line - err := codecScan(c, ci, oid, format, src, &line) + err := codecScan(c, m, oid, format, src, &line) if err != nil { return nil, err } diff --git a/pgtype/line_test.go b/pgtype/line_test.go index 3ed8fc4b..6c7b734b 100644 --- a/pgtype/line_test.go +++ b/pgtype/line_test.go @@ -11,7 +11,7 @@ import ( func TestLineTranscode(t *testing.T) { conn := testutil.MustConnectPgx(t) defer conn.Close(context.Background()) - if _, ok := conn.ConnInfo().TypeForName("line"); !ok { + if _, ok := conn.TypeMap().TypeForName("line"); !ok { t.Skip("Skipping due to no line type") } diff --git a/pgtype/lseg.go b/pgtype/lseg.go index 471b36b2..8f65c7c3 100644 --- a/pgtype/lseg.go +++ b/pgtype/lseg.go @@ -71,7 +71,7 @@ func (LsegCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (LsegCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (LsegCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(LsegValuer); !ok { return nil } @@ -126,7 +126,7 @@ func (encodePlanLsegCodecText) Encode(value interface{}, buf []byte) (newBuf []b return buf, nil } -func (LsegCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (LsegCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -220,17 +220,17 @@ func (scanPlanTextAnyToLsegScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanLseg(Lseg{P: [2]Vec2{{x1, y1}, {x2, y2}}, Valid: true}) } -func (c LsegCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c LsegCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c LsegCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c LsegCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var lseg Lseg - err := codecScan(c, ci, oid, format, src, &lseg) + err := codecScan(c, m, oid, format, src, &lseg) if err != nil { return nil, err } diff --git a/pgtype/macaddr.go b/pgtype/macaddr.go index 5b42811a..23ca55d1 100644 --- a/pgtype/macaddr.go +++ b/pgtype/macaddr.go @@ -15,7 +15,7 @@ func (MacaddrCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (MacaddrCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (MacaddrCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -78,7 +78,7 @@ func (encodePlanMacaddrCodecTextHardwareAddr) Encode(value interface{}, buf []by return append(buf, addr.String()...), nil } -func (MacaddrCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (MacaddrCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: switch target.(type) { @@ -144,17 +144,17 @@ func (scanPlanTextMacaddrToHardwareAddr) Scan(src []byte, dst interface{}) error return nil } -func (c MacaddrCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c MacaddrCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c MacaddrCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c MacaddrCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var addr net.HardwareAddr - err := codecScan(c, ci, oid, format, src, &addr) + err := codecScan(c, m, oid, format, src, &addr) if err != nil { return nil, err } diff --git a/pgtype/numeric.go b/pgtype/numeric.go index d2311f3a..3e7f972f 100644 --- a/pgtype/numeric.go +++ b/pgtype/numeric.go @@ -249,7 +249,7 @@ func (NumericCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (NumericCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (NumericCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -501,7 +501,7 @@ func encodeNumericText(n Numeric, buf []byte) (newBuf []byte, err error) { return buf, nil } -func (NumericCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (NumericCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -710,7 +710,7 @@ func (scanPlanTextAnyToNumericScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanNumeric(Numeric{Int: num, Exp: exp, Valid: true}) } -func (c NumericCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c NumericCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -720,25 +720,25 @@ func (c NumericCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format in } var n Numeric - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } - buf, err := ci.Encode(oid, TextFormatCode, n, nil) + buf, err := m.Encode(oid, TextFormatCode, n, nil) if err != nil { return nil, err } return string(buf), nil } -func (c NumericCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c NumericCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n Numeric - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } diff --git a/pgtype/path.go b/pgtype/path.go index 62a23219..c1355e41 100644 --- a/pgtype/path.go +++ b/pgtype/path.go @@ -73,7 +73,7 @@ func (PathCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (PathCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (PathCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(PathValuer); !ok { return nil } @@ -153,7 +153,7 @@ func (encodePlanPathCodecText) Encode(value interface{}, buf []byte) (newBuf []b return buf, nil } -func (PathCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (PathCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -254,17 +254,17 @@ func (scanPlanTextAnyToPathScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanPath(Path{P: points, Closed: closed, Valid: true}) } -func (c PathCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c PathCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c PathCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c PathCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var path Path - err := codecScan(c, ci, oid, format, src, &path) + err := codecScan(c, m, oid, format, src, &path) if err != nil { return nil, err } diff --git a/pgtype/pgtype.go b/pgtype/pgtype.go index 81431826..90f07d51 100644 --- a/pgtype/pgtype.go +++ b/pgtype/pgtype.go @@ -141,18 +141,18 @@ type Codec interface { // PlanEncode returns an Encode plan for encoding value into PostgreSQL format for oid and format. If no plan can be // found then nil is returned. - PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan + PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan // PlanScan returns a ScanPlan for scanning a PostgreSQL value into a destination with the same type as target. If // actualTarget is true then the returned ScanPlan may be optimized to directly scan into target. If no plan can be // found then nil is returned. - PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan + PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan // DecodeDatabaseSQLValue returns src decoded into a value compatible with the sql.Scanner interface. - DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) + DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) // DecodeValue returns src decoded into its default format. - DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) + DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) } type nullAssignmentError struct { @@ -169,7 +169,9 @@ type Type struct { OID uint32 } -type ConnInfo struct { +// Map is the mapping between PostgreSQL server types and Go type handling logic. It can encode values for +// transmission to a PostgreSQL server and scan received values. +type Map struct { oidToType map[uint32]*Type nameToType map[string]*Type reflectTypeToName map[reflect.Type]string @@ -180,19 +182,19 @@ type ConnInfo struct { // TryWrapEncodePlanFuncs is a slice of functions that will wrap a value that cannot be encoded by the Codec. Every // time a wrapper is found the PlanEncode method will be recursively called with the new value. This allows several layers of wrappers - // to be built up. There are default functions placed in this slice by NewConnInfo(). In most cases these functions + // to be built up. There are default functions placed in this slice by NewMap(). In most cases these functions // should run last. i.e. Additional functions should typically be prepended not appended. TryWrapEncodePlanFuncs []TryWrapEncodePlanFunc // TryWrapScanPlanFuncs is a slice of functions that will wrap a target that cannot be scanned into by the Codec. Every // time a wrapper is found the PlanScan method will be recursively called with the new target. This allows several layers of wrappers - // to be built up. There are default functions placed in this slice by NewConnInfo(). In most cases these functions + // to be built up. There are default functions placed in this slice by NewMap(). In most cases these functions // should run last. i.e. Additional functions should typically be prepended not appended. TryWrapScanPlanFuncs []TryWrapScanPlanFunc } -func NewConnInfo() *ConnInfo { - ci := &ConnInfo{ +func NewMap() *Map { + m := &Map{ oidToType: make(map[uint32]*Type), nameToType: make(map[string]*Type), reflectTypeToName: make(map[reflect.Type]string), @@ -218,121 +220,121 @@ func NewConnInfo() *ConnInfo { }, } - ci.RegisterType(&Type{Name: "aclitem", OID: ACLItemOID, Codec: &TextFormatOnlyCodec{TextCodec{}}}) - ci.RegisterType(&Type{Name: "bit", OID: BitOID, Codec: BitsCodec{}}) - ci.RegisterType(&Type{Name: "bool", OID: BoolOID, Codec: BoolCodec{}}) - ci.RegisterType(&Type{Name: "box", OID: BoxOID, Codec: BoxCodec{}}) - ci.RegisterType(&Type{Name: "bpchar", OID: BPCharOID, Codec: TextCodec{}}) - ci.RegisterType(&Type{Name: "bytea", OID: ByteaOID, Codec: ByteaCodec{}}) - ci.RegisterType(&Type{Name: "char", OID: QCharOID, Codec: QCharCodec{}}) - ci.RegisterType(&Type{Name: "cid", OID: CIDOID, Codec: Uint32Codec{}}) - ci.RegisterType(&Type{Name: "cidr", OID: CIDROID, Codec: InetCodec{}}) - ci.RegisterType(&Type{Name: "circle", OID: CircleOID, Codec: CircleCodec{}}) - ci.RegisterType(&Type{Name: "date", OID: DateOID, Codec: DateCodec{}}) - ci.RegisterType(&Type{Name: "float4", OID: Float4OID, Codec: Float4Codec{}}) - ci.RegisterType(&Type{Name: "float8", OID: Float8OID, Codec: Float8Codec{}}) - ci.RegisterType(&Type{Name: "inet", OID: InetOID, Codec: InetCodec{}}) - ci.RegisterType(&Type{Name: "int2", OID: Int2OID, Codec: Int2Codec{}}) - ci.RegisterType(&Type{Name: "int4", OID: Int4OID, Codec: Int4Codec{}}) - ci.RegisterType(&Type{Name: "int8", OID: Int8OID, Codec: Int8Codec{}}) - ci.RegisterType(&Type{Name: "interval", OID: IntervalOID, Codec: IntervalCodec{}}) - ci.RegisterType(&Type{Name: "json", OID: JSONOID, Codec: JSONCodec{}}) - ci.RegisterType(&Type{Name: "jsonb", OID: JSONBOID, Codec: JSONBCodec{}}) - ci.RegisterType(&Type{Name: "line", OID: LineOID, Codec: LineCodec{}}) - ci.RegisterType(&Type{Name: "lseg", OID: LsegOID, Codec: LsegCodec{}}) - ci.RegisterType(&Type{Name: "macaddr", OID: MacaddrOID, Codec: MacaddrCodec{}}) - ci.RegisterType(&Type{Name: "name", OID: NameOID, Codec: TextCodec{}}) - ci.RegisterType(&Type{Name: "numeric", OID: NumericOID, Codec: NumericCodec{}}) - ci.RegisterType(&Type{Name: "oid", OID: OIDOID, Codec: Uint32Codec{}}) - ci.RegisterType(&Type{Name: "path", OID: PathOID, Codec: PathCodec{}}) - ci.RegisterType(&Type{Name: "point", OID: PointOID, Codec: PointCodec{}}) - ci.RegisterType(&Type{Name: "polygon", OID: PolygonOID, Codec: PolygonCodec{}}) - ci.RegisterType(&Type{Name: "record", OID: RecordOID, Codec: RecordCodec{}}) - ci.RegisterType(&Type{Name: "text", OID: TextOID, Codec: TextCodec{}}) - ci.RegisterType(&Type{Name: "tid", OID: TIDOID, Codec: TIDCodec{}}) - ci.RegisterType(&Type{Name: "time", OID: TimeOID, Codec: TimeCodec{}}) - ci.RegisterType(&Type{Name: "timestamp", OID: TimestampOID, Codec: TimestampCodec{}}) - ci.RegisterType(&Type{Name: "timestamptz", OID: TimestamptzOID, Codec: TimestamptzCodec{}}) - ci.RegisterType(&Type{Name: "unknown", OID: UnknownOID, Codec: TextCodec{}}) - ci.RegisterType(&Type{Name: "uuid", OID: UUIDOID, Codec: UUIDCodec{}}) - ci.RegisterType(&Type{Name: "varbit", OID: VarbitOID, Codec: BitsCodec{}}) - ci.RegisterType(&Type{Name: "varchar", OID: VarcharOID, Codec: TextCodec{}}) - ci.RegisterType(&Type{Name: "xid", OID: XIDOID, Codec: Uint32Codec{}}) + m.RegisterType(&Type{Name: "aclitem", OID: ACLItemOID, Codec: &TextFormatOnlyCodec{TextCodec{}}}) + m.RegisterType(&Type{Name: "bit", OID: BitOID, Codec: BitsCodec{}}) + m.RegisterType(&Type{Name: "bool", OID: BoolOID, Codec: BoolCodec{}}) + m.RegisterType(&Type{Name: "box", OID: BoxOID, Codec: BoxCodec{}}) + m.RegisterType(&Type{Name: "bpchar", OID: BPCharOID, Codec: TextCodec{}}) + m.RegisterType(&Type{Name: "bytea", OID: ByteaOID, Codec: ByteaCodec{}}) + m.RegisterType(&Type{Name: "char", OID: QCharOID, Codec: QCharCodec{}}) + m.RegisterType(&Type{Name: "cid", OID: CIDOID, Codec: Uint32Codec{}}) + m.RegisterType(&Type{Name: "cidr", OID: CIDROID, Codec: InetCodec{}}) + m.RegisterType(&Type{Name: "circle", OID: CircleOID, Codec: CircleCodec{}}) + m.RegisterType(&Type{Name: "date", OID: DateOID, Codec: DateCodec{}}) + m.RegisterType(&Type{Name: "float4", OID: Float4OID, Codec: Float4Codec{}}) + m.RegisterType(&Type{Name: "float8", OID: Float8OID, Codec: Float8Codec{}}) + m.RegisterType(&Type{Name: "inet", OID: InetOID, Codec: InetCodec{}}) + m.RegisterType(&Type{Name: "int2", OID: Int2OID, Codec: Int2Codec{}}) + m.RegisterType(&Type{Name: "int4", OID: Int4OID, Codec: Int4Codec{}}) + m.RegisterType(&Type{Name: "int8", OID: Int8OID, Codec: Int8Codec{}}) + m.RegisterType(&Type{Name: "interval", OID: IntervalOID, Codec: IntervalCodec{}}) + m.RegisterType(&Type{Name: "json", OID: JSONOID, Codec: JSONCodec{}}) + m.RegisterType(&Type{Name: "jsonb", OID: JSONBOID, Codec: JSONBCodec{}}) + m.RegisterType(&Type{Name: "line", OID: LineOID, Codec: LineCodec{}}) + m.RegisterType(&Type{Name: "lseg", OID: LsegOID, Codec: LsegCodec{}}) + m.RegisterType(&Type{Name: "macaddr", OID: MacaddrOID, Codec: MacaddrCodec{}}) + m.RegisterType(&Type{Name: "name", OID: NameOID, Codec: TextCodec{}}) + m.RegisterType(&Type{Name: "numeric", OID: NumericOID, Codec: NumericCodec{}}) + m.RegisterType(&Type{Name: "oid", OID: OIDOID, Codec: Uint32Codec{}}) + m.RegisterType(&Type{Name: "path", OID: PathOID, Codec: PathCodec{}}) + m.RegisterType(&Type{Name: "point", OID: PointOID, Codec: PointCodec{}}) + m.RegisterType(&Type{Name: "polygon", OID: PolygonOID, Codec: PolygonCodec{}}) + m.RegisterType(&Type{Name: "record", OID: RecordOID, Codec: RecordCodec{}}) + m.RegisterType(&Type{Name: "text", OID: TextOID, Codec: TextCodec{}}) + m.RegisterType(&Type{Name: "tid", OID: TIDOID, Codec: TIDCodec{}}) + m.RegisterType(&Type{Name: "time", OID: TimeOID, Codec: TimeCodec{}}) + m.RegisterType(&Type{Name: "timestamp", OID: TimestampOID, Codec: TimestampCodec{}}) + m.RegisterType(&Type{Name: "timestamptz", OID: TimestamptzOID, Codec: TimestamptzCodec{}}) + m.RegisterType(&Type{Name: "unknown", OID: UnknownOID, Codec: TextCodec{}}) + m.RegisterType(&Type{Name: "uuid", OID: UUIDOID, Codec: UUIDCodec{}}) + m.RegisterType(&Type{Name: "varbit", OID: VarbitOID, Codec: BitsCodec{}}) + m.RegisterType(&Type{Name: "varchar", OID: VarcharOID, Codec: TextCodec{}}) + m.RegisterType(&Type{Name: "xid", OID: XIDOID, Codec: Uint32Codec{}}) - ci.RegisterType(&Type{Name: "daterange", OID: DaterangeOID, Codec: &RangeCodec{ElementType: ci.oidToType[DateOID]}}) - ci.RegisterType(&Type{Name: "int4range", OID: Int4rangeOID, Codec: &RangeCodec{ElementType: ci.oidToType[Int4OID]}}) - ci.RegisterType(&Type{Name: "int8range", OID: Int8rangeOID, Codec: &RangeCodec{ElementType: ci.oidToType[Int8OID]}}) - ci.RegisterType(&Type{Name: "numrange", OID: NumrangeOID, Codec: &RangeCodec{ElementType: ci.oidToType[NumericOID]}}) - ci.RegisterType(&Type{Name: "tsrange", OID: TsrangeOID, Codec: &RangeCodec{ElementType: ci.oidToType[TimestampOID]}}) - ci.RegisterType(&Type{Name: "tstzrange", OID: TstzrangeOID, Codec: &RangeCodec{ElementType: ci.oidToType[TimestamptzOID]}}) + m.RegisterType(&Type{Name: "daterange", OID: DaterangeOID, Codec: &RangeCodec{ElementType: m.oidToType[DateOID]}}) + m.RegisterType(&Type{Name: "int4range", OID: Int4rangeOID, Codec: &RangeCodec{ElementType: m.oidToType[Int4OID]}}) + m.RegisterType(&Type{Name: "int8range", OID: Int8rangeOID, Codec: &RangeCodec{ElementType: m.oidToType[Int8OID]}}) + m.RegisterType(&Type{Name: "numrange", OID: NumrangeOID, Codec: &RangeCodec{ElementType: m.oidToType[NumericOID]}}) + m.RegisterType(&Type{Name: "tsrange", OID: TsrangeOID, Codec: &RangeCodec{ElementType: m.oidToType[TimestampOID]}}) + m.RegisterType(&Type{Name: "tstzrange", OID: TstzrangeOID, Codec: &RangeCodec{ElementType: m.oidToType[TimestamptzOID]}}) - ci.RegisterType(&Type{Name: "_aclitem", OID: ACLItemArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[ACLItemOID]}}) - ci.RegisterType(&Type{Name: "_bit", OID: BitArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[BitOID]}}) - ci.RegisterType(&Type{Name: "_bool", OID: BoolArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[BoolOID]}}) - ci.RegisterType(&Type{Name: "_box", OID: BoxArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[BoxOID]}}) - ci.RegisterType(&Type{Name: "_bpchar", OID: BPCharArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[BPCharOID]}}) - ci.RegisterType(&Type{Name: "_bytea", OID: ByteaArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[ByteaOID]}}) - ci.RegisterType(&Type{Name: "_char", OID: QCharArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[QCharOID]}}) - ci.RegisterType(&Type{Name: "_cid", OID: CIDArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[CIDOID]}}) - ci.RegisterType(&Type{Name: "_cidr", OID: CIDRArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[CIDROID]}}) - ci.RegisterType(&Type{Name: "_circle", OID: CircleArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[CircleOID]}}) - ci.RegisterType(&Type{Name: "_date", OID: DateArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[DateOID]}}) - ci.RegisterType(&Type{Name: "_daterange", OID: DaterangeArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[DaterangeOID]}}) - ci.RegisterType(&Type{Name: "_float4", OID: Float4ArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[Float4OID]}}) - ci.RegisterType(&Type{Name: "_float8", OID: Float8ArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[Float8OID]}}) - ci.RegisterType(&Type{Name: "_inet", OID: InetArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[InetOID]}}) - ci.RegisterType(&Type{Name: "_int2", OID: Int2ArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[Int2OID]}}) - ci.RegisterType(&Type{Name: "_int4", OID: Int4ArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[Int4OID]}}) - ci.RegisterType(&Type{Name: "_int4range", OID: Int4rangeArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[Int4rangeOID]}}) - ci.RegisterType(&Type{Name: "_int8", OID: Int8ArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[Int8OID]}}) - ci.RegisterType(&Type{Name: "_int8range", OID: Int8rangeArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[Int8rangeOID]}}) - ci.RegisterType(&Type{Name: "_interval", OID: IntervalArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[IntervalOID]}}) - ci.RegisterType(&Type{Name: "_json", OID: JSONArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[JSONOID]}}) - ci.RegisterType(&Type{Name: "_jsonb", OID: JSONBArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[JSONBOID]}}) - ci.RegisterType(&Type{Name: "_line", OID: LineArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[LineOID]}}) - ci.RegisterType(&Type{Name: "_lseg", OID: LsegArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[LsegOID]}}) - ci.RegisterType(&Type{Name: "_macaddr", OID: MacaddrArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[MacaddrOID]}}) - ci.RegisterType(&Type{Name: "_name", OID: NameArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[NameOID]}}) - ci.RegisterType(&Type{Name: "_numeric", OID: NumericArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[NumericOID]}}) - ci.RegisterType(&Type{Name: "_numrange", OID: NumrangeArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[NumrangeOID]}}) - ci.RegisterType(&Type{Name: "_oid", OID: OIDArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[OIDOID]}}) - ci.RegisterType(&Type{Name: "_path", OID: PathArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[PathOID]}}) - ci.RegisterType(&Type{Name: "_point", OID: PointArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[PointOID]}}) - ci.RegisterType(&Type{Name: "_polygon", OID: PolygonArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[PolygonOID]}}) - ci.RegisterType(&Type{Name: "_record", OID: RecordArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[RecordOID]}}) - ci.RegisterType(&Type{Name: "_text", OID: TextArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[TextOID]}}) - ci.RegisterType(&Type{Name: "_tid", OID: TIDArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[TIDOID]}}) - ci.RegisterType(&Type{Name: "_time", OID: TimeArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[TimeOID]}}) - ci.RegisterType(&Type{Name: "_timestamp", OID: TimestampArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[TimestampOID]}}) - ci.RegisterType(&Type{Name: "_timestamptz", OID: TimestamptzArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[TimestamptzOID]}}) - ci.RegisterType(&Type{Name: "_tsrange", OID: TsrangeArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[TsrangeOID]}}) - ci.RegisterType(&Type{Name: "_tstzrange", OID: TstzrangeArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[TstzrangeOID]}}) - ci.RegisterType(&Type{Name: "_uuid", OID: UUIDArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[UUIDOID]}}) - ci.RegisterType(&Type{Name: "_varbit", OID: VarbitArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[VarbitOID]}}) - ci.RegisterType(&Type{Name: "_varchar", OID: VarcharArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[VarcharOID]}}) - ci.RegisterType(&Type{Name: "_xid", OID: XIDArrayOID, Codec: &ArrayCodec{ElementType: ci.oidToType[XIDOID]}}) + m.RegisterType(&Type{Name: "_aclitem", OID: ACLItemArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[ACLItemOID]}}) + m.RegisterType(&Type{Name: "_bit", OID: BitArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[BitOID]}}) + m.RegisterType(&Type{Name: "_bool", OID: BoolArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[BoolOID]}}) + m.RegisterType(&Type{Name: "_box", OID: BoxArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[BoxOID]}}) + m.RegisterType(&Type{Name: "_bpchar", OID: BPCharArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[BPCharOID]}}) + m.RegisterType(&Type{Name: "_bytea", OID: ByteaArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[ByteaOID]}}) + m.RegisterType(&Type{Name: "_char", OID: QCharArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[QCharOID]}}) + m.RegisterType(&Type{Name: "_cid", OID: CIDArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[CIDOID]}}) + m.RegisterType(&Type{Name: "_cidr", OID: CIDRArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[CIDROID]}}) + m.RegisterType(&Type{Name: "_circle", OID: CircleArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[CircleOID]}}) + m.RegisterType(&Type{Name: "_date", OID: DateArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[DateOID]}}) + m.RegisterType(&Type{Name: "_daterange", OID: DaterangeArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[DaterangeOID]}}) + m.RegisterType(&Type{Name: "_float4", OID: Float4ArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[Float4OID]}}) + m.RegisterType(&Type{Name: "_float8", OID: Float8ArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[Float8OID]}}) + m.RegisterType(&Type{Name: "_inet", OID: InetArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[InetOID]}}) + m.RegisterType(&Type{Name: "_int2", OID: Int2ArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[Int2OID]}}) + m.RegisterType(&Type{Name: "_int4", OID: Int4ArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[Int4OID]}}) + m.RegisterType(&Type{Name: "_int4range", OID: Int4rangeArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[Int4rangeOID]}}) + m.RegisterType(&Type{Name: "_int8", OID: Int8ArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[Int8OID]}}) + m.RegisterType(&Type{Name: "_int8range", OID: Int8rangeArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[Int8rangeOID]}}) + m.RegisterType(&Type{Name: "_interval", OID: IntervalArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[IntervalOID]}}) + m.RegisterType(&Type{Name: "_json", OID: JSONArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[JSONOID]}}) + m.RegisterType(&Type{Name: "_jsonb", OID: JSONBArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[JSONBOID]}}) + m.RegisterType(&Type{Name: "_line", OID: LineArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[LineOID]}}) + m.RegisterType(&Type{Name: "_lseg", OID: LsegArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[LsegOID]}}) + m.RegisterType(&Type{Name: "_macaddr", OID: MacaddrArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[MacaddrOID]}}) + m.RegisterType(&Type{Name: "_name", OID: NameArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[NameOID]}}) + m.RegisterType(&Type{Name: "_numeric", OID: NumericArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[NumericOID]}}) + m.RegisterType(&Type{Name: "_numrange", OID: NumrangeArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[NumrangeOID]}}) + m.RegisterType(&Type{Name: "_oid", OID: OIDArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[OIDOID]}}) + m.RegisterType(&Type{Name: "_path", OID: PathArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[PathOID]}}) + m.RegisterType(&Type{Name: "_point", OID: PointArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[PointOID]}}) + m.RegisterType(&Type{Name: "_polygon", OID: PolygonArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[PolygonOID]}}) + m.RegisterType(&Type{Name: "_record", OID: RecordArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[RecordOID]}}) + m.RegisterType(&Type{Name: "_text", OID: TextArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[TextOID]}}) + m.RegisterType(&Type{Name: "_tid", OID: TIDArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[TIDOID]}}) + m.RegisterType(&Type{Name: "_time", OID: TimeArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[TimeOID]}}) + m.RegisterType(&Type{Name: "_timestamp", OID: TimestampArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[TimestampOID]}}) + m.RegisterType(&Type{Name: "_timestamptz", OID: TimestamptzArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[TimestamptzOID]}}) + m.RegisterType(&Type{Name: "_tsrange", OID: TsrangeArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[TsrangeOID]}}) + m.RegisterType(&Type{Name: "_tstzrange", OID: TstzrangeArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[TstzrangeOID]}}) + m.RegisterType(&Type{Name: "_uuid", OID: UUIDArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[UUIDOID]}}) + m.RegisterType(&Type{Name: "_varbit", OID: VarbitArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[VarbitOID]}}) + m.RegisterType(&Type{Name: "_varchar", OID: VarcharArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[VarcharOID]}}) + m.RegisterType(&Type{Name: "_xid", OID: XIDArrayOID, Codec: &ArrayCodec{ElementType: m.oidToType[XIDOID]}}) registerDefaultPgTypeVariants := func(name, arrayName string, value interface{}) { // T - ci.RegisterDefaultPgType(value, name) + m.RegisterDefaultPgType(value, name) // *T valueType := reflect.TypeOf(value) - ci.RegisterDefaultPgType(reflect.New(valueType).Interface(), name) + m.RegisterDefaultPgType(reflect.New(valueType).Interface(), name) // []T sliceType := reflect.SliceOf(valueType) - ci.RegisterDefaultPgType(reflect.MakeSlice(sliceType, 0, 0).Interface(), arrayName) + m.RegisterDefaultPgType(reflect.MakeSlice(sliceType, 0, 0).Interface(), arrayName) // *[]T - ci.RegisterDefaultPgType(reflect.New(sliceType).Interface(), arrayName) + m.RegisterDefaultPgType(reflect.New(sliceType).Interface(), arrayName) // []*T sliceOfPointerType := reflect.SliceOf(reflect.TypeOf(reflect.New(valueType).Interface())) - ci.RegisterDefaultPgType(reflect.MakeSlice(sliceOfPointerType, 0, 0).Interface(), arrayName) + m.RegisterDefaultPgType(reflect.MakeSlice(sliceOfPointerType, 0, 0).Interface(), arrayName) // *[]*T - ci.RegisterDefaultPgType(reflect.New(sliceOfPointerType).Interface(), arrayName) + m.RegisterDefaultPgType(reflect.New(sliceOfPointerType).Interface(), arrayName) } // Integer types that directly map to a PostgreSQL type @@ -358,57 +360,57 @@ func NewConnInfo() *ConnInfo { registerDefaultPgTypeVariants("inet", "_inet", net.IP{}) registerDefaultPgTypeVariants("cidr", "_cidr", net.IPNet{}) - return ci + return m } -func (ci *ConnInfo) RegisterType(t *Type) { - ci.oidToType[t.OID] = t - ci.nameToType[t.Name] = t - ci.oidToFormatCode[t.OID] = t.Codec.PreferredFormat() - ci.reflectTypeToType = nil // Invalidated by type registration +func (m *Map) RegisterType(t *Type) { + m.oidToType[t.OID] = t + m.nameToType[t.Name] = t + m.oidToFormatCode[t.OID] = t.Codec.PreferredFormat() + m.reflectTypeToType = nil // Invalidated by type registration } // RegisterDefaultPgType registers a mapping of a Go type to a PostgreSQL type name. Typically the data type to be // encoded or decoded is determined by the PostgreSQL OID. But if the OID of a value to be encoded or decoded is // unknown, this additional mapping will be used by TypeForValue to determine a suitable data type. -func (ci *ConnInfo) RegisterDefaultPgType(value interface{}, name string) { - ci.reflectTypeToName[reflect.TypeOf(value)] = name - ci.reflectTypeToType = nil // Invalidated by registering a default type +func (m *Map) RegisterDefaultPgType(value interface{}, name string) { + m.reflectTypeToName[reflect.TypeOf(value)] = name + m.reflectTypeToType = nil // Invalidated by registering a default type } -func (ci *ConnInfo) TypeForOID(oid uint32) (*Type, bool) { - dt, ok := ci.oidToType[oid] +func (m *Map) TypeForOID(oid uint32) (*Type, bool) { + dt, ok := m.oidToType[oid] return dt, ok } -func (ci *ConnInfo) TypeForName(name string) (*Type, bool) { - dt, ok := ci.nameToType[name] +func (m *Map) TypeForName(name string) (*Type, bool) { + dt, ok := m.nameToType[name] return dt, ok } -func (ci *ConnInfo) buildReflectTypeToType() { - ci.reflectTypeToType = make(map[reflect.Type]*Type) +func (m *Map) buildReflectTypeToType() { + m.reflectTypeToType = make(map[reflect.Type]*Type) - for reflectType, name := range ci.reflectTypeToName { - if dt, ok := ci.nameToType[name]; ok { - ci.reflectTypeToType[reflectType] = dt + for reflectType, name := range m.reflectTypeToName { + if dt, ok := m.nameToType[name]; ok { + m.reflectTypeToType[reflectType] = dt } } } // TypeForValue finds a data type suitable for v. Use RegisterType to register types that can encode and decode // themselves. Use RegisterDefaultPgType to register that can be handled by a registered data type. -func (ci *ConnInfo) TypeForValue(v interface{}) (*Type, bool) { - if ci.reflectTypeToType == nil { - ci.buildReflectTypeToType() +func (m *Map) TypeForValue(v interface{}) (*Type, bool) { + if m.reflectTypeToType == nil { + m.buildReflectTypeToType() } - dt, ok := ci.reflectTypeToType[reflect.TypeOf(v)] + dt, ok := m.reflectTypeToType[reflect.TypeOf(v)] return dt, ok } -func (ci *ConnInfo) FormatCodeForOID(oid uint32) int16 { - fc, ok := ci.oidToFormatCode[oid] +func (m *Map) FormatCodeForOID(oid uint32) int16 { + fc, ok := m.oidToFormatCode[oid] if ok { return fc } @@ -431,13 +433,13 @@ type ScanPlan interface { type scanPlanCodecSQLScanner struct { c Codec - ci *ConnInfo + m *Map oid uint32 formatCode int16 } func (plan *scanPlanCodecSQLScanner) Scan(src []byte, dst interface{}) error { - value, err := plan.c.DecodeDatabaseSQLValue(plan.ci, plan.oid, plan.formatCode, src) + value, err := plan.c.DecodeDatabaseSQLValue(plan.m, plan.oid, plan.formatCode, src) if err != nil { return err } @@ -876,13 +878,13 @@ func (plan *wrapByteSliceScanPlan) Scan(src []byte, dst interface{}) error { type pointerEmptyInterfaceScanPlan struct { codec Codec - ci *ConnInfo + m *Map oid uint32 formatCode int16 } func (plan *pointerEmptyInterfaceScanPlan) Scan(src []byte, dst interface{}) error { - value, err := plan.codec.DecodeValue(plan.ci, plan.oid, plan.formatCode, src) + value, err := plan.codec.DecodeValue(plan.m, plan.oid, plan.formatCode, src) if err != nil { return err } @@ -991,7 +993,7 @@ func (plan *wrapPtrMultiDimSliceScanPlan) Scan(src []byte, target interface{}) e } // PlanScan prepares a plan to scan a value into target. -func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, target interface{}) ScanPlan { +func (m *Map) PlanScan(oid uint32, formatCode int16, target interface{}) ScanPlan { if _, ok := target.(*UndecodedBytes); ok { return scanPlanAnyToUndecodedBytes{} } @@ -1020,22 +1022,22 @@ func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, target interface{}) S var dt *Type - if dataType, ok := ci.TypeForOID(oid); ok { + if dataType, ok := m.TypeForOID(oid); ok { dt = dataType - } else if dataType, ok := ci.TypeForValue(target); ok { + } else if dataType, ok := m.TypeForValue(target); ok { dt = dataType oid = dt.OID // Preserve assumed OID in case we are recursively called below. } if dt != nil { - if plan := dt.Codec.PlanScan(ci, oid, formatCode, target, false); plan != nil { + if plan := dt.Codec.PlanScan(m, oid, formatCode, target, false); plan != nil { return plan } } - for _, f := range ci.TryWrapScanPlanFuncs { + for _, f := range m.TryWrapScanPlanFuncs { if wrapperPlan, nextDst, ok := f(target); ok { - if nextPlan := ci.PlanScan(oid, formatCode, nextDst); nextPlan != nil { + if nextPlan := m.PlanScan(oid, formatCode, nextDst); nextPlan != nil { if _, failed := nextPlan.(*scanPlanFail); !failed { wrapperPlan.SetNext(nextPlan) return wrapperPlan @@ -1046,11 +1048,11 @@ func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, target interface{}) S if dt != nil { if _, ok := target.(*interface{}); ok { - return &pointerEmptyInterfaceScanPlan{codec: dt.Codec, ci: ci, oid: oid, formatCode: formatCode} + return &pointerEmptyInterfaceScanPlan{codec: dt.Codec, m: m, oid: oid, formatCode: formatCode} } if _, ok := target.(sql.Scanner); ok { - return &scanPlanCodecSQLScanner{c: dt.Codec, ci: ci, oid: oid, formatCode: formatCode} + return &scanPlanCodecSQLScanner{c: dt.Codec, m: m, oid: oid, formatCode: formatCode} } } @@ -1061,12 +1063,12 @@ func (ci *ConnInfo) PlanScan(oid uint32, formatCode int16, target interface{}) S return &scanPlanFail{oid: oid, formatCode: formatCode} } -func (ci *ConnInfo) Scan(oid uint32, formatCode int16, src []byte, dst interface{}) error { +func (m *Map) Scan(oid uint32, formatCode int16, src []byte, dst interface{}) error { if dst == nil { return nil } - plan := ci.PlanScan(oid, formatCode, dst) + plan := m.PlanScan(oid, formatCode, dst) return plan.Scan(src, dst) } @@ -1091,15 +1093,15 @@ func scanUnknownType(oid uint32, formatCode int16, buf []byte, dest interface{}) var ErrScanTargetTypeChanged = errors.New("scan target type changed") -func codecScan(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte, dst interface{}) error { - scanPlan := codec.PlanScan(ci, oid, format, dst, true) +func codecScan(codec Codec, m *Map, oid uint32, format int16, src []byte, dst interface{}) error { + scanPlan := codec.PlanScan(m, oid, format, dst, true) if scanPlan == nil { return fmt.Errorf("PlanScan did not find a plan") } return scanPlan.Scan(src, dst) } -func codecDecodeToTextFormat(codec Codec, ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func codecDecodeToTextFormat(codec Codec, m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -1107,11 +1109,11 @@ func codecDecodeToTextFormat(codec Codec, ci *ConnInfo, oid uint32, format int16 if format == TextFormatCode { return string(src), nil } else { - value, err := codec.DecodeValue(ci, oid, format, src) + value, err := codec.DecodeValue(m, oid, format, src) if err != nil { return nil, err } - buf, err := ci.Encode(oid, TextFormatCode, value, nil) + buf, err := m.Encode(oid, TextFormatCode, value, nil) if err != nil { return nil, err } @@ -1121,29 +1123,29 @@ func codecDecodeToTextFormat(codec Codec, ci *ConnInfo, oid uint32, format int16 // PlanEncode returns an Encode plan for encoding value into PostgreSQL format for oid and format. If no plan can be // found then nil is returned. -func (ci *ConnInfo) PlanEncode(oid uint32, format int16, value interface{}) EncodePlan { +func (m *Map) PlanEncode(oid uint32, format int16, value interface{}) EncodePlan { var dt *Type if oid == 0 { - if dataType, ok := ci.TypeForValue(value); ok { + if dataType, ok := m.TypeForValue(value); ok { dt = dataType oid = dt.OID // Preserve assumed OID in case we are recursively called below. } } else { - if dataType, ok := ci.TypeForOID(oid); ok { + if dataType, ok := m.TypeForOID(oid); ok { dt = dataType } } if dt != nil { - if plan := dt.Codec.PlanEncode(ci, oid, format, value); plan != nil { + if plan := dt.Codec.PlanEncode(m, oid, format, value); plan != nil { return plan } - for _, f := range ci.TryWrapEncodePlanFuncs { + for _, f := range m.TryWrapEncodePlanFuncs { if wrapperPlan, nextValue, ok := f(value); ok { - if nextPlan := ci.PlanEncode(oid, format, nextValue); nextPlan != nil { + if nextPlan := m.PlanEncode(oid, format, nextValue); nextPlan != nil { wrapperPlan.SetNext(nextPlan) return wrapperPlan } @@ -1615,12 +1617,12 @@ func (plan *wrapMultiDimSliceEncodePlan) Encode(value interface{}, buf []byte) ( // Encode appends the encoded bytes of value to buf. If value is the SQL value NULL then append nothing and return // (nil, nil). The caller of Encode is responsible for writing the correct NULL value or the length of the data // written. -func (ci *ConnInfo) Encode(oid uint32, formatCode int16, value interface{}, buf []byte) (newBuf []byte, err error) { +func (m *Map) Encode(oid uint32, formatCode int16, value interface{}, buf []byte) (newBuf []byte, err error) { if value == nil { return nil, nil } - plan := ci.PlanEncode(oid, formatCode, value) + plan := m.PlanEncode(oid, formatCode, value) if plan == nil { return nil, fmt.Errorf("unable to encode %#v into OID %d", value, oid) } diff --git a/pgtype/pgtype_test.go b/pgtype/pgtype_test.go index 2917c31c..bbec30f3 100644 --- a/pgtype/pgtype_test.go +++ b/pgtype/pgtype_test.go @@ -67,59 +67,59 @@ func mustParseMacaddr(t testing.TB, s string) net.HardwareAddr { return addr } -func TestConnInfoScanNilIsNoOp(t *testing.T) { - ci := pgtype.NewConnInfo() +func TestTypeMapScanNilIsNoOp(t *testing.T) { + m := pgtype.NewMap() - err := ci.Scan(pgtype.TextOID, pgx.TextFormatCode, []byte("foo"), nil) + err := m.Scan(pgtype.TextOID, pgx.TextFormatCode, []byte("foo"), nil) assert.NoError(t, err) } -func TestConnInfoScanTextFormatInterfacePtr(t *testing.T) { - ci := pgtype.NewConnInfo() +func TestTypeMapScanTextFormatInterfacePtr(t *testing.T) { + m := pgtype.NewMap() var got interface{} - err := ci.Scan(pgtype.TextOID, pgx.TextFormatCode, []byte("foo"), &got) + err := m.Scan(pgtype.TextOID, pgx.TextFormatCode, []byte("foo"), &got) require.NoError(t, err) assert.Equal(t, "foo", got) } -func TestConnInfoScanTextFormatNonByteaIntoByteSlice(t *testing.T) { - ci := pgtype.NewConnInfo() +func TestTypeMapScanTextFormatNonByteaIntoByteSlice(t *testing.T) { + m := pgtype.NewMap() var got []byte - err := ci.Scan(pgtype.JSONBOID, pgx.TextFormatCode, []byte("{}"), &got) + err := m.Scan(pgtype.JSONBOID, pgx.TextFormatCode, []byte("{}"), &got) require.NoError(t, err) assert.Equal(t, []byte("{}"), got) } -func TestConnInfoScanBinaryFormatInterfacePtr(t *testing.T) { - ci := pgtype.NewConnInfo() +func TestTypeMapScanBinaryFormatInterfacePtr(t *testing.T) { + m := pgtype.NewMap() var got interface{} - err := ci.Scan(pgtype.TextOID, pgx.BinaryFormatCode, []byte("foo"), &got) + err := m.Scan(pgtype.TextOID, pgx.BinaryFormatCode, []byte("foo"), &got) require.NoError(t, err) assert.Equal(t, "foo", got) } -func TestConnInfoScanUnknownOIDToStringsAndBytes(t *testing.T) { +func TestTypeMapScanUnknownOIDToStringsAndBytes(t *testing.T) { unknownOID := uint32(999999) srcBuf := []byte("foo") - ci := pgtype.NewConnInfo() + m := pgtype.NewMap() var s string - err := ci.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &s) + err := m.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &s) assert.NoError(t, err) assert.Equal(t, "foo", s) var rs _string - err = ci.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &rs) + err = m.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &rs) assert.NoError(t, err) assert.Equal(t, "foo", string(rs)) var b []byte - err = ci.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &b) + err = m.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &b) assert.NoError(t, err) assert.Equal(t, []byte("foo"), b) var rb _byteSlice - err = ci.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &rb) + err = m.Scan(unknownOID, pgx.TextFormatCode, srcBuf, &rb) assert.NoError(t, err) assert.Equal(t, []byte("foo"), []byte(rb)) } @@ -129,7 +129,7 @@ type pgCustomType struct { b string } -func (ct *pgCustomType) DecodeText(ci *pgtype.ConnInfo, buf []byte) error { +func (ct *pgCustomType) DecodeText(m *pgtype.Map, buf []byte) error { // This is not a complete parser for the text format of composite types. This is just for test purposes. if buf == nil { return errors.New("cannot parse null") @@ -150,58 +150,58 @@ func (ct *pgCustomType) DecodeText(ci *pgtype.ConnInfo, buf []byte) error { return nil } -func TestConnInfoScanUnregisteredOIDToCustomType(t *testing.T) { +func TestTypeMapScanUnregisteredOIDToCustomType(t *testing.T) { t.Skip("TODO - unskip later in v5") // may no longer be relevent unregisteredOID := uint32(999999) - ci := pgtype.NewConnInfo() + m := pgtype.NewMap() var ct pgCustomType - err := ci.Scan(unregisteredOID, pgx.TextFormatCode, []byte("(foo,bar)"), &ct) + err := m.Scan(unregisteredOID, pgx.TextFormatCode, []byte("(foo,bar)"), &ct) assert.NoError(t, err) assert.Equal(t, "foo", ct.a) assert.Equal(t, "bar", ct.b) // Scan value into pointer to custom type var pCt *pgCustomType - err = ci.Scan(unregisteredOID, pgx.TextFormatCode, []byte("(foo,bar)"), &pCt) + err = m.Scan(unregisteredOID, pgx.TextFormatCode, []byte("(foo,bar)"), &pCt) assert.NoError(t, err) require.NotNil(t, pCt) assert.Equal(t, "foo", pCt.a) assert.Equal(t, "bar", pCt.b) // Scan null into pointer to custom type - err = ci.Scan(unregisteredOID, pgx.TextFormatCode, nil, &pCt) + err = m.Scan(unregisteredOID, pgx.TextFormatCode, nil, &pCt) assert.NoError(t, err) assert.Nil(t, pCt) } -func TestConnInfoScanUnknownOIDTextFormat(t *testing.T) { - ci := pgtype.NewConnInfo() +func TestTypeMapScanUnknownOIDTextFormat(t *testing.T) { + m := pgtype.NewMap() var n int32 - err := ci.Scan(0, pgx.TextFormatCode, []byte("123"), &n) + err := m.Scan(0, pgx.TextFormatCode, []byte("123"), &n) assert.NoError(t, err) assert.EqualValues(t, 123, n) } -func TestConnInfoScanUnknownOIDIntoSQLScanner(t *testing.T) { - ci := pgtype.NewConnInfo() +func TestTypeMapScanUnknownOIDIntoSQLScanner(t *testing.T) { + m := pgtype.NewMap() var s sql.NullString - err := ci.Scan(0, pgx.TextFormatCode, []byte(nil), &s) + err := m.Scan(0, pgx.TextFormatCode, []byte(nil), &s) assert.NoError(t, err) assert.Equal(t, "", s.String) assert.False(t, s.Valid) } -func BenchmarkConnInfoScanInt4IntoBinaryDecoder(b *testing.B) { - ci := pgtype.NewConnInfo() +func BenchmarkTypeMapScanInt4IntoBinaryDecoder(b *testing.B) { + m := pgtype.NewMap() src := []byte{0, 0, 0, 42} var v pgtype.Int4 for i := 0; i < b.N; i++ { v = pgtype.Int4{} - err := ci.Scan(pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) + err := m.Scan(pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) if err != nil { b.Fatal(err) } @@ -211,14 +211,14 @@ func BenchmarkConnInfoScanInt4IntoBinaryDecoder(b *testing.B) { } } -func BenchmarkConnInfoScanInt4IntoGoInt32(b *testing.B) { - ci := pgtype.NewConnInfo() +func BenchmarkTypeMapScanInt4IntoGoInt32(b *testing.B) { + m := pgtype.NewMap() src := []byte{0, 0, 0, 42} var v int32 for i := 0; i < b.N; i++ { v = 0 - err := ci.Scan(pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) + err := m.Scan(pgtype.Int4OID, pgtype.BinaryFormatCode, src, &v) if err != nil { b.Fatal(err) } @@ -229,11 +229,11 @@ func BenchmarkConnInfoScanInt4IntoGoInt32(b *testing.B) { } func BenchmarkScanPlanScanInt4IntoBinaryDecoder(b *testing.B) { - ci := pgtype.NewConnInfo() + m := pgtype.NewMap() src := []byte{0, 0, 0, 42} var v pgtype.Int4 - plan := ci.PlanScan(pgtype.Int4OID, pgtype.BinaryFormatCode, &v) + plan := m.PlanScan(pgtype.Int4OID, pgtype.BinaryFormatCode, &v) for i := 0; i < b.N; i++ { v = pgtype.Int4{} @@ -248,11 +248,11 @@ func BenchmarkScanPlanScanInt4IntoBinaryDecoder(b *testing.B) { } func BenchmarkScanPlanScanInt4IntoGoInt32(b *testing.B) { - ci := pgtype.NewConnInfo() + m := pgtype.NewMap() src := []byte{0, 0, 0, 42} var v int32 - plan := ci.PlanScan(pgtype.Int4OID, pgtype.BinaryFormatCode, &v) + plan := m.PlanScan(pgtype.Int4OID, pgtype.BinaryFormatCode, &v) for i := 0; i < b.N; i++ { v = 0 diff --git a/pgtype/point.go b/pgtype/point.go index 0a300fe2..4a9637ee 100644 --- a/pgtype/point.go +++ b/pgtype/point.go @@ -127,7 +127,7 @@ func (PointCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (PointCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (PointCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(PointValuer); !ok { return nil } @@ -177,7 +177,7 @@ func (encodePlanPointCodecText) Encode(value interface{}, buf []byte) (newBuf [] )...), nil } -func (PointCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (PointCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -195,17 +195,17 @@ func (PointCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interf return nil } -func (c PointCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c PointCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c PointCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c PointCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var point Point - err := codecScan(c, ci, oid, format, src, &point) + err := codecScan(c, m, oid, format, src, &point) if err != nil { return nil, err } diff --git a/pgtype/polygon.go b/pgtype/polygon.go index e4a1b2af..5a090ff0 100644 --- a/pgtype/polygon.go +++ b/pgtype/polygon.go @@ -72,7 +72,7 @@ func (PolygonCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (PolygonCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (PolygonCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(PolygonValuer); !ok { return nil } @@ -138,7 +138,7 @@ func (encodePlanPolygonCodecText) Encode(value interface{}, buf []byte) (newBuf return buf, nil } -func (PolygonCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (PolygonCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -235,17 +235,17 @@ func (scanPlanTextAnyToPolygonScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanPolygon(Polygon{P: points, Valid: true}) } -func (c PolygonCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c PolygonCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c PolygonCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c PolygonCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var polygon Polygon - err := codecScan(c, ci, oid, format, src, &polygon) + err := codecScan(c, m, oid, format, src, &polygon) if err != nil { return nil, err } diff --git a/pgtype/qchar.go b/pgtype/qchar.go index 5c712369..ce2c3dcb 100644 --- a/pgtype/qchar.go +++ b/pgtype/qchar.go @@ -22,7 +22,7 @@ func (QCharCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (QCharCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (QCharCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case TextFormatCode, BinaryFormatCode: switch value.(type) { @@ -56,7 +56,7 @@ func (encodePlanQcharCodecRune) Encode(value interface{}, buf []byte) (newBuf [] return buf, nil } -func (QCharCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (QCharCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case TextFormatCode, BinaryFormatCode: switch target.(type) { @@ -114,26 +114,26 @@ func (scanPlanQcharCodecRune) Scan(src []byte, dst interface{}) error { return nil } -func (c QCharCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c QCharCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var r rune - err := codecScan(c, ci, oid, format, src, &r) + err := codecScan(c, m, oid, format, src, &r) if err != nil { return nil, err } return string(r), nil } -func (c QCharCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c QCharCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var r rune - err := codecScan(c, ci, oid, format, src, &r) + err := codecScan(c, m, oid, format, src, &r) if err != nil { return nil, err } diff --git a/pgtype/range_codec.go b/pgtype/range_codec.go index 98903d3a..9628ce4b 100644 --- a/pgtype/range_codec.go +++ b/pgtype/range_codec.go @@ -86,16 +86,16 @@ func (c *RangeCodec) PreferredFormat() int16 { return TextFormatCode } -func (c *RangeCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (c *RangeCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(RangeValuer); !ok { return nil } switch format { case BinaryFormatCode: - return &encodePlanRangeCodecRangeValuerToBinary{rc: c, ci: ci} + return &encodePlanRangeCodecRangeValuerToBinary{rc: c, m: m} case TextFormatCode: - return &encodePlanRangeCodecRangeValuerToText{rc: c, ci: ci} + return &encodePlanRangeCodecRangeValuerToText{rc: c, m: m} } return nil @@ -103,7 +103,7 @@ func (c *RangeCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value in type encodePlanRangeCodecRangeValuerToBinary struct { rc *RangeCodec - ci *ConnInfo + m *Map } func (plan *encodePlanRangeCodecRangeValuerToBinary) Encode(value interface{}, buf []byte) (newBuf []byte, err error) { @@ -149,7 +149,7 @@ func (plan *encodePlanRangeCodecRangeValuerToBinary) Encode(value interface{}, b sp := len(buf) buf = pgio.AppendInt32(buf, -1) - lowerPlan := plan.ci.PlanEncode(plan.rc.ElementType.OID, BinaryFormatCode, lower) + lowerPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, BinaryFormatCode, lower) if lowerPlan == nil { return nil, fmt.Errorf("cannot encode %v as element of range", lower) } @@ -173,7 +173,7 @@ func (plan *encodePlanRangeCodecRangeValuerToBinary) Encode(value interface{}, b sp := len(buf) buf = pgio.AppendInt32(buf, -1) - upperPlan := plan.ci.PlanEncode(plan.rc.ElementType.OID, BinaryFormatCode, upper) + upperPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, BinaryFormatCode, upper) if upperPlan == nil { return nil, fmt.Errorf("cannot encode %v as element of range", upper) } @@ -194,7 +194,7 @@ func (plan *encodePlanRangeCodecRangeValuerToBinary) Encode(value interface{}, b type encodePlanRangeCodecRangeValuerToText struct { rc *RangeCodec - ci *ConnInfo + m *Map } func (plan *encodePlanRangeCodecRangeValuerToText) Encode(value interface{}, buf []byte) (newBuf []byte, err error) { @@ -223,7 +223,7 @@ func (plan *encodePlanRangeCodecRangeValuerToText) Encode(value interface{}, buf return nil, fmt.Errorf("Lower cannot be null unless LowerType is Unbounded") } - lowerPlan := plan.ci.PlanEncode(plan.rc.ElementType.OID, TextFormatCode, lower) + lowerPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, TextFormatCode, lower) if lowerPlan == nil { return nil, fmt.Errorf("cannot encode %v as element of range", lower) } @@ -244,7 +244,7 @@ func (plan *encodePlanRangeCodecRangeValuerToText) Encode(value interface{}, buf return nil, fmt.Errorf("Upper cannot be null unless UpperType is Unbounded") } - upperPlan := plan.ci.PlanEncode(plan.rc.ElementType.OID, TextFormatCode, upper) + upperPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, TextFormatCode, upper) if upperPlan == nil { return nil, fmt.Errorf("cannot encode %v as element of range", upper) } @@ -270,17 +270,17 @@ func (plan *encodePlanRangeCodecRangeValuerToText) Encode(value interface{}, buf return buf, nil } -func (c *RangeCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (c *RangeCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: switch target.(type) { case RangeScanner: - return &scanPlanBinaryRangeToRangeScanner{rc: c, ci: ci} + return &scanPlanBinaryRangeToRangeScanner{rc: c, m: m} } case TextFormatCode: switch target.(type) { case RangeScanner: - return &scanPlanTextRangeToRangeScanner{rc: c, ci: ci} + return &scanPlanTextRangeToRangeScanner{rc: c, m: m} } } @@ -289,7 +289,7 @@ func (c *RangeCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target int type scanPlanBinaryRangeToRangeScanner struct { rc *RangeCodec - ci *ConnInfo + m *Map } func (plan *scanPlanBinaryRangeToRangeScanner) Scan(src []byte, target interface{}) error { @@ -311,7 +311,7 @@ func (plan *scanPlanBinaryRangeToRangeScanner) Scan(src []byte, target interface lowerTarget, upperTarget := rangeScanner.ScanBounds() if ubr.LowerType == Inclusive || ubr.LowerType == Exclusive { - lowerPlan := plan.ci.PlanScan(plan.rc.ElementType.OID, BinaryFormatCode, lowerTarget) + lowerPlan := plan.m.PlanScan(plan.rc.ElementType.OID, BinaryFormatCode, lowerTarget) if lowerPlan == nil { return fmt.Errorf("cannot scan into %v from range element", lowerTarget) } @@ -323,7 +323,7 @@ func (plan *scanPlanBinaryRangeToRangeScanner) Scan(src []byte, target interface } if ubr.UpperType == Inclusive || ubr.UpperType == Exclusive { - upperPlan := plan.ci.PlanScan(plan.rc.ElementType.OID, BinaryFormatCode, upperTarget) + upperPlan := plan.m.PlanScan(plan.rc.ElementType.OID, BinaryFormatCode, upperTarget) if upperPlan == nil { return fmt.Errorf("cannot scan into %v from range element", upperTarget) } @@ -339,7 +339,7 @@ func (plan *scanPlanBinaryRangeToRangeScanner) Scan(src []byte, target interface type scanPlanTextRangeToRangeScanner struct { rc *RangeCodec - ci *ConnInfo + m *Map } func (plan *scanPlanTextRangeToRangeScanner) Scan(src []byte, target interface{}) error { @@ -361,7 +361,7 @@ func (plan *scanPlanTextRangeToRangeScanner) Scan(src []byte, target interface{} lowerTarget, upperTarget := rangeScanner.ScanBounds() if utr.LowerType == Inclusive || utr.LowerType == Exclusive { - lowerPlan := plan.ci.PlanScan(plan.rc.ElementType.OID, TextFormatCode, lowerTarget) + lowerPlan := plan.m.PlanScan(plan.rc.ElementType.OID, TextFormatCode, lowerTarget) if lowerPlan == nil { return fmt.Errorf("cannot scan into %v from range element", lowerTarget) } @@ -373,7 +373,7 @@ func (plan *scanPlanTextRangeToRangeScanner) Scan(src []byte, target interface{} } if utr.UpperType == Inclusive || utr.UpperType == Exclusive { - upperPlan := plan.ci.PlanScan(plan.rc.ElementType.OID, TextFormatCode, upperTarget) + upperPlan := plan.m.PlanScan(plan.rc.ElementType.OID, TextFormatCode, upperTarget) if upperPlan == nil { return fmt.Errorf("cannot scan into %v from range element", upperTarget) } @@ -387,7 +387,7 @@ func (plan *scanPlanTextRangeToRangeScanner) Scan(src []byte, target interface{} return rangeScanner.SetBoundTypes(utr.LowerType, utr.UpperType) } -func (c *RangeCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c *RangeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -404,12 +404,12 @@ func (c *RangeCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int } } -func (c *RangeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c *RangeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var r GenericRange - err := c.PlanScan(ci, oid, format, &r, true).Scan(src, &r) + err := c.PlanScan(m, oid, format, &r, true).Scan(src, &r) return r, err } diff --git a/pgtype/record_codec.go b/pgtype/record_codec.go index 92c197b2..c31aa63c 100644 --- a/pgtype/record_codec.go +++ b/pgtype/record_codec.go @@ -21,15 +21,15 @@ func (RecordCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (RecordCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (RecordCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { return nil } -func (RecordCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (RecordCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { if format == BinaryFormatCode { switch target.(type) { case CompositeIndexScanner: - return &scanPlanBinaryRecordToCompositeIndexScanner{ci: ci} + return &scanPlanBinaryRecordToCompositeIndexScanner{m: m} } } @@ -37,7 +37,7 @@ func (RecordCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter } type scanPlanBinaryRecordToCompositeIndexScanner struct { - ci *ConnInfo + m *Map } func (plan *scanPlanBinaryRecordToCompositeIndexScanner) Scan(src []byte, target interface{}) error { @@ -47,11 +47,11 @@ func (plan *scanPlanBinaryRecordToCompositeIndexScanner) Scan(src []byte, target return targetScanner.ScanNull() } - scanner := NewCompositeBinaryScanner(plan.ci, src) + scanner := NewCompositeBinaryScanner(plan.m, src) for i := 0; scanner.Next(); i++ { fieldTarget := targetScanner.ScanIndex(i) if fieldTarget != nil { - fieldPlan := plan.ci.PlanScan(scanner.OID(), BinaryFormatCode, fieldTarget) + fieldPlan := plan.m.PlanScan(scanner.OID(), BinaryFormatCode, fieldTarget) if fieldPlan == nil { return fmt.Errorf("unable to scan OID %d in binary format into %v", scanner.OID(), fieldTarget) } @@ -70,7 +70,7 @@ func (plan *scanPlanBinaryRecordToCompositeIndexScanner) Scan(src []byte, target return nil } -func (RecordCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (RecordCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } @@ -87,7 +87,7 @@ func (RecordCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16 } } -func (RecordCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (RecordCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } @@ -96,11 +96,11 @@ func (RecordCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byt case TextFormatCode: return string(src), nil case BinaryFormatCode: - scanner := NewCompositeBinaryScanner(ci, src) + scanner := NewCompositeBinaryScanner(m, src) values := make([]interface{}, scanner.FieldCount()) for i := 0; scanner.Next(); i++ { var v interface{} - fieldPlan := ci.PlanScan(scanner.OID(), BinaryFormatCode, &v) + fieldPlan := m.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) } diff --git a/pgtype/text.go b/pgtype/text.go index 7e4f8b99..2c551958 100644 --- a/pgtype/text.go +++ b/pgtype/text.go @@ -90,7 +90,7 @@ func (TextCodec) PreferredFormat() int16 { return TextFormatCode } -func (TextCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (TextCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case TextFormatCode, BinaryFormatCode: switch value.(type) { @@ -156,7 +156,7 @@ func (encodePlanTextCodecTextValuer) Encode(value interface{}, buf []byte) (newB return buf, nil } -func (TextCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (TextCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case TextFormatCode, BinaryFormatCode: @@ -175,11 +175,11 @@ func (TextCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interfa return nil } -func (c TextCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return c.DecodeValue(ci, oid, format, src) +func (c TextCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) } -func (c TextCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c TextCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } diff --git a/pgtype/tid.go b/pgtype/tid.go index cc38f404..2744cb15 100644 --- a/pgtype/tid.go +++ b/pgtype/tid.go @@ -82,7 +82,7 @@ func (TIDCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (TIDCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (TIDCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(TIDValuer); !ok { return nil } @@ -130,7 +130,7 @@ func (encodePlanTIDCodecText) Encode(value interface{}, buf []byte) (newBuf []by return buf, nil } -func (TIDCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (TIDCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -223,17 +223,17 @@ func (scanPlanTextAnyToTIDScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanTID(TID{BlockNumber: uint32(blockNumber), OffsetNumber: uint16(offsetNumber), Valid: true}) } -func (c TIDCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c TIDCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c TIDCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c TIDCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var tid TID - err := codecScan(c, ci, oid, format, src, &tid) + err := codecScan(c, m, oid, format, src, &tid) if err != nil { return nil, err } diff --git a/pgtype/time.go b/pgtype/time.go index 734687cb..71e7f597 100644 --- a/pgtype/time.go +++ b/pgtype/time.go @@ -74,7 +74,7 @@ func (TimeCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (TimeCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (TimeCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(TimeValuer); !ok { return nil } @@ -129,7 +129,7 @@ func (encodePlanTimeCodecText) Encode(value interface{}, buf []byte) (newBuf []b return append(buf, s...), nil } -func (TimeCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (TimeCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -215,17 +215,17 @@ func (scanPlanTextAnyToTimeScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanTime(Time{Microseconds: usec, Valid: true}) } -func (c TimeCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { - return codecDecodeToTextFormat(c, ci, oid, format, src) +func (c TimeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) } -func (c TimeCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c TimeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var t Time - err := codecScan(c, ci, oid, format, src, &t) + err := codecScan(c, m, oid, format, src, &t) if err != nil { return nil, err } diff --git a/pgtype/timestamp.go b/pgtype/timestamp.go index 24ee76b0..9cfa7702 100644 --- a/pgtype/timestamp.go +++ b/pgtype/timestamp.go @@ -75,7 +75,7 @@ func (TimestampCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (TimestampCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (TimestampCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(TimestampValuer); !ok { return nil } @@ -152,7 +152,7 @@ func discardTimeZone(t time.Time) time.Time { return t } -func (TimestampCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (TimestampCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -230,13 +230,13 @@ func (scanPlanTextTimestampToTimestampScanner) Scan(src []byte, dst interface{}) return scanner.ScanTimestamp(ts) } -func (c TimestampCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c TimestampCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var ts Timestamp - err := codecScan(c, ci, oid, format, src, &ts) + err := codecScan(c, m, oid, format, src, &ts) if err != nil { return nil, err } @@ -248,13 +248,13 @@ func (c TimestampCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format return ts.Time, nil } -func (c TimestampCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c TimestampCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var ts Timestamp - err := codecScan(c, ci, oid, format, src, &ts) + err := codecScan(c, m, oid, format, src, &ts) if err != nil { return nil, err } diff --git a/pgtype/timestamptz.go b/pgtype/timestamptz.go index ea2ebfbe..0bdd0fd6 100644 --- a/pgtype/timestamptz.go +++ b/pgtype/timestamptz.go @@ -133,7 +133,7 @@ func (TimestamptzCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (TimestamptzCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (TimestamptzCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(TimestamptzValuer); !ok { return nil } @@ -200,7 +200,7 @@ func (encodePlanTimestamptzCodecText) Encode(value interface{}, buf []byte) (new return buf, nil } -func (TimestamptzCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (TimestamptzCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -287,13 +287,13 @@ func (scanPlanTextTimestamptzToTimestamptzScanner) Scan(src []byte, dst interfac return scanner.ScanTimestamptz(tstz) } -func (c TimestamptzCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c TimestamptzCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var tstz Timestamptz - err := codecScan(c, ci, oid, format, src, &tstz) + err := codecScan(c, m, oid, format, src, &tstz) if err != nil { return nil, err } @@ -305,13 +305,13 @@ func (c TimestamptzCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, forma return tstz.Time, nil } -func (c TimestamptzCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c TimestamptzCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var tstz Timestamptz - err := codecScan(c, ci, oid, format, src, &tstz) + err := codecScan(c, m, oid, format, src, &tstz) if err != nil { return nil, err } diff --git a/pgtype/uint32.go b/pgtype/uint32.go index 7d481a27..44238fa0 100644 --- a/pgtype/uint32.go +++ b/pgtype/uint32.go @@ -85,7 +85,7 @@ func (Uint32Codec) PreferredFormat() int16 { return BinaryFormatCode } -func (Uint32Codec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (Uint32Codec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { switch format { case BinaryFormatCode: switch value.(type) { @@ -196,7 +196,7 @@ func (encodePlanUint32CodecTextInt64Valuer) Encode(value interface{}, buf []byte return append(buf, strconv.FormatInt(v.Int, 10)...), nil } -func (Uint32Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (Uint32Codec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: @@ -218,26 +218,26 @@ func (Uint32Codec) PlanScan(ci *ConnInfo, oid uint32, format int16, target inter return nil } -func (c Uint32Codec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c Uint32Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var n uint32 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } return int64(n), nil } -func (c Uint32Codec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c Uint32Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var n uint32 - err := codecScan(c, ci, oid, format, src, &n) + err := codecScan(c, m, oid, format, src, &n) if err != nil { return nil, err } diff --git a/pgtype/uuid.go b/pgtype/uuid.go index 2655a124..39df8537 100644 --- a/pgtype/uuid.go +++ b/pgtype/uuid.go @@ -122,7 +122,7 @@ func (UUIDCodec) PreferredFormat() int16 { return BinaryFormatCode } -func (UUIDCodec) PlanEncode(ci *ConnInfo, oid uint32, format int16, value interface{}) EncodePlan { +func (UUIDCodec) PlanEncode(m *Map, oid uint32, format int16, value interface{}) EncodePlan { if _, ok := value.(UUIDValuer); !ok { return nil } @@ -167,7 +167,7 @@ func (encodePlanUUIDCodecTextUUIDValuer) Encode(value interface{}, buf []byte) ( return append(buf, encodeUUID(uuid.Bytes)...), nil } -func (UUIDCodec) PlanScan(ci *ConnInfo, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { +func (UUIDCodec) PlanScan(m *Map, oid uint32, format int16, target interface{}, actualTarget bool) ScanPlan { switch format { case BinaryFormatCode: switch target.(type) { @@ -220,13 +220,13 @@ func (scanPlanTextAnyToUUIDScanner) Scan(src []byte, dst interface{}) error { return scanner.ScanUUID(UUID{Bytes: buf, Valid: true}) } -func (c UUIDCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16, src []byte) (driver.Value, error) { +func (c UUIDCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { if src == nil { return nil, nil } var uuid UUID - err := codecScan(c, ci, oid, format, src, &uuid) + err := codecScan(c, m, oid, format, src, &uuid) if err != nil { return nil, err } @@ -234,13 +234,13 @@ func (c UUIDCodec) DecodeDatabaseSQLValue(ci *ConnInfo, oid uint32, format int16 return encodeUUID(uuid.Bytes), nil } -func (c UUIDCodec) DecodeValue(ci *ConnInfo, oid uint32, format int16, src []byte) (interface{}, error) { +func (c UUIDCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (interface{}, error) { if src == nil { return nil, nil } var uuid UUID - err := codecScan(c, ci, oid, format, src, &uuid) + err := codecScan(c, m, oid, format, src, &uuid) if err != nil { return nil, err } diff --git a/query_test.go b/query_test.go index 2f8975ac..3728f8a3 100644 --- a/query_test.go +++ b/query_test.go @@ -1358,7 +1358,7 @@ func TestScanRow(t *testing.T) { for resultReader.NextRow() { var n int32 - err := pgx.ScanRow(conn.ConnInfo(), resultReader.FieldDescriptions(), resultReader.Values(), &n) + err := pgx.ScanRow(conn.TypeMap(), resultReader.FieldDescriptions(), resultReader.Values(), &n) assert.NoError(t, err) sum += n rowCount++ diff --git a/rows.go b/rows.go index 25a42466..805be100 100644 --- a/rows.go +++ b/rows.go @@ -100,7 +100,7 @@ type rowLog interface { type connRows struct { ctx context.Context logger rowLog - connInfo *pgtype.ConnInfo + typeMap *pgtype.Map values [][]byte rowCount int err error @@ -196,7 +196,7 @@ func (rows *connRows) Next() bool { } func (rows *connRows) Scan(dest ...interface{}) error { - ci := rows.connInfo + m := rows.typeMap fieldDescriptions := rows.FieldDescriptions() values := rows.values @@ -215,7 +215,7 @@ func (rows *connRows) Scan(dest ...interface{}) error { rows.scanPlans = make([]pgtype.ScanPlan, len(values)) rows.scanTypes = make([]reflect.Type, len(values)) for i := range dest { - rows.scanPlans[i] = ci.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i]) + rows.scanPlans[i] = m.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i]) rows.scanTypes[i] = reflect.TypeOf(dest[i]) } } @@ -226,7 +226,7 @@ func (rows *connRows) Scan(dest ...interface{}) error { } if rows.scanTypes[i] != reflect.TypeOf(dst) { - rows.scanPlans[i] = ci.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i]) + rows.scanPlans[i] = m.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i]) rows.scanTypes[i] = reflect.TypeOf(dest[i]) } @@ -257,8 +257,8 @@ func (rows *connRows) Values() ([]interface{}, error) { continue } - if dt, ok := rows.connInfo.TypeForOID(fd.DataTypeOID); ok { - value, err := dt.Codec.DecodeValue(rows.connInfo, fd.DataTypeOID, fd.Format, buf) + if dt, ok := rows.typeMap.TypeForOID(fd.DataTypeOID); ok { + value, err := dt.Codec.DecodeValue(rows.typeMap, fd.DataTypeOID, fd.Format, buf) if err != nil { rows.fatal(err) } @@ -303,11 +303,11 @@ func (e ScanArgError) Unwrap() error { // ScanRow decodes raw row data into dest. It can be used to scan rows read from the lower level pgconn interface. // -// connInfo - OID to Go type mapping. +// typeMap - OID to Go type mapping. // fieldDescriptions - OID and format of values // values - the raw data as returned from the PostgreSQL server // dest - the destination that values will be decoded into -func ScanRow(connInfo *pgtype.ConnInfo, fieldDescriptions []pgproto3.FieldDescription, values [][]byte, dest ...interface{}) error { +func ScanRow(typeMap *pgtype.Map, fieldDescriptions []pgproto3.FieldDescription, values [][]byte, dest ...interface{}) error { if len(fieldDescriptions) != len(values) { return fmt.Errorf("number of field descriptions must equal number of values, got %d and %d", len(fieldDescriptions), len(values)) } @@ -320,7 +320,7 @@ func ScanRow(connInfo *pgtype.ConnInfo, fieldDescriptions []pgproto3.FieldDescri continue } - err := connInfo.Scan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, values[i], d) + err := typeMap.Scan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, values[i], d) if err != nil { return ScanArgError{ColumnIndex: i, Err: err} } diff --git a/stdlib/sql.go b/stdlib/sql.go index b9079fc8..7624605c 100644 --- a/stdlib/sql.go +++ b/stdlib/sql.go @@ -519,7 +519,7 @@ func (r *Rows) Columns() []string { // ColumnTypeDatabaseTypeName returns the database system type name. If the name is unknown the OID is returned. func (r *Rows) ColumnTypeDatabaseTypeName(index int) string { - if dt, ok := r.conn.conn.ConnInfo().TypeForOID(r.rows.FieldDescriptions()[index].DataTypeOID); ok { + if dt, ok := r.conn.conn.TypeMap().TypeForOID(r.rows.FieldDescriptions()[index].DataTypeOID); ok { return strings.ToUpper(dt.Name) } @@ -594,7 +594,7 @@ func (r *Rows) Close() error { } func (r *Rows) Next(dest []driver.Value) error { - ci := r.conn.conn.ConnInfo() + m := r.conn.conn.TypeMap() fieldDescriptions := r.rows.FieldDescriptions() if r.valueFuncs == nil { @@ -607,21 +607,21 @@ func (r *Rows) Next(dest []driver.Value) error { switch fd.DataTypeOID { case pgtype.BoolOID: var d bool - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return d, err } case pgtype.ByteaOID: var d []byte - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return d, err } case pgtype.CIDOID, pgtype.OIDOID, pgtype.XIDOID: var d pgtype.Uint32 - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) if err != nil { @@ -631,7 +631,7 @@ func (r *Rows) Next(dest []driver.Value) error { } case pgtype.DateOID: var d pgtype.Date - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) if err != nil { @@ -641,42 +641,42 @@ func (r *Rows) Next(dest []driver.Value) error { } case pgtype.Float4OID: var d float32 - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return float64(d), err } case pgtype.Float8OID: var d float64 - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return d, err } case pgtype.Int2OID: var d int16 - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return int64(d), err } case pgtype.Int4OID: var d int32 - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return int64(d), err } case pgtype.Int8OID: var d int64 - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return d, err } case pgtype.JSONOID, pgtype.JSONBOID: var d []byte - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) if err != nil { @@ -686,7 +686,7 @@ func (r *Rows) Next(dest []driver.Value) error { } case pgtype.TimestampOID: var d pgtype.Timestamp - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) if err != nil { @@ -696,7 +696,7 @@ func (r *Rows) Next(dest []driver.Value) error { } case pgtype.TimestamptzOID: var d pgtype.Timestamptz - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) if err != nil { @@ -706,7 +706,7 @@ func (r *Rows) Next(dest []driver.Value) error { } default: var d string - scanPlan := ci.PlanScan(dataTypeOID, format, &d) + scanPlan := m.PlanScan(dataTypeOID, format, &d) r.valueFuncs[i] = func(src []byte) (driver.Value, error) { err := scanPlan.Scan(src, &d) return d, err diff --git a/values.go b/values.go index 7661a94e..075ac2ff 100644 --- a/values.go +++ b/values.go @@ -24,7 +24,7 @@ func (e SerializationError) Error() string { return string(e) } -func convertSimpleArgument(ci *pgtype.ConnInfo, arg interface{}) (interface{}, error) { +func convertSimpleArgument(m *pgtype.Map, arg interface{}) (interface{}, error) { if arg == nil { return nil, nil } @@ -79,8 +79,8 @@ func convertSimpleArgument(ci *pgtype.ConnInfo, arg interface{}) (interface{}, e return int64(arg), nil } - if _, found := ci.TypeForValue(arg); found { - buf, err := ci.Encode(0, TextFormatCode, arg, nil) + if _, found := m.TypeForValue(arg); found { + buf, err := m.Encode(0, TextFormatCode, arg, nil) if err != nil { return nil, err } @@ -92,16 +92,16 @@ func convertSimpleArgument(ci *pgtype.ConnInfo, arg interface{}) (interface{}, e if refVal.Kind() == reflect.Ptr { arg = refVal.Elem().Interface() - return convertSimpleArgument(ci, arg) + return convertSimpleArgument(m, arg) } if strippedArg, ok := stripNamedType(&refVal); ok { - return convertSimpleArgument(ci, strippedArg) + return convertSimpleArgument(m, strippedArg) } return nil, SerializationError(fmt.Sprintf("Cannot encode %T in simple protocol - %T must implement driver.Valuer, pgtype.TextEncoder, or be a native type", arg, arg)) } -func encodePreparedStatementArgument(ci *pgtype.ConnInfo, buf []byte, oid uint32, arg interface{}) ([]byte, error) { +func encodePreparedStatementArgument(m *pgtype.Map, buf []byte, oid uint32, arg interface{}) ([]byte, error) { if arg == nil { return pgio.AppendInt32(buf, -1), nil } @@ -120,13 +120,13 @@ func encodePreparedStatementArgument(ci *pgtype.ConnInfo, buf []byte, oid uint32 return pgio.AppendInt32(buf, -1), nil } arg = refVal.Elem().Interface() - return encodePreparedStatementArgument(ci, buf, oid, arg) + return encodePreparedStatementArgument(m, buf, oid, arg) } - if _, ok := ci.TypeForOID(oid); ok { + if _, ok := m.TypeForOID(oid); ok { sp := len(buf) buf = pgio.AppendInt32(buf, -1) - argBuf, err := ci.Encode(oid, BinaryFormatCode, arg, buf) + argBuf, err := m.Encode(oid, BinaryFormatCode, arg, buf) if err != nil { return nil, err } @@ -138,7 +138,7 @@ func encodePreparedStatementArgument(ci *pgtype.ConnInfo, buf []byte, oid uint32 } if strippedArg, ok := stripNamedType(&refVal); ok { - return encodePreparedStatementArgument(ci, buf, oid, strippedArg) + return encodePreparedStatementArgument(m, buf, oid, strippedArg) } return nil, SerializationError(fmt.Sprintf("Cannot encode %T into oid %v - %T must implement Encoder or be converted to a string", arg, oid, arg)) } @@ -146,13 +146,13 @@ func encodePreparedStatementArgument(ci *pgtype.ConnInfo, buf []byte, oid uint32 // chooseParameterFormatCode determines the correct format code for an // argument to a prepared statement. It defaults to TextFormatCode if no // determination can be made. -func chooseParameterFormatCode(ci *pgtype.ConnInfo, oid uint32, arg interface{}) int16 { +func chooseParameterFormatCode(m *pgtype.Map, oid uint32, arg interface{}) int16 { switch arg.(type) { case string, *string: return TextFormatCode } - return ci.FormatCodeForOID(oid) + return m.FormatCodeForOID(oid) } func stripNamedType(val *reflect.Value) (interface{}, bool) { diff --git a/values_test.go b/values_test.go index 05139d29..81138bfa 100644 --- a/values_test.go +++ b/values_test.go @@ -79,7 +79,7 @@ func TestJSONAndJSONBTranscode(t *testing.T) { testWithAndWithoutPreferSimpleProtocol(t, func(t *testing.T, conn *pgx.Conn) { for _, typename := range []string{"json", "jsonb"} { - if _, ok := conn.ConnInfo().TypeForName(typename); !ok { + if _, ok := conn.TypeMap().TypeForName(typename); !ok { continue // No JSON/JSONB type -- must be running against old PostgreSQL } @@ -96,7 +96,7 @@ func TestJSONAndJSONBTranscodeExtendedOnly(t *testing.T) { defer closeConn(t, conn) for _, typename := range []string{"json", "jsonb"} { - if _, ok := conn.ConnInfo().TypeForName(typename); !ok { + if _, ok := conn.TypeMap().TypeForName(typename); !ok { continue // No JSON/JSONB type -- must be running against old PostgreSQL } testJSONSingleLevelStringMap(t, conn, typename)