Skip to content

Commit 48337a4

Browse files
committed
crud: improve Result* types
Now a user can specify his custom type as a type for rows. The patch also removes unnecessary types to make it easier for a user to work with the API. Part of #271
1 parent 306ef71 commit 48337a4

18 files changed

+229
-150
lines changed

crud/delete.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// DeleteResult describes result for `crud.delete` method.
10-
type DeleteResult = Result
11-
129
// DeleteOpts describes options for `crud.delete` method.
1310
type DeleteOpts = SimpleOperationOpts
1411

crud/error.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,30 @@ type ErrorMany struct {
7575
Errors []Error
7676
}
7777

78+
// DecodeMsgpack provides custom msgpack decoder.
79+
func (e *ErrorMany) DecodeMsgpack(d *decoder) error {
80+
l, err := d.DecodeArrayLen()
81+
if err != nil {
82+
return err
83+
}
84+
85+
var errs []Error
86+
for i := 0; i < l; i++ {
87+
var crudErr *Error = nil
88+
if err := d.Decode(&crudErr); err != nil {
89+
return err
90+
} else if crudErr != nil {
91+
errs = append(errs, *crudErr)
92+
}
93+
}
94+
95+
if len(errs) > 0 {
96+
*e = ErrorMany{Errors: errs}
97+
}
98+
99+
return nil
100+
}
101+
78102
// Error converts an Error to a string.
79103
func (errs ErrorMany) Error() string {
80104
var str []string

crud/example_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package crud_test
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
"time"
7+
8+
"github.com/tarantool/go-tarantool"
9+
"github.com/tarantool/go-tarantool/crud"
10+
)
11+
12+
const (
13+
exampleServer = "127.0.0.1:3013"
14+
exampleSpace = "test"
15+
)
16+
17+
var exampleOpts = tarantool.Opts{
18+
Timeout: 500 * time.Millisecond,
19+
User: "test",
20+
Pass: "test",
21+
}
22+
23+
func exampleConnect() *tarantool.Connection {
24+
conn, err := tarantool.Connect(exampleServer, exampleOpts)
25+
if err != nil {
26+
panic("Connection is not established: " + err.Error())
27+
}
28+
return conn
29+
}
30+
31+
// ExampleResult_rowsInterface demonstrates how to use a helper type Result
32+
// to decode a crud response. In this example, rows are decoded as an
33+
// interface{} type.
34+
func ExampleResult_rowsInterface() {
35+
conn := exampleConnect()
36+
req := crud.NewReplaceRequest(exampleSpace).
37+
Tuple([]interface{}{uint(2010), nil, "bla"})
38+
39+
ret := crud.Result{}
40+
if err := conn.Do(req).GetTyped(&ret); err != nil {
41+
fmt.Printf("Failed to execute request: %s", err)
42+
return
43+
}
44+
45+
fmt.Println(ret.Metadata)
46+
fmt.Println(ret.Rows)
47+
// Output:
48+
// [{id unsigned false} {bucket_id unsigned true} {name string false}]
49+
// [[2010 45 bla]]
50+
}
51+
52+
// ExampleResult_rowsCustomType demonstrates how to use a helper type Result
53+
// to decode a crud response. In this example, rows are decoded as a
54+
// custom type.
55+
func ExampleResult_rowsCustomType() {
56+
conn := exampleConnect()
57+
req := crud.NewReplaceRequest(exampleSpace).
58+
Tuple([]interface{}{uint(2010), nil, "bla"})
59+
60+
type Tuple struct {
61+
_msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused
62+
Id uint64
63+
BucketId uint64
64+
Name string
65+
}
66+
ret := crud.MakeResult(reflect.TypeOf(Tuple{}))
67+
68+
if err := conn.Do(req).GetTyped(&ret); err != nil {
69+
fmt.Printf("Failed to execute request: %s", err)
70+
return
71+
}
72+
73+
fmt.Println(ret.Metadata)
74+
rows := ret.Rows.([]Tuple)
75+
fmt.Println(rows)
76+
// Output:
77+
// [{id unsigned false} {bucket_id unsigned true} {name string false}]
78+
// [{{} 2010 45 bla}]
79+
}
80+
81+
// ExampleResult_many demonstrates that there is no difference in a
82+
// response from *ManyRequest.
83+
func ExampleResult_many() {
84+
conn := exampleConnect()
85+
req := crud.NewReplaceManyRequest(exampleSpace).
86+
Tuples([]crud.Tuple{
87+
[]interface{}{uint(2010), nil, "bla"},
88+
[]interface{}{uint(2011), nil, "bla"},
89+
})
90+
91+
ret := crud.Result{}
92+
if err := conn.Do(req).GetTyped(&ret); err != nil {
93+
fmt.Printf("Failed to execute request: %s", err)
94+
return
95+
}
96+
97+
fmt.Println(ret.Metadata)
98+
fmt.Println(ret.Rows)
99+
// Output:
100+
// [{id unsigned false} {bucket_id unsigned true} {name string false}]
101+
// [[2010 45 bla] [2011 4 bla]]
102+
}
103+
104+
// ExampleResult_error demonstrates how to use a helper type Result
105+
// to handle a crud error.
106+
func ExampleResult_error() {
107+
conn := exampleConnect()
108+
req := crud.NewReplaceRequest("not_exist").
109+
Tuple([]interface{}{uint(2010), nil, "bla"})
110+
111+
ret := crud.Result{}
112+
if err := conn.Do(req).GetTyped(&ret); err != nil {
113+
crudErr := err.(crud.Error)
114+
fmt.Printf("Failed to execute request: %s", crudErr)
115+
} else {
116+
fmt.Println(ret.Metadata)
117+
fmt.Println(ret.Rows)
118+
}
119+
// Output:
120+
// Failed to execute request: ReplaceError: Space "not_exist" doesn't exist
121+
}
122+
123+
// ExampleResult_errorMany demonstrates how to use a helper type Result
124+
// to handle a crud error for a *ManyRequest.
125+
func ExampleResult_errorMany() {
126+
conn := exampleConnect()
127+
initReq := crud.NewReplaceRequest("not_exist").
128+
Tuple([]interface{}{uint(2010), nil, "bla"})
129+
if _, err := conn.Do(initReq).Get(); err != nil {
130+
fmt.Printf("Failed to initialize the example: %s\n", err)
131+
}
132+
133+
req := crud.NewInsertManyRequest(exampleSpace).
134+
Tuples([]crud.Tuple{
135+
[]interface{}{uint(2010), nil, "bla"},
136+
[]interface{}{uint(2010), nil, "bla"},
137+
})
138+
ret := crud.Result{}
139+
if err := conn.Do(req).GetTyped(&ret); err != nil {
140+
crudErr := err.(crud.ErrorMany)
141+
// We need to trim the error message to make the example repeatable.
142+
errmsg := crudErr.Error()[:10]
143+
fmt.Printf("Failed to execute request: %s", errmsg)
144+
} else {
145+
fmt.Println(ret.Metadata)
146+
fmt.Println(ret.Rows)
147+
}
148+
// Output:
149+
// Failed to execute request: CallError:
150+
}

crud/get.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// GetResult describes result for `crud.get` method.
10-
type GetResult = Result
11-
129
// GetOpts describes options for `crud.get` method.
1310
type GetOpts struct {
1411
// Timeout is a `vshard.call` timeout and vshard

crud/insert.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// InsertResult describes result for `crud.insert` method.
10-
type InsertResult = Result
11-
129
// InsertOpts describes options for `crud.insert` method.
1310
type InsertOpts = SimpleOperationOpts
1411

@@ -65,9 +62,6 @@ func (req *InsertRequest) Context(ctx context.Context) *InsertRequest {
6562
return req
6663
}
6764

68-
// InsertObjectResult describes result for `crud.insert_object` method.
69-
type InsertObjectResult = Result
70-
7165
// InsertObjectOpts describes options for `crud.insert_object` method.
7266
type InsertObjectOpts = SimpleOperationObjectOpts
7367

crud/insert_many.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// InsertManyResult describes result for `crud.insert_many` method.
10-
type InsertManyResult = ResultMany
11-
129
// InsertManyOpts describes options for `crud.insert_many` method.
1310
type InsertManyOpts = OperationManyOpts
1411

@@ -65,9 +62,6 @@ func (req *InsertManyRequest) Context(ctx context.Context) *InsertManyRequest {
6562
return req
6663
}
6764

68-
// InsertObjectManyResult describes result for `crud.insert_object_many` method.
69-
type InsertObjectManyResult = ResultMany
70-
7165
// InsertObjectManyOpts describes options for `crud.insert_object_many` method.
7266
type InsertObjectManyOpts = OperationObjectManyOpts
7367

crud/max.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// MaxResult describes result for `crud.max` method.
10-
type MaxResult = Result
11-
129
// MaxOpts describes options for `crud.max` method.
1310
type MaxOpts = BorderOpts
1411

crud/min.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// MinResult describes result for `crud.min` method.
10-
type MinResult = Result
11-
129
// MinOpts describes options for `crud.min` method.
1310
type MinOpts = BorderOpts
1411

crud/msgpack.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package crud
55

66
import (
77
"gopkg.in/vmihailenco/msgpack.v2"
8+
msgpcode "gopkg.in/vmihailenco/msgpack.v2/codes"
89
)
910

1011
type encoder = msgpack.Encoder
@@ -21,3 +22,8 @@ type MapObject map[string]interface{}
2122
func (o MapObject) EncodeMsgpack(enc *encoder) {
2223
enc.Encode(o)
2324
}
25+
26+
func msgpackIsArray(code byte) bool {
27+
return code == msgpcode.Array16 || code == msgpcode.Array32 ||
28+
msgpcode.IsFixedArray(code)
29+
}

crud/msgpack_v5.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package crud
55

66
import (
77
"github.com/vmihailenco/msgpack/v5"
8+
"github.com/vmihailenco/msgpack/v5/msgpcode"
89
)
910

1011
type encoder = msgpack.Encoder
@@ -21,3 +22,8 @@ type MapObject map[string]interface{}
2122
func (o MapObject) EncodeMsgpack(enc *encoder) {
2223
enc.Encode(o)
2324
}
25+
26+
func msgpackIsArray(code byte) bool {
27+
return code == msgpcode.Array16 || code == msgpcode.Array32 ||
28+
msgpcode.IsFixedArray(code)
29+
}

crud/replace.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// ReplaceResult describes result for `crud.replace` method.
10-
type ReplaceResult = Result
11-
129
// ReplaceOpts describes options for `crud.replace` method.
1310
type ReplaceOpts = SimpleOperationOpts
1411

@@ -65,9 +62,6 @@ func (req *ReplaceRequest) Context(ctx context.Context) *ReplaceRequest {
6562
return req
6663
}
6764

68-
// ReplaceObjectResult describes result for `crud.replace_object` method.
69-
type ReplaceObjectResult = Result
70-
7165
// ReplaceObjectOpts describes options for `crud.replace_object` method.
7266
type ReplaceObjectOpts = SimpleOperationObjectOpts
7367

crud/replace_many.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import (
66
"github.com/tarantool/go-tarantool"
77
)
88

9-
// ReplaceManyResult describes result for `crud.replace_many` method.
10-
type ReplaceManyResult = ResultMany
11-
129
// ReplaceManyOpts describes options for `crud.replace_many` method.
1310
type ReplaceManyOpts = OperationManyOpts
1411

@@ -65,9 +62,6 @@ func (req *ReplaceManyRequest) Context(ctx context.Context) *ReplaceManyRequest
6562
return req
6663
}
6764

68-
// ReplaceObjectManyResult describes result for `crud.replace_object_many` method.
69-
type ReplaceObjectManyResult = ResultMany
70-
7165
// ReplaceObjectManyOpts describes options for `crud.replace_object_many` method.
7266
type ReplaceObjectManyOpts = OperationObjectManyOpts
7367

0 commit comments

Comments
 (0)