diff --git a/bench_test.go b/bench_test.go index 5a999ee8..40520d57 100644 --- a/bench_test.go +++ b/bench_test.go @@ -48,16 +48,16 @@ func createNarrowTestData(b *testing.B, conn *Connection) { func removeBinaryEncoders() (encoders map[Oid]func(*MessageReader, int32) interface{}) { encoders = make(map[Oid]func(*MessageReader, int32) interface{}) - for k, v := range valueTranscoders { + for k, v := range ValueTranscoders { encoders[k] = v.DecodeBinary - valueTranscoders[k].DecodeBinary = nil + ValueTranscoders[k].DecodeBinary = nil } return } func restoreBinaryEncoders(encoders map[Oid]func(*MessageReader, int32) interface{}) { for k, v := range encoders { - valueTranscoders[k].DecodeBinary = v + ValueTranscoders[k].DecodeBinary = v } } diff --git a/connection.go b/connection.go index cbebd2fb..8a6020a6 100644 --- a/connection.go +++ b/connection.go @@ -310,7 +310,7 @@ func (c *Connection) Prepare(name, sql string) (err error) { ps.FieldDescriptions = c.rxRowDescription(r) for i := range ps.FieldDescriptions { oid := ps.FieldDescriptions[i].DataType - if valueTranscoders[oid] != nil && valueTranscoders[oid].DecodeBinary != nil { + if ValueTranscoders[oid] != nil && ValueTranscoders[oid].DecodeBinary != nil { ps.FieldDescriptions[i].FormatCode = 1 } } @@ -375,7 +375,7 @@ func (c *Connection) sendPreparedQuery(ps *preparedStatement, arguments ...inter w.writeCString(ps.Name) w.write(int16(len(ps.ParameterOids))) for _, oid := range ps.ParameterOids { - transcoder := valueTranscoders[oid] + transcoder := ValueTranscoders[oid] if transcoder == nil { transcoder = defaultTranscoder } @@ -384,7 +384,7 @@ func (c *Connection) sendPreparedQuery(ps *preparedStatement, arguments ...inter w.write(int16(len(arguments))) for i, oid := range ps.ParameterOids { - transcoder := valueTranscoders[oid] + transcoder := ValueTranscoders[oid] if transcoder == nil { transcoder = defaultTranscoder } @@ -393,7 +393,7 @@ func (c *Connection) sendPreparedQuery(ps *preparedStatement, arguments ...inter w.write(int16(len(ps.FieldDescriptions))) for _, fd := range ps.FieldDescriptions { - transcoder := valueTranscoders[fd.DataType] + transcoder := ValueTranscoders[fd.DataType] if transcoder != nil && transcoder.DecodeBinary != nil { w.write(int16(1)) } else { diff --git a/data_row_reader.go b/data_row_reader.go index 6684177d..dd557361 100644 --- a/data_row_reader.go +++ b/data_row_reader.go @@ -27,7 +27,7 @@ func (r *DataRowReader) ReadValue() interface{} { size := r.mr.ReadInt32() if size > -1 { - if vt, present := valueTranscoders[fieldDescription.DataType]; present { + if vt, present := ValueTranscoders[fieldDescription.DataType]; present { switch fieldDescription.FormatCode { case 0: return vt.DecodeText(r.mr, size) diff --git a/value_transcoder.go b/value_transcoder.go index 27725d96..9614ea58 100644 --- a/value_transcoder.go +++ b/value_transcoder.go @@ -7,77 +7,89 @@ import ( "unsafe" ) -type valueTranscoder struct { - DecodeText func(*MessageReader, int32) interface{} +// ValueTranscoder stores all the data necessary to encode and decode values from +// a PostgreSQL server +type ValueTranscoder struct { + // DecodeText decodes values returned from the server in text format + DecodeText func(*MessageReader, int32) interface{} + // DecodeBinary decodes values returned from the server in binary format DecodeBinary func(*MessageReader, int32) interface{} - EncodeTo func(*messageWriter, interface{}) + // EncodeTo encodes values to send to the server + EncodeTo func(*messageWriter, interface{}) + // EncodeFormat is the format values are encoded for transmission. + // 0 = text + // 1 = binary EncodeFormat int16 } -var valueTranscoders map[Oid]*valueTranscoder -var defaultTranscoder *valueTranscoder +// ValueTranscoders is used to transcode values being sent to and received from +// the PostgreSQL server. Additional types can be transcoded by adding a +// *ValueTranscoder for the appropriate Oid to the map. +var ValueTranscoders map[Oid]*ValueTranscoder + +var defaultTranscoder *ValueTranscoder func init() { - valueTranscoders = make(map[Oid]*valueTranscoder) + ValueTranscoders = make(map[Oid]*ValueTranscoder) // bool - valueTranscoders[Oid(16)] = &valueTranscoder{ + ValueTranscoders[Oid(16)] = &ValueTranscoder{ DecodeText: decodeBoolFromText, DecodeBinary: decodeBoolFromBinary, EncodeTo: encodeBool, EncodeFormat: 1} // bytea - valueTranscoders[Oid(17)] = &valueTranscoder{ + ValueTranscoders[Oid(17)] = &ValueTranscoder{ DecodeText: decodeByteaFromText, EncodeTo: encodeBytea, EncodeFormat: 1} // int8 - valueTranscoders[Oid(20)] = &valueTranscoder{ + ValueTranscoders[Oid(20)] = &ValueTranscoder{ DecodeText: decodeInt8FromText, DecodeBinary: decodeInt8FromBinary, EncodeTo: encodeInt8, EncodeFormat: 1} // int2 - valueTranscoders[Oid(21)] = &valueTranscoder{ + ValueTranscoders[Oid(21)] = &ValueTranscoder{ DecodeText: decodeInt2FromText, DecodeBinary: decodeInt2FromBinary, EncodeTo: encodeInt2, EncodeFormat: 1} // int4 - valueTranscoders[Oid(23)] = &valueTranscoder{ + ValueTranscoders[Oid(23)] = &ValueTranscoder{ DecodeText: decodeInt4FromText, DecodeBinary: decodeInt4FromBinary, EncodeTo: encodeInt4, EncodeFormat: 1} // text - valueTranscoders[Oid(25)] = &valueTranscoder{ + ValueTranscoders[Oid(25)] = &ValueTranscoder{ DecodeText: decodeTextFromText, EncodeTo: encodeText} // float4 - valueTranscoders[Oid(700)] = &valueTranscoder{ + ValueTranscoders[Oid(700)] = &ValueTranscoder{ DecodeText: decodeFloat4FromText, DecodeBinary: decodeFloat4FromBinary, EncodeTo: encodeFloat4, EncodeFormat: 1} // float8 - valueTranscoders[Oid(701)] = &valueTranscoder{ + ValueTranscoders[Oid(701)] = &ValueTranscoder{ DecodeText: decodeFloat8FromText, DecodeBinary: decodeFloat8FromBinary, EncodeTo: encodeFloat8, EncodeFormat: 1} // varchar -- same as text - valueTranscoders[Oid(1043)] = valueTranscoders[Oid(25)] + ValueTranscoders[Oid(1043)] = ValueTranscoders[Oid(25)] // use text transcoder for anything we don't understand - defaultTranscoder = valueTranscoders[Oid(25)] + defaultTranscoder = ValueTranscoders[Oid(25)] } func decodeBoolFromText(mr *MessageReader, size int32) interface{} {