mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-13 03:02:49 +00:00
updated bunch of file paths and changed the way posts are loaded
This commit is contained in:
539
node_modules/mongodb-core/lib/connection/commands.js
generated
vendored
Normal file
539
node_modules/mongodb-core/lib/connection/commands.js
generated
vendored
Normal file
@@ -0,0 +1,539 @@
|
||||
"use strict";
|
||||
|
||||
var f = require('util').format
|
||||
, Long = require('bson').Long
|
||||
, setProperty = require('./utils').setProperty
|
||||
, getProperty = require('./utils').getProperty
|
||||
, getSingleProperty = require('./utils').getSingleProperty;
|
||||
|
||||
// Incrementing request id
|
||||
var _requestId = 0;
|
||||
|
||||
// Wire command operation ids
|
||||
var OP_QUERY = 2004;
|
||||
var OP_GETMORE = 2005;
|
||||
var OP_KILL_CURSORS = 2007;
|
||||
|
||||
// Query flags
|
||||
var OPTS_NONE = 0;
|
||||
var OPTS_TAILABLE_CURSOR = 2;
|
||||
var OPTS_SLAVE = 4;
|
||||
var OPTS_OPLOG_REPLAY = 8;
|
||||
var OPTS_NO_CURSOR_TIMEOUT = 16;
|
||||
var OPTS_AWAIT_DATA = 32;
|
||||
var OPTS_EXHAUST = 64;
|
||||
var OPTS_PARTIAL = 128;
|
||||
|
||||
// Response flags
|
||||
var CURSOR_NOT_FOUND = 0;
|
||||
var QUERY_FAILURE = 2;
|
||||
var SHARD_CONFIG_STALE = 4;
|
||||
var AWAIT_CAPABLE = 8;
|
||||
|
||||
/**************************************************************
|
||||
* QUERY
|
||||
**************************************************************/
|
||||
var Query = function(bson, ns, query, options) {
|
||||
var self = this;
|
||||
// Basic options needed to be passed in
|
||||
if(ns == null) throw new Error("ns must be specified for query");
|
||||
if(query == null) throw new Error("query must be specified for query");
|
||||
|
||||
// Validate that we are not passing 0x00 in the colletion name
|
||||
if(!!~ns.indexOf("\x00")) {
|
||||
throw new Error("namespace cannot contain a null character");
|
||||
}
|
||||
|
||||
// Basic options
|
||||
this.bson = bson;
|
||||
this.ns = ns;
|
||||
this.query = query;
|
||||
|
||||
// Ensure empty options
|
||||
this.options = options || {};
|
||||
|
||||
// Additional options
|
||||
this.numberToSkip = options.numberToSkip || 0;
|
||||
this.numberToReturn = options.numberToReturn || 0;
|
||||
this.returnFieldSelector = options.returnFieldSelector || null;
|
||||
this.requestId = _requestId++;
|
||||
|
||||
// Serialization option
|
||||
this.serializeFunctions = typeof options.serializeFunctions == 'boolean' ? options.serializeFunctions : false;
|
||||
this.ignoreUndefined = typeof options.ignoreUndefined == 'boolean' ? options.ignoreUndefined : false;
|
||||
this.maxBsonSize = options.maxBsonSize || 1024 * 1024 * 16;
|
||||
this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : true;
|
||||
this.batchSize = self.numberToReturn;
|
||||
|
||||
// Flags
|
||||
this.tailable = false;
|
||||
this.slaveOk = false;
|
||||
this.oplogReplay = false;
|
||||
this.noCursorTimeout = false;
|
||||
this.awaitData = false;
|
||||
this.exhaust = false;
|
||||
this.partial = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Assign a new request Id
|
||||
Query.prototype.incRequestId = function() {
|
||||
this.requestId = _requestId++;
|
||||
}
|
||||
|
||||
//
|
||||
// Assign a new request Id
|
||||
Query.nextRequestId = function() {
|
||||
return _requestId + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Uses a single allocated buffer for the process, avoiding multiple memory allocations
|
||||
Query.prototype.toBin = function() {
|
||||
var self = this;
|
||||
var buffers = [];
|
||||
var projection = null;
|
||||
|
||||
// Set up the flags
|
||||
var flags = 0;
|
||||
if(this.tailable) {
|
||||
flags |= OPTS_TAILABLE_CURSOR;
|
||||
}
|
||||
|
||||
if(this.slaveOk) {
|
||||
flags |= OPTS_SLAVE;
|
||||
}
|
||||
|
||||
if(this.oplogReplay) {
|
||||
flags |= OPTS_OPLOG_REPLAY;
|
||||
}
|
||||
|
||||
if(this.noCursorTimeout) {
|
||||
flags |= OPTS_NO_CURSOR_TIMEOUT;
|
||||
}
|
||||
|
||||
if(this.awaitData) {
|
||||
flags |= OPTS_AWAIT_DATA;
|
||||
}
|
||||
|
||||
if(this.exhaust) {
|
||||
flags |= OPTS_EXHAUST;
|
||||
}
|
||||
|
||||
if(this.partial) {
|
||||
flags |= OPTS_PARTIAL;
|
||||
}
|
||||
|
||||
// If batchSize is different to self.numberToReturn
|
||||
if(self.batchSize != self.numberToReturn) self.numberToReturn = self.batchSize;
|
||||
|
||||
// Allocate write protocol header buffer
|
||||
var header = new Buffer(
|
||||
4 * 4 // Header
|
||||
+ 4 // Flags
|
||||
+ Buffer.byteLength(self.ns) + 1 // namespace
|
||||
+ 4 // numberToSkip
|
||||
+ 4 // numberToReturn
|
||||
);
|
||||
|
||||
// Add header to buffers
|
||||
buffers.push(header);
|
||||
|
||||
// Serialize the query
|
||||
var query = self.bson.serialize(this.query
|
||||
, this.checkKeys
|
||||
, true
|
||||
, this.serializeFunctions
|
||||
, 0, this.ignoreUndefined);
|
||||
|
||||
// Add query document
|
||||
buffers.push(query);
|
||||
|
||||
if(self.returnFieldSelector && Object.keys(self.returnFieldSelector).length > 0) {
|
||||
// Serialize the projection document
|
||||
projection = self.bson.serialize(this.returnFieldSelector, this.checkKeys, true, this.serializeFunctions, this.ignoreUndefined);
|
||||
// Add projection document
|
||||
buffers.push(projection);
|
||||
}
|
||||
|
||||
// Total message size
|
||||
var totalLength = header.length + query.length + (projection ? projection.length : 0);
|
||||
|
||||
// Set up the index
|
||||
var index = 4;
|
||||
|
||||
// Write total document length
|
||||
header[3] = (totalLength >> 24) & 0xff;
|
||||
header[2] = (totalLength >> 16) & 0xff;
|
||||
header[1] = (totalLength >> 8) & 0xff;
|
||||
header[0] = (totalLength) & 0xff;
|
||||
|
||||
// Write header information 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;
|
||||
|
||||
// Write header information responseTo
|
||||
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 header information OP_QUERY
|
||||
header[index + 3] = (OP_QUERY >> 24) & 0xff;
|
||||
header[index + 2] = (OP_QUERY >> 16) & 0xff;
|
||||
header[index + 1] = (OP_QUERY >> 8) & 0xff;
|
||||
header[index] = (OP_QUERY) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Write header information flags
|
||||
header[index + 3] = (flags >> 24) & 0xff;
|
||||
header[index + 2] = (flags >> 16) & 0xff;
|
||||
header[index + 1] = (flags >> 8) & 0xff;
|
||||
header[index] = (flags) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Write collection name
|
||||
index = index + header.write(this.ns, index, 'utf8') + 1;
|
||||
header[index - 1] = 0;
|
||||
|
||||
// Write header information flags numberToSkip
|
||||
header[index + 3] = (this.numberToSkip >> 24) & 0xff;
|
||||
header[index + 2] = (this.numberToSkip >> 16) & 0xff;
|
||||
header[index + 1] = (this.numberToSkip >> 8) & 0xff;
|
||||
header[index] = (this.numberToSkip) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Write header information flags numberToReturn
|
||||
header[index + 3] = (this.numberToReturn >> 24) & 0xff;
|
||||
header[index + 2] = (this.numberToReturn >> 16) & 0xff;
|
||||
header[index + 1] = (this.numberToReturn >> 8) & 0xff;
|
||||
header[index] = (this.numberToReturn) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Return the buffers
|
||||
return buffers;
|
||||
}
|
||||
|
||||
Query.getRequestId = function() {
|
||||
return ++_requestId;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
* GETMORE
|
||||
**************************************************************/
|
||||
var GetMore = function(bson, ns, cursorId, opts) {
|
||||
opts = opts || {};
|
||||
this.numberToReturn = opts.numberToReturn || 0;
|
||||
this.requestId = _requestId++;
|
||||
this.bson = bson;
|
||||
this.ns = ns;
|
||||
this.cursorId = cursorId;
|
||||
}
|
||||
|
||||
//
|
||||
// Uses a single allocated buffer for the process, avoiding multiple memory allocations
|
||||
GetMore.prototype.toBin = function() {
|
||||
var length = 4 + Buffer.byteLength(this.ns) + 1 + 4 + 8 + (4 * 4);
|
||||
// Create command buffer
|
||||
var index = 0;
|
||||
// Allocate buffer
|
||||
var _buffer = new Buffer(length);
|
||||
|
||||
// Write header information
|
||||
// index = write32bit(index, _buffer, length);
|
||||
_buffer[index + 3] = (length >> 24) & 0xff;
|
||||
_buffer[index + 2] = (length >> 16) & 0xff;
|
||||
_buffer[index + 1] = (length >> 8) & 0xff;
|
||||
_buffer[index] = (length) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, requestId);
|
||||
_buffer[index + 3] = (this.requestId >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.requestId >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.requestId >> 8) & 0xff;
|
||||
_buffer[index] = (this.requestId) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, 0);
|
||||
_buffer[index + 3] = (0 >> 24) & 0xff;
|
||||
_buffer[index + 2] = (0 >> 16) & 0xff;
|
||||
_buffer[index + 1] = (0 >> 8) & 0xff;
|
||||
_buffer[index] = (0) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, OP_GETMORE);
|
||||
_buffer[index + 3] = (OP_GETMORE >> 24) & 0xff;
|
||||
_buffer[index + 2] = (OP_GETMORE >> 16) & 0xff;
|
||||
_buffer[index + 1] = (OP_GETMORE >> 8) & 0xff;
|
||||
_buffer[index] = (OP_GETMORE) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, 0);
|
||||
_buffer[index + 3] = (0 >> 24) & 0xff;
|
||||
_buffer[index + 2] = (0 >> 16) & 0xff;
|
||||
_buffer[index + 1] = (0 >> 8) & 0xff;
|
||||
_buffer[index] = (0) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Write collection name
|
||||
index = index + _buffer.write(this.ns, index, 'utf8') + 1;
|
||||
_buffer[index - 1] = 0;
|
||||
|
||||
// Write batch size
|
||||
// index = write32bit(index, _buffer, numberToReturn);
|
||||
_buffer[index + 3] = (this.numberToReturn >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.numberToReturn >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.numberToReturn >> 8) & 0xff;
|
||||
_buffer[index] = (this.numberToReturn) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Write cursor id
|
||||
// index = write32bit(index, _buffer, cursorId.getLowBits());
|
||||
_buffer[index + 3] = (this.cursorId.getLowBits() >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.cursorId.getLowBits() >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.cursorId.getLowBits() >> 8) & 0xff;
|
||||
_buffer[index] = (this.cursorId.getLowBits()) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, cursorId.getHighBits());
|
||||
_buffer[index + 3] = (this.cursorId.getHighBits() >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.cursorId.getHighBits() >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.cursorId.getHighBits() >> 8) & 0xff;
|
||||
_buffer[index] = (this.cursorId.getHighBits()) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Return buffer
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
* KILLCURSOR
|
||||
**************************************************************/
|
||||
var KillCursor = function(bson, cursorIds) {
|
||||
this.requestId = _requestId++;
|
||||
this.cursorIds = cursorIds;
|
||||
}
|
||||
|
||||
//
|
||||
// Uses a single allocated buffer for the process, avoiding multiple memory allocations
|
||||
KillCursor.prototype.toBin = function() {
|
||||
var length = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8);
|
||||
|
||||
// Create command buffer
|
||||
var index = 0;
|
||||
var _buffer = new Buffer(length);
|
||||
|
||||
// Write header information
|
||||
// index = write32bit(index, _buffer, length);
|
||||
_buffer[index + 3] = (length >> 24) & 0xff;
|
||||
_buffer[index + 2] = (length >> 16) & 0xff;
|
||||
_buffer[index + 1] = (length >> 8) & 0xff;
|
||||
_buffer[index] = (length) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, requestId);
|
||||
_buffer[index + 3] = (this.requestId >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.requestId >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.requestId >> 8) & 0xff;
|
||||
_buffer[index] = (this.requestId) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, 0);
|
||||
_buffer[index + 3] = (0 >> 24) & 0xff;
|
||||
_buffer[index + 2] = (0 >> 16) & 0xff;
|
||||
_buffer[index + 1] = (0 >> 8) & 0xff;
|
||||
_buffer[index] = (0) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, OP_KILL_CURSORS);
|
||||
_buffer[index + 3] = (OP_KILL_CURSORS >> 24) & 0xff;
|
||||
_buffer[index + 2] = (OP_KILL_CURSORS >> 16) & 0xff;
|
||||
_buffer[index + 1] = (OP_KILL_CURSORS >> 8) & 0xff;
|
||||
_buffer[index] = (OP_KILL_CURSORS) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, 0);
|
||||
_buffer[index + 3] = (0 >> 24) & 0xff;
|
||||
_buffer[index + 2] = (0 >> 16) & 0xff;
|
||||
_buffer[index + 1] = (0 >> 8) & 0xff;
|
||||
_buffer[index] = (0) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Write batch size
|
||||
// index = write32bit(index, _buffer, this.cursorIds.length);
|
||||
_buffer[index + 3] = (this.cursorIds.length >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.cursorIds.length >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.cursorIds.length >> 8) & 0xff;
|
||||
_buffer[index] = (this.cursorIds.length) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// Write all the cursor ids into the array
|
||||
for(var i = 0; i < this.cursorIds.length; i++) {
|
||||
// Write cursor id
|
||||
// index = write32bit(index, _buffer, cursorIds[i].getLowBits());
|
||||
_buffer[index + 3] = (this.cursorIds[i].getLowBits() >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.cursorIds[i].getLowBits() >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.cursorIds[i].getLowBits() >> 8) & 0xff;
|
||||
_buffer[index] = (this.cursorIds[i].getLowBits()) & 0xff;
|
||||
index = index + 4;
|
||||
|
||||
// index = write32bit(index, _buffer, cursorIds[i].getHighBits());
|
||||
_buffer[index + 3] = (this.cursorIds[i].getHighBits() >> 24) & 0xff;
|
||||
_buffer[index + 2] = (this.cursorIds[i].getHighBits() >> 16) & 0xff;
|
||||
_buffer[index + 1] = (this.cursorIds[i].getHighBits() >> 8) & 0xff;
|
||||
_buffer[index] = (this.cursorIds[i].getHighBits()) & 0xff;
|
||||
index = index + 4;
|
||||
}
|
||||
|
||||
// Return buffer
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
var Response = function(bson, data, opts) {
|
||||
opts = opts || {promoteLongs: true};
|
||||
this.parsed = false;
|
||||
|
||||
//
|
||||
// Parse Header
|
||||
//
|
||||
this.index = 0;
|
||||
this.raw = data;
|
||||
this.data = data;
|
||||
this.bson = bson;
|
||||
this.opts = opts;
|
||||
|
||||
// Read the message length
|
||||
this.length = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
|
||||
// Fetch the request id for this reply
|
||||
this.requestId = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
|
||||
// Fetch the id of the request that triggered the response
|
||||
this.responseTo = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
|
||||
// Skip op-code field
|
||||
this.index = this.index + 4;
|
||||
|
||||
// Unpack flags
|
||||
this.responseFlags = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
|
||||
// Unpack the cursor
|
||||
var lowBits = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
var highBits = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
// Create long object
|
||||
this.cursorId = new Long(lowBits, highBits);
|
||||
|
||||
// Unpack the starting from
|
||||
this.startingFrom = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
|
||||
// Unpack the number of objects returned
|
||||
this.numberReturned = data[this.index] | data[this.index + 1] << 8 | data[this.index + 2] << 16 | data[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
|
||||
// Preallocate document array
|
||||
this.documents = new Array(this.numberReturned);
|
||||
|
||||
// Flag values
|
||||
this.cursorNotFound = (this.responseFlags & CURSOR_NOT_FOUND) != 0;
|
||||
this.queryFailure = (this.responseFlags & QUERY_FAILURE) != 0;
|
||||
this.shardConfigStale = (this.responseFlags & SHARD_CONFIG_STALE) != 0;
|
||||
this.awaitCapable = (this.responseFlags & AWAIT_CAPABLE) != 0;
|
||||
this.promoteLongs = typeof opts.promoteLongs == 'boolean' ? opts.promoteLongs : true;
|
||||
}
|
||||
|
||||
Response.prototype.isParsed = function() {
|
||||
return this.parsed;
|
||||
}
|
||||
|
||||
// Validation buffers
|
||||
var firstBatch = new Buffer('firstBatch', 'utf8');
|
||||
var nextBatch = new Buffer('nextBatch', 'utf8');
|
||||
var cursorId = new Buffer('id', 'utf8').toString('hex');
|
||||
|
||||
var documentBuffers = {
|
||||
firstBatch: firstBatch.toString('hex'),
|
||||
nextBatch: nextBatch.toString('hex')
|
||||
};
|
||||
|
||||
Response.prototype.parse = function(options) {
|
||||
// Don't parse again if not needed
|
||||
if(this.parsed) return;
|
||||
options = options || {};
|
||||
|
||||
// Allow the return of raw documents instead of parsing
|
||||
var raw = options.raw || false;
|
||||
var documentsReturnedIn = options.documentsReturnedIn || null;
|
||||
|
||||
//
|
||||
// Single document and documentsReturnedIn set
|
||||
//
|
||||
if(this.numberReturned == 1 && documentsReturnedIn != null && raw) {
|
||||
// Calculate the bson size
|
||||
var bsonSize = this.data[this.index] | this.data[this.index + 1] << 8 | this.data[this.index + 2] << 16 | this.data[this.index + 3] << 24;
|
||||
// Slice out the buffer containing the command result document
|
||||
var document = this.data.slice(this.index, this.index + bsonSize);
|
||||
// Set up field we wish to keep as raw
|
||||
var fieldsAsRaw = {}
|
||||
fieldsAsRaw[documentsReturnedIn] = true;
|
||||
// Set up the options
|
||||
var _options = {promoteLongs: this.opts.promoteLongs, fieldsAsRaw: fieldsAsRaw};
|
||||
|
||||
// Deserialize but keep the array of documents in non-parsed form
|
||||
var doc = this.bson.deserialize(document, _options);
|
||||
|
||||
// Get the documents
|
||||
this.documents = doc.cursor[documentsReturnedIn];
|
||||
this.numberReturned = this.documents.length;
|
||||
// Ensure we have a Long valie cursor id
|
||||
this.cursorId = typeof doc.cursor.id == 'number'
|
||||
? Long.fromNumber(doc.cursor.id)
|
||||
: doc.cursor.id;
|
||||
|
||||
// Adjust the index
|
||||
this.index = this.index + bsonSize;
|
||||
|
||||
// Set as parsed
|
||||
this.parsed = true
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse Body
|
||||
//
|
||||
for(var i = 0; i < this.numberReturned; i++) {
|
||||
var bsonSize = this.data[this.index] | this.data[this.index + 1] << 8 | this.data[this.index + 2] << 16 | this.data[this.index + 3] << 24;
|
||||
// Parse options
|
||||
var _options = {promoteLongs: this.opts.promoteLongs};
|
||||
|
||||
// If we have raw results specified slice the return document
|
||||
if(raw) {
|
||||
this.documents[i] = this.data.slice(this.index, this.index + bsonSize);
|
||||
} else {
|
||||
this.documents[i] = this.bson.deserialize(this.data.slice(this.index, this.index + bsonSize), _options);
|
||||
}
|
||||
|
||||
// Adjust the index
|
||||
this.index = this.index + bsonSize;
|
||||
}
|
||||
|
||||
// Set parsed
|
||||
this.parsed = true;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Query: Query
|
||||
, GetMore: GetMore
|
||||
, Response: Response
|
||||
, KillCursor: KillCursor
|
||||
}
|
||||
488
node_modules/mongodb-core/lib/connection/connection.js
generated
vendored
Normal file
488
node_modules/mongodb-core/lib/connection/connection.js
generated
vendored
Normal file
@@ -0,0 +1,488 @@
|
||||
"use strict";
|
||||
|
||||
var inherits = require('util').inherits
|
||||
, EventEmitter = require('events').EventEmitter
|
||||
, net = require('net')
|
||||
, tls = require('tls')
|
||||
, f = require('util').format
|
||||
, getSingleProperty = require('./utils').getSingleProperty
|
||||
, debugOptions = require('./utils').debugOptions
|
||||
, Response = require('./commands').Response
|
||||
, MongoError = require('../error')
|
||||
, Logger = require('./logger');
|
||||
|
||||
var _id = 0;
|
||||
var debugFields = ['host', 'port', 'size', 'keepAlive', 'keepAliveInitialDelay', 'noDelay'
|
||||
, 'connectionTimeout', 'socketTimeout', 'singleBufferSerializtion', 'ssl', 'ca', 'cert'
|
||||
, 'rejectUnauthorized', 'promoteLongs', 'checkServerIdentity'];
|
||||
|
||||
/**
|
||||
* Creates a new Connection instance
|
||||
* @class
|
||||
* @param {string} options.host The server host
|
||||
* @param {number} options.port The server port
|
||||
* @param {number} [options.size=5] Server connection pool size
|
||||
* @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
|
||||
* @param {number} [options.keepAliveInitialDelay=0] Initial delay before TCP keep alive enabled
|
||||
* @param {boolean} [options.noDelay=true] TCP Connection no delay
|
||||
* @param {number} [options.connectionTimeout=0] TCP Connection timeout setting
|
||||
* @param {number} [options.socketTimeout=0] TCP Socket timeout setting
|
||||
* @param {boolean} [options.singleBufferSerializtion=true] Serialize into single buffer, trade of peak memory for serialization speed
|
||||
* @param {boolean} [options.ssl=false] Use SSL for connection
|
||||
* @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function.
|
||||
* @param {Buffer} [options.ca] SSL Certificate store binary buffer
|
||||
* @param {Buffer} [options.cert] SSL Certificate binary buffer
|
||||
* @param {Buffer} [options.key] SSL Key file binary buffer
|
||||
* @param {string} [options.passphrase] SSL Certificate pass phrase
|
||||
* @param {boolean} [options.rejectUnauthorized=true] Reject unauthorized server certificates
|
||||
* @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
|
||||
* @fires Connection#connect
|
||||
* @fires Connection#close
|
||||
* @fires Connection#error
|
||||
* @fires Connection#timeout
|
||||
* @fires Connection#parseError
|
||||
* @return {Connection} A cursor instance
|
||||
*/
|
||||
var Connection = function(options) {
|
||||
// Add event listener
|
||||
EventEmitter.call(this);
|
||||
// Set empty if no options passed
|
||||
this.options = options || {};
|
||||
// Identification information
|
||||
this.id = _id++;
|
||||
// Logger instance
|
||||
this.logger = Logger('Connection', options);
|
||||
// No bson parser passed in
|
||||
if(!options.bson) throw new Error("must pass in valid bson parser");
|
||||
// Get bson parser
|
||||
this.bson = options.bson;
|
||||
// Grouping tag used for debugging purposes
|
||||
this.tag = options.tag;
|
||||
// Message handler
|
||||
this.messageHandler = options.messageHandler;
|
||||
|
||||
// Max BSON message size
|
||||
this.maxBsonMessageSize = options.maxBsonMessageSize || (1024 * 1024 * 16 * 4);
|
||||
// Debug information
|
||||
if(this.logger.isDebug()) this.logger.debug(f('creating connection %s with options [%s]', this.id, JSON.stringify(debugOptions(debugFields, options))));
|
||||
|
||||
// Default options
|
||||
this.port = options.port || 27017;
|
||||
this.host = options.host || 'localhost';
|
||||
this.keepAlive = typeof options.keepAlive == 'boolean' ? options.keepAlive : true;
|
||||
this.keepAliveInitialDelay = options.keepAliveInitialDelay || 0;
|
||||
this.noDelay = typeof options.noDelay == 'boolean' ? options.noDelay : true;
|
||||
this.connectionTimeout = options.connectionTimeout || 0;
|
||||
this.socketTimeout = options.socketTimeout || 0;
|
||||
|
||||
// If connection was destroyed
|
||||
this.destroyed = false;
|
||||
|
||||
// Check if we have a domain socket
|
||||
this.domainSocket = this.host.indexOf('\/') != -1;
|
||||
|
||||
// Serialize commands using function
|
||||
this.singleBufferSerializtion = typeof options.singleBufferSerializtion == 'boolean' ? options.singleBufferSerializtion : true;
|
||||
this.serializationFunction = this.singleBufferSerializtion ? 'toBinUnified' : 'toBin';
|
||||
|
||||
// SSL options
|
||||
this.ca = options.ca || null;
|
||||
this.cert = options.cert || null;
|
||||
this.key = options.key || null;
|
||||
this.passphrase = options.passphrase || null;
|
||||
this.ssl = typeof options.ssl == 'boolean' ? options.ssl : false;
|
||||
this.rejectUnauthorized = typeof options.rejectUnauthorized == 'boolean' ? options.rejectUnauthorized : true;
|
||||
this.checkServerIdentity = typeof options.checkServerIdentity == 'boolean'
|
||||
|| typeof options.checkServerIdentity == 'function' ? options.checkServerIdentity : true;
|
||||
|
||||
// If ssl not enabled
|
||||
if(!this.ssl) this.rejectUnauthorized = false;
|
||||
|
||||
// Response options
|
||||
this.responseOptions = {
|
||||
promoteLongs: typeof options.promoteLongs == 'boolean' ? options.promoteLongs : true
|
||||
}
|
||||
|
||||
// Flushing
|
||||
this.flushing = false;
|
||||
this.queue = [];
|
||||
|
||||
// Internal state
|
||||
this.connection = null;
|
||||
this.writeStream = null;
|
||||
}
|
||||
|
||||
inherits(Connection, EventEmitter);
|
||||
|
||||
//
|
||||
// Connection handlers
|
||||
var errorHandler = function(self) {
|
||||
return function(err) {
|
||||
// Debug information
|
||||
if(self.logger.isDebug()) self.logger.debug(f('connection %s for [%s:%s] errored out with [%s]', self.id, self.host, self.port, JSON.stringify(err)));
|
||||
// Emit the error
|
||||
if(self.listeners('error').length > 0) self.emit("error", MongoError.create(err), self);
|
||||
}
|
||||
}
|
||||
|
||||
var timeoutHandler = function(self) {
|
||||
return function() {
|
||||
// Debug information
|
||||
if(self.logger.isDebug()) self.logger.debug(f('connection %s for [%s:%s] timed out', self.id, self.host, self.port));
|
||||
// Emit timeout error
|
||||
self.emit("timeout"
|
||||
, MongoError.create(f("connection %s to %s:%s timed out", self.id, self.host, self.port))
|
||||
, self);
|
||||
}
|
||||
}
|
||||
|
||||
var closeHandler = function(self) {
|
||||
return function(hadError) {
|
||||
// Debug information
|
||||
if(self.logger.isDebug()) self.logger.debug(f('connection %s with for [%s:%s] closed', self.id, self.host, self.port));
|
||||
// Emit close event
|
||||
if(!hadError) {
|
||||
self.emit("close"
|
||||
, MongoError.create(f("connection %s to %s:%s closed", self.id, self.host, self.port))
|
||||
, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dataHandler = function(self) {
|
||||
return function(data) {
|
||||
// Parse until we are done with the data
|
||||
while(data.length > 0) {
|
||||
// If we still have bytes to read on the current message
|
||||
if(self.bytesRead > 0 && self.sizeOfMessage > 0) {
|
||||
// Calculate the amount of remaining bytes
|
||||
var remainingBytesToRead = self.sizeOfMessage - self.bytesRead;
|
||||
// Check if the current chunk contains the rest of the message
|
||||
if(remainingBytesToRead > data.length) {
|
||||
// Copy the new data into the exiting buffer (should have been allocated when we know the message size)
|
||||
data.copy(self.buffer, self.bytesRead);
|
||||
// Adjust the number of bytes read so it point to the correct index in the buffer
|
||||
self.bytesRead = self.bytesRead + data.length;
|
||||
|
||||
// Reset state of buffer
|
||||
data = new Buffer(0);
|
||||
} else {
|
||||
// Copy the missing part of the data into our current buffer
|
||||
data.copy(self.buffer, self.bytesRead, 0, remainingBytesToRead);
|
||||
// Slice the overflow into a new buffer that we will then re-parse
|
||||
data = data.slice(remainingBytesToRead);
|
||||
|
||||
// Emit current complete message
|
||||
try {
|
||||
var emitBuffer = self.buffer;
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Emit the buffer
|
||||
self.messageHandler(new Response(self.bson, emitBuffer, self.responseOptions), self);
|
||||
} catch(err) {
|
||||
var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
|
||||
sizeOfMessage:self.sizeOfMessage,
|
||||
bytesRead:self.bytesRead,
|
||||
stubBuffer:self.stubBuffer}};
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Stub buffer is kept in case we don't get enough bytes to determine the
|
||||
// size of the message (< 4 bytes)
|
||||
if(self.stubBuffer != null && self.stubBuffer.length > 0) {
|
||||
// If we have enough bytes to determine the message size let's do it
|
||||
if(self.stubBuffer.length + data.length > 4) {
|
||||
// Prepad the data
|
||||
var newData = new Buffer(self.stubBuffer.length + data.length);
|
||||
self.stubBuffer.copy(newData, 0);
|
||||
data.copy(newData, self.stubBuffer.length);
|
||||
// Reassign for parsing
|
||||
data = newData;
|
||||
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
|
||||
} else {
|
||||
|
||||
// Add the the bytes to the stub buffer
|
||||
var newStubBuffer = new Buffer(self.stubBuffer.length + data.length);
|
||||
// Copy existing stub buffer
|
||||
self.stubBuffer.copy(newStubBuffer, 0);
|
||||
// Copy missing part of the data
|
||||
data.copy(newStubBuffer, self.stubBuffer.length);
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
}
|
||||
} else {
|
||||
if(data.length > 4) {
|
||||
// Retrieve the message size
|
||||
// var sizeOfMessage = data.readUInt32LE(0);
|
||||
var sizeOfMessage = data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24;
|
||||
// If we have a negative sizeOfMessage emit error and return
|
||||
if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonMessageSize) {
|
||||
var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{
|
||||
sizeOfMessage: sizeOfMessage,
|
||||
bytesRead: self.bytesRead,
|
||||
stubBuffer: self.stubBuffer}};
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure that the size of message is larger than 0 and less than the max allowed
|
||||
if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonMessageSize && sizeOfMessage > data.length) {
|
||||
self.buffer = new Buffer(sizeOfMessage);
|
||||
// Copy all the data into the buffer
|
||||
data.copy(self.buffer, 0);
|
||||
// Update bytes read
|
||||
self.bytesRead = data.length;
|
||||
// Update sizeOfMessage
|
||||
self.sizeOfMessage = sizeOfMessage;
|
||||
// Ensure stub buffer is null
|
||||
self.stubBuffer = null;
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
|
||||
} else if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonMessageSize && sizeOfMessage == data.length) {
|
||||
try {
|
||||
var emitBuffer = data;
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
// Emit the message
|
||||
self.messageHandler(new Response(self.bson, emitBuffer, self.responseOptions), self);
|
||||
} catch (err) {
|
||||
var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
|
||||
sizeOfMessage:self.sizeOfMessage,
|
||||
bytesRead:self.bytesRead,
|
||||
stubBuffer:self.stubBuffer}};
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
}
|
||||
} else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxBsonMessageSize) {
|
||||
var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{
|
||||
sizeOfMessage:sizeOfMessage,
|
||||
bytesRead:0,
|
||||
buffer:null,
|
||||
stubBuffer:null}};
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
|
||||
// Clear out the state of the parser
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
} else {
|
||||
var emitBuffer = data.slice(0, sizeOfMessage);
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Copy rest of message
|
||||
data = data.slice(sizeOfMessage);
|
||||
// Emit the message
|
||||
self.messageHandler(new Response(self.bson, emitBuffer, self.responseOptions), self);
|
||||
}
|
||||
} else {
|
||||
// Create a buffer that contains the space for the non-complete message
|
||||
self.stubBuffer = new Buffer(data.length)
|
||||
// Copy the data to the stub buffer
|
||||
data.copy(self.stubBuffer, 0);
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect
|
||||
* @method
|
||||
*/
|
||||
Connection.prototype.connect = function(_options) {
|
||||
var self = this;
|
||||
_options = _options || {};
|
||||
// Check if we are overriding the promoteLongs
|
||||
if(typeof _options.promoteLongs == 'boolean') {
|
||||
self.responseOptions.promoteLongs = _options.promoteLongs;
|
||||
}
|
||||
|
||||
// Create new connection instance
|
||||
self.connection = self.domainSocket
|
||||
? net.createConnection(self.host)
|
||||
: net.createConnection(self.port, self.host);
|
||||
|
||||
// Set the options for the connection
|
||||
self.connection.setKeepAlive(self.keepAlive, self.keepAliveInitialDelay);
|
||||
self.connection.setTimeout(self.connectionTimeout);
|
||||
self.connection.setNoDelay(self.noDelay);
|
||||
|
||||
// If we have ssl enabled
|
||||
if(self.ssl) {
|
||||
var sslOptions = {
|
||||
socket: self.connection
|
||||
, rejectUnauthorized: self.rejectUnauthorized
|
||||
}
|
||||
|
||||
if(self.ca) sslOptions.ca = self.ca;
|
||||
if(self.cert) sslOptions.cert = self.cert;
|
||||
if(self.key) sslOptions.key = self.key;
|
||||
if(self.passphrase) sslOptions.passphrase = self.passphrase;
|
||||
|
||||
// Override checkServerIdentity behavior
|
||||
if(self.checkServerIdentity == false) {
|
||||
// Skip the identiy check by retuning undefined as per node documents
|
||||
// https://nodejs.org/api/tls.html#tls_tls_connect_options_callback
|
||||
sslOptions.checkServerIdentity = function(servername, cert) {
|
||||
return undefined;
|
||||
}
|
||||
} else if(typeof self.checkServerIdentity == 'function') {
|
||||
sslOptions.checkServerIdentity = self.checkServerIdentity;
|
||||
}
|
||||
|
||||
// Attempt SSL connection
|
||||
self.connection = tls.connect(self.port, self.host, sslOptions, function() {
|
||||
// Error on auth or skip
|
||||
if(self.connection.authorizationError && self.rejectUnauthorized) {
|
||||
return self.emit("error", self.connection.authorizationError, self, {ssl:true});
|
||||
}
|
||||
|
||||
// Set socket timeout instead of connection timeout
|
||||
self.connection.setTimeout(self.socketTimeout);
|
||||
// We are done emit connect
|
||||
self.emit('connect', self);
|
||||
});
|
||||
self.connection.setTimeout(self.connectionTimeout);
|
||||
} else {
|
||||
self.connection.on('connect', function() {
|
||||
// Set socket timeout instead of connection timeout
|
||||
self.connection.setTimeout(self.socketTimeout);
|
||||
// Emit connect event
|
||||
self.emit('connect', self);
|
||||
});
|
||||
}
|
||||
|
||||
// Add handlers for events
|
||||
self.connection.once('error', errorHandler(self));
|
||||
self.connection.once('timeout', timeoutHandler(self));
|
||||
self.connection.once('close', closeHandler(self));
|
||||
self.connection.on('data', dataHandler(self));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy connection
|
||||
* @method
|
||||
*/
|
||||
Connection.prototype.destroy = function() {
|
||||
if(this.connection) {
|
||||
this.connection.end();
|
||||
this.connection.destroy();
|
||||
}
|
||||
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to connection
|
||||
* @method
|
||||
* @param {Command} command Command to write out need to implement toBin and toBinUnified
|
||||
*/
|
||||
Connection.prototype.write = function(buffer) {
|
||||
// Debug Log
|
||||
if(this.logger.isDebug()) {
|
||||
if(!Array.isArray(buffer)) {
|
||||
this.logger.debug(f('writing buffer [%s] to %s:%s', buffer.toString('hex'), this.host, this.port));
|
||||
} else {
|
||||
for(var i = 0; i < buffer.length; i++)
|
||||
this.logger.debug(f('writing buffer [%s] to %s:%s', buffer[i].toString('hex'), this.host, this.port));
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the command
|
||||
if(!Array.isArray(buffer)) return this.connection.write(buffer, 'binary');
|
||||
// Iterate over all buffers and write them in order to the socket
|
||||
for(var i = 0; i < buffer.length; i++) this.connection.write(buffer[i], 'binary');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return id of connection as a string
|
||||
* @method
|
||||
* @return {string}
|
||||
*/
|
||||
Connection.prototype.toString = function() {
|
||||
return "" + this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return json object of connection
|
||||
* @method
|
||||
* @return {object}
|
||||
*/
|
||||
Connection.prototype.toJSON = function() {
|
||||
return {id: this.id, host: this.host, port: this.port};
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the connection connected
|
||||
* @method
|
||||
* @return {boolean}
|
||||
*/
|
||||
Connection.prototype.isConnected = function() {
|
||||
if(this.destroyed) return false;
|
||||
return !this.connection.destroyed && this.connection.writable;
|
||||
}
|
||||
|
||||
/**
|
||||
* A server connect event, used to verify that the connection is up and running
|
||||
*
|
||||
* @event Connection#connect
|
||||
* @type {Connection}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The server connection closed, all pool connections closed
|
||||
*
|
||||
* @event Connection#close
|
||||
* @type {Connection}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The server connection caused an error, all pool connections closed
|
||||
*
|
||||
* @event Connection#error
|
||||
* @type {Connection}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The server connection timed out, all pool connections closed
|
||||
*
|
||||
* @event Connection#timeout
|
||||
* @type {Connection}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The driver experienced an invalid message, all pool connections closed
|
||||
*
|
||||
* @event Connection#parseError
|
||||
* @type {Connection}
|
||||
*/
|
||||
|
||||
module.exports = Connection;
|
||||
196
node_modules/mongodb-core/lib/connection/logger.js
generated
vendored
Normal file
196
node_modules/mongodb-core/lib/connection/logger.js
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
"use strict";
|
||||
|
||||
var f = require('util').format
|
||||
, MongoError = require('../error');
|
||||
|
||||
// Filters for classes
|
||||
var classFilters = {};
|
||||
var filteredClasses = {};
|
||||
var level = null;
|
||||
// Save the process id
|
||||
var pid = process.pid;
|
||||
// current logger
|
||||
var currentLogger = null;
|
||||
|
||||
/**
|
||||
* Creates a new Logger instance
|
||||
* @class
|
||||
* @param {string} className The Class name associated with the logging instance
|
||||
* @param {object} [options=null] Optional settings.
|
||||
* @param {Function} [options.logger=null] Custom logger function;
|
||||
* @param {string} [options.loggerLevel=error] Override default global log level.
|
||||
* @return {Logger} a Logger instance.
|
||||
*/
|
||||
var Logger = function(className, options) {
|
||||
if(!(this instanceof Logger)) return new Logger(className, options);
|
||||
options = options || {};
|
||||
|
||||
// Current reference
|
||||
var self = this;
|
||||
this.className = className;
|
||||
|
||||
// Current logger
|
||||
if(currentLogger == null && options.logger) {
|
||||
currentLogger = options.logger;
|
||||
} else if(currentLogger == null) {
|
||||
currentLogger = console.log;
|
||||
}
|
||||
|
||||
// Set level of logging, default is error
|
||||
if(level == null) {
|
||||
level = options.loggerLevel || 'error';
|
||||
}
|
||||
|
||||
// Add all class names
|
||||
if(filteredClasses[this.className] == null) classFilters[this.className] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message at the debug level
|
||||
* @method
|
||||
* @param {string} message The message to log
|
||||
* @param {object} object additional meta data to log
|
||||
* @return {null}
|
||||
*/
|
||||
Logger.prototype.debug = function(message, object) {
|
||||
if(this.isDebug()
|
||||
&& ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
|
||||
|| (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
|
||||
var dateTime = new Date().getTime();
|
||||
var msg = f("[%s-%s:%s] %s %s", 'DEBUG', this.className, pid, dateTime, message);
|
||||
var state = {
|
||||
type: 'debug', message: message, className: this.className, pid: pid, date: dateTime
|
||||
};
|
||||
if(object) state.meta = object;
|
||||
currentLogger(msg, state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message at the info level
|
||||
* @method
|
||||
* @param {string} message The message to log
|
||||
* @param {object} object additional meta data to log
|
||||
* @return {null}
|
||||
*/
|
||||
Logger.prototype.info = function(message, object) {
|
||||
if(this.isInfo()
|
||||
&& ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
|
||||
|| (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
|
||||
var dateTime = new Date().getTime();
|
||||
var msg = f("[%s-%s:%s] %s %s", 'INFO', this.className, pid, dateTime, message);
|
||||
var state = {
|
||||
type: 'info', message: message, className: this.className, pid: pid, date: dateTime
|
||||
};
|
||||
if(object) state.meta = object;
|
||||
currentLogger(msg, state);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Log a message at the error level
|
||||
* @method
|
||||
* @param {string} message The message to log
|
||||
* @param {object} object additional meta data to log
|
||||
* @return {null}
|
||||
*/
|
||||
Logger.prototype.error = function(message, object) {
|
||||
if(this.isError()
|
||||
&& ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className])
|
||||
|| (Object.keys(filteredClasses).length == 0 && classFilters[this.className]))) {
|
||||
var dateTime = new Date().getTime();
|
||||
var msg = f("[%s-%s:%s] %s %s", 'ERROR', this.className, pid, dateTime, message);
|
||||
var state = {
|
||||
type: 'error', message: message, className: this.className, pid: pid, date: dateTime
|
||||
};
|
||||
if(object) state.meta = object;
|
||||
currentLogger(msg, state);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the logger set at info level
|
||||
* @method
|
||||
* @return {boolean}
|
||||
*/
|
||||
Logger.prototype.isInfo = function() {
|
||||
return level == 'info' || level == 'debug';
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the logger set at error level
|
||||
* @method
|
||||
* @return {boolean}
|
||||
*/
|
||||
Logger.prototype.isError = function() {
|
||||
return level == 'error' || level == 'info' || level == 'debug';
|
||||
},
|
||||
|
||||
/**
|
||||
* Is the logger set at debug level
|
||||
* @method
|
||||
* @return {boolean}
|
||||
*/
|
||||
Logger.prototype.isDebug = function() {
|
||||
return level == 'debug';
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the logger to default settings, error and no filtered classes
|
||||
* @method
|
||||
* @return {null}
|
||||
*/
|
||||
Logger.reset = function() {
|
||||
level = 'error';
|
||||
filteredClasses = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current logger function
|
||||
* @method
|
||||
* @return {function}
|
||||
*/
|
||||
Logger.currentLogger = function() {
|
||||
return currentLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current logger function
|
||||
* @method
|
||||
* @param {function} logger Logger function.
|
||||
* @return {null}
|
||||
*/
|
||||
Logger.setCurrentLogger = function(logger) {
|
||||
if(typeof logger != 'function') throw new MongoError("current logger must be a function");
|
||||
currentLogger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set what classes to log.
|
||||
* @method
|
||||
* @param {string} type The type of filter (currently only class)
|
||||
* @param {string[]} values The filters to apply
|
||||
* @return {null}
|
||||
*/
|
||||
Logger.filter = function(type, values) {
|
||||
if(type == 'class' && Array.isArray(values)) {
|
||||
filteredClasses = {};
|
||||
|
||||
values.forEach(function(x) {
|
||||
filteredClasses[x] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current log level
|
||||
* @method
|
||||
* @param {string} level Set current log level (debug, info, error)
|
||||
* @return {null}
|
||||
*/
|
||||
Logger.setLevel = function(_level) {
|
||||
if(_level != 'info' && _level != 'error' && _level != 'debug') throw new Error(f("%s is an illegal logging level", _level));
|
||||
level = _level;
|
||||
}
|
||||
|
||||
module.exports = Logger;
|
||||
321
node_modules/mongodb-core/lib/connection/pool.js
generated
vendored
Normal file
321
node_modules/mongodb-core/lib/connection/pool.js
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
"use strict";
|
||||
|
||||
var inherits = require('util').inherits
|
||||
, EventEmitter = require('events').EventEmitter
|
||||
, Connection = require('./connection')
|
||||
, Query = require('./commands').Query
|
||||
, Logger = require('./logger')
|
||||
, f = require('util').format;
|
||||
|
||||
var DISCONNECTED = 'disconnected';
|
||||
var CONNECTING = 'connecting';
|
||||
var CONNECTED = 'connected';
|
||||
var DESTROYED = 'destroyed';
|
||||
|
||||
var _id = 0;
|
||||
|
||||
/**
|
||||
* Creates a new Pool instance
|
||||
* @class
|
||||
* @param {string} options.host The server host
|
||||
* @param {number} options.port The server port
|
||||
* @param {number} [options.size=5] Server connection pool size
|
||||
* @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
|
||||
* @param {number} [options.keepAliveInitialDelay=0] Initial delay before TCP keep alive enabled
|
||||
* @param {boolean} [options.noDelay=true] TCP Connection no delay
|
||||
* @param {number} [options.connectionTimeout=0] TCP Connection timeout setting
|
||||
* @param {number} [options.socketTimeout=0] TCP Socket timeout setting
|
||||
* @param {boolean} [options.singleBufferSerializtion=true] Serialize into single buffer, trade of peak memory for serialization speed
|
||||
* @param {boolean} [options.ssl=false] Use SSL for connection
|
||||
* @param {boolean|function} [options.checkServerIdentity=true] Ensure we check server identify during SSL, set to false to disable checking. Only works for Node 0.12.x or higher. You can pass in a boolean or your own checkServerIdentity override function.
|
||||
* @param {Buffer} [options.ca] SSL Certificate store binary buffer
|
||||
* @param {Buffer} [options.cert] SSL Certificate binary buffer
|
||||
* @param {Buffer} [options.key] SSL Key file binary buffer
|
||||
* @param {string} [options.passPhrase] SSL Certificate pass phrase
|
||||
* @param {boolean} [options.rejectUnauthorized=false] Reject unauthorized server certificates
|
||||
* @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
|
||||
* @fires Pool#connect
|
||||
* @fires Pool#close
|
||||
* @fires Pool#error
|
||||
* @fires Pool#timeout
|
||||
* @fires Pool#parseError
|
||||
* @return {Pool} A cursor instance
|
||||
*/
|
||||
var Pool = function(options) {
|
||||
var self = this;
|
||||
// Add event listener
|
||||
EventEmitter.call(this);
|
||||
// Set empty if no options passed
|
||||
this.options = options || {};
|
||||
this.size = typeof options.size == 'number' && !isNaN(options.size) ? options.size : 5;
|
||||
|
||||
// Message handler
|
||||
this.messageHandler = options.messageHandler;
|
||||
// No bson parser passed in
|
||||
if(!options.bson) throw new Error("must pass in valid bson parser");
|
||||
// Contains all connections
|
||||
this.connections = [];
|
||||
this.state = DISCONNECTED;
|
||||
// Round robin index
|
||||
this.index = 0;
|
||||
this.dead = false;
|
||||
// Logger instance
|
||||
this.logger = Logger('Pool', options);
|
||||
// If we are monitoring this server we will create an exclusive reserved socket for that
|
||||
this.monitoring = typeof options.monitoring == 'boolean' ? options.monitoring : false;
|
||||
// Pool id
|
||||
this.id = _id++;
|
||||
// Grouping tag used for debugging purposes
|
||||
this.tag = options.tag;
|
||||
}
|
||||
|
||||
inherits(Pool, EventEmitter);
|
||||
|
||||
var errorHandler = function(self) {
|
||||
return function(err, connection) {
|
||||
if(self.logger.isDebug()) self.logger.debug(f('pool [%s] errored out [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
|
||||
if(!self.dead) {
|
||||
self.state = DISCONNECTED;
|
||||
self.dead = true;
|
||||
self.destroy();
|
||||
self.emit('error', err, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var timeoutHandler = function(self) {
|
||||
return function(err, connection) {
|
||||
if(self.logger.isDebug()) self.logger.debug(f('pool [%s] timed out [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
|
||||
if(!self.dead) {
|
||||
self.state = DISCONNECTED;
|
||||
self.dead = true;
|
||||
self.destroy();
|
||||
self.emit('timeout', err, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var closeHandler = function(self) {
|
||||
return function(err, connection) {
|
||||
if(self.logger.isDebug()) self.logger.debug(f('pool [%s] closed [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
|
||||
if(!self.dead) {
|
||||
self.state = DISCONNECTED;
|
||||
self.dead = true;
|
||||
self.destroy();
|
||||
self.emit('close', err, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var parseErrorHandler = function(self) {
|
||||
return function(err, connection) {
|
||||
if(self.logger.isDebug()) self.logger.debug(f('pool [%s] errored out [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
|
||||
if(!self.dead) {
|
||||
self.state = DISCONNECTED;
|
||||
self.dead = true;
|
||||
self.destroy();
|
||||
self.emit('parseError', err, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var connectHandler = function(self) {
|
||||
return function(connection) {
|
||||
self.connections.push(connection);
|
||||
// We have connected to all servers
|
||||
if(self.connections.length == self.size) {
|
||||
self.state = CONNECTED;
|
||||
// Done connecting
|
||||
self.emit("connect", self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy pool
|
||||
* @method
|
||||
*/
|
||||
Pool.prototype.destroy = function() {
|
||||
this.state = DESTROYED;
|
||||
// Set dead
|
||||
this.dead = true;
|
||||
// Destroy all the connections
|
||||
this.connections.forEach(function(c) {
|
||||
// Destroy all event emitters
|
||||
["close", "message", "error", "timeout", "parseError", "connect"].forEach(function(e) {
|
||||
c.removeAllListeners(e);
|
||||
});
|
||||
|
||||
// Destroy the connection
|
||||
c.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
var execute = null;
|
||||
|
||||
try {
|
||||
execute = setImmediate;
|
||||
} catch(err) {
|
||||
execute = process.nextTick;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect pool
|
||||
* @method
|
||||
*/
|
||||
Pool.prototype.connect = function(_options) {
|
||||
var self = this;
|
||||
// Set to connecting
|
||||
this.state = CONNECTING
|
||||
// No dead
|
||||
this.dead = false;
|
||||
|
||||
// Ensure we allow for a little time to setup connections
|
||||
var wait = 1;
|
||||
|
||||
// Connect all sockets
|
||||
for(var i = 0; i < this.size; i++) {
|
||||
setTimeout(function() {
|
||||
execute(function() {
|
||||
self.options.messageHandler = self.messageHandler;
|
||||
var connection = new Connection(self.options);
|
||||
|
||||
// Add all handlers
|
||||
connection.once('close', closeHandler(self));
|
||||
connection.once('error', errorHandler(self));
|
||||
connection.once('timeout', timeoutHandler(self));
|
||||
connection.once('parseError', parseErrorHandler(self));
|
||||
connection.on('connect', connectHandler(self));
|
||||
|
||||
// Start connection
|
||||
connection.connect(_options);
|
||||
});
|
||||
}, wait);
|
||||
|
||||
// wait for 1 miliseconds before attempting to connect, spacing out connections
|
||||
wait = wait + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pool connection (round-robin)
|
||||
* @method
|
||||
* @return {Connection}
|
||||
*/
|
||||
Pool.prototype.get = function(options) {
|
||||
options = options || {};
|
||||
|
||||
// Set the current index
|
||||
this.index = this.index + 1;
|
||||
|
||||
if(this.connections.length == 1) {
|
||||
return this.connections[0];
|
||||
} else if(this.monitoring && options.monitoring) {
|
||||
return this.connections[this.connections.length - 1];
|
||||
} else if(this.monitoring) {
|
||||
this.index = this.index % (this.connections.length - 1);
|
||||
return this.connections[this.index];
|
||||
} else {
|
||||
this.index = this.index % this.connections.length;
|
||||
return this.connections[this.index];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce the poolSize to the provided max connections value
|
||||
* @method
|
||||
* @param {number} maxConnections reduce the poolsize to maxConnections
|
||||
*/
|
||||
Pool.prototype.capConnections = function(maxConnections) {
|
||||
// Do we have more connections than specified slice it
|
||||
if(this.connections.length > maxConnections) {
|
||||
// Get the rest of the connections
|
||||
var connections = this.connections.slice(maxConnections);
|
||||
// Cap the active connections
|
||||
this.connections = this.connections.slice(0, maxConnections);
|
||||
|
||||
if (this.index >= maxConnections){
|
||||
// Go back to the beggining of the pool if capping connections
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
// Remove all listeners
|
||||
for(var i = 0; i < connections.length; i++) {
|
||||
connections[i].removeAllListeners('close');
|
||||
connections[i].removeAllListeners('error');
|
||||
connections[i].removeAllListeners('timeout');
|
||||
connections[i].removeAllListeners('parseError');
|
||||
connections[i].removeAllListeners('connect');
|
||||
connections[i].destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all pool connections
|
||||
* @method
|
||||
* @return {array}
|
||||
*/
|
||||
Pool.prototype.getAll = function() {
|
||||
return this.connections.slice(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the pool connected
|
||||
* @method
|
||||
* @return {boolean}
|
||||
*/
|
||||
Pool.prototype.isConnected = function() {
|
||||
for(var i = 0; i < this.connections.length; i++) {
|
||||
if(!this.connections[i].isConnected()) return false;
|
||||
}
|
||||
|
||||
return this.state == CONNECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was the pool destroyed
|
||||
* @method
|
||||
* @return {boolean}
|
||||
*/
|
||||
Pool.prototype.isDestroyed = function() {
|
||||
return this.state == DESTROYED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A server connect event, used to verify that the connection is up and running
|
||||
*
|
||||
* @event Pool#connect
|
||||
* @type {Pool}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The server connection closed, all pool connections closed
|
||||
*
|
||||
* @event Pool#close
|
||||
* @type {Pool}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The server connection caused an error, all pool connections closed
|
||||
*
|
||||
* @event Pool#error
|
||||
* @type {Pool}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The server connection timed out, all pool connections closed
|
||||
*
|
||||
* @event Pool#timeout
|
||||
* @type {Pool}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The driver experienced an invalid message, all pool connections closed
|
||||
*
|
||||
* @event Pool#parseError
|
||||
* @type {Pool}
|
||||
*/
|
||||
|
||||
module.exports = Pool;
|
||||
77
node_modules/mongodb-core/lib/connection/utils.js
generated
vendored
Normal file
77
node_modules/mongodb-core/lib/connection/utils.js
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
|
||||
// Set property function
|
||||
var setProperty = function(obj, prop, flag, values) {
|
||||
Object.defineProperty(obj, prop.name, {
|
||||
enumerable:true,
|
||||
set: function(value) {
|
||||
if(typeof value != 'boolean') throw new Error(f("%s required a boolean", prop.name));
|
||||
// Flip the bit to 1
|
||||
if(value == true) values.flags |= flag;
|
||||
// Flip the bit to 0 if it's set, otherwise ignore
|
||||
if(value == false && (values.flags & flag) == flag) values.flags ^= flag;
|
||||
prop.value = value;
|
||||
}
|
||||
, get: function() { return prop.value; }
|
||||
});
|
||||
}
|
||||
|
||||
// Set property function
|
||||
var getProperty = function(obj, propName, fieldName, values, func) {
|
||||
Object.defineProperty(obj, propName, {
|
||||
enumerable:true,
|
||||
get: function() {
|
||||
// Not parsed yet, parse it
|
||||
if(values[fieldName] == null && obj.isParsed && !obj.isParsed()) {
|
||||
obj.parse();
|
||||
}
|
||||
|
||||
// Do we have a post processing function
|
||||
if(typeof func == 'function') return func(values[fieldName]);
|
||||
// Return raw value
|
||||
return values[fieldName];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Set simple property
|
||||
var getSingleProperty = function(obj, name, value) {
|
||||
Object.defineProperty(obj, name, {
|
||||
enumerable:true,
|
||||
get: function() {
|
||||
return value
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Shallow copy
|
||||
var copy = function(fObj, tObj) {
|
||||
tObj = tObj || {};
|
||||
for(var name in fObj) tObj[name] = fObj[name];
|
||||
return tObj;
|
||||
}
|
||||
|
||||
var debugOptions = function(debugFields, options) {
|
||||
var finaloptions = {};
|
||||
debugFields.forEach(function(n) {
|
||||
finaloptions[n] = options[n];
|
||||
});
|
||||
|
||||
return finaloptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
var bindToCurrentDomain = function(callback) {
|
||||
var domain = process.domain;
|
||||
if(domain == null || callback == null) return callback;
|
||||
return domain.bind(callback);
|
||||
}
|
||||
|
||||
exports.setProperty = setProperty;
|
||||
exports.getProperty = getProperty;
|
||||
exports.getSingleProperty = getSingleProperty;
|
||||
exports.copy = copy;
|
||||
exports.bindToCurrentDomain = bindToCurrentDomain;
|
||||
exports.debugOptions = debugOptions;
|
||||
Reference in New Issue
Block a user