• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / go-tarantool / 12350021459

16 Dec 2024 09:06AM UTC coverage: 73.845%. First build
12350021459

push

github

oleg-jukovec
Release v2.2.0

6042 of 8182 relevant lines covered (73.85%)

4998.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.64
/crud/result.go
1
package crud
2

3
import (
4
        "fmt"
5
        "reflect"
6

7
        "github.com/vmihailenco/msgpack/v5"
8
        "github.com/vmihailenco/msgpack/v5/msgpcode"
9
)
10

11
// FieldFormat contains field definition: {name='...',type='...'[,is_nullable=...]}.
12
type FieldFormat struct {
13
        Name       string
14
        Type       string
15
        IsNullable bool
16
}
17

18
// DecodeMsgpack provides custom msgpack decoder.
19
func (format *FieldFormat) DecodeMsgpack(d *msgpack.Decoder) error {
124✔
20
        l, err := d.DecodeMapLen()
124✔
21
        if err != nil {
124✔
22
                return err
×
23
        }
×
24
        for i := 0; i < l; i++ {
413✔
25
                key, err := d.DecodeString()
289✔
26
                if err != nil {
289✔
27
                        return err
×
28
                }
×
29
                switch key {
289✔
30
                case "name":
124✔
31
                        if format.Name, err = d.DecodeString(); err != nil {
124✔
32
                                return err
×
33
                        }
×
34
                case "type":
124✔
35
                        if format.Type, err = d.DecodeString(); err != nil {
124✔
36
                                return err
×
37
                        }
×
38
                case "is_nullable":
41✔
39
                        if format.IsNullable, err = d.DecodeBool(); err != nil {
41✔
40
                                return err
×
41
                        }
×
42
                default:
×
43
                        if err := d.Skip(); err != nil {
×
44
                                return err
×
45
                        }
×
46
                }
47
        }
48

49
        return nil
124✔
50
}
51

52
// Result describes CRUD result as an object containing metadata and rows.
53
type Result struct {
54
        Metadata []FieldFormat
55
        Rows     interface{}
56
        rowType  reflect.Type
57
}
58

59
// MakeResult create a Result object with a custom row type for decoding.
60
func MakeResult(rowType reflect.Type) Result {
4✔
61
        return Result{
4✔
62
                rowType: rowType,
4✔
63
        }
4✔
64
}
4✔
65

66
func msgpackIsArray(code byte) bool {
63✔
67
        return code == msgpcode.Array16 || code == msgpcode.Array32 ||
63✔
68
                msgpcode.IsFixedArray(code)
63✔
69
}
63✔
70

71
// DecodeMsgpack provides custom msgpack decoder.
72
func (r *Result) DecodeMsgpack(d *msgpack.Decoder) error {
60✔
73
        arrLen, err := d.DecodeArrayLen()
60✔
74
        if err != nil {
60✔
75
                return err
×
76
        }
×
77

78
        if arrLen == 0 {
60✔
79
                return fmt.Errorf("unexpected empty response array")
×
80
        }
×
81

82
        // DecodeMapLen processes `nil` as zero length map,
83
        // so in `return nil, err` case we don't miss error info.
84
        // https://github.com/vmihailenco/msgpack/blob/3f7bd806fea698e7a9fe80979aa3512dea0a7368/decode_map.go#L79-L81
85
        l, err := d.DecodeMapLen()
60✔
86
        if err != nil {
60✔
87
                return err
×
88
        }
×
89

90
        for i := 0; i < l; i++ {
138✔
91
                key, err := d.DecodeString()
78✔
92
                if err != nil {
78✔
93
                        return err
×
94
                }
×
95

96
                switch key {
78✔
97
                case "metadata":
39✔
98
                        metadataLen, err := d.DecodeArrayLen()
39✔
99
                        if err != nil {
39✔
100
                                return err
×
101
                        }
×
102

103
                        metadata := make([]FieldFormat, metadataLen)
39✔
104

39✔
105
                        for i := 0; i < metadataLen; i++ {
154✔
106
                                fieldFormat := FieldFormat{}
115✔
107
                                if err = d.Decode(&fieldFormat); err != nil {
115✔
108
                                        return err
×
109
                                }
×
110

111
                                metadata[i] = fieldFormat
115✔
112
                        }
113

114
                        r.Metadata = metadata
39✔
115
                case "rows":
39✔
116
                        if r.rowType != nil {
43✔
117
                                tuples := reflect.New(reflect.SliceOf(r.rowType))
4✔
118
                                if err = d.DecodeValue(tuples); err != nil {
4✔
119
                                        return err
×
120
                                }
×
121
                                r.Rows = tuples.Elem().Interface()
4✔
122
                        } else {
35✔
123
                                var decoded []interface{}
35✔
124
                                if err = d.Decode(&decoded); err != nil {
35✔
125
                                        return err
×
126
                                }
×
127
                                r.Rows = decoded
35✔
128
                        }
129
                default:
×
130
                        if err := d.Skip(); err != nil {
×
131
                                return err
×
132
                        }
×
133
                }
134
        }
135

136
        if arrLen > 1 {
120✔
137
                code, err := d.PeekCode()
60✔
138
                if err != nil {
60✔
139
                        return err
×
140
                }
×
141

142
                if msgpackIsArray(code) {
64✔
143
                        crudErr := newErrorMany(r.rowType)
4✔
144
                        if err := d.Decode(&crudErr); err != nil {
4✔
145
                                return err
×
146
                        }
×
147
                        if crudErr != nil {
8✔
148
                                return *crudErr
4✔
149
                        }
4✔
150
                } else if code != msgpcode.Nil {
58✔
151
                        crudErr := newError(r.rowType)
2✔
152
                        if err := d.Decode(&crudErr); err != nil {
2✔
153
                                return err
×
154
                        }
×
155
                        if crudErr != nil {
4✔
156
                                return *crudErr
2✔
157
                        }
2✔
158
                } else {
54✔
159
                        if err := d.DecodeNil(); err != nil {
54✔
160
                                return err
×
161
                        }
×
162
                }
163
        }
164

165
        for i := 2; i < arrLen; i++ {
54✔
166
                if err := d.Skip(); err != nil {
×
167
                        return err
×
168
                }
×
169
        }
170

171
        return nil
54✔
172
}
173

174
// NumberResult describes CRUD result as an object containing number.
175
type NumberResult struct {
176
        Value uint64
177
}
178

179
// DecodeMsgpack provides custom msgpack decoder.
180
func (r *NumberResult) DecodeMsgpack(d *msgpack.Decoder) error {
2✔
181
        arrLen, err := d.DecodeArrayLen()
2✔
182
        if err != nil {
2✔
183
                return err
×
184
        }
×
185

186
        if arrLen == 0 {
2✔
187
                return fmt.Errorf("unexpected empty response array")
×
188
        }
×
189

190
        // DecodeUint64 processes `nil` as `0`,
191
        // so in `return nil, err` case we don't miss error info.
192
        // https://github.com/vmihailenco/msgpack/blob/3f7bd806fea698e7a9fe80979aa3512dea0a7368/decode_number.go#L91-L93
193
        if r.Value, err = d.DecodeUint64(); err != nil {
2✔
194
                return err
×
195
        }
×
196

197
        if arrLen > 1 {
4✔
198
                var crudErr *Error = nil
2✔
199

2✔
200
                if err := d.Decode(&crudErr); err != nil {
2✔
201
                        return err
×
202
                }
×
203

204
                if crudErr != nil {
3✔
205
                        return crudErr
1✔
206
                }
1✔
207
        }
208

209
        for i := 2; i < arrLen; i++ {
1✔
210
                if err := d.Skip(); err != nil {
×
211
                        return err
×
212
                }
×
213
        }
214

215
        return nil
1✔
216
}
217

218
// BoolResult describes CRUD result as an object containing bool.
219
type BoolResult struct {
220
        Value bool
221
}
222

223
// DecodeMsgpack provides custom msgpack decoder.
224
func (r *BoolResult) DecodeMsgpack(d *msgpack.Decoder) error {
2✔
225
        arrLen, err := d.DecodeArrayLen()
2✔
226
        if err != nil {
2✔
227
                return err
×
228
        }
×
229

230
        if arrLen == 0 {
2✔
231
                return fmt.Errorf("unexpected empty response array")
×
232
        }
×
233

234
        // DecodeBool processes `nil` as `false`,
235
        // so in `return nil, err` case we don't miss error info.
236
        // https://github.com/vmihailenco/msgpack/blob/3f7bd806fea698e7a9fe80979aa3512dea0a7368/decode.go#L367-L369
237
        if r.Value, err = d.DecodeBool(); err != nil {
2✔
238
                return err
×
239
        }
×
240

241
        if arrLen > 1 {
3✔
242
                var crudErr *Error = nil
1✔
243

1✔
244
                if err := d.Decode(&crudErr); err != nil {
1✔
245
                        return err
×
246
                }
×
247

248
                if crudErr != nil {
2✔
249
                        return crudErr
1✔
250
                }
1✔
251
        }
252

253
        for i := 2; i < arrLen; i++ {
1✔
254
                if err := d.Skip(); err != nil {
×
255
                        return err
×
256
                }
×
257
        }
258

259
        return nil
1✔
260
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc