Skip to content

Commit d8a3a5d

Browse files
committed
api: add structures to describe CRUD response
1 parent 735b0a7 commit d8a3a5d

21 files changed

+520
-2
lines changed

crud/count.go

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

9+
// CountResult describes result for `crud.count` method.
10+
type CountResult = NumberResult
11+
912
// CountOpts describes options for `crud.count` method.
1013
type CountOpts struct {
1114
// Timeout is a `vshard.call` timeout and vshard

crud/delete.go

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

9+
// DeleteResult describes result for `crud.delete` method.
10+
type DeleteResult = Result
11+
912
// DeleteOpts describes options for `crud.delete` method.
1013
type DeleteOpts = SimpleOperationOpts
1114

crud/error.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package crud
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
)
7+
8+
// CrudError describes CRUD error object.
9+
type CrudError struct {
10+
// ClassName is an error class that implies its source (for example, "CountError").
11+
ClassName string
12+
// Err is the text of reason.
13+
Err string
14+
// File is a source code file where the error was caught.
15+
File string
16+
// Line is a number of line in the source code file where the error was caught.
17+
Line uint64
18+
// Stack is an information about the call stack when an error
19+
// occurs in a string format.
20+
Stack string
21+
// Str is the text of reason with error class.
22+
Str string
23+
}
24+
25+
// NewCrudError creates new CRUD error.
26+
func NewCrudError(rawErr interface{}) (*CrudError, error) {
27+
var (
28+
mapErr map[interface{}]interface{}
29+
ok bool
30+
)
31+
32+
crudErr := CrudError{}
33+
34+
if mapErr, ok = rawErr.(map[interface{}]interface{}); !ok {
35+
return nil, errors.New(fmt.Sprintf("Unexpected CRUD error format: %#v", rawErr))
36+
}
37+
38+
if value, ok := mapErr["class_name"]; ok {
39+
if className, ok := value.(string); ok {
40+
crudErr.ClassName = className
41+
}
42+
}
43+
44+
if value, ok := mapErr["err"]; ok {
45+
if err, ok := value.(string); ok {
46+
crudErr.Err = err
47+
}
48+
}
49+
50+
if value, ok := mapErr["file"]; ok {
51+
if file, ok := value.(string); ok {
52+
crudErr.File = file
53+
}
54+
}
55+
56+
if value, ok := mapErr["line"]; ok {
57+
if line, ok := value.(uint64); ok {
58+
crudErr.Line = line
59+
}
60+
}
61+
62+
if value, ok := mapErr["stack"]; ok {
63+
if stack, ok := value.(string); ok {
64+
crudErr.Stack = stack
65+
}
66+
}
67+
68+
if value, ok := mapErr["str"]; ok {
69+
if str, ok := value.(string); ok {
70+
crudErr.Str = str
71+
}
72+
}
73+
74+
return &crudErr, nil
75+
}
76+
77+
// Error converts an CrudError to a string.
78+
func (err CrudError) Error() string {
79+
return err.Str
80+
}

crud/get.go

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

9+
// GetResult describes result for `crud.get` method.
10+
type GetResult = Result
11+
912
// GetOpts describes options for `crud.get` method.
1013
type GetOpts struct {
1114
// Timeout is a `vshard.call` timeout and vshard

crud/insert.go

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

9+
// InsertResult describes result for `crud.insert` method.
10+
type InsertResult = Result
11+
912
// InsertOpts describes options for `crud.insert` method.
1013
type InsertOpts = SimpleOperationOpts
1114

@@ -62,6 +65,9 @@ func (req *InsertRequest) Context(ctx context.Context) *InsertRequest {
6265
return req
6366
}
6467

68+
// InsertObjectResult describes result for `crud.insert_object` method.
69+
type InsertObjectResult = Result
70+
6571
// InsertObjectOpts describes options for `crud.insert_object` method.
6672
type InsertObjectOpts = SimpleOperationObjectOpts
6773

crud/insert_many.go

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

9+
// InsertManyResult describes result for `crud.insert_many` method.
10+
type InsertManyResult = Result
11+
912
// InsertManyOpts describes options for `crud.insert_many` method.
1013
type InsertManyOpts = OperationManyOpts
1114

@@ -62,7 +65,10 @@ func (req *InsertManyRequest) Context(ctx context.Context) *InsertManyRequest {
6265
return req
6366
}
6467

65-
// InsertManyOpts describes options for `crud.insert_object_many` method.
68+
// InsertObjectManyResult describes result for `crud.insert_object_many` method.
69+
type InsertObjectManyResult = Result
70+
71+
// InsertObjectManyOpts describes options for `crud.insert_object_many` method.
6672
type InsertObjectManyOpts = OperationObjectManyOpts
6773

6874
// InsertObjectManyRequest helps you to create request object to call

crud/len.go

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

9+
// LenResult describes result for `crud.len` method.
10+
type LenResult = NumberResult
11+
912
// LenOpts describes options for `crud.len` method.
1013
type LenOpts = BaseOpts
1114

crud/max.go

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

9+
// MaxResult describes result for `crud.max` method.
10+
type MaxResult = Result
11+
912
// MaxOpts describes options for `crud.max` method.
1013
type MaxOpts = BorderOpts
1114

crud/min.go

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

9+
// MinResult describes result for `crud.min` method.
10+
type MinResult = Result
11+
912
// MinOpts describes options for `crud.min` method.
1013
type MinOpts = BorderOpts
1114

crud/msgpack.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
)
1111

1212
type encoder = msgpack.Encoder
13+
type decoder = msgpack.Decoder
1314

1415
// Object is an interface to describe object for CRUD methods.
1516
type Object interface {

crud/msgpack_v5.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
)
1111

1212
type encoder = msgpack.Encoder
13+
type decoder = msgpack.Decoder
1314

1415
// Object is an interface to describe object for CRUD methods.
1516
type Object interface {

crud/replace.go

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

9+
// ReplaceResult describes result for `crud.replace` method.
10+
type ReplaceResult = Result
11+
912
// ReplaceOpts describes options for `crud.replace` method.
1013
type ReplaceOpts = SimpleOperationOpts
1114

@@ -62,6 +65,9 @@ func (req *ReplaceRequest) Context(ctx context.Context) *ReplaceRequest {
6265
return req
6366
}
6467

68+
// ReplaceObjectResult describes result for `crud.replace_object` method.
69+
type ReplaceObjectResult = Result
70+
6571
// ReplaceObjectOpts describes options for `crud.replace_object` method.
6672
type ReplaceObjectOpts = SimpleOperationObjectOpts
6773

crud/replace_many.go

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

9+
// ReplaceManyResult describes result for `crud.replace_many` method.
10+
type ReplaceManyResult = Result
11+
912
// ReplaceManyOpts describes options for `crud.replace_many` method.
1013
type ReplaceManyOpts = OperationManyOpts
1114

@@ -62,6 +65,9 @@ func (req *ReplaceManyRequest) Context(ctx context.Context) *ReplaceManyRequest
6265
return req
6366
}
6467

68+
// ReplaceObjectManyResult describes result for `crud.replace_object_many` method.
69+
type ReplaceObjectManyResult = Result
70+
6571
// ReplaceObjectManyOpts describes options for `crud.replace_object_many` method.
6672
type ReplaceObjectManyOpts = OperationObjectManyOpts
6773

crud/result.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package crud
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
helpers "github.com/tarantool/go-tarantool/test_helpers"
8+
)
9+
10+
// Result describes CRUD result as an object containing metadata and rows.
11+
type Result struct {
12+
Metadata []interface{}
13+
Rows []interface{}
14+
}
15+
16+
// DecodeMsgpack provides custom msgpack decoder.
17+
func (r *Result) DecodeMsgpack(dec *decoder) error {
18+
var (
19+
res map[interface{}]interface{}
20+
ok bool
21+
)
22+
23+
crudResp := struct {
24+
Res []interface{}
25+
}{}
26+
27+
if err := dec.Decode(&crudResp.Res); err != nil {
28+
return err
29+
}
30+
if len(crudResp.Res) < 2 {
31+
return errors.New(fmt.Sprintf("Unexpected CRUD response format: %#v", crudResp.Res))
32+
}
33+
34+
// crudResp.Res[1] - CRUD error.
35+
if crudResp.Res[1] != nil {
36+
crudErr, err := NewCrudError(crudResp.Res[1])
37+
if err != nil {
38+
return err
39+
}
40+
41+
return crudErr
42+
}
43+
44+
// crudResp.Res[0] - CRUD result in {metadata, rows} format.
45+
if res, ok = crudResp.Res[0].(map[interface{}]interface{}); !ok {
46+
return errors.New(fmt.Sprintf("Unexpected CRUD result: %#v", crudResp.Res[0]))
47+
}
48+
49+
if rawMetadata, ok := res["metadata"]; !ok {
50+
return errors.New("Failed to get CRUD metadata")
51+
} else {
52+
if metadata, ok := rawMetadata.([]interface{}); !ok {
53+
return errors.New(fmt.Sprintf("Unexpected CRUD metadata: %#v", rawMetadata))
54+
} else {
55+
r.Metadata = metadata
56+
}
57+
}
58+
59+
if rawTuples, ok := res["rows"]; !ok {
60+
return errors.New("Failed to get CRUD rows")
61+
} else {
62+
if tpls, ok := rawTuples.([]interface{}); !ok {
63+
return errors.New(fmt.Sprintf("Unexpected CRUD rows: %#v", rawTuples))
64+
} else {
65+
r.Rows = tpls
66+
}
67+
}
68+
69+
return nil
70+
}
71+
72+
// NumberResult describes CRUD result as an object containing number.
73+
type NumberResult struct {
74+
Value uint64
75+
}
76+
77+
// DecodeMsgpack provides custom msgpack decoder.
78+
func (r *NumberResult) DecodeMsgpack(dec *decoder) error {
79+
var (
80+
res uint64
81+
err error
82+
)
83+
84+
crudResp := struct {
85+
Res []interface{}
86+
}{}
87+
88+
if err := dec.Decode(&crudResp.Res); err != nil {
89+
return err
90+
}
91+
92+
// crudResp.Res[1] - CRUD error.
93+
if len(crudResp.Res) > 1 && crudResp.Res[1] != nil {
94+
crudErr, err := NewCrudError(crudResp.Res[1])
95+
if err != nil {
96+
return err
97+
}
98+
99+
return crudErr
100+
}
101+
102+
// crudResp.Res[0] - CRUD result in {number} format.
103+
if res, err = helpers.ConvertUint64(crudResp.Res[0]); err != nil {
104+
return errors.New(fmt.Sprintf("Unexpected CRUD result: %#v", crudResp.Res[0]))
105+
}
106+
107+
r.Value = res
108+
109+
return nil
110+
}
111+
112+
// BoolResult describes CRUD result as an object containing bool.
113+
type BoolResult struct {
114+
Value bool
115+
}
116+
117+
// DecodeMsgpack provides custom msgpack decoder.
118+
func (r *BoolResult) DecodeMsgpack(dec *decoder) error {
119+
var (
120+
res bool
121+
ok bool
122+
)
123+
124+
crudResp := struct {
125+
Res []interface{}
126+
}{}
127+
128+
if err := dec.Decode(&crudResp.Res); err != nil {
129+
return err
130+
}
131+
132+
// crudResp.Res[1] - CRUD error.
133+
if len(crudResp.Res) > 1 && crudResp.Res[1] != nil {
134+
crudErr, err := NewCrudError(crudResp.Res[1])
135+
if err != nil {
136+
return err
137+
}
138+
139+
return crudErr
140+
}
141+
142+
// crudResp.Res[0] - CRUD result in {bool} format.
143+
if res, ok = crudResp.Res[0].(bool); !ok {
144+
return errors.New(fmt.Sprintf("Unexpected CRUD result: %#v", crudResp.Res[0]))
145+
}
146+
147+
r.Value = res
148+
149+
return nil
150+
}

crud/select.go

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

9+
// SelectResult describes result for `crud.select` method.
10+
type SelectResult = Result
11+
912
// SelectOpts describes options for `crud.select` method.
1013
type SelectOpts struct {
1114
// Timeout is a `vshard.call` timeout and vshard

0 commit comments

Comments
 (0)