Skip to content

Commit 4e57c54

Browse files
committed
readme: move custom unpacking example to tests
1 parent cc0bc89 commit 4e57c54

File tree

2 files changed

+194
-180
lines changed

2 files changed

+194
-180
lines changed

README.md

Lines changed: 0 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ faster than other packages according to public benchmarks.
2525
* [API reference](#api-reference)
2626
* [Help](#help)
2727
* [Usage](#usage)
28-
* [Custom (un)packing and typed selects and function calls](#custom-unpacking-and-typed-selects-and-function-calls)
2928
* [Options](#options)
3029
* [Tests](#tests)
3130
* [Alternative connectors](#alternative-connectors)
@@ -121,185 +120,6 @@ will also be happy to provide advice or receive feedback.
121120
To enable support of UUID in msgpack with [google/uuid](https://github.com/google/uuid),
122121
import tarantool/uuid submodule.
123122

124-
## Custom (un)packing and typed selects and function calls
125-
126-
You can specify custom pack/unpack functions for your types. This will allow you
127-
to store complex structures inside a tuple and may speed up you requests.
128-
129-
Alternatively, you can just instruct the `msgpack` library to encode your
130-
structure as an array. This is safe "magic". It will be easier to implement than
131-
a custom packer/unpacker, but it will work slower.
132-
133-
```go
134-
import (
135-
"github.com/tarantool/go-tarantool"
136-
"gopkg.in/vmihailenco/msgpack.v2"
137-
)
138-
139-
type Member struct {
140-
Name string
141-
Nonce string
142-
Val uint
143-
}
144-
145-
type Tuple struct {
146-
Cid uint
147-
Orig string
148-
Members []Member
149-
}
150-
151-
/* same effect in a "magic" way, but slower */
152-
type Tuple2 struct {
153-
_msgpack struct{} `msgpack:",asArray"`
154-
155-
Cid uint
156-
Orig string
157-
Members []Member
158-
}
159-
160-
func (m *Member) EncodeMsgpack(e *msgpack.Encoder) error {
161-
if err := e.EncodeSliceLen(2); err != nil {
162-
return err
163-
}
164-
if err := e.EncodeString(m.Name); err != nil {
165-
return err
166-
}
167-
if err := e.EncodeUint(m.Val); err != nil {
168-
return err
169-
}
170-
return nil
171-
}
172-
173-
func (m *Member) DecodeMsgpack(d *msgpack.Decoder) error {
174-
var err error
175-
var l int
176-
if l, err = d.DecodeSliceLen(); err != nil {
177-
return err
178-
}
179-
if l != 2 {
180-
return fmt.Errorf("array len doesn't match: %d", l)
181-
}
182-
if m.Name, err = d.DecodeString(); err != nil {
183-
return err
184-
}
185-
if m.Val, err = d.DecodeUint(); err != nil {
186-
return err
187-
}
188-
return nil
189-
}
190-
191-
func (c *Tuple) EncodeMsgpack(e *msgpack.Encoder) error {
192-
if err := e.EncodeSliceLen(3); err != nil {
193-
return err
194-
}
195-
if err := e.EncodeUint(c.Cid); err != nil {
196-
return err
197-
}
198-
if err := e.EncodeString(c.Orig); err != nil {
199-
return err
200-
}
201-
if err := e.EncodeSliceLen(len(c.Members)); err != nil {
202-
return err
203-
}
204-
for _, m := range c.Members {
205-
e.Encode(m)
206-
}
207-
return nil
208-
}
209-
210-
func (c *Tuple) DecodeMsgpack(d *msgpack.Decoder) error {
211-
var err error
212-
var l int
213-
if l, err = d.DecodeSliceLen(); err != nil {
214-
return err
215-
}
216-
if l != 3 {
217-
return fmt.Errorf("array len doesn't match: %d", l)
218-
}
219-
if c.Cid, err = d.DecodeUint(); err != nil {
220-
return err
221-
}
222-
if c.Orig, err = d.DecodeString(); err != nil {
223-
return err
224-
}
225-
if l, err = d.DecodeSliceLen(); err != nil {
226-
return err
227-
}
228-
c.Members = make([]Member, l)
229-
for i := 0; i < l; i++ {
230-
d.Decode(&c.Members[i])
231-
}
232-
return nil
233-
}
234-
235-
func main() {
236-
// establish connection ...
237-
238-
tuple := Tuple{777, "orig", []Member{{"lol", "", 1}, {"wut", "", 3}}}
239-
_, err = conn.Replace(spaceNo, tuple) // NOTE: insert structure itself
240-
if err != nil {
241-
t.Errorf("Failed to insert: %s", err.Error())
242-
return
243-
}
244-
245-
var tuples []Tuple
246-
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, IterEq, []interface{}{777}, &tuples)
247-
if err != nil {
248-
t.Errorf("Failed to SelectTyped: %s", err.Error())
249-
return
250-
}
251-
252-
// same result in a "magic" way
253-
var tuples2 []Tuple2
254-
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, IterEq, []interface{}{777}, &tuples2)
255-
if err != nil {
256-
t.Errorf("Failed to SelectTyped: %s", err.Error())
257-
return
258-
}
259-
260-
// call function 'func_name' returning a table of custom tuples
261-
var tuples3 []Tuple
262-
err = client.CallTyped("func_name", []interface{}{1, 2, 3}, &tuples3)
263-
if err != nil {
264-
t.Errorf("Failed to CallTyped: %s", err.Error())
265-
return
266-
}
267-
}
268-
269-
/*
270-
// Old way to register types
271-
func init() {
272-
msgpack.Register(reflect.TypeOf(Tuple{}), encodeTuple, decodeTuple)
273-
msgpack.Register(reflect.TypeOf(Member{}), encodeMember, decodeMember)
274-
}
275-
276-
func encodeMember(e *msgpack.Encoder, v reflect.Value) error {
277-
m := v.Interface().(Member)
278-
// same code as in EncodeMsgpack
279-
return nil
280-
}
281-
282-
func decodeMember(d *msgpack.Decoder, v reflect.Value) error {
283-
m := v.Addr().Interface().(*Member)
284-
// same code as in DecodeMsgpack
285-
return nil
286-
}
287-
288-
func encodeTuple(e *msgpack.Encoder, v reflect.Value) error {
289-
c := v.Interface().(Tuple)
290-
// same code as in EncodeMsgpack
291-
return nil
292-
}
293-
294-
func decodeTuple(d *msgpack.Decoder, v reflect.Value) error {
295-
c := v.Addr().Interface().(*Tuple)
296-
// same code as in DecodeMsgpack
297-
return nil
298-
}
299-
*/
300-
301-
```
302-
303123
## Options
304124

305125
* `Timeout` - timeout for any particular request. If `Timeout` is zero request,

example_custom_unpacking_test.go

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package tarantool_test
2+
3+
import (
4+
"fmt"
5+
"github.com/tarantool/go-tarantool"
6+
"gopkg.in/vmihailenco/msgpack.v2"
7+
"log"
8+
"time"
9+
)
10+
11+
type Twin struct {
12+
Name string
13+
Nonce string
14+
Val uint
15+
}
16+
17+
type TweedledeeTuple struct {
18+
Cid uint
19+
Orig string
20+
Members []Twin
21+
}
22+
23+
/* Same effect in a "magic" way, but slower */
24+
type TweedledumTuple struct {
25+
_msgpack struct{} `msgpack:",asArray"`
26+
27+
Cid uint
28+
Orig string
29+
Members []Twin
30+
}
31+
32+
func (m *Twin) EncodeMsgpack(e *msgpack.Encoder) error {
33+
if err := e.EncodeSliceLen(2); err != nil {
34+
return err
35+
}
36+
if err := e.EncodeString(m.Name); err != nil {
37+
return err
38+
}
39+
if err := e.EncodeUint(m.Val); err != nil {
40+
return err
41+
}
42+
return nil
43+
}
44+
45+
func (m *Twin) DecodeMsgpack(d *msgpack.Decoder) error {
46+
var err error
47+
var l int
48+
if l, err = d.DecodeSliceLen(); err != nil {
49+
return err
50+
}
51+
if l != 2 {
52+
return fmt.Errorf("array len doesn't match: %d", l)
53+
}
54+
if m.Name, err = d.DecodeString(); err != nil {
55+
return err
56+
}
57+
if m.Val, err = d.DecodeUint(); err != nil {
58+
return err
59+
}
60+
return nil
61+
}
62+
63+
func (c *TweedledeeTuple) EncodeMsgpack(e *msgpack.Encoder) error {
64+
if err := e.EncodeSliceLen(3); err != nil {
65+
return err
66+
}
67+
if err := e.EncodeUint(c.Cid); err != nil {
68+
return err
69+
}
70+
if err := e.EncodeString(c.Orig); err != nil {
71+
return err
72+
}
73+
if err := e.EncodeSliceLen(len(c.Members)); err != nil {
74+
return err
75+
}
76+
for _, m := range c.Members {
77+
e.Encode(m)
78+
}
79+
return nil
80+
}
81+
82+
func (c *TweedledeeTuple) DecodeMsgpack(d *msgpack.Decoder) error {
83+
var err error
84+
var l int
85+
if l, err = d.DecodeSliceLen(); err != nil {
86+
return err
87+
}
88+
if l != 3 {
89+
return fmt.Errorf("array len doesn't match: %d", l)
90+
}
91+
if c.Cid, err = d.DecodeUint(); err != nil {
92+
return err
93+
}
94+
if c.Orig, err = d.DecodeString(); err != nil {
95+
return err
96+
}
97+
if l, err = d.DecodeSliceLen(); err != nil {
98+
return err
99+
}
100+
c.Members = make([]Twin, l)
101+
for i := 0; i < l; i++ {
102+
d.Decode(&c.Members[i])
103+
}
104+
return nil
105+
}
106+
107+
// Custom (un)packing and typed selects and function calls
108+
//
109+
// You can specify custom pack/unpack functions for your types. This will allow
110+
// you to store complex structures inside a tuple and may speed up you requests.
111+
//
112+
// Alternatively, you can just instruct the `msgpack` library to encode your
113+
// structure as an array. This is safe "magic". It will be easier to implement than
114+
// a custom packer/unpacker, but it will work slower.
115+
func Example_customUnpacking() {
116+
// Establish connection ...
117+
server := "127.0.0.1:3013"
118+
opts := tarantool.Opts{
119+
Timeout: 500 * time.Millisecond,
120+
Reconnect: 1 * time.Second,
121+
MaxReconnects: 3,
122+
User: "test",
123+
Pass: "test",
124+
}
125+
conn, err := tarantool.Connect(server, opts)
126+
if err != nil {
127+
log.Fatalf("Failed to connect: %s", err.Error())
128+
}
129+
130+
spaceNo := uint32(524)
131+
indexNo := uint32(0)
132+
133+
tuple := TweedledeeTuple{777, "orig", []Twin{{"lol", "", 1}, {"wut", "", 3}}}
134+
_, err = conn.Replace(spaceNo, tuple) // NOTE: insert structure itself
135+
if err != nil {
136+
log.Fatalf("Failed to insert: %s", err.Error())
137+
return
138+
}
139+
140+
var tuples []TweedledeeTuple
141+
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, tarantool.IterEq, []interface{}{777}, &tuples)
142+
if err != nil {
143+
log.Fatalf("Failed to SelectTyped: %s", err.Error())
144+
return
145+
}
146+
147+
// Same result in a "magic" way
148+
var tuples2 []TweedledumTuple
149+
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, tarantool.IterEq, []interface{}{777}, &tuples2)
150+
if err != nil {
151+
log.Fatalf("Failed to SelectTyped: %s", err.Error())
152+
return
153+
}
154+
155+
// Call function 'func_name' returning a table of custom tuples
156+
var tuples3 []TweedledeeTuple
157+
err = conn.CallTyped("func_name", []interface{}{1, 2, 3}, &tuples3)
158+
if err != nil {
159+
log.Fatalf("Failed to CallTyped: %s", err.Error())
160+
return
161+
}
162+
}
163+
164+
/*
165+
// Old way to register types
166+
func init() {
167+
msgpack.Register(reflect.TypeOf(TweedledeeTuple{}), encodeTuple, decodeTuple)
168+
msgpack.Register(reflect.TypeOf(Twin{}), encodeMember, decodeMember)
169+
}
170+
171+
func encodeMember(e *msgpack.Encoder, v reflect.Value) error {
172+
m := v.Interface().(Twin)
173+
// same code as in EncodeMsgpack
174+
return nil
175+
}
176+
177+
func decodeMember(d *msgpack.Decoder, v reflect.Value) error {
178+
m := v.Addr().Interface().(*Twin)
179+
// same code as in DecodeMsgpack
180+
return nil
181+
}
182+
183+
func encodeTuple(e *msgpack.Encoder, v reflect.Value) error {
184+
c := v.Interface().(TweedledeeTuple)
185+
// same code as in EncodeMsgpack
186+
return nil
187+
}
188+
189+
func decodeTuple(d *msgpack.Decoder, v reflect.Value) error {
190+
c := v.Addr().Interface().(*TweedledeeTuple)
191+
// same code as in DecodeMsgpack
192+
return nil
193+
}
194+
*/

0 commit comments

Comments
 (0)