Skip to content

Commit 063ff8d

Browse files
committed
readme: move custom unpacking example to tests
Commented out code with old way to register types has been removed. Part of #123
1 parent 613127d commit 063ff8d

File tree

2 files changed

+163
-180
lines changed

2 files changed

+163
-180
lines changed

README.md

-180
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ faster than other packages according to public benchmarks.
2626
* [API reference](#api-reference)
2727
* [Walking\-through example in Go](#walking-through-example-in-go)
2828
* [Help](#help)
29-
* [Custom (un)packing and typed selects and function calls](#custom-unpacking-and-typed-selects-and-function-calls)
3029
* [Options](#options)
3130
* [Tests](#tests)
3231
* [Alternative connectors](#alternative-connectors)
@@ -173,185 +172,6 @@ To contact `go-tarantool` developers on any problems, create an issue at
173172
The developers of the [Tarantool server](http://github.com/tarantool/tarantool)
174173
will also be happy to provide advice or receive feedback.
175174

176-
## Custom (un)packing and typed selects and function calls
177-
178-
You can specify custom pack/unpack functions for your types. This will allow you
179-
to store complex structures inside a tuple and may speed up you requests.
180-
181-
Alternatively, you can just instruct the `msgpack` library to encode your
182-
structure as an array. This is safe "magic". It will be easier to implement than
183-
a custom packer/unpacker, but it will work slower.
184-
185-
```go
186-
import (
187-
"github.com/tarantool/go-tarantool"
188-
"gopkg.in/vmihailenco/msgpack.v2"
189-
)
190-
191-
type Member struct {
192-
Name string
193-
Nonce string
194-
Val uint
195-
}
196-
197-
type Tuple struct {
198-
Cid uint
199-
Orig string
200-
Members []Member
201-
}
202-
203-
/* same effect in a "magic" way, but slower */
204-
type Tuple2 struct {
205-
_msgpack struct{} `msgpack:",asArray"`
206-
207-
Cid uint
208-
Orig string
209-
Members []Member
210-
}
211-
212-
func (m *Member) EncodeMsgpack(e *msgpack.Encoder) error {
213-
if err := e.EncodeSliceLen(2); err != nil {
214-
return err
215-
}
216-
if err := e.EncodeString(m.Name); err != nil {
217-
return err
218-
}
219-
if err := e.EncodeUint(m.Val); err != nil {
220-
return err
221-
}
222-
return nil
223-
}
224-
225-
func (m *Member) DecodeMsgpack(d *msgpack.Decoder) error {
226-
var err error
227-
var l int
228-
if l, err = d.DecodeSliceLen(); err != nil {
229-
return err
230-
}
231-
if l != 2 {
232-
return fmt.Errorf("array len doesn't match: %d", l)
233-
}
234-
if m.Name, err = d.DecodeString(); err != nil {
235-
return err
236-
}
237-
if m.Val, err = d.DecodeUint(); err != nil {
238-
return err
239-
}
240-
return nil
241-
}
242-
243-
func (c *Tuple) EncodeMsgpack(e *msgpack.Encoder) error {
244-
if err := e.EncodeSliceLen(3); err != nil {
245-
return err
246-
}
247-
if err := e.EncodeUint(c.Cid); err != nil {
248-
return err
249-
}
250-
if err := e.EncodeString(c.Orig); err != nil {
251-
return err
252-
}
253-
if err := e.EncodeSliceLen(len(c.Members)); err != nil {
254-
return err
255-
}
256-
for _, m := range c.Members {
257-
e.Encode(m)
258-
}
259-
return nil
260-
}
261-
262-
func (c *Tuple) DecodeMsgpack(d *msgpack.Decoder) error {
263-
var err error
264-
var l int
265-
if l, err = d.DecodeSliceLen(); err != nil {
266-
return err
267-
}
268-
if l != 3 {
269-
return fmt.Errorf("array len doesn't match: %d", l)
270-
}
271-
if c.Cid, err = d.DecodeUint(); err != nil {
272-
return err
273-
}
274-
if c.Orig, err = d.DecodeString(); err != nil {
275-
return err
276-
}
277-
if l, err = d.DecodeSliceLen(); err != nil {
278-
return err
279-
}
280-
c.Members = make([]Member, l)
281-
for i := 0; i < l; i++ {
282-
d.Decode(&c.Members[i])
283-
}
284-
return nil
285-
}
286-
287-
func main() {
288-
// establish connection ...
289-
290-
tuple := Tuple{777, "orig", []Member{{"lol", "", 1}, {"wut", "", 3}}}
291-
_, err = conn.Replace(spaceNo, tuple) // NOTE: insert structure itself
292-
if err != nil {
293-
t.Errorf("Failed to insert: %s", err.Error())
294-
return
295-
}
296-
297-
var tuples []Tuple
298-
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, IterEq, []interface{}{777}, &tuples)
299-
if err != nil {
300-
t.Errorf("Failed to SelectTyped: %s", err.Error())
301-
return
302-
}
303-
304-
// same result in a "magic" way
305-
var tuples2 []Tuple2
306-
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, IterEq, []interface{}{777}, &tuples2)
307-
if err != nil {
308-
t.Errorf("Failed to SelectTyped: %s", err.Error())
309-
return
310-
}
311-
312-
// call function 'func_name' returning a table of custom tuples
313-
var tuples3 []Tuple
314-
err = client.CallTyped("func_name", []interface{}{1, 2, 3}, &tuples3)
315-
if err != nil {
316-
t.Errorf("Failed to CallTyped: %s", err.Error())
317-
return
318-
}
319-
}
320-
321-
/*
322-
// Old way to register types
323-
func init() {
324-
msgpack.Register(reflect.TypeOf(Tuple{}), encodeTuple, decodeTuple)
325-
msgpack.Register(reflect.TypeOf(Member{}), encodeMember, decodeMember)
326-
}
327-
328-
func encodeMember(e *msgpack.Encoder, v reflect.Value) error {
329-
m := v.Interface().(Member)
330-
// same code as in EncodeMsgpack
331-
return nil
332-
}
333-
334-
func decodeMember(d *msgpack.Decoder, v reflect.Value) error {
335-
m := v.Addr().Interface().(*Member)
336-
// same code as in DecodeMsgpack
337-
return nil
338-
}
339-
340-
func encodeTuple(e *msgpack.Encoder, v reflect.Value) error {
341-
c := v.Interface().(Tuple)
342-
// same code as in EncodeMsgpack
343-
return nil
344-
}
345-
346-
func decodeTuple(d *msgpack.Decoder, v reflect.Value) error {
347-
c := v.Addr().Interface().(*Tuple)
348-
// same code as in DecodeMsgpack
349-
return nil
350-
}
351-
*/
352-
353-
```
354-
355175
## Options
356176

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

example_custom_unpacking_test.go

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
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+
// Example demonstrates how to use custom (un)packing with typed selects and
108+
// function calls.
109+
//
110+
// You can specify custom pack/unpack functions for your types. This will allow
111+
// you to store complex structures inside a tuple and may speed up you requests.
112+
//
113+
// Alternatively, you can just instruct the `msgpack` library to encode your
114+
// structure as an array. This is safe "magic". It will be easier to implement than
115+
// a custom packer/unpacker, but it will work slower.
116+
func Example_customUnpacking() {
117+
// Establish connection ...
118+
server := "127.0.0.1:3013"
119+
opts := tarantool.Opts{
120+
Timeout: 500 * time.Millisecond,
121+
Reconnect: 1 * time.Second,
122+
MaxReconnects: 3,
123+
User: "test",
124+
Pass: "test",
125+
}
126+
conn, err := tarantool.Connect(server, opts)
127+
if err != nil {
128+
log.Fatalf("Failed to connect: %s", err.Error())
129+
}
130+
131+
spaceNo := uint32(524)
132+
indexNo := uint32(0)
133+
134+
tuple := TweedledeeTuple{777, "orig", []Twin{{"lol", "", 1}, {"wut", "", 3}}}
135+
_, err = conn.Replace(spaceNo, tuple) // NOTE: insert structure itself
136+
if err != nil {
137+
log.Fatalf("Failed to insert: %s", err.Error())
138+
return
139+
}
140+
141+
var tuples []TweedledeeTuple
142+
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, tarantool.IterEq, []interface{}{777}, &tuples)
143+
if err != nil {
144+
log.Fatalf("Failed to SelectTyped: %s", err.Error())
145+
return
146+
}
147+
148+
// Same result in a "magic" way
149+
var tuples2 []TweedledumTuple
150+
err = conn.SelectTyped(spaceNo, indexNo, 0, 1, tarantool.IterEq, []interface{}{777}, &tuples2)
151+
if err != nil {
152+
log.Fatalf("Failed to SelectTyped: %s", err.Error())
153+
return
154+
}
155+
156+
// Call function 'func_name' returning a table of custom tuples
157+
var tuples3 []TweedledeeTuple
158+
err = conn.CallTyped("func_name", []interface{}{1, 2, 3}, &tuples3)
159+
if err != nil {
160+
log.Fatalf("Failed to CallTyped: %s", err.Error())
161+
return
162+
}
163+
}

0 commit comments

Comments
 (0)