From 6aee9ae336c3d91f526fbe168cd89b84d46dcb28 Mon Sep 17 00:00:00 2001 From: Oleg Jukovec Date: Thu, 19 May 2022 11:22:34 +0300 Subject: [PATCH] migration: Use msgpack.v5 by default An user can continue to use msgpack.v2 with tag: go_tarantool_msgpack_v2 There are two problems that cannot be unified: - Different signature and logic of RegisterExt in msgpack.v2[1] and msgpack.v5[2]. - Different logic of map decoding, see[3][4]. These issues have been fixed in msgpack.v5 implementation, see msgpack.go and uuid/msgpack.go. Files naming changed: msgpack.go - msgpack.v5 usage for the code msgpack_helper_test.go - msgpack.v5 usage for tests msgpack_v2.go - msgpack.v2 usage for the code msgpack_v2_helper_test.go - msgpack.v2 usage for tests 1. https://pkg.go.dev/github.com/vmihailenco/msgpack@v2.9.2+incompatible#RegisterExt 2. https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#RegisterExt 3. https://github.com/vmihailenco/msgpack/issues/327/ 4. https://msgpack.uptrace.dev/guide/#decoding-maps-into-an-interface/ --- go.mod | 1 + go.sum | 5 ++ msgpack.go | 36 +++++++----- msgpack_helper_test.go | 13 ++-- msgpack_v2.go | 101 ++++++++++++++++++++++++++++++++ msgpack_v2_helper_test.go | 25 ++++++++ queue/msgpack.go | 5 +- queue/msgpack_helper_test.go | 5 +- queue/msgpack_v2.go | 17 ++++++ queue/msgpack_v2_helper_test.go | 25 ++++++++ uuid/msgpack.go | 15 ++++- uuid/msgpack_helper_test.go | 5 +- uuid/msgpack_v2.go | 25 ++++++++ uuid/msgpack_v2_helper_test.go | 13 ++++ 14 files changed, 266 insertions(+), 25 deletions(-) create mode 100644 msgpack_v2.go create mode 100644 msgpack_v2_helper_test.go create mode 100644 queue/msgpack_v2.go create mode 100644 queue/msgpack_v2_helper_test.go create mode 100644 uuid/msgpack_v2.go create mode 100644 uuid/msgpack_v2_helper_test.go diff --git a/go.mod b/go.mod index 152329b1f..9ee73b548 100644 --- a/go.mod +++ b/go.mod @@ -9,4 +9,5 @@ require ( google.golang.org/appengine v1.6.7 // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/vmihailenco/msgpack.v2 v2.9.2 + github.com/vmihailenco/msgpack/v5 v5.3.5 ) diff --git a/go.sum b/go.sum index 1f9e791b4..1f81425f3 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,13 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= diff --git a/msgpack.go b/msgpack.go index d00c382cb..35821959f 100644 --- a/msgpack.go +++ b/msgpack.go @@ -1,10 +1,13 @@ +//go:build !go_tarantool_msgpack_v2 +// +build !go_tarantool_msgpack_v2 + package tarantool import ( "io" - "gopkg.in/vmihailenco/msgpack.v2" - msgpcode "gopkg.in/vmihailenco/msgpack.v2/codes" + "github.com/vmihailenco/msgpack/v5" + "github.com/vmihailenco/msgpack/v5/msgpcode" ) type Encoder struct { @@ -22,15 +25,18 @@ func newEncoder(w io.Writer) *Encoder { func newDecoder(r io.Reader) *Decoder { dec := msgpack.NewDecoder(r) + dec.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { + return dec.DecodeUntypedMap() + }) return &Decoder{Decoder: dec} } func (e *Encoder) encodeUintImpl(v uint64) error { - return e.EncodeUint(uint(v)) + return e.EncodeUint(v) } func (e *Encoder) encodeIntImpl(v int64) error { - return e.EncodeInt(int(v)) + return e.EncodeInt(v) } func msgpackIsUint(code byte) bool { @@ -54,45 +60,45 @@ func msgpackIsString(code byte) bool { } func (s *single) DecodeMsgpack(d *msgpack.Decoder) error { - return s.decodeMsgpackImpl(&Decoder{d}) + return s.decodeMsgpackImpl(&Decoder{Decoder: d}) } func (space *Space) DecodeMsgpack(d *msgpack.Decoder) error { - return space.decodeMsgpackImpl(&Decoder{d}) + return space.decodeMsgpackImpl(&Decoder{Decoder: d}) } func (field *Field) DecodeMsgpack(d *msgpack.Decoder) error { - return field.decodeMsgpackImpl(&Decoder{d}) + return field.decodeMsgpackImpl(&Decoder{Decoder: d}) } func (index *Index) DecodeMsgpack(d *msgpack.Decoder) error { - return index.decodeMsgpackImpl(&Decoder{d}) + return index.decodeMsgpackImpl(&Decoder{Decoder: d}) } func (indexField *IndexField) DecodeMsgpack(d *msgpack.Decoder) error { - return indexField.decodeMsgpackImpl(&Decoder{d}) + return indexField.decodeMsgpackImpl(&Decoder{Decoder: d}) } func (k IntKey) EncodeMsgpack(enc *msgpack.Encoder) error { - return k.encodeMsgpackImpl(&Encoder{enc}) + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) } func (k UintKey) EncodeMsgpack(enc *msgpack.Encoder) error { - return k.encodeMsgpackImpl(&Encoder{enc}) + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) } func (k StringKey) EncodeMsgpack(enc *msgpack.Encoder) error { - return k.encodeMsgpackImpl(&Encoder{enc}) + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) } func (k IntIntKey) EncodeMsgpack(enc *msgpack.Encoder) error { - return k.encodeMsgpackImpl(&Encoder{enc}) + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) } func (o Op) EncodeMsgpack(enc *msgpack.Encoder) error { - return o.encodeMsgpackImpl(&Encoder{enc}) + return o.encodeMsgpackImpl(&Encoder{Encoder: enc}) } func (o OpSplice) EncodeMsgpack(enc *msgpack.Encoder) error { - return o.encodeMsgpackImpl(&Encoder{enc}) + return o.encodeMsgpackImpl(&Encoder{Encoder: enc}) } diff --git a/msgpack_helper_test.go b/msgpack_helper_test.go index d7f7346f1..d9f607eac 100644 --- a/msgpack_helper_test.go +++ b/msgpack_helper_test.go @@ -1,22 +1,25 @@ +//go:build !go_tarantool_msgpack_v2 +// +build !go_tarantool_msgpack_v2 + package tarantool_test import ( . "github.com/tarantool/go-tarantool" - "gopkg.in/vmihailenco/msgpack.v2" + "github.com/vmihailenco/msgpack/v5" ) func (m *Member) EncodeMsgpack(e *msgpack.Encoder) error { - return m.encodeMsgpackImpl(&Encoder{e}) + return m.encodeMsgpackImpl(&Encoder{Encoder: e}) } func (m *Member) DecodeMsgpack(d *msgpack.Decoder) error { - return m.decodeMsgpackImpl(&Decoder{d}) + return m.decodeMsgpackImpl(&Decoder{Decoder: d}) } func (c *Tuple2) EncodeMsgpack(e *msgpack.Encoder) error { - return c.encodeMsgpackImpl(&Encoder{e}) + return c.encodeMsgpackImpl(&Encoder{Encoder: e}) } func (c *Tuple2) DecodeMsgpack(d *msgpack.Decoder) error { - return c.decodeMsgpackImpl(&Decoder{d}) + return c.decodeMsgpackImpl(&Decoder{Decoder: d}) } diff --git a/msgpack_v2.go b/msgpack_v2.go new file mode 100644 index 000000000..83290446d --- /dev/null +++ b/msgpack_v2.go @@ -0,0 +1,101 @@ +//go:build go_tarantool_msgpack_v2 +// +build go_tarantool_msgpack_v2 + +package tarantool + +import ( + "io" + + "gopkg.in/vmihailenco/msgpack.v2" + msgpcode "gopkg.in/vmihailenco/msgpack.v2/codes" +) + +type Encoder struct { + *msgpack.Encoder +} + +type Decoder struct { + *msgpack.Decoder +} + +func newEncoder(w io.Writer) *Encoder { + enc := msgpack.NewEncoder(w) + return &Encoder{Encoder: enc} +} + +func newDecoder(r io.Reader) *Decoder { + dec := msgpack.NewDecoder(r) + return &Decoder{Decoder: dec} +} + +func (e *Encoder) encodeUintImpl(v uint64) error { + return e.EncodeUint(uint(v)) +} + +func (e *Encoder) encodeIntImpl(v int64) error { + return e.EncodeInt(int(v)) +} + +func msgpackIsUint(code byte) bool { + return code == msgpcode.Uint8 || code == msgpcode.Uint16 || + code == msgpcode.Uint32 || code == msgpcode.Uint64 || + msgpcode.IsFixedNum(code) +} + +func msgpackIsMap(code byte) bool { + return code == msgpcode.Map16 || code == msgpcode.Map32 || msgpcode.IsFixedMap(code) +} + +func msgpackIsArray(code byte) bool { + return code == msgpcode.Array16 || code == msgpcode.Array32 || + msgpcode.IsFixedArray(code) +} + +func msgpackIsString(code byte) bool { + return msgpcode.IsFixedString(code) || code == msgpcode.Str8 || + code == msgpcode.Str16 || code == msgpcode.Str32 +} + +func (s *single) DecodeMsgpack(d *msgpack.Decoder) error { + return s.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (space *Space) DecodeMsgpack(d *msgpack.Decoder) error { + return space.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (field *Field) DecodeMsgpack(d *msgpack.Decoder) error { + return field.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (index *Index) DecodeMsgpack(d *msgpack.Decoder) error { + return index.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (indexField *IndexField) DecodeMsgpack(d *msgpack.Decoder) error { + return indexField.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (k IntKey) EncodeMsgpack(enc *msgpack.Encoder) error { + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) +} + +func (k UintKey) EncodeMsgpack(enc *msgpack.Encoder) error { + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) +} + +func (k StringKey) EncodeMsgpack(enc *msgpack.Encoder) error { + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) +} + +func (k IntIntKey) EncodeMsgpack(enc *msgpack.Encoder) error { + return k.encodeMsgpackImpl(&Encoder{Encoder: enc}) +} + +func (o Op) EncodeMsgpack(enc *msgpack.Encoder) error { + return o.encodeMsgpackImpl(&Encoder{Encoder: enc}) +} + +func (o OpSplice) EncodeMsgpack(enc *msgpack.Encoder) error { + return o.encodeMsgpackImpl(&Encoder{Encoder: enc}) +} diff --git a/msgpack_v2_helper_test.go b/msgpack_v2_helper_test.go new file mode 100644 index 000000000..303c0b937 --- /dev/null +++ b/msgpack_v2_helper_test.go @@ -0,0 +1,25 @@ +//go:build go_tarantool_msgpack_v2 +// +build go_tarantool_msgpack_v2 + +package tarantool_test + +import ( + . "github.com/tarantool/go-tarantool" + "gopkg.in/vmihailenco/msgpack.v2" +) + +func (m *Member) EncodeMsgpack(e *msgpack.Encoder) error { + return m.encodeMsgpackImpl(&Encoder{Encoder: e}) +} + +func (m *Member) DecodeMsgpack(d *msgpack.Decoder) error { + return m.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (c *Tuple2) EncodeMsgpack(e *msgpack.Encoder) error { + return c.encodeMsgpackImpl(&Encoder{Encoder: e}) +} + +func (c *Tuple2) DecodeMsgpack(d *msgpack.Decoder) error { + return c.decodeMsgpackImpl(&Decoder{Decoder: d}) +} diff --git a/queue/msgpack.go b/queue/msgpack.go index a1696c7d5..5505c40a6 100644 --- a/queue/msgpack.go +++ b/queue/msgpack.go @@ -1,8 +1,11 @@ +//go:build !go_tarantool_msgpack_v2 +// +build !go_tarantool_msgpack_v2 + package queue import ( "github.com/tarantool/go-tarantool" - "gopkg.in/vmihailenco/msgpack.v2" + "github.com/vmihailenco/msgpack/v5" ) func (qd *queueData) DecodeMsgpack(d *msgpack.Decoder) error { diff --git a/queue/msgpack_helper_test.go b/queue/msgpack_helper_test.go index 47c3c26f7..33a33987c 100644 --- a/queue/msgpack_helper_test.go +++ b/queue/msgpack_helper_test.go @@ -1,8 +1,11 @@ +//go:build !go_tarantool_msgpack_v2 +// +build !go_tarantool_msgpack_v2 + package queue_test import ( . "github.com/tarantool/go-tarantool" - "gopkg.in/vmihailenco/msgpack.v2" + "github.com/vmihailenco/msgpack/v5" ) func (c *customData) DecodeMsgpack(d *msgpack.Decoder) error { diff --git a/queue/msgpack_v2.go b/queue/msgpack_v2.go new file mode 100644 index 000000000..cc28ace93 --- /dev/null +++ b/queue/msgpack_v2.go @@ -0,0 +1,17 @@ +//go:build go_tarantool_msgpack_v2 +// +build go_tarantool_msgpack_v2 + +package queue + +import ( + "github.com/tarantool/go-tarantool" + "gopkg.in/vmihailenco/msgpack.v2" +) + +func (qd *queueData) DecodeMsgpack(d *msgpack.Decoder) error { + return qd.decodeMsgpackImpl(&tarantool.Decoder{Decoder: d}) +} + +func (t *Task) DecodeMsgpack(d *msgpack.Decoder) error { + return t.decodeMsgpackImpl(&tarantool.Decoder{Decoder: d}) +} diff --git a/queue/msgpack_v2_helper_test.go b/queue/msgpack_v2_helper_test.go new file mode 100644 index 000000000..cc722617b --- /dev/null +++ b/queue/msgpack_v2_helper_test.go @@ -0,0 +1,25 @@ +//go:build go_tarantool_msgpack_v2 +// +build go_tarantool_msgpack_v2 + +package queue_test + +import ( + . "github.com/tarantool/go-tarantool" + "gopkg.in/vmihailenco/msgpack.v2" +) + +func (c *customData) DecodeMsgpack(d *msgpack.Decoder) error { + return c.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (c *customData) EncodeMsgpack(e *msgpack.Encoder) error { + return c.encodeMsgpackImpl(&Encoder{Encoder: e}) +} + +func (c *dummyData) DecodeMsgpack(d *msgpack.Decoder) error { + return c.decodeMsgpackImpl(&Decoder{Decoder: d}) +} + +func (c *dummyData) EncodeMsgpack(e *msgpack.Encoder) error { + return c.encodeMsgpackImpl(&Encoder{Encoder: e}) +} diff --git a/uuid/msgpack.go b/uuid/msgpack.go index 6dc4de478..0d4adc683 100644 --- a/uuid/msgpack.go +++ b/uuid/msgpack.go @@ -1,3 +1,6 @@ +//go:build !go_tarantool_msgpack_v2 +// +build !go_tarantool_msgpack_v2 + package uuid import ( @@ -5,7 +8,7 @@ import ( "github.com/google/uuid" . "github.com/tarantool/go-tarantool" - "gopkg.in/vmihailenco/msgpack.v2" + "github.com/vmihailenco/msgpack/v5" ) func encodeUUID(e *msgpack.Encoder, v reflect.Value) error { @@ -18,5 +21,13 @@ func decodeUUID(d *msgpack.Decoder, v reflect.Value) error { func init() { msgpack.Register(reflect.TypeOf((*uuid.UUID)(nil)).Elem(), encodeUUID, decodeUUID) - msgpack.RegisterExt(UUID_extId, (*uuid.UUID)(nil)) + msgpack.RegisterExtEncoder(UUID_extId, uuid.UUID{}, + func(e *msgpack.Encoder, v reflect.Value) ([]byte, error) { + uuid := v.Interface().(uuid.UUID) + return uuid.MarshalBinary() + }) + msgpack.RegisterExtDecoder(UUID_extId, uuid.UUID{}, + func(d *msgpack.Decoder, v reflect.Value, extLen int) error { + return decodeUUID(d, v) + }) } diff --git a/uuid/msgpack_helper_test.go b/uuid/msgpack_helper_test.go index 1a36ab828..6a1ad5321 100644 --- a/uuid/msgpack_helper_test.go +++ b/uuid/msgpack_helper_test.go @@ -1,8 +1,11 @@ +//go:build !go_tarantool_msgpack_v2 +// +build !go_tarantool_msgpack_v2 + package uuid_test import ( . "github.com/tarantool/go-tarantool" - "gopkg.in/vmihailenco/msgpack.v2" + "github.com/vmihailenco/msgpack/v5" ) func (t *TupleUUID) DecodeMsgpack(d *msgpack.Decoder) error { diff --git a/uuid/msgpack_v2.go b/uuid/msgpack_v2.go new file mode 100644 index 000000000..56b8d0026 --- /dev/null +++ b/uuid/msgpack_v2.go @@ -0,0 +1,25 @@ +//go:build go_tarantool_msgpack_v2 +// +build go_tarantool_msgpack_v2 + +package uuid + +import ( + "reflect" + + "github.com/google/uuid" + . "github.com/tarantool/go-tarantool" + "gopkg.in/vmihailenco/msgpack.v2" +) + +func encodeUUID(e *msgpack.Encoder, v reflect.Value) error { + return encodeUUIDImpl(&Encoder{Encoder: e}, v) +} + +func decodeUUID(d *msgpack.Decoder, v reflect.Value) error { + return decodeUUIDImpl(&Decoder{Decoder: d}, v) +} + +func init() { + msgpack.Register(reflect.TypeOf((*uuid.UUID)(nil)).Elem(), encodeUUID, decodeUUID) + msgpack.RegisterExt(UUID_extId, (*uuid.UUID)(nil)) +} diff --git a/uuid/msgpack_v2_helper_test.go b/uuid/msgpack_v2_helper_test.go new file mode 100644 index 000000000..bb7aea98c --- /dev/null +++ b/uuid/msgpack_v2_helper_test.go @@ -0,0 +1,13 @@ +//go:build go_tarantool_msgpack_v2 +// +build go_tarantool_msgpack_v2 + +package uuid_test + +import ( + . "github.com/tarantool/go-tarantool" + "gopkg.in/vmihailenco/msgpack.v2" +) + +func (t *TupleUUID) DecodeMsgpack(d *msgpack.Decoder) error { + return t.decodeMsgpackImpl(&Decoder{Decoder: d}) +}