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.
Files changed (133) hide show
  1. package/HISTORY.md +0 -10
  2. package/index.js +4 -4
  3. package/lib/admin.js +56 -56
  4. package/lib/aggregation_cursor.js +7 -3
  5. package/lib/bulk/common.js +18 -13
  6. package/lib/change_stream.js +196 -89
  7. package/lib/collection.js +217 -169
  8. package/lib/command_cursor.js +17 -7
  9. package/lib/core/auth/auth_provider.js +158 -0
  10. package/lib/core/auth/defaultAuthProviders.js +29 -0
  11. package/lib/core/auth/gssapi.js +241 -0
  12. package/lib/core/auth/mongo_credentials.js +81 -0
  13. package/lib/core/auth/mongocr.js +51 -0
  14. package/lib/core/auth/plain.js +35 -0
  15. package/lib/core/auth/scram.js +293 -0
  16. package/lib/core/auth/sspi.js +131 -0
  17. package/lib/core/auth/x509.js +26 -0
  18. package/lib/core/connection/apm.js +236 -0
  19. package/lib/core/connection/command_result.js +36 -0
  20. package/lib/core/connection/commands.js +507 -0
  21. package/lib/core/connection/connect.js +370 -0
  22. package/lib/core/connection/connection.js +624 -0
  23. package/lib/core/connection/logger.js +246 -0
  24. package/lib/core/connection/msg.js +219 -0
  25. package/lib/core/connection/pool.js +1285 -0
  26. package/lib/core/connection/utils.js +57 -0
  27. package/lib/core/cursor.js +752 -0
  28. package/lib/core/error.js +186 -0
  29. package/lib/core/index.js +50 -0
  30. package/lib/core/sdam/monitoring.js +228 -0
  31. package/lib/core/sdam/server.js +467 -0
  32. package/lib/core/sdam/server_description.js +163 -0
  33. package/lib/core/sdam/server_selectors.js +244 -0
  34. package/lib/core/sdam/srv_polling.js +135 -0
  35. package/lib/core/sdam/topology.js +1151 -0
  36. package/lib/core/sdam/topology_description.js +408 -0
  37. package/lib/core/sessions.js +711 -0
  38. package/lib/core/tools/smoke_plugin.js +61 -0
  39. package/lib/core/topologies/mongos.js +1337 -0
  40. package/lib/core/topologies/read_preference.js +202 -0
  41. package/lib/core/topologies/replset.js +1507 -0
  42. package/lib/core/topologies/replset_state.js +1121 -0
  43. package/lib/core/topologies/server.js +984 -0
  44. package/lib/core/topologies/shared.js +453 -0
  45. package/lib/core/transactions.js +167 -0
  46. package/lib/core/uri_parser.js +631 -0
  47. package/lib/core/utils.js +165 -0
  48. package/lib/core/wireprotocol/command.js +170 -0
  49. package/lib/core/wireprotocol/compression.js +73 -0
  50. package/lib/core/wireprotocol/constants.js +13 -0
  51. package/lib/core/wireprotocol/get_more.js +86 -0
  52. package/lib/core/wireprotocol/index.js +18 -0
  53. package/lib/core/wireprotocol/kill_cursors.js +70 -0
  54. package/lib/core/wireprotocol/query.js +224 -0
  55. package/lib/core/wireprotocol/shared.js +115 -0
  56. package/lib/core/wireprotocol/write_command.js +50 -0
  57. package/lib/cursor.js +40 -46
  58. package/lib/db.js +141 -95
  59. package/lib/dynamic_loaders.js +32 -0
  60. package/lib/error.js +12 -10
  61. package/lib/gridfs/chunk.js +2 -2
  62. package/lib/gridfs/grid_store.js +31 -25
  63. package/lib/gridfs-stream/index.js +4 -4
  64. package/lib/gridfs-stream/upload.js +1 -1
  65. package/lib/mongo_client.js +37 -15
  66. package/lib/operations/add_user.js +96 -0
  67. package/lib/operations/aggregate.js +24 -13
  68. package/lib/operations/aggregate_operation.js +127 -0
  69. package/lib/operations/bulk_write.js +104 -0
  70. package/lib/operations/close.js +47 -0
  71. package/lib/operations/collection_ops.js +28 -287
  72. package/lib/operations/collections.js +55 -0
  73. package/lib/operations/command.js +120 -0
  74. package/lib/operations/command_v2.js +43 -0
  75. package/lib/operations/common_functions.js +372 -0
  76. package/lib/operations/{mongo_client_ops.js → connect.js} +185 -157
  77. package/lib/operations/count.js +72 -0
  78. package/lib/operations/count_documents.js +46 -0
  79. package/lib/operations/create_collection.js +118 -0
  80. package/lib/operations/create_index.js +92 -0
  81. package/lib/operations/create_indexes.js +61 -0
  82. package/lib/operations/cursor_ops.js +3 -4
  83. package/lib/operations/db_ops.js +15 -12
  84. package/lib/operations/delete_many.js +25 -0
  85. package/lib/operations/delete_one.js +25 -0
  86. package/lib/operations/distinct.js +85 -0
  87. package/lib/operations/drop.js +53 -0
  88. package/lib/operations/drop_index.js +42 -0
  89. package/lib/operations/drop_indexes.js +23 -0
  90. package/lib/operations/estimated_document_count.js +33 -0
  91. package/lib/operations/execute_db_admin_command.js +34 -0
  92. package/lib/operations/execute_operation.js +165 -0
  93. package/lib/operations/explain.js +23 -0
  94. package/lib/operations/find_and_modify.js +98 -0
  95. package/lib/operations/find_one.js +33 -0
  96. package/lib/operations/find_one_and_delete.js +16 -0
  97. package/lib/operations/find_one_and_replace.js +18 -0
  98. package/lib/operations/find_one_and_update.js +19 -0
  99. package/lib/operations/geo_haystack_search.js +79 -0
  100. package/lib/operations/has_next.js +40 -0
  101. package/lib/operations/index_exists.js +39 -0
  102. package/lib/operations/index_information.js +23 -0
  103. package/lib/operations/indexes.js +22 -0
  104. package/lib/operations/insert_many.js +63 -0
  105. package/lib/operations/insert_one.js +75 -0
  106. package/lib/operations/is_capped.js +19 -0
  107. package/lib/operations/list_indexes.js +66 -0
  108. package/lib/operations/map_reduce.js +189 -0
  109. package/lib/operations/next.js +32 -0
  110. package/lib/operations/operation.js +63 -0
  111. package/lib/operations/options_operation.js +32 -0
  112. package/lib/operations/profiling_level.js +31 -0
  113. package/lib/operations/re_index.js +28 -0
  114. package/lib/operations/remove_user.js +52 -0
  115. package/lib/operations/rename.js +61 -0
  116. package/lib/operations/replace_one.js +47 -0
  117. package/lib/operations/set_profiling_level.js +48 -0
  118. package/lib/operations/stats.js +45 -0
  119. package/lib/operations/to_array.js +68 -0
  120. package/lib/operations/update_many.js +29 -0
  121. package/lib/operations/update_one.js +44 -0
  122. package/lib/operations/validate_collection.js +40 -0
  123. package/lib/read_concern.js +55 -0
  124. package/lib/topologies/mongos.js +3 -3
  125. package/lib/topologies/native_topology.js +22 -2
  126. package/lib/topologies/replset.js +3 -3
  127. package/lib/topologies/server.js +4 -4
  128. package/lib/topologies/topology_base.js +6 -6
  129. package/lib/url_parser.js +4 -3
  130. package/lib/utils.js +46 -59
  131. package/lib/write_concern.js +66 -0
  132. package/package.json +15 -6
  133. 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
+ };