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,246 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var f = require('util').format,
|
|
4
|
+
MongoError = require('../error').MongoError;
|
|
5
|
+
|
|
6
|
+
// Filters for classes
|
|
7
|
+
var classFilters = {};
|
|
8
|
+
var filteredClasses = {};
|
|
9
|
+
var level = null;
|
|
10
|
+
// Save the process id
|
|
11
|
+
var pid = process.pid;
|
|
12
|
+
// current logger
|
|
13
|
+
var currentLogger = null;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new Logger instance
|
|
17
|
+
* @class
|
|
18
|
+
* @param {string} className The Class name associated with the logging instance
|
|
19
|
+
* @param {object} [options=null] Optional settings.
|
|
20
|
+
* @param {Function} [options.logger=null] Custom logger function;
|
|
21
|
+
* @param {string} [options.loggerLevel=error] Override default global log level.
|
|
22
|
+
* @return {Logger} a Logger instance.
|
|
23
|
+
*/
|
|
24
|
+
var Logger = function(className, options) {
|
|
25
|
+
if (!(this instanceof Logger)) return new Logger(className, options);
|
|
26
|
+
options = options || {};
|
|
27
|
+
|
|
28
|
+
// Current reference
|
|
29
|
+
this.className = className;
|
|
30
|
+
|
|
31
|
+
// Current logger
|
|
32
|
+
if (options.logger) {
|
|
33
|
+
currentLogger = options.logger;
|
|
34
|
+
} else if (currentLogger == null) {
|
|
35
|
+
currentLogger = console.log;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Set level of logging, default is error
|
|
39
|
+
if (options.loggerLevel) {
|
|
40
|
+
level = options.loggerLevel || 'error';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Add all class names
|
|
44
|
+
if (filteredClasses[this.className] == null) classFilters[this.className] = true;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Log a message at the debug level
|
|
49
|
+
* @method
|
|
50
|
+
* @param {string} message The message to log
|
|
51
|
+
* @param {object} object additional meta data to log
|
|
52
|
+
* @return {null}
|
|
53
|
+
*/
|
|
54
|
+
Logger.prototype.debug = function(message, object) {
|
|
55
|
+
if (
|
|
56
|
+
this.isDebug() &&
|
|
57
|
+
((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
|
|
58
|
+
(Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
|
|
59
|
+
) {
|
|
60
|
+
var dateTime = new Date().getTime();
|
|
61
|
+
var msg = f('[%s-%s:%s] %s %s', 'DEBUG', this.className, pid, dateTime, message);
|
|
62
|
+
var state = {
|
|
63
|
+
type: 'debug',
|
|
64
|
+
message: message,
|
|
65
|
+
className: this.className,
|
|
66
|
+
pid: pid,
|
|
67
|
+
date: dateTime
|
|
68
|
+
};
|
|
69
|
+
if (object) state.meta = object;
|
|
70
|
+
currentLogger(msg, state);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Log a message at the warn level
|
|
76
|
+
* @method
|
|
77
|
+
* @param {string} message The message to log
|
|
78
|
+
* @param {object} object additional meta data to log
|
|
79
|
+
* @return {null}
|
|
80
|
+
*/
|
|
81
|
+
(Logger.prototype.warn = function(message, object) {
|
|
82
|
+
if (
|
|
83
|
+
this.isWarn() &&
|
|
84
|
+
((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
|
|
85
|
+
(Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
|
|
86
|
+
) {
|
|
87
|
+
var dateTime = new Date().getTime();
|
|
88
|
+
var msg = f('[%s-%s:%s] %s %s', 'WARN', this.className, pid, dateTime, message);
|
|
89
|
+
var state = {
|
|
90
|
+
type: 'warn',
|
|
91
|
+
message: message,
|
|
92
|
+
className: this.className,
|
|
93
|
+
pid: pid,
|
|
94
|
+
date: dateTime
|
|
95
|
+
};
|
|
96
|
+
if (object) state.meta = object;
|
|
97
|
+
currentLogger(msg, state);
|
|
98
|
+
}
|
|
99
|
+
}),
|
|
100
|
+
/**
|
|
101
|
+
* Log a message at the info level
|
|
102
|
+
* @method
|
|
103
|
+
* @param {string} message The message to log
|
|
104
|
+
* @param {object} object additional meta data to log
|
|
105
|
+
* @return {null}
|
|
106
|
+
*/
|
|
107
|
+
(Logger.prototype.info = function(message, object) {
|
|
108
|
+
if (
|
|
109
|
+
this.isInfo() &&
|
|
110
|
+
((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
|
|
111
|
+
(Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
|
|
112
|
+
) {
|
|
113
|
+
var dateTime = new Date().getTime();
|
|
114
|
+
var msg = f('[%s-%s:%s] %s %s', 'INFO', this.className, pid, dateTime, message);
|
|
115
|
+
var state = {
|
|
116
|
+
type: 'info',
|
|
117
|
+
message: message,
|
|
118
|
+
className: this.className,
|
|
119
|
+
pid: pid,
|
|
120
|
+
date: dateTime
|
|
121
|
+
};
|
|
122
|
+
if (object) state.meta = object;
|
|
123
|
+
currentLogger(msg, state);
|
|
124
|
+
}
|
|
125
|
+
}),
|
|
126
|
+
/**
|
|
127
|
+
* Log a message at the error level
|
|
128
|
+
* @method
|
|
129
|
+
* @param {string} message The message to log
|
|
130
|
+
* @param {object} object additional meta data to log
|
|
131
|
+
* @return {null}
|
|
132
|
+
*/
|
|
133
|
+
(Logger.prototype.error = function(message, object) {
|
|
134
|
+
if (
|
|
135
|
+
this.isError() &&
|
|
136
|
+
((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
|
|
137
|
+
(Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
|
|
138
|
+
) {
|
|
139
|
+
var dateTime = new Date().getTime();
|
|
140
|
+
var msg = f('[%s-%s:%s] %s %s', 'ERROR', this.className, pid, dateTime, message);
|
|
141
|
+
var state = {
|
|
142
|
+
type: 'error',
|
|
143
|
+
message: message,
|
|
144
|
+
className: this.className,
|
|
145
|
+
pid: pid,
|
|
146
|
+
date: dateTime
|
|
147
|
+
};
|
|
148
|
+
if (object) state.meta = object;
|
|
149
|
+
currentLogger(msg, state);
|
|
150
|
+
}
|
|
151
|
+
}),
|
|
152
|
+
/**
|
|
153
|
+
* Is the logger set at info level
|
|
154
|
+
* @method
|
|
155
|
+
* @return {boolean}
|
|
156
|
+
*/
|
|
157
|
+
(Logger.prototype.isInfo = function() {
|
|
158
|
+
return level === 'info' || level === 'debug';
|
|
159
|
+
}),
|
|
160
|
+
/**
|
|
161
|
+
* Is the logger set at error level
|
|
162
|
+
* @method
|
|
163
|
+
* @return {boolean}
|
|
164
|
+
*/
|
|
165
|
+
(Logger.prototype.isError = function() {
|
|
166
|
+
return level === 'error' || level === 'info' || level === 'debug';
|
|
167
|
+
}),
|
|
168
|
+
/**
|
|
169
|
+
* Is the logger set at error level
|
|
170
|
+
* @method
|
|
171
|
+
* @return {boolean}
|
|
172
|
+
*/
|
|
173
|
+
(Logger.prototype.isWarn = function() {
|
|
174
|
+
return level === 'error' || level === 'warn' || level === 'info' || level === 'debug';
|
|
175
|
+
}),
|
|
176
|
+
/**
|
|
177
|
+
* Is the logger set at debug level
|
|
178
|
+
* @method
|
|
179
|
+
* @return {boolean}
|
|
180
|
+
*/
|
|
181
|
+
(Logger.prototype.isDebug = function() {
|
|
182
|
+
return level === 'debug';
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Resets the logger to default settings, error and no filtered classes
|
|
187
|
+
* @method
|
|
188
|
+
* @return {null}
|
|
189
|
+
*/
|
|
190
|
+
Logger.reset = function() {
|
|
191
|
+
level = 'error';
|
|
192
|
+
filteredClasses = {};
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get the current logger function
|
|
197
|
+
* @method
|
|
198
|
+
* @return {function}
|
|
199
|
+
*/
|
|
200
|
+
Logger.currentLogger = function() {
|
|
201
|
+
return currentLogger;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Set the current logger function
|
|
206
|
+
* @method
|
|
207
|
+
* @param {function} logger Logger function.
|
|
208
|
+
* @return {null}
|
|
209
|
+
*/
|
|
210
|
+
Logger.setCurrentLogger = function(logger) {
|
|
211
|
+
if (typeof logger !== 'function') throw new MongoError('current logger must be a function');
|
|
212
|
+
currentLogger = logger;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Set what classes to log.
|
|
217
|
+
* @method
|
|
218
|
+
* @param {string} type The type of filter (currently only class)
|
|
219
|
+
* @param {string[]} values The filters to apply
|
|
220
|
+
* @return {null}
|
|
221
|
+
*/
|
|
222
|
+
Logger.filter = function(type, values) {
|
|
223
|
+
if (type === 'class' && Array.isArray(values)) {
|
|
224
|
+
filteredClasses = {};
|
|
225
|
+
|
|
226
|
+
values.forEach(function(x) {
|
|
227
|
+
filteredClasses[x] = true;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Set the current log level
|
|
234
|
+
* @method
|
|
235
|
+
* @param {string} level Set current log level (debug, info, error)
|
|
236
|
+
* @return {null}
|
|
237
|
+
*/
|
|
238
|
+
Logger.setLevel = function(_level) {
|
|
239
|
+
if (_level !== 'info' && _level !== 'error' && _level !== 'debug' && _level !== 'warn') {
|
|
240
|
+
throw new Error(f('%s is an illegal logging level', _level));
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
level = _level;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
module.exports = Logger;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Implementation of OP_MSG spec:
|
|
4
|
+
// https://github.com/mongodb/specifications/blob/master/source/message/OP_MSG.rst
|
|
5
|
+
//
|
|
6
|
+
// struct Section {
|
|
7
|
+
// uint8 payloadType;
|
|
8
|
+
// union payload {
|
|
9
|
+
// document document; // payloadType == 0
|
|
10
|
+
// struct sequence { // payloadType == 1
|
|
11
|
+
// int32 size;
|
|
12
|
+
// cstring identifier;
|
|
13
|
+
// document* documents;
|
|
14
|
+
// };
|
|
15
|
+
// };
|
|
16
|
+
// };
|
|
17
|
+
|
|
18
|
+
// struct OP_MSG {
|
|
19
|
+
// struct MsgHeader {
|
|
20
|
+
// int32 messageLength;
|
|
21
|
+
// int32 requestID;
|
|
22
|
+
// int32 responseTo;
|
|
23
|
+
// int32 opCode = 2013;
|
|
24
|
+
// };
|
|
25
|
+
// uint32 flagBits;
|
|
26
|
+
// Section+ sections;
|
|
27
|
+
// [uint32 checksum;]
|
|
28
|
+
// };
|
|
29
|
+
|
|
30
|
+
const opcodes = require('../wireprotocol/shared').opcodes;
|
|
31
|
+
const databaseNamespace = require('../wireprotocol/shared').databaseNamespace;
|
|
32
|
+
const ReadPreference = require('../topologies/read_preference');
|
|
33
|
+
|
|
34
|
+
// Incrementing request id
|
|
35
|
+
let _requestId = 0;
|
|
36
|
+
|
|
37
|
+
// Msg Flags
|
|
38
|
+
const OPTS_CHECKSUM_PRESENT = 1;
|
|
39
|
+
const OPTS_MORE_TO_COME = 2;
|
|
40
|
+
const OPTS_EXHAUST_ALLOWED = 1 << 16;
|
|
41
|
+
|
|
42
|
+
class Msg {
|
|
43
|
+
constructor(bson, ns, command, options) {
|
|
44
|
+
// Basic options needed to be passed in
|
|
45
|
+
if (command == null) throw new Error('query must be specified for query');
|
|
46
|
+
|
|
47
|
+
// Basic options
|
|
48
|
+
this.bson = bson;
|
|
49
|
+
this.ns = ns;
|
|
50
|
+
this.command = command;
|
|
51
|
+
this.command.$db = databaseNamespace(ns);
|
|
52
|
+
|
|
53
|
+
if (options.readPreference && options.readPreference.mode !== ReadPreference.PRIMARY) {
|
|
54
|
+
this.command.$readPreference = options.readPreference.toJSON();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Ensure empty options
|
|
58
|
+
this.options = options || {};
|
|
59
|
+
|
|
60
|
+
// Additional options
|
|
61
|
+
this.requestId = Msg.getRequestId();
|
|
62
|
+
|
|
63
|
+
// Serialization option
|
|
64
|
+
this.serializeFunctions =
|
|
65
|
+
typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
|
|
66
|
+
this.ignoreUndefined =
|
|
67
|
+
typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : false;
|
|
68
|
+
this.checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false;
|
|
69
|
+
this.maxBsonSize = options.maxBsonSize || 1024 * 1024 * 16;
|
|
70
|
+
|
|
71
|
+
// flags
|
|
72
|
+
this.checksumPresent = false;
|
|
73
|
+
this.moreToCome = options.moreToCome || false;
|
|
74
|
+
this.exhaustAllowed = false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
toBin() {
|
|
78
|
+
const buffers = [];
|
|
79
|
+
let flags = 0;
|
|
80
|
+
|
|
81
|
+
if (this.checksumPresent) {
|
|
82
|
+
flags |= OPTS_CHECKSUM_PRESENT;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (this.moreToCome) {
|
|
86
|
+
flags |= OPTS_MORE_TO_COME;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (this.exhaustAllowed) {
|
|
90
|
+
flags |= OPTS_EXHAUST_ALLOWED;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const header = new Buffer(
|
|
94
|
+
4 * 4 + // Header
|
|
95
|
+
4 // Flags
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
buffers.push(header);
|
|
99
|
+
|
|
100
|
+
let totalLength = header.length;
|
|
101
|
+
const command = this.command;
|
|
102
|
+
totalLength += this.makeDocumentSegment(buffers, command);
|
|
103
|
+
|
|
104
|
+
header.writeInt32LE(totalLength, 0); // messageLength
|
|
105
|
+
header.writeInt32LE(this.requestId, 4); // requestID
|
|
106
|
+
header.writeInt32LE(0, 8); // responseTo
|
|
107
|
+
header.writeInt32LE(opcodes.OP_MSG, 12); // opCode
|
|
108
|
+
header.writeUInt32LE(flags, 16); // flags
|
|
109
|
+
return buffers;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
makeDocumentSegment(buffers, document) {
|
|
113
|
+
const payloadTypeBuffer = new Buffer(1);
|
|
114
|
+
payloadTypeBuffer[0] = 0;
|
|
115
|
+
|
|
116
|
+
const documentBuffer = this.serializeBson(document);
|
|
117
|
+
buffers.push(payloadTypeBuffer);
|
|
118
|
+
buffers.push(documentBuffer);
|
|
119
|
+
|
|
120
|
+
return payloadTypeBuffer.length + documentBuffer.length;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
serializeBson(document) {
|
|
124
|
+
return this.bson.serialize(document, {
|
|
125
|
+
checkKeys: this.checkKeys,
|
|
126
|
+
serializeFunctions: this.serializeFunctions,
|
|
127
|
+
ignoreUndefined: this.ignoreUndefined
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
Msg.getRequestId = function() {
|
|
133
|
+
return ++_requestId;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
class BinMsg {
|
|
137
|
+
constructor(bson, message, msgHeader, msgBody, opts) {
|
|
138
|
+
opts = opts || { promoteLongs: true, promoteValues: true, promoteBuffers: false };
|
|
139
|
+
this.parsed = false;
|
|
140
|
+
this.raw = message;
|
|
141
|
+
this.data = msgBody;
|
|
142
|
+
this.bson = bson;
|
|
143
|
+
this.opts = opts;
|
|
144
|
+
|
|
145
|
+
// Read the message header
|
|
146
|
+
this.length = msgHeader.length;
|
|
147
|
+
this.requestId = msgHeader.requestId;
|
|
148
|
+
this.responseTo = msgHeader.responseTo;
|
|
149
|
+
this.opCode = msgHeader.opCode;
|
|
150
|
+
this.fromCompressed = msgHeader.fromCompressed;
|
|
151
|
+
|
|
152
|
+
// Read response flags
|
|
153
|
+
this.responseFlags = msgBody.readInt32LE(0);
|
|
154
|
+
this.checksumPresent = (this.responseFlags & OPTS_CHECKSUM_PRESENT) !== 0;
|
|
155
|
+
this.moreToCome = (this.responseFlags & OPTS_MORE_TO_COME) !== 0;
|
|
156
|
+
this.exhaustAllowed = (this.responseFlags & OPTS_EXHAUST_ALLOWED) !== 0;
|
|
157
|
+
this.promoteLongs = typeof opts.promoteLongs === 'boolean' ? opts.promoteLongs : true;
|
|
158
|
+
this.promoteValues = typeof opts.promoteValues === 'boolean' ? opts.promoteValues : true;
|
|
159
|
+
this.promoteBuffers = typeof opts.promoteBuffers === 'boolean' ? opts.promoteBuffers : false;
|
|
160
|
+
|
|
161
|
+
this.documents = [];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
isParsed() {
|
|
165
|
+
return this.parsed;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
parse(options) {
|
|
169
|
+
// Don't parse again if not needed
|
|
170
|
+
if (this.parsed) return;
|
|
171
|
+
options = options || {};
|
|
172
|
+
|
|
173
|
+
this.index = 4;
|
|
174
|
+
// Allow the return of raw documents instead of parsing
|
|
175
|
+
const raw = options.raw || false;
|
|
176
|
+
const documentsReturnedIn = options.documentsReturnedIn || null;
|
|
177
|
+
const promoteLongs =
|
|
178
|
+
typeof options.promoteLongs === 'boolean' ? options.promoteLongs : this.opts.promoteLongs;
|
|
179
|
+
const promoteValues =
|
|
180
|
+
typeof options.promoteValues === 'boolean' ? options.promoteValues : this.opts.promoteValues;
|
|
181
|
+
const promoteBuffers =
|
|
182
|
+
typeof options.promoteBuffers === 'boolean'
|
|
183
|
+
? options.promoteBuffers
|
|
184
|
+
: this.opts.promoteBuffers;
|
|
185
|
+
|
|
186
|
+
// Set up the options
|
|
187
|
+
const _options = {
|
|
188
|
+
promoteLongs: promoteLongs,
|
|
189
|
+
promoteValues: promoteValues,
|
|
190
|
+
promoteBuffers: promoteBuffers
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
while (this.index < this.data.length) {
|
|
194
|
+
const payloadType = this.data.readUInt8(this.index++);
|
|
195
|
+
if (payloadType === 1) {
|
|
196
|
+
console.error('TYPE 1');
|
|
197
|
+
} else if (payloadType === 0) {
|
|
198
|
+
const bsonSize = this.data.readUInt32LE(this.index);
|
|
199
|
+
const bin = this.data.slice(this.index, this.index + bsonSize);
|
|
200
|
+
this.documents.push(raw ? bin : this.bson.deserialize(bin, _options));
|
|
201
|
+
|
|
202
|
+
this.index += bsonSize;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (this.documents.length === 1 && documentsReturnedIn != null && raw) {
|
|
207
|
+
const fieldsAsRaw = {};
|
|
208
|
+
fieldsAsRaw[documentsReturnedIn] = true;
|
|
209
|
+
_options.fieldsAsRaw = fieldsAsRaw;
|
|
210
|
+
|
|
211
|
+
const doc = this.bson.deserialize(this.documents[0], _options);
|
|
212
|
+
this.documents = [doc];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this.parsed = true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = { Msg, BinMsg };
|