3 var MongoError = require('../error');
5 // Wire command operation ids
10 var Insert = function(requestId, ismaster, bson, ns, documents, options) {
11 // Basic options needed to be passed in
12 if(ns == null) throw new MongoError("ns must be specified for query");
13 if(!Array.isArray(documents) || documents.length == 0) throw new MongoError("documents array must contain at least one document to insert");
15 // Validate that we are not passing 0x00 in the colletion name
16 if(!!~ns.indexOf("\x00")) {
17 throw new MongoError("namespace cannot contain a null character");
21 this.requestId = requestId;
24 this.documents = documents;
25 this.ismaster = ismaster;
27 // Ensure empty options
28 options = options || {};
31 this.serializeFunctions = typeof options.serializeFunctions == 'boolean' ? options.serializeFunctions : false;
32 this.ignoreUndefined = typeof options.ignoreUndefined == 'boolean' ? options.ignoreUndefined : false;
33 this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : true;
34 this.continueOnError = typeof options.continueOnError == 'boolean' ? options.continueOnError : false;
36 this.flags = this.continueOnError ? 1 : 0;
40 Insert.prototype.toBin = function() {
41 // Contains all the buffers to be written
45 var header = new Buffer(
48 + Buffer.byteLength(this.ns) + 1 // namespace
51 // Add header to buffers
54 // Total length of the message
55 var totalLength = header.length;
57 // Serialize all the documents
58 for(var i = 0; i < this.documents.length; i++) {
59 var buffer = this.bson.serialize(this.documents[i]
62 , this.serializeFunctions
63 , 0, this.ignoreUndefined);
65 // Document is larger than maxBsonObjectSize, terminate serialization
66 if(buffer.length > this.ismaster.maxBsonObjectSize) {
67 throw new MongoError("Document exceeds maximum allowed bson size of " + this.ismaster.maxBsonObjectSize + " bytes");
70 // Add to total length of wire protocol message
71 totalLength = totalLength + buffer.length;
76 // Command is larger than maxMessageSizeBytes terminate serialization
77 if(totalLength > this.ismaster.maxMessageSizeBytes) {
78 throw new MongoError("Command exceeds maximum message size of " + this.ismaster.maxMessageSizeBytes + " bytes");
81 // Add all the metadata
84 // Write header length
85 header[index + 3] = (totalLength >> 24) & 0xff;
86 header[index + 2] = (totalLength >> 16) & 0xff;
87 header[index + 1] = (totalLength >> 8) & 0xff;
88 header[index] = (totalLength) & 0xff;
91 // Write header requestId
92 header[index + 3] = (this.requestId >> 24) & 0xff;
93 header[index + 2] = (this.requestId >> 16) & 0xff;
94 header[index + 1] = (this.requestId >> 8) & 0xff;
95 header[index] = (this.requestId) & 0xff;
99 header[index + 3] = (0 >> 24) & 0xff;
100 header[index + 2] = (0 >> 16) & 0xff;
101 header[index + 1] = (0 >> 8) & 0xff;
102 header[index] = (0) & 0xff;
106 header[index + 3] = (OP_INSERT >> 24) & 0xff;
107 header[index + 2] = (OP_INSERT >> 16) & 0xff;
108 header[index + 1] = (OP_INSERT >> 8) & 0xff;
109 header[index] = (OP_INSERT) & 0xff;
113 header[index + 3] = (this.flags >> 24) & 0xff;
114 header[index + 2] = (this.flags >> 16) & 0xff;
115 header[index + 1] = (this.flags >> 8) & 0xff;
116 header[index] = (this.flags) & 0xff;
119 // Write collection name
120 index = index + header.write(this.ns, index, 'utf8') + 1;
121 header[index - 1] = 0;
123 // Return the buffers
127 var Update = function(requestId, ismaster, bson, ns, update, options) {
128 // Basic options needed to be passed in
129 if(ns == null) throw new MongoError("ns must be specified for query");
131 // Ensure empty options
132 options = options || {};
135 this.requestId = requestId;
138 this.ismaster = ismaster;
141 this.serializeFunctions = typeof options.serializeFunctions == 'boolean' ? options.serializeFunctions : false;
142 this.ignoreUndefined = typeof options.ignoreUndefined == 'boolean' ? options.ignoreUndefined : false;
143 this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : false;
145 // Unpack the update document
146 this.upsert = typeof update[0].upsert == 'boolean' ? update[0].upsert : false;
147 this.multi = typeof update[0].multi == 'boolean' ? update[0].multi : false;
148 this.q = update[0].q;
149 this.u = update[0].u;
152 this.flags = this.upsert ? 1 : 0;
153 this.flags = this.multi ? this.flags | 2 : this.flags;
157 Update.prototype.toBin = function() {
158 // Contains all the buffers to be written
162 var header = new Buffer(
165 + Buffer.byteLength(this.ns) + 1 // namespace
169 // Add header to buffers
170 buffers.push(header);
172 // Total length of the message
173 var totalLength = header.length;
175 // Serialize the selector
176 var selector = this.bson.serialize(this.q
179 , this.serializeFunctions
180 , 0, this.ignoreUndefined);
181 buffers.push(selector);
182 totalLength = totalLength + selector.length;
184 // Serialize the update
185 var update = this.bson.serialize(this.u
188 , this.serializeFunctions
189 , 0, this.ignoreUndefined);
190 buffers.push(update);
191 totalLength = totalLength + update.length;
193 // Index in header buffer
196 // Write header length
197 header[index + 3] = (totalLength >> 24) & 0xff;
198 header[index + 2] = (totalLength >> 16) & 0xff;
199 header[index + 1] = (totalLength >> 8) & 0xff;
200 header[index] = (totalLength) & 0xff;
203 // Write header requestId
204 header[index + 3] = (this.requestId >> 24) & 0xff;
205 header[index + 2] = (this.requestId >> 16) & 0xff;
206 header[index + 1] = (this.requestId >> 8) & 0xff;
207 header[index] = (this.requestId) & 0xff;
211 header[index + 3] = (0 >> 24) & 0xff;
212 header[index + 2] = (0 >> 16) & 0xff;
213 header[index + 1] = (0 >> 8) & 0xff;
214 header[index] = (0) & 0xff;
218 header[index + 3] = (OP_UPDATE >> 24) & 0xff;
219 header[index + 2] = (OP_UPDATE >> 16) & 0xff;
220 header[index + 1] = (OP_UPDATE >> 8) & 0xff;
221 header[index] = (OP_UPDATE) & 0xff;
225 header[index + 3] = (0 >> 24) & 0xff;
226 header[index + 2] = (0 >> 16) & 0xff;
227 header[index + 1] = (0 >> 8) & 0xff;
228 header[index] = (0) & 0xff;
231 // Write collection name
232 index = index + header.write(this.ns, index, 'utf8') + 1;
233 header[index - 1] = 0;
236 header[index + 3] = (this.flags >> 24) & 0xff;
237 header[index + 2] = (this.flags >> 16) & 0xff;
238 header[index + 1] = (this.flags >> 8) & 0xff;
239 header[index] = (this.flags) & 0xff;
242 // Return the buffers
246 var Remove = function(requestId, ismaster, bson, ns, remove, options) {
247 // Basic options needed to be passed in
248 if(ns == null) throw new MongoError("ns must be specified for query");
250 // Ensure empty options
251 options = options || {};
254 this.requestId = requestId;
257 this.ismaster = ismaster;
260 this.serializeFunctions = typeof options.serializeFunctions == 'boolean' ? options.serializeFunctions : false;
261 this.ignoreUndefined = typeof options.ignoreUndefined == 'boolean' ? options.ignoreUndefined : false;
262 this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : false;
264 // Unpack the update document
265 this.limit = typeof remove[0].limit == 'number' ? remove[0].limit : 1;
266 this.q = remove[0].q;
269 this.flags = this.limit == 1 ? 1 : 0;
273 Remove.prototype.toBin = function() {
274 // Contains all the buffers to be written
278 var header = new Buffer(
281 + Buffer.byteLength(this.ns) + 1 // namespace
285 // Add header to buffers
286 buffers.push(header);
288 // Total length of the message
289 var totalLength = header.length;
291 // Serialize the selector
292 var selector = this.bson.serialize(this.q
295 , this.serializeFunctions
296 , 0, this.ignoreUndefined);
297 buffers.push(selector);
298 totalLength = totalLength + selector.length;
300 // Index in header buffer
303 // Write header length
304 header[index + 3] = (totalLength >> 24) & 0xff;
305 header[index + 2] = (totalLength >> 16) & 0xff;
306 header[index + 1] = (totalLength >> 8) & 0xff;
307 header[index] = (totalLength) & 0xff;
310 // Write header requestId
311 header[index + 3] = (this.requestId >> 24) & 0xff;
312 header[index + 2] = (this.requestId >> 16) & 0xff;
313 header[index + 1] = (this.requestId >> 8) & 0xff;
314 header[index] = (this.requestId) & 0xff;
318 header[index + 3] = (0 >> 24) & 0xff;
319 header[index + 2] = (0 >> 16) & 0xff;
320 header[index + 1] = (0 >> 8) & 0xff;
321 header[index] = (0) & 0xff;
325 header[index + 3] = (OP_DELETE >> 24) & 0xff;
326 header[index + 2] = (OP_DELETE >> 16) & 0xff;
327 header[index + 1] = (OP_DELETE >> 8) & 0xff;
328 header[index] = (OP_DELETE) & 0xff;
332 header[index + 3] = (0 >> 24) & 0xff;
333 header[index + 2] = (0 >> 16) & 0xff;
334 header[index + 1] = (0 >> 8) & 0xff;
335 header[index] = (0) & 0xff;
338 // Write collection name
339 index = index + header.write(this.ns, index, 'utf8') + 1;
340 header[index - 1] = 0;
343 header[index + 3] = (this.flags >> 24) & 0xff;
344 header[index + 2] = (this.flags >> 16) & 0xff;
345 header[index + 1] = (this.flags >> 8) & 0xff;
346 header[index] = (this.flags) & 0xff;
349 // Return the buffers