This repository has been archived by the owner on Feb 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
322 lines (258 loc) · 9.57 KB
/
request.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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
package protocol
import (
"fmt"
"sort"
"gopkg.in/mgo.v2/bson"
)
// RequestType describes the type of a client request.
type RequestType string
// The supported request types.
const (
RequestTypeUpdate RequestType = "update"
RequestTypeInsert RequestType = "insert"
RequestTypeGetMore RequestType = "getMore"
RequestTypeDelete RequestType = "delete"
RequestTypeKillCursors RequestType = "killCursors"
RequestTypeQuery RequestType = "query"
RequestTypeCommand RequestType = "command"
RequestTypeFindAndUpdate RequestType = "findAndUpdate"
RequestTypeFindAndDelete RequestType = "findAndDelete"
RequestTypeUnknown RequestType = "unknown"
)
// AllRequestTypeNames returns a lexicographically sorted list with all
// request types supported by the decoder.
func AllRequestTypeNames() []string {
list := []string{
string(RequestTypeUpdate),
string(RequestTypeInsert),
string(RequestTypeGetMore),
string(RequestTypeDelete),
string(RequestTypeKillCursors),
string(RequestTypeQuery),
string(RequestTypeCommand),
string(RequestTypeFindAndUpdate),
string(RequestTypeFindAndDelete),
string(RequestTypeUnknown),
}
sort.Strings(list)
return list
}
// ReplyType describes the type of expected (if any) reply for a client request.
type ReplyType uint8
// The supported reply types.
const (
// No reply needed
ReplyTypeNone ReplyType = iota
// Reply via an OP_REPLY message (opcode 1)
ReplyTypeOpReply
// Reply via an OP_MSG message (opcode 2013).
ReplyTypeOpMsg
)
// Request represents a client request.
type Request interface {
// Opcode returns the opcode identifying this request type.
Opcode() int32
// GetType returns a string representation of this request type.
GetType() RequestType
// GetReplyType returns the type of reply expected for this request.
GetReplyType() ReplyType
// RequestID returns the unique request ID for an incoming request.
RequestID() int32
}
// RPCHeader provides information about a request or response payload.
type RPCHeader struct {
MessageLength int32
RequestID int32
ResponseTo int32
Opcode int32
}
// The size of the mongo RPC header in bytes
const sizeOfRPCHeader = 16
// PayloadLength returns the size of the request payload exluding the header.
func (h RPCHeader) PayloadLength() int {
return int(h.MessageLength) - sizeOfRPCHeader
}
// RequestInfo provides low-level information about a request and implements
// a subset of the Request interface methods. It's used as a mixin for concrete
// Request definitions to avoid code repetition.
type RequestInfo struct {
// The standard RPC header used by all request and responses.
Header RPCHeader
// The type of this request.
RequestType RequestType
// The type of expected reply for this request. Depending on the request
// opcode, the reply:
// - can be omitted (e.g. OP_INSERT/UPDATE/DELETE/KILL_CURSORS)
// - uses the OP_REPLY format (OP_QUERY, OP_GETMORE)
// - uses the new OP_MSG format (for requests using OP_MSG envelopes).
ReplyType ReplyType
}
// Opcode returns the opcode for this request.
func (r RequestInfo) Opcode() int32 { return r.Header.Opcode }
// RequestID returns the unique request ID for this request.
func (r RequestInfo) RequestID() int32 { return r.Header.RequestID }
// GetType returns the type of this request.
func (r RequestInfo) GetType() RequestType { return r.RequestType }
// GetReplyType returns the expected reply type for this request.
func (r RequestInfo) GetReplyType() ReplyType { return r.ReplyType }
// NamespacedCollection encodes a namespaced collection.
type NamespacedCollection struct {
Database string
Collection string
}
// String implements fmt.Stringer for NamespacedCollection.
func (c NamespacedCollection) String() string { return fmt.Sprintf("%s.%s", c.Database, c.Collection) }
// UpdateFlag represents the allowed flag values for an update request.
type UpdateFlag uint32
// The list of supported update flags.
const (
// If set, the database will insert the supplied object into the
// collection if no matching document is found.
UpdateFlagUpsert UpdateFlag = 1 << iota
// If set, the database will update all matching objects in the
// collection. Otherwise only updates first matching document.
UpdateFlagMulti
)
// UpdateRequest represents an update request.
type UpdateRequest struct {
RequestInfo
Collection NamespacedCollection
Updates []UpdateTarget
}
// UpdateTarget represents a single update operation.
type UpdateTarget struct {
Selector bson.M
Update bson.M
ArrayFilters []bson.M
Flags UpdateFlag
}
// InsertFlag represents the allowed flag values for an insert request.
type InsertFlag uint32
// The list of supported insert flags.
const (
// If set, the database will continue processing a bulk inseert request
// even if an error occurs.
InsertFlagContinueOnError InsertFlag = 1 << iota
)
// InsertRequest represents an single or bulk document insert request.
type InsertRequest struct {
RequestInfo
Collection NamespacedCollection
Flags InsertFlag
Inserts []bson.M
}
// GetMoreRequest represents a request to read additional documents off a cursor.
type GetMoreRequest struct {
RequestInfo
Collection NamespacedCollection
NumToReturn int32
CursorID int64
}
// ReplyExpected always returns true for GetMore requests.
func (GetMoreRequest) ReplyExpected() bool { return true }
// DeleteRequest represents a request to delete a set of documents.
type DeleteRequest struct {
RequestInfo
Collection NamespacedCollection
Deletes []DeleteTarget
}
// DeleteTarget represents a single delete operation.
type DeleteTarget struct {
Selector bson.M
Limit int
}
// KillCursorsRequest represents a request to close a set of active cursors.
type KillCursorsRequest struct {
RequestInfo
CursorIDs []int64
}
// QueryFlag represents the allowed flag values for a query request.
type QueryFlag uint32
// The list of supported query flags.
const (
_ QueryFlag = 1 << iota // bit 0 is reserved.
// Tailable means cursor is not closed when the last data is retrieved. Rather,
// the cursor marks the final object’s position. You can resume using the
// cursor later, from where it was located, if more data were received. Like
// any “latent cursor”, the cursor may become invalid at some point
// (CursorNotFound) – for example if the final object it references were
// deleted.
QueryFlagTailableCursor
// Allow query of replica slave. Normally these return an error except for namespace “local”.
QueryFlagSlaveOK
// Internal replication use only - driver should not set.
QueryFlagOplogReplay
// The server normally times out idle cursors after an inactivity period (10 minutes) to prevent excess memory use. Set this option to prevent that.
QueryFlagNoCursorTimeout
// Use with TailableCursor. If we are at the end of the data, block for a while rather than returning no data. After a timeout period, we do return as normal.
QueryFlagAwaitData
// Stream the data down full blast in multiple “more” packages, on the assumption that the client will fully read all data queried. Faster when you are pulling a lot of data and know you want to pull it all down. Note: the client is not allowed to not read all the data unless it closes the connection.
QueryFlagExhaust
// Get partial results from a mongos if some shards are down (instead of throwing an error)
QueryFlagPartial
)
// QueryRequest represents a search query.
type QueryRequest struct {
RequestInfo
Collection NamespacedCollection
Flags QueryFlag
NumToSkip int32
NumToReturn int32
Query bson.M
Sort bson.M
FieldSelector bson.M
}
// FindAndUpdateRequest encapsulates the arguments for a find and replace
// command. This command updates the matched document and returns back
// either the original document or the modified document depending on the
// value of the ReturnUpdatedDoc flag.
//
// See https://docs.mongodb.com/manual/reference/command/findAndModify/#findandmodify
type FindAndUpdateRequest struct {
RequestInfo
Collection NamespacedCollection
// Query for matching the document to update
Query bson.M
// Optional sort order in case multiple documents match the query. Only
// the first document will be affected by this operation.
Sort bson.M
Update bson.M
ArrayFilters []bson.M
// Create the document if missing.
Upsert bool
// If true, return back the updated document; otherwise return the
// original document before applying the update.
ReturnUpdatedDoc bool
// An optional selector for the fields in the returned document.
FieldSelector bson.M
}
// FindAndDeleteRequest encapsulates the arguments for a find and delete
// command (issued via a call to findAndModify with remove: true). This command
// deletes the matched document and returns it back to the caller.
//
// See https://docs.mongodb.com/manual/reference/command/findAndModify/#findandmodify
type FindAndDeleteRequest struct {
RequestInfo
Collection NamespacedCollection
// Query for matching the document to update
Query bson.M
// Optional sort order in case multiple documents match the query. Only
// the first document will be affected by this operation.
Sort bson.M
// An optional selector for the fields in the returned document.
FieldSelector bson.M
}
// CommandRequest represents a mongo command sent by a mongo client.
type CommandRequest struct {
RequestInfo
Collection NamespacedCollection
Command string
Args bson.M
}
// UnknownRequest represents a client request that the parser does not know how
// to decode.
type UnknownRequest struct {
RequestInfo
// The raw payload of the captured request (sans header)
Payload []byte
}