123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- "use strict";
- var MongoError = require('../error');
- // Wire command operation ids
- var OP_UPDATE = 2001;
- var OP_INSERT = 2002;
- var OP_DELETE = 2006;
- var Insert = function(requestId, ismaster, bson, ns, documents, options) {
- // Basic options needed to be passed in
- if(ns == null) throw new MongoError("ns must be specified for query");
- if(!Array.isArray(documents) || documents.length == 0) throw new MongoError("documents array must contain at least one document to insert");
- // Validate that we are not passing 0x00 in the collection name
- if(!!~ns.indexOf("\x00")) {
- throw new MongoError("namespace cannot contain a null character");
- }
- // Set internal
- this.requestId = requestId;
- this.bson = bson;
- this.ns = ns;
- this.documents = documents;
- this.ismaster = ismaster;
- // Ensure empty options
- options = options || {};
- // Unpack options
- this.serializeFunctions = typeof options.serializeFunctions == 'boolean' ? options.serializeFunctions : false;
- this.ignoreUndefined = typeof options.ignoreUndefined == 'boolean' ? options.ignoreUndefined : false;
- this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : true;
- this.continueOnError = typeof options.continueOnError == 'boolean' ? options.continueOnError : false;
- // Set flags
- this.flags = this.continueOnError ? 1 : 0;
- }
- // To Binary
- Insert.prototype.toBin = function() {
- // Contains all the buffers to be written
- var buffers = [];
- // Header buffer
- var header = new Buffer(
- 4 * 4 // Header
- + 4 // Flags
- + Buffer.byteLength(this.ns) + 1 // namespace
- );
- // Add header to buffers
- buffers.push(header);
- // Total length of the message
- var totalLength = header.length;
- // Serialize all the documents
- for(var i = 0; i < this.documents.length; i++) {
- var buffer = this.bson.serialize(this.documents[i], {
- checkKeys: this.checkKeys,
- serializeFunctions: this.serializeFunctions,
- ignoreUndefined: this.ignoreUndefined,
- });
- // Document is larger than maxBsonObjectSize, terminate serialization
- if(buffer.length > this.ismaster.maxBsonObjectSize) {
- throw new MongoError("Document exceeds maximum allowed bson size of " + this.ismaster.maxBsonObjectSize + " bytes");
- }
- // Add to total length of wire protocol message
- totalLength = totalLength + buffer.length;
- // Add to buffer
- buffers.push(buffer);
- }
- // Command is larger than maxMessageSizeBytes terminate serialization
- if(totalLength > this.ismaster.maxMessageSizeBytes) {
- throw new MongoError("Command exceeds maximum message size of " + this.ismaster.maxMessageSizeBytes + " bytes");
- }
- // Add all the metadata
- var index = 0;
- // Write header length
- header[index + 3] = (totalLength >> 24) & 0xff;
- header[index + 2] = (totalLength >> 16) & 0xff;
- header[index + 1] = (totalLength >> 8) & 0xff;
- header[index] = (totalLength) & 0xff;
- index = index + 4;
- // Write header requestId
- header[index + 3] = (this.requestId >> 24) & 0xff;
- header[index + 2] = (this.requestId >> 16) & 0xff;
- header[index + 1] = (this.requestId >> 8) & 0xff;
- header[index] = (this.requestId) & 0xff;
- index = index + 4;
- // No flags
- header[index + 3] = (0 >> 24) & 0xff;
- header[index + 2] = (0 >> 16) & 0xff;
- header[index + 1] = (0 >> 8) & 0xff;
- header[index] = (0) & 0xff;
- index = index + 4;
- // Operation
- header[index + 3] = (OP_INSERT >> 24) & 0xff;
- header[index + 2] = (OP_INSERT >> 16) & 0xff;
- header[index + 1] = (OP_INSERT >> 8) & 0xff;
- header[index] = (OP_INSERT) & 0xff;
- index = index + 4;
- // Flags
- header[index + 3] = (this.flags >> 24) & 0xff;
- header[index + 2] = (this.flags >> 16) & 0xff;
- header[index + 1] = (this.flags >> 8) & 0xff;
- header[index] = (this.flags) & 0xff;
- index = index + 4;
- // Write collection name
- index = index + header.write(this.ns, index, 'utf8') + 1;
- header[index - 1] = 0;
- // Return the buffers
- return buffers;
- }
- var Update = function(requestId, ismaster, bson, ns, update, options) {
- // Basic options needed to be passed in
- if(ns == null) throw new MongoError("ns must be specified for query");
- // Ensure empty options
- options = options || {};
- // Set internal
- this.requestId = requestId;
- this.bson = bson;
- this.ns = ns;
- this.ismaster = ismaster;
- // Unpack options
- this.serializeFunctions = typeof options.serializeFunctions == 'boolean' ? options.serializeFunctions : false;
- this.ignoreUndefined = typeof options.ignoreUndefined == 'boolean' ? options.ignoreUndefined : false;
- this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : false;
- // Unpack the update document
- this.upsert = typeof update[0].upsert == 'boolean' ? update[0].upsert : false;
- this.multi = typeof update[0].multi == 'boolean' ? update[0].multi : false;
- this.q = update[0].q;
- this.u = update[0].u;
- // Create flag value
- this.flags = this.upsert ? 1 : 0;
- this.flags = this.multi ? this.flags | 2 : this.flags;
- }
- // To Binary
- Update.prototype.toBin = function() {
- // Contains all the buffers to be written
- var buffers = [];
- // Header buffer
- var header = new Buffer(
- 4 * 4 // Header
- + 4 // ZERO
- + Buffer.byteLength(this.ns) + 1 // namespace
- + 4 // Flags
- );
- // Add header to buffers
- buffers.push(header);
- // Total length of the message
- var totalLength = header.length;
- // Serialize the selector
- var selector = this.bson.serialize(this.q, {
- checkKeys: this.checkKeys,
- serializeFunctions: this.serializeFunctions,
- ignoreUndefined: this.ignoreUndefined,
- });
- buffers.push(selector);
- totalLength = totalLength + selector.length;
- // Serialize the update
- var update = this.bson.serialize(this.u, {
- checkKeys: this.checkKeys,
- serializeFunctions: this.serializeFunctions,
- ignoreUndefined: this.ignoreUndefined,
- });
- buffers.push(update);
- totalLength = totalLength + update.length;
- // Index in header buffer
- var index = 0;
- // Write header length
- header[index + 3] = (totalLength >> 24) & 0xff;
- header[index + 2] = (totalLength >> 16) & 0xff;
- header[index + 1] = (totalLength >> 8) & 0xff;
- header[index] = (totalLength) & 0xff;
- index = index + 4;
- // Write header requestId
- header[index + 3] = (this.requestId >> 24) & 0xff;
- header[index + 2] = (this.requestId >> 16) & 0xff;
- header[index + 1] = (this.requestId >> 8) & 0xff;
- header[index] = (this.requestId) & 0xff;
- index = index + 4;
- // No flags
- header[index + 3] = (0 >> 24) & 0xff;
- header[index + 2] = (0 >> 16) & 0xff;
- header[index + 1] = (0 >> 8) & 0xff;
- header[index] = (0) & 0xff;
- index = index + 4;
- // Operation
- header[index + 3] = (OP_UPDATE >> 24) & 0xff;
- header[index + 2] = (OP_UPDATE >> 16) & 0xff;
- header[index + 1] = (OP_UPDATE >> 8) & 0xff;
- header[index] = (OP_UPDATE) & 0xff;
- index = index + 4;
- // Write ZERO
- header[index + 3] = (0 >> 24) & 0xff;
- header[index + 2] = (0 >> 16) & 0xff;
- header[index + 1] = (0 >> 8) & 0xff;
- header[index] = (0) & 0xff;
- index = index + 4;
- // Write collection name
- index = index + header.write(this.ns, index, 'utf8') + 1;
- header[index - 1] = 0;
- // Flags
- header[index + 3] = (this.flags >> 24) & 0xff;
- header[index + 2] = (this.flags >> 16) & 0xff;
- header[index + 1] = (this.flags >> 8) & 0xff;
- header[index] = (this.flags) & 0xff;
- index = index + 4;
- // Return the buffers
- return buffers;
- }
- var Remove = function(requestId, ismaster, bson, ns, remove, options) {
- // Basic options needed to be passed in
- if(ns == null) throw new MongoError("ns must be specified for query");
- // Ensure empty options
- options = options || {};
- // Set internal
- this.requestId = requestId;
- this.bson = bson;
- this.ns = ns;
- this.ismaster = ismaster;
- // Unpack options
- this.serializeFunctions = typeof options.serializeFunctions == 'boolean' ? options.serializeFunctions : false;
- this.ignoreUndefined = typeof options.ignoreUndefined == 'boolean' ? options.ignoreUndefined : false;
- this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : false;
- // Unpack the update document
- this.limit = typeof remove[0].limit == 'number' ? remove[0].limit : 1;
- this.q = remove[0].q;
- // Create flag value
- this.flags = this.limit == 1 ? 1 : 0;
- }
- // To Binary
- Remove.prototype.toBin = function() {
- // Contains all the buffers to be written
- var buffers = [];
- // Header buffer
- var header = new Buffer(
- 4 * 4 // Header
- + 4 // ZERO
- + Buffer.byteLength(this.ns) + 1 // namespace
- + 4 // Flags
- );
- // Add header to buffers
- buffers.push(header);
- // Total length of the message
- var totalLength = header.length;
- // Serialize the selector
- var selector = this.bson.serialize(this.q, {
- checkKeys: this.checkKeys,
- serializeFunctions: this.serializeFunctions,
- ignoreUndefined: this.ignoreUndefined,
- });
- buffers.push(selector);
- totalLength = totalLength + selector.length;
- // Index in header buffer
- var index = 0;
- // Write header length
- header[index + 3] = (totalLength >> 24) & 0xff;
- header[index + 2] = (totalLength >> 16) & 0xff;
- header[index + 1] = (totalLength >> 8) & 0xff;
- header[index] = (totalLength) & 0xff;
- index = index + 4;
- // Write header requestId
- header[index + 3] = (this.requestId >> 24) & 0xff;
- header[index + 2] = (this.requestId >> 16) & 0xff;
- header[index + 1] = (this.requestId >> 8) & 0xff;
- header[index] = (this.requestId) & 0xff;
- index = index + 4;
- // No flags
- header[index + 3] = (0 >> 24) & 0xff;
- header[index + 2] = (0 >> 16) & 0xff;
- header[index + 1] = (0 >> 8) & 0xff;
- header[index] = (0) & 0xff;
- index = index + 4;
- // Operation
- header[index + 3] = (OP_DELETE >> 24) & 0xff;
- header[index + 2] = (OP_DELETE >> 16) & 0xff;
- header[index + 1] = (OP_DELETE >> 8) & 0xff;
- header[index] = (OP_DELETE) & 0xff;
- index = index + 4;
- // Write ZERO
- header[index + 3] = (0 >> 24) & 0xff;
- header[index + 2] = (0 >> 16) & 0xff;
- header[index + 1] = (0 >> 8) & 0xff;
- header[index] = (0) & 0xff;
- index = index + 4;
- // Write collection name
- index = index + header.write(this.ns, index, 'utf8') + 1;
- header[index - 1] = 0;
- // Write ZERO
- header[index + 3] = (this.flags >> 24) & 0xff;
- header[index + 2] = (this.flags >> 16) & 0xff;
- header[index + 1] = (this.flags >> 8) & 0xff;
- header[index] = (this.flags) & 0xff;
- index = index + 4;
- // Return the buffers
- return buffers;
- }
- module.exports = {
- Insert: Insert
- , Update: Update
- , Remove: Remove
- }
|