Skip to content

Commit 536e750

Browse files
Move UUID support to submodule
To use UUID with google/uuid in msgpack, import tarantool/go-tarantool/uuid submodule.
1 parent 67374a5 commit 536e750

File tree

5 files changed

+211
-118
lines changed

5 files changed

+211
-118
lines changed

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,51 @@ func main() {
284284
}
285285
```
286286

287+
To enable support of UUID in msgpack with [google/uuid](https://github.com/google/uuid),
288+
import tarantool/uuid submodule.
289+
```go
290+
package main
291+
292+
import (
293+
"log"
294+
"time"
295+
296+
"github.com/tarantool/go-tarantool"
297+
_ "github.com/tarantool/go-tarantool/uuid"
298+
"github.com/google/uuid"
299+
)
300+
301+
func main() {
302+
server := "127.0.0.1:3013"
303+
opts := tarantool.Opts{
304+
Timeout: 500 * time.Millisecond,
305+
Reconnect: 1 * time.Second,
306+
MaxReconnects: 3,
307+
User: "test",
308+
Pass: "test",
309+
}
310+
client, err := tarantool.Connect(server, opts)
311+
if err != nil {
312+
log.Fatalf("Failed to connect: %s", err.Error())
313+
}
314+
315+
spaceNo := uint32(524)
316+
indexNo := uint32(0)
317+
318+
id, uuidErr := uuid.Parse("c8f0fa1f-da29-438c-a040-393f1126ad39")
319+
if uuidErr != nil {
320+
t.Errorf("Failed to prepare uuid: %s", uuidErr)
321+
}
322+
323+
resp, err := conn.Replace(space, index, 0, 1, IterEq, []interface{}{ id })
324+
325+
log.Println("UUID tuple replace")
326+
log.Println("Error", err)
327+
log.Println("Code", resp.Code)
328+
log.Println("Data", resp.Data)
329+
}
330+
```
331+
287332
## Schema
288333

289334
```go

tarantool_test.go

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
. "github.com/tarantool/go-tarantool"
1111
"gopkg.in/vmihailenco/msgpack.v2"
12-
"github.com/google/uuid"
1312
)
1413

1514
type Member struct {
@@ -1006,119 +1005,3 @@ func TestComplexStructs(t *testing.T) {
10061005
return
10071006
}
10081007
}
1009-
1010-
1011-
var uuidSpace = "testUUID"
1012-
var uuidIndex = "primary"
1013-
1014-
type TupleUUID struct {
1015-
id uuid.UUID
1016-
}
1017-
1018-
func (t *TupleUUID) DecodeMsgpack(d *msgpack.Decoder) error {
1019-
var err error
1020-
var l int
1021-
if l, err = d.DecodeSliceLen(); err != nil {
1022-
return err
1023-
}
1024-
if l != 1 {
1025-
return fmt.Errorf("array len doesn't match: %d", l)
1026-
}
1027-
res, err := d.DecodeInterface()
1028-
if err != nil {
1029-
return err
1030-
}
1031-
t.id = res.(uuid.UUID)
1032-
return nil
1033-
}
1034-
1035-
func connectWithValidation(t *testing.T) *Connection {
1036-
conn, err := Connect(server, opts)
1037-
if err != nil {
1038-
t.Errorf("Failed to connect: %s", err.Error())
1039-
}
1040-
if conn == nil {
1041-
t.Errorf("conn is nil after Connect")
1042-
}
1043-
return conn
1044-
}
1045-
1046-
func skipIfUUIDUnsupported(t *testing.T, conn *Connection) {
1047-
resp, err := conn.Eval("return pcall(require('msgpack').encode, require('uuid').new())", []interface{}{})
1048-
if err != nil {
1049-
t.Errorf("Failed to Eval: %s", err.Error())
1050-
}
1051-
if resp == nil {
1052-
t.Errorf("Response is nil after Eval")
1053-
}
1054-
if len(resp.Data) < 1 {
1055-
t.Errorf("Response.Data is empty after Eval")
1056-
}
1057-
val := resp.Data[0].(bool)
1058-
if val != true {
1059-
t.Skip("Skipping test for Tarantool without UUID support in msgpack")
1060-
}
1061-
}
1062-
1063-
func TestUUIDselect(t *testing.T) {
1064-
conn := connectWithValidation(t)
1065-
defer conn.Close()
1066-
1067-
skipIfUUIDUnsupported(t, conn)
1068-
1069-
id, uuidErr := uuid.Parse("c8f0fa1f-da29-438c-a040-393f1126ad39")
1070-
if uuidErr != nil {
1071-
t.Errorf("Failed to prepare test uuid: %s", uuidErr)
1072-
}
1073-
1074-
resp, errSel := conn.Select(uuidSpace, uuidIndex, 0, 1, IterEq, []interface{}{ id })
1075-
if errSel != nil {
1076-
t.Errorf("UUID select failed: %s", errSel.Error())
1077-
}
1078-
if resp == nil {
1079-
t.Errorf("Response is nil after Select")
1080-
}
1081-
if len(resp.Data) != 1 {
1082-
t.Errorf("Response Data len != 1")
1083-
}
1084-
1085-
var tuples []TupleUUID
1086-
errTyp := conn.SelectTyped(uuidSpace, uuidIndex, 0, 1, IterEq, []interface{}{ id }, &tuples)
1087-
if errTyp != nil {
1088-
t.Errorf("Failed to SelectTyped: %s", errTyp.Error())
1089-
}
1090-
if len(tuples) != 1 {
1091-
t.Errorf("Result len of SelectTyped != 1")
1092-
}
1093-
if tuples[0].id != id {
1094-
t.Errorf("Bad value loaded from SelectTyped: %s", tuples[0].id)
1095-
}
1096-
}
1097-
1098-
func TestUUIDreplace(t *testing.T) {
1099-
conn := connectWithValidation(t)
1100-
defer conn.Close()
1101-
1102-
skipIfUUIDUnsupported(t, conn)
1103-
1104-
id, uuidErr := uuid.Parse("64d22e4d-ac92-4a23-899a-e59f34af5479")
1105-
if uuidErr != nil {
1106-
t.Errorf("Failed to prepare test uuid: %s", uuidErr)
1107-
}
1108-
1109-
_, errRep := conn.Replace(uuidSpace, []interface{}{ id })
1110-
if errRep != nil {
1111-
t.Errorf("UUID replace failed: %s", errRep)
1112-
}
1113-
1114-
resp, errSel := conn.Select(uuidSpace, uuidIndex, 0, 1, IterEq, []interface{}{ id })
1115-
if errSel != nil {
1116-
t.Errorf("UUID select failed: %s", errSel)
1117-
}
1118-
if resp == nil {
1119-
t.Errorf("Response is nil after Select")
1120-
}
1121-
if len(resp.Data) != 1 {
1122-
t.Errorf("Response Data len != 1")
1123-
}
1124-
}

uuid/config.lua

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
box.cfg{
2+
listen = 3013,
3+
wal_dir = 'xlog',
4+
snap_dir = 'snap',
5+
}
6+
7+
box.schema.user.create('test', { password = 'test' , if_not_exists = true })
8+
box.schema.user.grant('test', 'execute', 'universe', nil, { if_not_exists = true })
9+
10+
local uuid = require('uuid')
11+
local msgpack = require('msgpack')
12+
13+
local uuid_msgpack_supported = pcall(msgpack.encode, uuid.new())
14+
if not uuid_msgpack_supported then
15+
error('UUID unsupported, use Tarantool 2.4.1 or newer')
16+
end
17+
18+
local s = box.schema.space.create('testUUID', {
19+
id = 524,
20+
if_not_exists = true,
21+
})
22+
s:create_index('primary', {
23+
type = 'tree',
24+
parts = {{ field = 1, type = 'uuid' }},
25+
if_not_exists = true
26+
})
27+
s:truncate()
28+
29+
box.schema.user.grant('test', 'read,write', 'space', 'testUUID', { if_not_exists = true })
30+
31+
s:insert({ uuid.fromstr("c8f0fa1f-da29-438c-a040-393f1126ad39") })

msgpack_ext.go renamed to uuid/uuid.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tarantool
1+
package uuid
22

33
import (
44
"fmt"

uuid/uuid_test.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package uuid_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
8+
. "github.com/tarantool/go-tarantool"
9+
_ "github.com/tarantool/go-tarantool/uuid"
10+
"gopkg.in/vmihailenco/msgpack.v2"
11+
"github.com/google/uuid"
12+
)
13+
14+
var server = "127.0.0.1:3013"
15+
var opts = Opts{
16+
Timeout: 500 * time.Millisecond,
17+
User: "test",
18+
Pass: "test",
19+
}
20+
21+
var space = "testUUID"
22+
var index = "primary"
23+
24+
type TupleUUID struct {
25+
id uuid.UUID
26+
}
27+
28+
func (t *TupleUUID) DecodeMsgpack(d *msgpack.Decoder) error {
29+
var err error
30+
var l int
31+
if l, err = d.DecodeSliceLen(); err != nil {
32+
return err
33+
}
34+
if l != 1 {
35+
return fmt.Errorf("array len doesn't match: %d", l)
36+
}
37+
res, err := d.DecodeInterface()
38+
if err != nil {
39+
return err
40+
}
41+
t.id = res.(uuid.UUID)
42+
return nil
43+
}
44+
45+
func connectWithValidation(t *testing.T) *Connection {
46+
conn, err := Connect(server, opts)
47+
if err != nil {
48+
t.Errorf("Failed to connect: %s", err.Error())
49+
}
50+
if conn == nil {
51+
t.Errorf("conn is nil after Connect")
52+
}
53+
return conn
54+
}
55+
56+
func skipIfUUIDUnsupported(t *testing.T, conn *Connection) {
57+
resp, err := conn.Eval("return pcall(require('msgpack').encode, require('uuid').new())", []interface{}{})
58+
if err != nil {
59+
t.Errorf("Failed to Eval: %s", err.Error())
60+
}
61+
if resp == nil {
62+
t.Errorf("Response is nil after Eval")
63+
}
64+
if len(resp.Data) < 1 {
65+
t.Errorf("Response.Data is empty after Eval")
66+
}
67+
val := resp.Data[0].(bool)
68+
if val != true {
69+
t.Skip("Skipping test for Tarantool without UUID support in msgpack")
70+
}
71+
}
72+
73+
func TestSelect(t *testing.T) {
74+
conn := connectWithValidation(t)
75+
defer conn.Close()
76+
77+
skipIfUUIDUnsupported(t, conn)
78+
79+
id, uuidErr := uuid.Parse("c8f0fa1f-da29-438c-a040-393f1126ad39")
80+
if uuidErr != nil {
81+
t.Errorf("Failed to prepare test uuid: %s", uuidErr)
82+
}
83+
84+
resp, errSel := conn.Select(space, index, 0, 1, IterEq, []interface{}{ id })
85+
if errSel != nil {
86+
t.Errorf("UUID select failed: %s", errSel.Error())
87+
}
88+
if resp == nil {
89+
t.Errorf("Response is nil after Select")
90+
}
91+
if len(resp.Data) != 1 {
92+
t.Errorf("Response Data len != 1")
93+
}
94+
95+
var tuples []TupleUUID
96+
errTyp := conn.SelectTyped(space, index, 0, 1, IterEq, []interface{}{ id }, &tuples)
97+
if errTyp != nil {
98+
t.Errorf("Failed to SelectTyped: %s", errTyp.Error())
99+
}
100+
if len(tuples) != 1 {
101+
t.Errorf("Result len of SelectTyped != 1")
102+
}
103+
if tuples[0].id != id {
104+
t.Errorf("Bad value loaded from SelectTyped: %s", tuples[0].id)
105+
}
106+
}
107+
108+
func TestReplace(t *testing.T) {
109+
conn := connectWithValidation(t)
110+
defer conn.Close()
111+
112+
skipIfUUIDUnsupported(t, conn)
113+
114+
id, uuidErr := uuid.Parse("64d22e4d-ac92-4a23-899a-e59f34af5479")
115+
if uuidErr != nil {
116+
t.Errorf("Failed to prepare test uuid: %s", uuidErr)
117+
}
118+
119+
_, errRep := conn.Replace(space, []interface{}{ id })
120+
if errRep != nil {
121+
t.Errorf("UUID replace failed: %s", errRep)
122+
}
123+
124+
resp, errSel := conn.Select(space, index, 0, 1, IterEq, []interface{}{ id })
125+
if errSel != nil {
126+
t.Errorf("UUID select failed: %s", errSel)
127+
}
128+
if resp == nil {
129+
t.Errorf("Response is nil after Select")
130+
}
131+
if len(resp.Data) != 1 {
132+
t.Errorf("Response Data len != 1")
133+
}
134+
}

0 commit comments

Comments
 (0)