mongodb 3.2.5 → 3.3.0-beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +0 -10
- package/index.js +4 -4
- package/lib/admin.js +56 -56
- package/lib/aggregation_cursor.js +7 -3
- package/lib/bulk/common.js +18 -13
- package/lib/change_stream.js +196 -89
- package/lib/collection.js +217 -169
- package/lib/command_cursor.js +17 -7
- package/lib/core/auth/auth_provider.js +158 -0
- package/lib/core/auth/defaultAuthProviders.js +29 -0
- package/lib/core/auth/gssapi.js +241 -0
- package/lib/core/auth/mongo_credentials.js +81 -0
- package/lib/core/auth/mongocr.js +51 -0
- package/lib/core/auth/plain.js +35 -0
- package/lib/core/auth/scram.js +293 -0
- package/lib/core/auth/sspi.js +131 -0
- package/lib/core/auth/x509.js +26 -0
- package/lib/core/connection/apm.js +236 -0
- package/lib/core/connection/command_result.js +36 -0
- package/lib/core/connection/commands.js +507 -0
- package/lib/core/connection/connect.js +370 -0
- package/lib/core/connection/connection.js +624 -0
- package/lib/core/connection/logger.js +246 -0
- package/lib/core/connection/msg.js +219 -0
- package/lib/core/connection/pool.js +1285 -0
- package/lib/core/connection/utils.js +57 -0
- package/lib/core/cursor.js +752 -0
- package/lib/core/error.js +186 -0
- package/lib/core/index.js +50 -0
- package/lib/core/sdam/monitoring.js +228 -0
- package/lib/core/sdam/server.js +467 -0
- package/lib/core/sdam/server_description.js +163 -0
- package/lib/core/sdam/server_selectors.js +244 -0
- package/lib/core/sdam/srv_polling.js +135 -0
- package/lib/core/sdam/topology.js +1151 -0
- package/lib/core/sdam/topology_description.js +408 -0
- package/lib/core/sessions.js +711 -0
- package/lib/core/tools/smoke_plugin.js +61 -0
- package/lib/core/topologies/mongos.js +1337 -0
- package/lib/core/topologies/read_preference.js +202 -0
- package/lib/core/topologies/replset.js +1507 -0
- package/lib/core/topologies/replset_state.js +1121 -0
- package/lib/core/topologies/server.js +984 -0
- package/lib/core/topologies/shared.js +453 -0
- package/lib/core/transactions.js +167 -0
- package/lib/core/uri_parser.js +631 -0
- package/lib/core/utils.js +165 -0
- package/lib/core/wireprotocol/command.js +170 -0
- package/lib/core/wireprotocol/compression.js +73 -0
- package/lib/core/wireprotocol/constants.js +13 -0
- package/lib/core/wireprotocol/get_more.js +86 -0
- package/lib/core/wireprotocol/index.js +18 -0
- package/lib/core/wireprotocol/kill_cursors.js +70 -0
- package/lib/core/wireprotocol/query.js +224 -0
- package/lib/core/wireprotocol/shared.js +115 -0
- package/lib/core/wireprotocol/write_command.js +50 -0
- package/lib/cursor.js +40 -46
- package/lib/db.js +141 -95
- package/lib/dynamic_loaders.js +32 -0
- package/lib/error.js +12 -10
- package/lib/gridfs/chunk.js +2 -2
- package/lib/gridfs/grid_store.js +31 -25
- package/lib/gridfs-stream/index.js +4 -4
- package/lib/gridfs-stream/upload.js +1 -1
- package/lib/mongo_client.js +37 -15
- package/lib/operations/add_user.js +96 -0
- package/lib/operations/aggregate.js +24 -13
- package/lib/operations/aggregate_operation.js +127 -0
- package/lib/operations/bulk_write.js +104 -0
- package/lib/operations/close.js +47 -0
- package/lib/operations/collection_ops.js +28 -287
- package/lib/operations/collections.js +55 -0
- package/lib/operations/command.js +120 -0
- package/lib/operations/command_v2.js +43 -0
- package/lib/operations/common_functions.js +372 -0
- package/lib/operations/{mongo_client_ops.js → connect.js} +185 -157
- package/lib/operations/count.js +72 -0
- package/lib/operations/count_documents.js +46 -0
- package/lib/operations/create_collection.js +118 -0
- package/lib/operations/create_index.js +92 -0
- package/lib/operations/create_indexes.js +61 -0
- package/lib/operations/cursor_ops.js +3 -4
- package/lib/operations/db_ops.js +15 -12
- package/lib/operations/delete_many.js +25 -0
- package/lib/operations/delete_one.js +25 -0
- package/lib/operations/distinct.js +85 -0
- package/lib/operations/drop.js +53 -0
- package/lib/operations/drop_index.js +42 -0
- package/lib/operations/drop_indexes.js +23 -0
- package/lib/operations/estimated_document_count.js +33 -0
- package/lib/operations/execute_db_admin_command.js +34 -0
- package/lib/operations/execute_operation.js +165 -0
- package/lib/operations/explain.js +23 -0
- package/lib/operations/find_and_modify.js +98 -0
- package/lib/operations/find_one.js +33 -0
- package/lib/operations/find_one_and_delete.js +16 -0
- package/lib/operations/find_one_and_replace.js +18 -0
- package/lib/operations/find_one_and_update.js +19 -0
- package/lib/operations/geo_haystack_search.js +79 -0
- package/lib/operations/has_next.js +40 -0
- package/lib/operations/index_exists.js +39 -0
- package/lib/operations/index_information.js +23 -0
- package/lib/operations/indexes.js +22 -0
- package/lib/operations/insert_many.js +63 -0
- package/lib/operations/insert_one.js +75 -0
- package/lib/operations/is_capped.js +19 -0
- package/lib/operations/list_indexes.js +66 -0
- package/lib/operations/map_reduce.js +189 -0
- package/lib/operations/next.js +32 -0
- package/lib/operations/operation.js +63 -0
- package/lib/operations/options_operation.js +32 -0
- package/lib/operations/profiling_level.js +31 -0
- package/lib/operations/re_index.js +28 -0
- package/lib/operations/remove_user.js +52 -0
- package/lib/operations/rename.js +61 -0
- package/lib/operations/replace_one.js +47 -0
- package/lib/operations/set_profiling_level.js +48 -0
- package/lib/operations/stats.js +45 -0
- package/lib/operations/to_array.js +68 -0
- package/lib/operations/update_many.js +29 -0
- package/lib/operations/update_one.js +44 -0
- package/lib/operations/validate_collection.js +40 -0
- package/lib/read_concern.js +55 -0
- package/lib/topologies/mongos.js +3 -3
- package/lib/topologies/native_topology.js +22 -2
- package/lib/topologies/replset.js +3 -3
- package/lib/topologies/server.js +4 -4
- package/lib/topologies/topology_base.js +6 -6
- package/lib/url_parser.js +4 -3
- package/lib/utils.js +46 -59
- package/lib/write_concern.js +66 -0
- package/package.json +15 -6
- package/lib/.DS_Store +0 -0
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var retrieveBSON = require('./utils').retrieveBSON;
|
|
4
|
+
var BSON = retrieveBSON();
|
|
5
|
+
var Long = BSON.Long;
|
|
6
|
+
const Buffer = require('safe-buffer').Buffer;
|
|
7
|
+
|
|
8
|
+
// Incrementing request id
|
|
9
|
+
var _requestId = 0;
|
|
10
|
+
|
|
11
|
+
// Wire command operation ids
|
|
12
|
+
var opcodes = require('../wireprotocol/shared').opcodes;
|
|
13
|
+
|
|
14
|
+
// Query flags
|
|
15
|
+
var OPTS_TAILABLE_CURSOR = 2;
|
|
16
|
+
var OPTS_SLAVE = 4;
|
|
17
|
+
var OPTS_OPLOG_REPLAY = 8;
|
|
18
|
+
var OPTS_NO_CURSOR_TIMEOUT = 16;
|
|
19
|
+
var OPTS_AWAIT_DATA = 32;
|
|
20
|
+
var OPTS_EXHAUST = 64;
|
|
21
|
+
var OPTS_PARTIAL = 128;
|
|
22
|
+
|
|
23
|
+
// Response flags
|
|
24
|
+
var CURSOR_NOT_FOUND = 1;
|
|
25
|
+
var QUERY_FAILURE = 2;
|
|
26
|
+
var SHARD_CONFIG_STALE = 4;
|
|
27
|
+
var AWAIT_CAPABLE = 8;
|
|
28
|
+
|
|
29
|
+
/**************************************************************
|
|
30
|
+
* QUERY
|
|
31
|
+
**************************************************************/
|
|
32
|
+
var Query = function(bson, ns, query, options) {
|
|
33
|
+
var self = this;
|
|
34
|
+
// Basic options needed to be passed in
|
|
35
|
+
if (ns == null) throw new Error('ns must be specified for query');
|
|
36
|
+
if (query == null) throw new Error('query must be specified for query');
|
|
37
|
+
|
|
38
|
+
// Validate that we are not passing 0x00 in the collection name
|
|
39
|
+
if (ns.indexOf('\x00') !== -1) {
|
|
40
|
+
throw new Error('namespace cannot contain a null character');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Basic options
|
|
44
|
+
this.bson = bson;
|
|
45
|
+
this.ns = ns;
|
|
46
|
+
this.query = query;
|
|
47
|
+
|
|
48
|
+
// Additional options
|
|
49
|
+
this.numberToSkip = options.numberToSkip || 0;
|
|
50
|
+
this.numberToReturn = options.numberToReturn || 0;
|
|
51
|
+
this.returnFieldSelector = options.returnFieldSelector || null;
|
|
52
|
+
this.requestId = Query.getRequestId();
|
|
53
|
+
|
|
54
|
+
// special case for pre-3.2 find commands, delete ASAP
|
|
55
|
+
this.pre32Limit = options.pre32Limit;
|
|
56
|
+
|
|
57
|
+
// Serialization option
|
|
58
|
+
this.serializeFunctions =
|
|
59
|
+
typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
|
|
60
|
+
this.ignoreUndefined =
|
|
61
|
+
typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : false;
|
|
62
|
+
this.maxBsonSize = options.maxBsonSize || 1024 * 1024 * 16;
|
|
63
|
+
this.checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : true;
|
|
64
|
+
this.batchSize = self.numberToReturn;
|
|
65
|
+
|
|
66
|
+
// Flags
|
|
67
|
+
this.tailable = false;
|
|
68
|
+
this.slaveOk = typeof options.slaveOk === 'boolean' ? options.slaveOk : false;
|
|
69
|
+
this.oplogReplay = false;
|
|
70
|
+
this.noCursorTimeout = false;
|
|
71
|
+
this.awaitData = false;
|
|
72
|
+
this.exhaust = false;
|
|
73
|
+
this.partial = false;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
//
|
|
77
|
+
// Assign a new request Id
|
|
78
|
+
Query.prototype.incRequestId = function() {
|
|
79
|
+
this.requestId = _requestId++;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
//
|
|
83
|
+
// Assign a new request Id
|
|
84
|
+
Query.nextRequestId = function() {
|
|
85
|
+
return _requestId + 1;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
//
|
|
89
|
+
// Uses a single allocated buffer for the process, avoiding multiple memory allocations
|
|
90
|
+
Query.prototype.toBin = function() {
|
|
91
|
+
var self = this;
|
|
92
|
+
var buffers = [];
|
|
93
|
+
var projection = null;
|
|
94
|
+
|
|
95
|
+
// Set up the flags
|
|
96
|
+
var flags = 0;
|
|
97
|
+
if (this.tailable) {
|
|
98
|
+
flags |= OPTS_TAILABLE_CURSOR;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (this.slaveOk) {
|
|
102
|
+
flags |= OPTS_SLAVE;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (this.oplogReplay) {
|
|
106
|
+
flags |= OPTS_OPLOG_REPLAY;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (this.noCursorTimeout) {
|
|
110
|
+
flags |= OPTS_NO_CURSOR_TIMEOUT;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (this.awaitData) {
|
|
114
|
+
flags |= OPTS_AWAIT_DATA;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (this.exhaust) {
|
|
118
|
+
flags |= OPTS_EXHAUST;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (this.partial) {
|
|
122
|
+
flags |= OPTS_PARTIAL;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// If batchSize is different to self.numberToReturn
|
|
126
|
+
if (self.batchSize !== self.numberToReturn) self.numberToReturn = self.batchSize;
|
|
127
|
+
|
|
128
|
+
// Allocate write protocol header buffer
|
|
129
|
+
var header = Buffer.alloc(
|
|
130
|
+
4 * 4 + // Header
|
|
131
|
+
4 + // Flags
|
|
132
|
+
Buffer.byteLength(self.ns) +
|
|
133
|
+
1 + // namespace
|
|
134
|
+
4 + // numberToSkip
|
|
135
|
+
4 // numberToReturn
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Add header to buffers
|
|
139
|
+
buffers.push(header);
|
|
140
|
+
|
|
141
|
+
// Serialize the query
|
|
142
|
+
var query = self.bson.serialize(this.query, {
|
|
143
|
+
checkKeys: this.checkKeys,
|
|
144
|
+
serializeFunctions: this.serializeFunctions,
|
|
145
|
+
ignoreUndefined: this.ignoreUndefined
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Add query document
|
|
149
|
+
buffers.push(query);
|
|
150
|
+
|
|
151
|
+
if (self.returnFieldSelector && Object.keys(self.returnFieldSelector).length > 0) {
|
|
152
|
+
// Serialize the projection document
|
|
153
|
+
projection = self.bson.serialize(this.returnFieldSelector, {
|
|
154
|
+
checkKeys: this.checkKeys,
|
|
155
|
+
serializeFunctions: this.serializeFunctions,
|
|
156
|
+
ignoreUndefined: this.ignoreUndefined
|
|
157
|
+
});
|
|
158
|
+
// Add projection document
|
|
159
|
+
buffers.push(projection);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Total message size
|
|
163
|
+
var totalLength = header.length + query.length + (projection ? projection.length : 0);
|
|
164
|
+
|
|
165
|
+
// Set up the index
|
|
166
|
+
var index = 4;
|
|
167
|
+
|
|
168
|
+
// Write total document length
|
|
169
|
+
header[3] = (totalLength >> 24) & 0xff;
|
|
170
|
+
header[2] = (totalLength >> 16) & 0xff;
|
|
171
|
+
header[1] = (totalLength >> 8) & 0xff;
|
|
172
|
+
header[0] = totalLength & 0xff;
|
|
173
|
+
|
|
174
|
+
// Write header information requestId
|
|
175
|
+
header[index + 3] = (this.requestId >> 24) & 0xff;
|
|
176
|
+
header[index + 2] = (this.requestId >> 16) & 0xff;
|
|
177
|
+
header[index + 1] = (this.requestId >> 8) & 0xff;
|
|
178
|
+
header[index] = this.requestId & 0xff;
|
|
179
|
+
index = index + 4;
|
|
180
|
+
|
|
181
|
+
// Write header information responseTo
|
|
182
|
+
header[index + 3] = (0 >> 24) & 0xff;
|
|
183
|
+
header[index + 2] = (0 >> 16) & 0xff;
|
|
184
|
+
header[index + 1] = (0 >> 8) & 0xff;
|
|
185
|
+
header[index] = 0 & 0xff;
|
|
186
|
+
index = index + 4;
|
|
187
|
+
|
|
188
|
+
// Write header information OP_QUERY
|
|
189
|
+
header[index + 3] = (opcodes.OP_QUERY >> 24) & 0xff;
|
|
190
|
+
header[index + 2] = (opcodes.OP_QUERY >> 16) & 0xff;
|
|
191
|
+
header[index + 1] = (opcodes.OP_QUERY >> 8) & 0xff;
|
|
192
|
+
header[index] = opcodes.OP_QUERY & 0xff;
|
|
193
|
+
index = index + 4;
|
|
194
|
+
|
|
195
|
+
// Write header information flags
|
|
196
|
+
header[index + 3] = (flags >> 24) & 0xff;
|
|
197
|
+
header[index + 2] = (flags >> 16) & 0xff;
|
|
198
|
+
header[index + 1] = (flags >> 8) & 0xff;
|
|
199
|
+
header[index] = flags & 0xff;
|
|
200
|
+
index = index + 4;
|
|
201
|
+
|
|
202
|
+
// Write collection name
|
|
203
|
+
index = index + header.write(this.ns, index, 'utf8') + 1;
|
|
204
|
+
header[index - 1] = 0;
|
|
205
|
+
|
|
206
|
+
// Write header information flags numberToSkip
|
|
207
|
+
header[index + 3] = (this.numberToSkip >> 24) & 0xff;
|
|
208
|
+
header[index + 2] = (this.numberToSkip >> 16) & 0xff;
|
|
209
|
+
header[index + 1] = (this.numberToSkip >> 8) & 0xff;
|
|
210
|
+
header[index] = this.numberToSkip & 0xff;
|
|
211
|
+
index = index + 4;
|
|
212
|
+
|
|
213
|
+
// Write header information flags numberToReturn
|
|
214
|
+
header[index + 3] = (this.numberToReturn >> 24) & 0xff;
|
|
215
|
+
header[index + 2] = (this.numberToReturn >> 16) & 0xff;
|
|
216
|
+
header[index + 1] = (this.numberToReturn >> 8) & 0xff;
|
|
217
|
+
header[index] = this.numberToReturn & 0xff;
|
|
218
|
+
index = index + 4;
|
|
219
|
+
|
|
220
|
+
// Return the buffers
|
|
221
|
+
return buffers;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
Query.getRequestId = function() {
|
|
225
|
+
return ++_requestId;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**************************************************************
|
|
229
|
+
* GETMORE
|
|
230
|
+
**************************************************************/
|
|
231
|
+
var GetMore = function(bson, ns, cursorId, opts) {
|
|
232
|
+
opts = opts || {};
|
|
233
|
+
this.numberToReturn = opts.numberToReturn || 0;
|
|
234
|
+
this.requestId = _requestId++;
|
|
235
|
+
this.bson = bson;
|
|
236
|
+
this.ns = ns;
|
|
237
|
+
this.cursorId = cursorId;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
//
|
|
241
|
+
// Uses a single allocated buffer for the process, avoiding multiple memory allocations
|
|
242
|
+
GetMore.prototype.toBin = function() {
|
|
243
|
+
var length = 4 + Buffer.byteLength(this.ns) + 1 + 4 + 8 + 4 * 4;
|
|
244
|
+
// Create command buffer
|
|
245
|
+
var index = 0;
|
|
246
|
+
// Allocate buffer
|
|
247
|
+
var _buffer = Buffer.alloc(length);
|
|
248
|
+
|
|
249
|
+
// Write header information
|
|
250
|
+
// index = write32bit(index, _buffer, length);
|
|
251
|
+
_buffer[index + 3] = (length >> 24) & 0xff;
|
|
252
|
+
_buffer[index + 2] = (length >> 16) & 0xff;
|
|
253
|
+
_buffer[index + 1] = (length >> 8) & 0xff;
|
|
254
|
+
_buffer[index] = length & 0xff;
|
|
255
|
+
index = index + 4;
|
|
256
|
+
|
|
257
|
+
// index = write32bit(index, _buffer, requestId);
|
|
258
|
+
_buffer[index + 3] = (this.requestId >> 24) & 0xff;
|
|
259
|
+
_buffer[index + 2] = (this.requestId >> 16) & 0xff;
|
|
260
|
+
_buffer[index + 1] = (this.requestId >> 8) & 0xff;
|
|
261
|
+
_buffer[index] = this.requestId & 0xff;
|
|
262
|
+
index = index + 4;
|
|
263
|
+
|
|
264
|
+
// index = write32bit(index, _buffer, 0);
|
|
265
|
+
_buffer[index + 3] = (0 >> 24) & 0xff;
|
|
266
|
+
_buffer[index + 2] = (0 >> 16) & 0xff;
|
|
267
|
+
_buffer[index + 1] = (0 >> 8) & 0xff;
|
|
268
|
+
_buffer[index] = 0 & 0xff;
|
|
269
|
+
index = index + 4;
|
|
270
|
+
|
|
271
|
+
// index = write32bit(index, _buffer, OP_GETMORE);
|
|
272
|
+
_buffer[index + 3] = (opcodes.OP_GETMORE >> 24) & 0xff;
|
|
273
|
+
_buffer[index + 2] = (opcodes.OP_GETMORE >> 16) & 0xff;
|
|
274
|
+
_buffer[index + 1] = (opcodes.OP_GETMORE >> 8) & 0xff;
|
|
275
|
+
_buffer[index] = opcodes.OP_GETMORE & 0xff;
|
|
276
|
+
index = index + 4;
|
|
277
|
+
|
|
278
|
+
// index = write32bit(index, _buffer, 0);
|
|
279
|
+
_buffer[index + 3] = (0 >> 24) & 0xff;
|
|
280
|
+
_buffer[index + 2] = (0 >> 16) & 0xff;
|
|
281
|
+
_buffer[index + 1] = (0 >> 8) & 0xff;
|
|
282
|
+
_buffer[index] = 0 & 0xff;
|
|
283
|
+
index = index + 4;
|
|
284
|
+
|
|
285
|
+
// Write collection name
|
|
286
|
+
index = index + _buffer.write(this.ns, index, 'utf8') + 1;
|
|
287
|
+
_buffer[index - 1] = 0;
|
|
288
|
+
|
|
289
|
+
// Write batch size
|
|
290
|
+
// index = write32bit(index, _buffer, numberToReturn);
|
|
291
|
+
_buffer[index + 3] = (this.numberToReturn >> 24) & 0xff;
|
|
292
|
+
_buffer[index + 2] = (this.numberToReturn >> 16) & 0xff;
|
|
293
|
+
_buffer[index + 1] = (this.numberToReturn >> 8) & 0xff;
|
|
294
|
+
_buffer[index] = this.numberToReturn & 0xff;
|
|
295
|
+
index = index + 4;
|
|
296
|
+
|
|
297
|
+
// Write cursor id
|
|
298
|
+
// index = write32bit(index, _buffer, cursorId.getLowBits());
|
|
299
|
+
_buffer[index + 3] = (this.cursorId.getLowBits() >> 24) & 0xff;
|
|
300
|
+
_buffer[index + 2] = (this.cursorId.getLowBits() >> 16) & 0xff;
|
|
301
|
+
_buffer[index + 1] = (this.cursorId.getLowBits() >> 8) & 0xff;
|
|
302
|
+
_buffer[index] = this.cursorId.getLowBits() & 0xff;
|
|
303
|
+
index = index + 4;
|
|
304
|
+
|
|
305
|
+
// index = write32bit(index, _buffer, cursorId.getHighBits());
|
|
306
|
+
_buffer[index + 3] = (this.cursorId.getHighBits() >> 24) & 0xff;
|
|
307
|
+
_buffer[index + 2] = (this.cursorId.getHighBits() >> 16) & 0xff;
|
|
308
|
+
_buffer[index + 1] = (this.cursorId.getHighBits() >> 8) & 0xff;
|
|
309
|
+
_buffer[index] = this.cursorId.getHighBits() & 0xff;
|
|
310
|
+
index = index + 4;
|
|
311
|
+
|
|
312
|
+
// Return buffer
|
|
313
|
+
return _buffer;
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
/**************************************************************
|
|
317
|
+
* KILLCURSOR
|
|
318
|
+
**************************************************************/
|
|
319
|
+
var KillCursor = function(bson, ns, cursorIds) {
|
|
320
|
+
this.ns = ns;
|
|
321
|
+
this.requestId = _requestId++;
|
|
322
|
+
this.cursorIds = cursorIds;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
//
|
|
326
|
+
// Uses a single allocated buffer for the process, avoiding multiple memory allocations
|
|
327
|
+
KillCursor.prototype.toBin = function() {
|
|
328
|
+
var length = 4 + 4 + 4 * 4 + this.cursorIds.length * 8;
|
|
329
|
+
|
|
330
|
+
// Create command buffer
|
|
331
|
+
var index = 0;
|
|
332
|
+
var _buffer = Buffer.alloc(length);
|
|
333
|
+
|
|
334
|
+
// Write header information
|
|
335
|
+
// index = write32bit(index, _buffer, length);
|
|
336
|
+
_buffer[index + 3] = (length >> 24) & 0xff;
|
|
337
|
+
_buffer[index + 2] = (length >> 16) & 0xff;
|
|
338
|
+
_buffer[index + 1] = (length >> 8) & 0xff;
|
|
339
|
+
_buffer[index] = length & 0xff;
|
|
340
|
+
index = index + 4;
|
|
341
|
+
|
|
342
|
+
// index = write32bit(index, _buffer, requestId);
|
|
343
|
+
_buffer[index + 3] = (this.requestId >> 24) & 0xff;
|
|
344
|
+
_buffer[index + 2] = (this.requestId >> 16) & 0xff;
|
|
345
|
+
_buffer[index + 1] = (this.requestId >> 8) & 0xff;
|
|
346
|
+
_buffer[index] = this.requestId & 0xff;
|
|
347
|
+
index = index + 4;
|
|
348
|
+
|
|
349
|
+
// index = write32bit(index, _buffer, 0);
|
|
350
|
+
_buffer[index + 3] = (0 >> 24) & 0xff;
|
|
351
|
+
_buffer[index + 2] = (0 >> 16) & 0xff;
|
|
352
|
+
_buffer[index + 1] = (0 >> 8) & 0xff;
|
|
353
|
+
_buffer[index] = 0 & 0xff;
|
|
354
|
+
index = index + 4;
|
|
355
|
+
|
|
356
|
+
// index = write32bit(index, _buffer, OP_KILL_CURSORS);
|
|
357
|
+
_buffer[index + 3] = (opcodes.OP_KILL_CURSORS >> 24) & 0xff;
|
|
358
|
+
_buffer[index + 2] = (opcodes.OP_KILL_CURSORS >> 16) & 0xff;
|
|
359
|
+
_buffer[index + 1] = (opcodes.OP_KILL_CURSORS >> 8) & 0xff;
|
|
360
|
+
_buffer[index] = opcodes.OP_KILL_CURSORS & 0xff;
|
|
361
|
+
index = index + 4;
|
|
362
|
+
|
|
363
|
+
// index = write32bit(index, _buffer, 0);
|
|
364
|
+
_buffer[index + 3] = (0 >> 24) & 0xff;
|
|
365
|
+
_buffer[index + 2] = (0 >> 16) & 0xff;
|
|
366
|
+
_buffer[index + 1] = (0 >> 8) & 0xff;
|
|
367
|
+
_buffer[index] = 0 & 0xff;
|
|
368
|
+
index = index + 4;
|
|
369
|
+
|
|
370
|
+
// Write batch size
|
|
371
|
+
// index = write32bit(index, _buffer, this.cursorIds.length);
|
|
372
|
+
_buffer[index + 3] = (this.cursorIds.length >> 24) & 0xff;
|
|
373
|
+
_buffer[index + 2] = (this.cursorIds.length >> 16) & 0xff;
|
|
374
|
+
_buffer[index + 1] = (this.cursorIds.length >> 8) & 0xff;
|
|
375
|
+
_buffer[index] = this.cursorIds.length & 0xff;
|
|
376
|
+
index = index + 4;
|
|
377
|
+
|
|
378
|
+
// Write all the cursor ids into the array
|
|
379
|
+
for (var i = 0; i < this.cursorIds.length; i++) {
|
|
380
|
+
// Write cursor id
|
|
381
|
+
// index = write32bit(index, _buffer, cursorIds[i].getLowBits());
|
|
382
|
+
_buffer[index + 3] = (this.cursorIds[i].getLowBits() >> 24) & 0xff;
|
|
383
|
+
_buffer[index + 2] = (this.cursorIds[i].getLowBits() >> 16) & 0xff;
|
|
384
|
+
_buffer[index + 1] = (this.cursorIds[i].getLowBits() >> 8) & 0xff;
|
|
385
|
+
_buffer[index] = this.cursorIds[i].getLowBits() & 0xff;
|
|
386
|
+
index = index + 4;
|
|
387
|
+
|
|
388
|
+
// index = write32bit(index, _buffer, cursorIds[i].getHighBits());
|
|
389
|
+
_buffer[index + 3] = (this.cursorIds[i].getHighBits() >> 24) & 0xff;
|
|
390
|
+
_buffer[index + 2] = (this.cursorIds[i].getHighBits() >> 16) & 0xff;
|
|
391
|
+
_buffer[index + 1] = (this.cursorIds[i].getHighBits() >> 8) & 0xff;
|
|
392
|
+
_buffer[index] = this.cursorIds[i].getHighBits() & 0xff;
|
|
393
|
+
index = index + 4;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Return buffer
|
|
397
|
+
return _buffer;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
var Response = function(bson, message, msgHeader, msgBody, opts) {
|
|
401
|
+
opts = opts || { promoteLongs: true, promoteValues: true, promoteBuffers: false };
|
|
402
|
+
this.parsed = false;
|
|
403
|
+
this.raw = message;
|
|
404
|
+
this.data = msgBody;
|
|
405
|
+
this.bson = bson;
|
|
406
|
+
this.opts = opts;
|
|
407
|
+
|
|
408
|
+
// Read the message header
|
|
409
|
+
this.length = msgHeader.length;
|
|
410
|
+
this.requestId = msgHeader.requestId;
|
|
411
|
+
this.responseTo = msgHeader.responseTo;
|
|
412
|
+
this.opCode = msgHeader.opCode;
|
|
413
|
+
this.fromCompressed = msgHeader.fromCompressed;
|
|
414
|
+
|
|
415
|
+
// Read the message body
|
|
416
|
+
this.responseFlags = msgBody.readInt32LE(0);
|
|
417
|
+
this.cursorId = new Long(msgBody.readInt32LE(4), msgBody.readInt32LE(8));
|
|
418
|
+
this.startingFrom = msgBody.readInt32LE(12);
|
|
419
|
+
this.numberReturned = msgBody.readInt32LE(16);
|
|
420
|
+
|
|
421
|
+
// Preallocate document array
|
|
422
|
+
this.documents = new Array(this.numberReturned);
|
|
423
|
+
|
|
424
|
+
// Flag values
|
|
425
|
+
this.cursorNotFound = (this.responseFlags & CURSOR_NOT_FOUND) !== 0;
|
|
426
|
+
this.queryFailure = (this.responseFlags & QUERY_FAILURE) !== 0;
|
|
427
|
+
this.shardConfigStale = (this.responseFlags & SHARD_CONFIG_STALE) !== 0;
|
|
428
|
+
this.awaitCapable = (this.responseFlags & AWAIT_CAPABLE) !== 0;
|
|
429
|
+
this.promoteLongs = typeof opts.promoteLongs === 'boolean' ? opts.promoteLongs : true;
|
|
430
|
+
this.promoteValues = typeof opts.promoteValues === 'boolean' ? opts.promoteValues : true;
|
|
431
|
+
this.promoteBuffers = typeof opts.promoteBuffers === 'boolean' ? opts.promoteBuffers : false;
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
Response.prototype.isParsed = function() {
|
|
435
|
+
return this.parsed;
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
Response.prototype.parse = function(options) {
|
|
439
|
+
// Don't parse again if not needed
|
|
440
|
+
if (this.parsed) return;
|
|
441
|
+
options = options || {};
|
|
442
|
+
|
|
443
|
+
// Allow the return of raw documents instead of parsing
|
|
444
|
+
var raw = options.raw || false;
|
|
445
|
+
var documentsReturnedIn = options.documentsReturnedIn || null;
|
|
446
|
+
var promoteLongs =
|
|
447
|
+
typeof options.promoteLongs === 'boolean' ? options.promoteLongs : this.opts.promoteLongs;
|
|
448
|
+
var promoteValues =
|
|
449
|
+
typeof options.promoteValues === 'boolean' ? options.promoteValues : this.opts.promoteValues;
|
|
450
|
+
var promoteBuffers =
|
|
451
|
+
typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : this.opts.promoteBuffers;
|
|
452
|
+
var bsonSize, _options;
|
|
453
|
+
|
|
454
|
+
// Set up the options
|
|
455
|
+
_options = {
|
|
456
|
+
promoteLongs: promoteLongs,
|
|
457
|
+
promoteValues: promoteValues,
|
|
458
|
+
promoteBuffers: promoteBuffers
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
// Position within OP_REPLY at which documents start
|
|
462
|
+
// (See https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/#wire-op-reply)
|
|
463
|
+
this.index = 20;
|
|
464
|
+
|
|
465
|
+
//
|
|
466
|
+
// Parse Body
|
|
467
|
+
//
|
|
468
|
+
for (var i = 0; i < this.numberReturned; i++) {
|
|
469
|
+
bsonSize =
|
|
470
|
+
this.data[this.index] |
|
|
471
|
+
(this.data[this.index + 1] << 8) |
|
|
472
|
+
(this.data[this.index + 2] << 16) |
|
|
473
|
+
(this.data[this.index + 3] << 24);
|
|
474
|
+
|
|
475
|
+
// If we have raw results specified slice the return document
|
|
476
|
+
if (raw) {
|
|
477
|
+
this.documents[i] = this.data.slice(this.index, this.index + bsonSize);
|
|
478
|
+
} else {
|
|
479
|
+
this.documents[i] = this.bson.deserialize(
|
|
480
|
+
this.data.slice(this.index, this.index + bsonSize),
|
|
481
|
+
_options
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Adjust the index
|
|
486
|
+
this.index = this.index + bsonSize;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (this.documents.length === 1 && documentsReturnedIn != null && raw) {
|
|
490
|
+
const fieldsAsRaw = {};
|
|
491
|
+
fieldsAsRaw[documentsReturnedIn] = true;
|
|
492
|
+
_options.fieldsAsRaw = fieldsAsRaw;
|
|
493
|
+
|
|
494
|
+
const doc = this.bson.deserialize(this.documents[0], _options);
|
|
495
|
+
this.documents = [doc];
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Set parsed
|
|
499
|
+
this.parsed = true;
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
module.exports = {
|
|
503
|
+
Query: Query,
|
|
504
|
+
GetMore: GetMore,
|
|
505
|
+
Response: Response,
|
|
506
|
+
KillCursor: KillCursor
|
|
507
|
+
};
|