forked from dropbox/godropbox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresponses.go
252 lines (218 loc) · 5.36 KB
/
responses.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
package memcache
import (
"github.com/dropbox/godropbox/errors"
)
func NewStatusCodeError(status ResponseStatus) error {
switch status {
case StatusNoError:
return nil
case StatusKeyNotFound:
return errors.New("Key not found")
case StatusKeyExists:
return errors.New("Key exists")
case StatusValueTooLarge:
return errors.New("Value too large")
case StatusInvalidArguments:
return errors.New("Invalid arguments")
case StatusItemNotStored:
return errors.New("Item not stored")
case StatusIncrDecrOnNonNumericValue:
return errors.New("Incr/decr on non-numeric value")
case StatusVbucketBelongsToAnotherServer:
return errors.New("VBucket belongs to another server")
case StatusAuthenticationError:
return errors.New("Authentication error")
case StatusAuthenticationContinue:
return errors.New("Authentication continue")
case StatusUnknownCommand:
return errors.New("Unknown command")
case StatusOutOfMemory:
return errors.New("Server out of memory")
case StatusNotSupported:
return errors.New("Not supported")
case StatusInternalError:
return errors.New("Server internal error")
case StatusBusy:
return errors.New("Server busy")
case StatusTempFailure:
return errors.New("Temporary server failure")
default:
return errors.Newf("Invalid status: %d", int(status))
}
}
// The genericResponse is an union of all response types. Response interfaces
// will cover the fact that there's only one implementation for everything.
type genericResponse struct {
// err and status are used by all responses.
err error
status ResponseStatus
// key is used by get / mutate / count responses. The rest is used only
// by get response.
item Item
// set to true only for get response
allowNotFound bool
// count is used by count response.
count uint64
// versions is used by version response.
versions map[int]string
// statEntries is used by stat response.
statEntries map[int](map[string]string)
}
func (r *genericResponse) Status() ResponseStatus {
return r.status
}
func (r *genericResponse) Error() error {
if r.err != nil {
return r.err
}
if r.status == StatusNoError {
return nil
}
if r.allowNotFound && r.status == StatusKeyNotFound {
return nil
}
return NewStatusCodeError(r.status)
}
func (r *genericResponse) Key() string {
return r.item.Key
}
func (r *genericResponse) Value() []byte {
return r.item.Value
}
func (r *genericResponse) Flags() uint32 {
return r.item.Flags
}
func (r *genericResponse) DataVersionId() uint64 {
return r.item.DataVersionId
}
func (r *genericResponse) Count() uint64 {
return r.count
}
func (r *genericResponse) Versions() map[int]string {
return r.versions
}
func (r *genericResponse) Entries() map[int](map[string]string) {
return r.statEntries
}
// This creates a Response from an error.
func NewErrorResponse(err error) Response {
return &genericResponse{
err: err,
}
}
// This creates a Response from status.
func NewResponse(status ResponseStatus) Response {
return &genericResponse{
status: status,
}
}
// This creates a GetResponse from an error.
func NewGetErrorResponse(key string, err error) GetResponse {
resp := &genericResponse{
err: err,
allowNotFound: true,
}
resp.item.Key = key
return resp
}
// This creates a normal GetResponse.
func NewGetResponse(
key string,
status ResponseStatus,
flags uint32,
value []byte,
version uint64) GetResponse {
resp := &genericResponse{
status: status,
allowNotFound: true,
}
resp.item.Key = key
if status == StatusNoError {
resp.item.Value = value
resp.item.Flags = flags
resp.item.DataVersionId = version
}
return resp
}
// This creates a MutateResponse from an error.
func NewMutateErrorResponse(key string, err error) MutateResponse {
resp := &genericResponse{
err: err,
}
resp.item.Key = key
return resp
}
// This creates a normal MutateResponse.
func NewMutateResponse(
key string,
status ResponseStatus,
version uint64) MutateResponse {
resp := &genericResponse{
status: status,
}
resp.item.Key = key
if status == StatusNoError {
resp.item.DataVersionId = version
}
return resp
}
// This creates a CountResponse from an error.
func NewCountErrorResponse(key string, err error) CountResponse {
resp := &genericResponse{
err: err,
}
resp.item.Key = key
return resp
}
// This creates a normal CountResponse.
func NewCountResponse(
key string,
status ResponseStatus,
count uint64) CountResponse {
resp := &genericResponse{
status: status,
}
resp.item.Key = key
if status == StatusNoError {
resp.count = count
}
return resp
}
// This creates a VersionResponse from an error.
func NewVersionErrorResponse(
err error,
versions map[int]string) VersionResponse {
return &genericResponse{
err: err,
versions: versions,
}
}
// This creates a normal VersionResponse.
func NewVersionResponse(
status ResponseStatus,
versions map[int]string) VersionResponse {
resp := &genericResponse{
status: status,
versions: versions,
}
return resp
}
// This creates a StatResponse from an error.
func NewStatErrorResponse(
err error,
entries map[int](map[string]string)) StatResponse {
return &genericResponse{
err: err,
statEntries: entries,
}
}
// This creates a normal StatResponse.
func NewStatResponse(
status ResponseStatus,
entries map[int](map[string]string)) StatResponse {
resp := &genericResponse{
status: status,
statEntries: entries,
}
return resp
}