2
0

CompositeType implements TypeValue

This commit is contained in:
Jack Christensen
2020-05-12 10:40:13 -05:00
parent e5992d0aed
commit 9cdd928cb8
4 changed files with 38 additions and 19 deletions
+2 -2
View File
@@ -100,7 +100,7 @@ func BenchmarkBinaryEncodingComposite(b *testing.B) {
ci := pgtype.NewConnInfo() ci := pgtype.NewConnInfo()
f1 := 2 f1 := 2
f2 := ptrS("bar") f2 := ptrS("bar")
c := pgtype.NewCompositeType(&pgtype.Int4{}, &pgtype.Text{}) c := pgtype.NewCompositeType("test", &pgtype.Int4{}, &pgtype.Text{})
b.ResetTimer() b.ResetTimer()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
@@ -163,7 +163,7 @@ func BenchmarkBinaryDecodingCompositeScan(b *testing.B) {
var f1 int var f1 int
var f2 *string var f2 *string
c := pgtype.NewCompositeType(&pgtype.Int4{}, &pgtype.Text{}) c := pgtype.NewCompositeType("test", &pgtype.Int4{}, &pgtype.Text{})
b.ResetTimer() b.ResetTimer()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
+22 -3
View File
@@ -8,8 +8,10 @@ import (
) )
type CompositeType struct { type CompositeType struct {
fields []Value
status Status status Status
typeName string
fields []Value
} }
// NewCompositeType creates a Composite object, which acts as a "schema" for // NewCompositeType creates a Composite object, which acts as a "schema" for
@@ -19,8 +21,8 @@ type CompositeType struct {
// SetFields method // SetFields method
// To read composite fields back pass result of Scan() method // To read composite fields back pass result of Scan() method
// to query Scan function. // to query Scan function.
func NewCompositeType(fields ...Value) *CompositeType { func NewCompositeType(typeName string, fields ...Value) *CompositeType {
return &CompositeType{fields, Undefined} return &CompositeType{typeName: typeName, fields: fields}
} }
func (src CompositeType) Get() interface{} { func (src CompositeType) Get() interface{} {
@@ -38,6 +40,23 @@ func (src CompositeType) Get() interface{} {
} }
} }
func (ct *CompositeType) NewTypeValue() Value {
a := &CompositeType{
typeName: ct.typeName,
fields: make([]Value, len(ct.fields)),
}
for i := range ct.fields {
a.fields[i] = NewValue(ct.fields[i])
}
return a
}
func (ct *CompositeType) TypeName() string {
return ct.typeName
}
func (dst *CompositeType) Set(src interface{}) error { func (dst *CompositeType) Set(src interface{}) error {
if src == nil { if src == nil {
dst.status = Null dst.status = Null
+3 -3
View File
@@ -12,7 +12,7 @@ import (
) )
func TestCompositeTypeSetAndGet(t *testing.T) { func TestCompositeTypeSetAndGet(t *testing.T) {
ct := pgtype.NewCompositeType(&pgtype.Text{}, &pgtype.Int4{}) ct := pgtype.NewCompositeType("test", &pgtype.Text{}, &pgtype.Int4{})
assert.Equal(t, pgtype.Undefined, ct.Get()) assert.Equal(t, pgtype.Undefined, ct.Get())
nilTests := []struct { nilTests := []struct {
@@ -54,7 +54,7 @@ func TestCompositeTypeSetAndGet(t *testing.T) {
} }
func TestCompositeTypeAssignTo(t *testing.T) { func TestCompositeTypeAssignTo(t *testing.T) {
ct := pgtype.NewCompositeType(&pgtype.Text{}, &pgtype.Int4{}) ct := pgtype.NewCompositeType("test", &pgtype.Text{}, &pgtype.Int4{})
{ {
err := ct.Set([]interface{}{"foo", int32(42)}) err := ct.Set([]interface{}{"foo", int32(42)})
@@ -161,7 +161,7 @@ func Example_composite() {
return return
} }
c := pgtype.NewCompositeType(&pgtype.Int4{}, &pgtype.Text{}) c := pgtype.NewCompositeType("mytype", &pgtype.Int4{}, &pgtype.Text{})
conn.ConnInfo().RegisterDataType(pgtype.DataType{Value: c, Name: "mytype", OID: oid}) conn.ConnInfo().RegisterDataType(pgtype.DataType{Value: c, Name: "mytype", OID: oid})
var a int var a int
+11 -11
View File
@@ -360,9 +360,7 @@ func (ci *ConnInfo) InitializeDataTypes(nameOIDs map[string]uint32) {
} }
func (ci *ConnInfo) RegisterDataType(t DataType) { func (ci *ConnInfo) RegisterDataType(t DataType) {
if tv, ok := t.Value.(TypeValue); ok { t.Value = NewValue(t.Value)
t.Value = tv.NewTypeValue()
}
ci.oidToDataType[t.OID] = &t ci.oidToDataType[t.OID] = &t
ci.nameToDataType[t.Name] = &t ci.nameToDataType[t.Name] = &t
@@ -469,15 +467,8 @@ func (ci *ConnInfo) DeepCopy() *ConnInfo {
ci2 := newConnInfo() ci2 := newConnInfo()
for _, dt := range ci.oidToDataType { for _, dt := range ci.oidToDataType {
var value Value
if tv, ok := dt.Value.(TypeValue); ok {
value = tv.NewTypeValue()
} else {
value = reflect.New(reflect.ValueOf(dt.Value).Elem().Type()).Interface().(Value)
}
ci2.RegisterDataType(DataType{ ci2.RegisterDataType(DataType{
Value: value, Value: NewValue(dt.Value),
Name: dt.Name, Name: dt.Name,
OID: dt.OID, OID: dt.OID,
}) })
@@ -844,6 +835,15 @@ func scanUnknownType(oid uint32, formatCode int16, buf []byte, dest interface{})
} }
} }
// NewValue returns a new instance of the same type as v.
func NewValue(v Value) Value {
if tv, ok := v.(TypeValue); ok {
return tv.NewTypeValue()
} else {
return reflect.New(reflect.ValueOf(v).Elem().Type()).Interface().(Value)
}
}
var nameValues map[string]Value var nameValues map[string]Value
func init() { func init() {