Skip to content

Commit 35b10d8

Browse files
committed
readme: move custom unpacking example to tests
Commented out code with old way to register types has been removed.
1 parent 744c6ac commit 35b10d8

File tree

2 files changed

+162
-180
lines changed

2 files changed

+162
-180
lines changed

README.md

Lines changed: 0 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ faster than other packages according to public benchmarks.
2323
* [API reference](#api-reference)
2424
* [Walking\-through example](#walking-through-example)
2525
* [Help](#help)
26-
* [Custom (un)packing and typed selects and function calls](#custom-unpacking-and-typed-selects-and-function-calls)
2726
* [Options](#options)
2827
* [Tests](#tests)
2928
* [Alternative connectors](#alternative-connectors)
@@ -170,185 +169,6 @@ To contact `go-tarantool` developers on any problems, create an issue at
170169
The developers of the [Tarantool server](http://github.com/tarantool/tarantool)
171170
will also be happy to provide advice or receive feedback.
172171

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

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

example_custom_unpacking_test.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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+
}

0 commit comments

Comments
 (0)